Question

I'm currently trying to create a new set of cascading dropdown lists by following this tutorial : http://blogs.msdn.com/b/rickandy/archive/2012/01/09/cascasding-dropdownlist-in-asp-net-mvc.aspx

problem is it doesnt work and I'm basically illiterate on javascript (currently I dont have the time to sit and learn it), somehow the dropdown lists are not working, only the first one shows the first hierarchy info.

This is what I've done:

First the controller:

Here's the index method:

public ActionResult Index()
    {
        var list = repo.GetParentEstablishments();

         ViewBag.Parent = (new SelectList(list.ToArray(),"EstablishmentId","Name"));
        return View();

    }

Here's the method that's supposed to return the list of children for the selected father:

 [HttpPost]
    public ActionResult Children(int parentId)
    {
        var parents = repo.GetChildrenEstablishments(parentId);
        return Json(new SelectList(parents, "EstablishmentId", "Name"));
    }

Here's the view for the index method:

@using (Html.BeginForm("Index", "Ticket", FormMethod.Post, new { id =     "ParentChildrenFormID", data_childrenListAction = @Url.Action("ChildrenList") }))
{
<fieldset>
    <legend> Parent/Children</legend>
    @Html.DropDownList("Parents", ViewBag.Parent as SelectList, "Select a Parent", new {id="ParentsID"})
    <div id="ChildrenDivId">
        <label for="Children">Children </label>
        <select id="ChildrenID" name="Children"></select>
    </div>
    <p>
        <input type ="submit" value="Submit" id="SubmitID" />
    </p>
 </fieldset>
}
<script src ="@Url.Content("~/Scripts/parentChildren.js")"></script>

And finally here's the script file:

$(function () {

$('#ChildrenDivId').hide();
$('#SubmitID').hide();

$('#ParentsID').change(function () {
    var URL = $('#ParentChildrenFormID').data('childrenListAction');
    $.getJSON(URL + '/' + $('#ParentsID').val(), function (data) {
        var items = '<option>Select a Children</option>';
        $.each(data, function (i, child) {
            items += "<option value='" + child.value+ "'>" + child.Name + "</option>";
            // state.Value cannot contain ' character. We are OK because state.Value = cnt++;
        });
        $('#ChildrenID').html(items);
        $('#StatesDivID').show();

    });
});

$('#ChildrenID').change(function () {
    $('#SubmitID').show();
});
});

For what I've managed to understand from the javascript function, the div that has the label and dropdown for the children should appear hidden once the page is loaded and appear once the user selects a parent from the first list, currently this is not happening and instead everything shows up once the page is loaded. Also once I select a parent nothing happens on the second list, I can infer from this that the javascrip file is not being executed on the users browser, why isn't it being executed? what am I doing wrong?

Thank in advance, any help will be appreciated.

Was it helpful?

Solution

You have an error on the following line

items += "<option value='" + child.value + "'>" + child.Name + "</option>";

Which should be:

items += "<option value='" + child.Value + "'>" + child.Text + "</option>";

Since your controller action is returning a SelectList, this class is an IEnumerable<SelectListItem> where SelectListItem has 2 properties called Value and Text.

There's also another issue with your code. You have used the folllowing to construct the url to your controller action:

URL + '/' + $('#ParentsID').val()

which will result in an url of the form:

/SomeController/Children/123

But the action argument of your Children action is called parentId. If you are using the default route setup, only an {id} parameter will be sent as part og of the uri path (that's the default route pattern: {controller}/{action}/{id} and not {controller}/{action}/{parentid}). So you should either change your route setup or pass the parentId parameter like this:

$.getJSON(URL, { parentId: $('#ParentsID').val() }, function (data) {
    ...
});

Yet another issue with your code is that your Children conrtoller action is decorated with the [HttpPost] attribute but the $.getJSON method sends a GET request. So it won't work. You could use the $.post method instead:

$.post(URL, { parentId: $('#ParentsID').val() }, function (data) {
    ...
});

Another issue is that you are showing the StatesDivID but your actual div that was hidden is ChildrenDivId. Make sure you are showing the proper element:

$('#ChildrenDivId').show();

Also make sure you have the jQuery script referenced before your parentChildren.js script. Right now you have included your script inside the view but cannot see jQuery being included. Maybe you have it in your _Layout.

I would recommend you using a javascript debugging tool such as FireBug or Chrome developer toolbar to analyze your javascript code.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top