Where to put ajax scripts for forms (what controller) in mvc?

300 Views Asked by At

This is my situation: I have a single view (lets call it view V) with a formform with multiple combo box for selecting some parameters.

I want to load the options of those combo box via AJAX calls dynamically (selecting one item on a combobox will load the other ones with data)

Each combobox makes an AJAX request to a different controller (which in turn call on different models to fetch the data) on the framework. Lets call those controllers C1, C2, C3 and the models M1, M2, M3.

These AJAX scripts on C1, C2 and C3 are very likely to be used on other views on the future

But i have my doubts if this is the correct way to go. Where do i put those AJAX scripts? On each controller or a separate one (probably called FormAPI or something like that)

Putting one ajax script on each controller i am coupling V with C1, C2 and C3, while making one controller for the three requests will only couple my view V with one controller. Also, from my point of view, such controller will be highly cohesive.

However, i am probably not keeping my code DRY because C1, C2 and C3 already have some logic to recieve requests of the type "get list of M1, M2 and M3", which i could render as JSON and return it to the view V

What happens in the future if i have another view V2 that needs requests to C1, C2, C3, ... CN? I think soon my code will be "spaghetti coupled"

What do you think?

Another question: Should i have logic on M1, M2, M3 to get arrays and lists of items? For instance, if M1 has multiple instances of M2, is it correct to create a method M1->getM2asArray()

1

There are 1 best solutions below

4
On

I had a similar case but it wasn’t combo-box it was with auto-completes, All scripts would be the scripts folder, reference to the script file in the mvc views.

I have several autocompletes on my MVC, I added one controller named it AutoCompleteController (that return Json data) and added jQuery & my custom script on the Layout page so they can be used on all the pages (In my application 90% of the pages have the autocomplete)

Example of my autocomplete controller

namespace ADM.Ntrasal.Web.UI.Browser.Controllers
{
    public class AutoCompleteController : Controller
    {
         private readonly IRepositories Repositories;
         public AutoCompleteController()
        {  //Prefare to use Ioc but for simplicity
            this.Repositories = new Repositories();
        }
        //
        // GET: /AutoComplete/

        public ActionResult EmployeeNames(string term)
        {
            var count = 10;
            var UserProfileRepostery = this.Repositories.Create<UserProfile>();


            var result = UserProfileRepostery.GetAll().Where(x =>
                  x.Employee_Name.ToLower().Contains(term.ToLower()))
              .Take(count).Select(x =>
                  new
                  {
                      label = x.Employee_Name,
                      id = x.UserID
                  });
            return Json(result, JsonRequestBehavior.AllowGet);
        }

    }
}

I made one AutoCompleteViewModule

public class AutoCompleteViewModule
{
public AutoCompleteViewModule()
{
    //default values
    AutocompleteCount = 10;
    Type = AutoCompleteTypes.EmployeeNames;
}
public string Id { get; set; }
public string Name { get; set; }
public string Field { get; set; }
public int AutocompleteCount { get; set; }
public AutoCompleteTypes Type { get; set; }

I added an editor template to manage the autocomplete output html

@model ADM.Ntrasal.UI.Web.Browser.Models.AutoCompleteViewModule
 <input type="text"  name="AutocompleteTextBox"
     data-target='@Model.Field'
     data-autocomplete="@Url.Action(@Model.Type.ToString(), 
     "AutoComplete", new { count =    @Model.AutocompleteCount })"
     value='@Model.Name' />
@Html.Hidden(@Model.Field)

If I don’t want to add the needed script for the autocomplete, I will put it in an optional section and reference the script whenever on any view I need an auto-complete.

I will use the below in my views:

@Html.EditorFor(x=>@Model.AutocompleteField)

I blogged about this in detail, I can put a link if you see it is helpful

For the second question, I will get the data in each Model as you suggested and call it in my autocomplete controller so it will provide the needed data for the autocomplete template (or partial view)