POIR
POIR

Reputation: 3190

Populate one dropdown list based on the selection of other dropdown

I am trying to populate one dropdown list based on the selection of other dropdown list. This is what I have till now.

This is the function that receive as a parameter the selected value for the first dropdownlist:

  [AcceptVerbs(HttpVerbs.Get)]
    public JsonResult GetTownsForCounty(string selectedCounty)
    {

        List<SelectListItem> list = new List<SelectListItem>();
        list.Add(new SelectListItem{Text=selectedCounty+"1", Value=selectedCounty+"1", Selected=false});
        list.Add(new SelectListItem{Text=selectedCounty+"2", Value=selectedCounty+"2", Selected=false});
        list.Add(new SelectListItem{Text=selectedCounty+"3", Value=selectedCounty+"3", Selected=false});

        var dropdowndata = list;

        return Json(dropdowndata, JsonRequestBehavior.AllowGet);
    }

In view:

@Html.DropDownListFor(item => item.County, counties)
@Html.DropDownListFor(item => item.Town, new List<SelectListItem>())

My javascript:

    $.get("/Subscription/GetTownsForCounty", { selectedCounty: county }, function (dropdowndata) {
        console.log(dropdowndata)

        var select = $("#Town");
        select.empty();
        $.each(dropdowndata, function (index, itemData) {
            select.append($('<option/>', {
                value: itemData.Value,
                text: itemData.Text
            }));
        });

    });

What am I doing wrong?

If I remove from route config next line it works:

  routes.MapRoute(name: "Subscription", 
    url: "subscription/{id}/{name}",
    defaults: new {
      controller="Subscription",
      action="Index",
      id=UrlParameter.Optional,
      name=UrlParameter.Optional});

If not, the response(dropdowndata) is the html of the page. Why?

Upvotes: 0

Views: 542

Answers (1)

xdumaine
xdumaine

Reputation: 10329

Answering your question about the route:

Your route that you remove has subscription/{id}/{name}, which means that when you try to request /Subscription/GetTownsForCounty, it's trying to pass GetTownsForCountry as the Id parameter to the Index action, instead of calling the GetTownsForCountry Action. When you remove this, it's probably falling back to the default route of {controller}/{action}/{id}, so that your request calls the correct action.

An important point:

You're trying to return JSON serialized SelectListItems which is not right. You should just return raw data as JSON, and build the select options on the client. It still works using SelectListItem, because it ends up just creating objects with those properties anyway, but you really shouldn't do it that way, because you're effectively creating controls, turned to data, turned to controls, which is not a good pattern.

[AcceptVerbs(HttpVerbs.Get)]
public JsonResult GetTownsForCounty(string selectedCounty)
{

    List<object> list = new List<object>();
    list.Add(new {Text=selectedCounty+"1", Value=selectedCounty+"1"});
    list.Add(new {Text=selectedCounty+"2", Value=selectedCounty+"2"});
    list.Add(new {Text=selectedCounty+"3", Value=selectedCounty+"3"});

    return Json(list, JsonRequestBehavior.AllowGet);
}

Upvotes: 2

Related Questions