5

In an ASP .NET MVC Razor view, I have a dropdown list as follows:

@Html.DropDownListFor(model => model.SelectedDeviceModel, Model.DeviceModelList)

DeviceModelList is just a SelectList.

How can I dynamically fill the DeviceModelList depending on a client side action like a button click or another drop down selection using Javascript/jQuery/Ajax?

dnatoli
  • 6,972
  • 9
  • 57
  • 96

1 Answers1

11

You could externalize this dropdown into a partial:

@model MyViewModel
@Html.DropDownListFor(model => model.SelectedDeviceModel, Model.DeviceModelList)

then in your main view include it inside some container:

@model MyViewModel
...
<div id="ddlcontainer">
    @Html.Partial("Foo", Model)
</div>
...

then you could have a controller action which takes some parameter and based on its value it renders this partial:

public ActionResult Foo(string someValue)
{
    MyViewModel model = ... go ahead and fill your view model
    return PartialView(model);
}

Now the last part is to send the AJAX request to refresh the drop down list when some event occurs. For example when the value of some other ddl changes (or something else, a button click or whatever):

$(function() {
    $('#SomeOtherDdlId').change(function() {
        // when the selection of some other drop down changes 
        // get the new value
        var value = $(this).val();

        // and send it as AJAX request to the newly created action
        $.ajax({
            url: '@Url.Action("foo")',
            type: 'POST',
            data: { someValue: value },
            success: function(result) {
                // when the AJAX succeeds refresh the ddl container with
                // the partial HTML returned by the Foo controller action
                $('#ddlcontainer').html(result);
            }
        });
    });
});

Another possibility consists into using JSON. Your Foo controller action would only return some Json object containing the new key/value collection and in the success callback of the AJAX request you would refresh the drop down list. In this case you don't need to externalize it into a separate partial. For example:

$(function() {
    $('#SomeOtherDdlId').change(function() {
        // when the selection of some other drop down changes 
        // get the new value
        var value = $(this).val();

        // and send it as AJAX request to the newly created action
        $.ajax({
            url: '@Url.Action("foo")',
            type: 'POST',
            data: { someValue: value },
            success: function(result) {
                // when the AJAX succeeds refresh the dropdown list with 
                // the JSON values returned from the controller action
                var selectedDeviceModel = $('#SelectedDeviceModel');
                selectedDeviceModel.empty();
                $.each(result, function(index, item) {
                    selectedDeviceModel.append(
                        $('<option/>', {
                            value: item.value,
                            text: item.text
                        })
                    );
                });
            }
        });
    });
});

and finally your Foo controller action will return Json:

public ActionResult Foo(string someValue)
{
    return Json(new[] {
        new { value = '1', text = 'text 1' },
        new { value = '2', text = 'text 2' },
        new { value = '3', text = 'text 3' }
    });
}

For a similar example you may take a look at the following answer.

Community
  • 1
  • 1
Darin Dimitrov
  • 1,023,142
  • 271
  • 3,287
  • 2,928
  • Using the partial was the way to go for me. Thanks! – dnatoli Aug 31 '11 at 07:12
  • @DarinDimitrov I've implemented your solution however I've added a second ajax request because based on the users drop down selection another ddl gets populated with values. My problem is that the second ajax request is not firing. Do you know why? – codingNightmares Feb 24 '14 at 19:07