25

I have two dropdownlist. The selected value from the first one loads the other. How do I do that when I have the helper methods in a controller?

@using (Html.BeginForm())
{
<div>
    <table width="100%" cellpadding="0" cellspacing="0">
        <tr>
            <td><b>Select a District:</b></td>
            <td>@Html.DropDownListFor(m => m.DistrictId, ViewData["DMManagers"] as IEnumerable<SelectListItem>, "Select One")</td>
        </tr>
        <tr>
            <td><b>Select a TM:</b></td>
            <td>@Html.DropDownListFor(m => m.TMId, ViewData["TMManagers"] as IEnumerable<SelectListItem>, "Select One")</td>
        </tr>
    </table>
</div>
}

private void LoadDistrictManagers()
{
    var _DMS = (from c in SessionHandler.CurrentContext.ChannelGroups
                join cgt in SessionHandler.CurrentContext.ChannelGroupTypes on c.ChannelGroupTypeId equals cgt.ChannelGroupTypeId
                where cgt.Name == "District Manager"
                select new { c.ChannelGroupId, c.Name }).OrderBy(m => m.Name);
    ViewData["DMManagers"] = new SelectList(_DMS, "ChannelGroupId", "Name");
}

private void LoadTerritoryManagers(int districtId)
{
    var _TMS = (from c in SessionHandler.CurrentContext.ChannelGroups
                join cgt in SessionHandler.CurrentContext.ChannelGroupTypes on c.ChannelGroupTypeId equals cgt.ChannelGroupTypeId
                where cgt.Name == "Territory" && c.ParentChannelGroupId == districtId
                select new { c.ChannelGroupId, c.Name }).OrderBy(m => m.Name);
    ViewData["TMManagers"] = new SelectList(_TMS, "ChannelGroupId", "Name");
}

public ActionResult SummaryReport()
{
    DistrictManagerModel model = new DistrictManagerModel();
    LoadDistrictManagers();
    return View("AreaManager", model);
}
ArunPratap
  • 4,816
  • 7
  • 25
  • 43
bladerunner
  • 889
  • 4
  • 16
  • 25

3 Answers3

36

Give both dropdowns unique IDs using the HTTPAttributes field:

@Html.DropDownListFor(m => m.DistrictId, ViewData["DMManagers"] as IEnumerable<SelectListItem>, "Select One", new {@id="ddlDMManagers"})

2nd dropdown should be initialized as an empty list:

@Html.DropDownListFor(m => m.TMId, Enumerable.Empty<SelectListItem>(), new {@id="ddlTMManagers"})

If you don't mind using jQuery ajax to update the 2nd dropdown when a 'change' event is triggered on the 1st dropdown:

$(function() {
    $('select#ddlDMManagers').change(function() {
        var districtId = $(this).val();


        $.ajax({
            url: 'LoadTerritoryManagers',
            type: 'POST',
            data: JSON.stringify({ districtId: districtId }),
            dataType: 'json',
            contentType: 'application/json',
            success: function (data) {
                $.each(data, function (key, TMManagers) {
                    $('select#ddlTMManagers').append('<option value="0">Select One</option>');
                    // loop through the TM Managers and fill the dropdown
                    $.each(TMManagers, function(index, manager) {
                        $('select#ddlTMManagers').append(
                            '<option value="' + manager.Id + '">'
                            + manager.Name + 
                            '</option>');
                    });
                });
            }
        });
    });
});

Add this class to your controller namespace:

public class TMManager
{
    public int Id {get; set;}
    public string Name {get; set;}
}

You will need to update your controller action, LoadTerritoryManagers(), to respond to the ajax request and return a JSON array of {Id,Name} objects.

    [HttpPost]
    public ActionResult LoadTerritoryManagers(int districtId)
    {
        var _TMS = (from c in SessionHandler.CurrentContext.ChannelGroups
                join cgt in SessionHandler.CurrentContext.ChannelGroupTypes on c.ChannelGroupTypeId equals cgt.ChannelGroupTypeId
                where cgt.Name == "Territory" && c.ParentChannelGroupId == districtId
                select new TMManager(){ Id = c.ChannelGroupId, Name = c.Name }).OrderBy(m => m.Name);

        if (_TMS == null)
            return Json(null);

        List<TMManager> managers = (List<TMManager>)_TMS.ToList();
        return Json(managers);
    }
BumbleB2na
  • 10,723
  • 6
  • 28
  • 30
  • Thanks for your help..its not populating the TMs. Could it be this line in the jquery? $.post('/LoadTerritoryManagers', { districtId: districtId }, function (TMManagers)...The app builds fine but when i change the District, the TMs' is not populated. – bladerunner Apr 25 '11 at 22:34
  • I think so, and I can help you further in an hour. If you want, try putting a breakpoint in your LoadTerritoryManagers() function and see if the function is even reached. If not, then the problem is in the $.post() like you suspect. If it is reached, I would use Chrome Developer tools or Firebug to add a breakpoint to the $.post() line and step through the code to see what is happening.. – BumbleB2na Apr 25 '11 at 22:48
  • I just tweaked this line: $.post('LoadTerritoryManagers', {districtId: districtId }, function (TMManagers) {...Now whenever i change the district value, it keeps adding Select One to the second dropdown list... – bladerunner Apr 25 '11 at 22:52
  • Good it's close. I updated the line for the $.each() statement. Try that. If that doesn't work, try TMManagers.d instead of TMManagers as in: $.each(TMManagers.d, function(..... – BumbleB2na Apr 25 '11 at 23:00
  • when i try the one you edited, the dropdownlist get filled with undefined...with the one above, i changed $.each(TMManagers.d, function(... this doesn't work. I think you are very close to make this work..thanks again for your help. – bladerunner Apr 25 '11 at 23:04
  • Hi BumbleB2na, i took your refactored code..it comes up with select one, undefined, select one, undefined in the dropdownlist. When i set a breakpoint on LoadTerritoryManagers, the districtId from the dropdownlist is passed, Also, the List is populated with the TMs' for that district. It could be in the jquery function..this line here $.each(data, function(key, TMManagers) thats not working..we are very close. – bladerunner Apr 26 '11 at 13:08
  • i tweaked this code..$.each(data, function (key, TMManagers) { $('select#ddlTMManagers').append(''); // loop through the TM Managers and fill the dropdown $.each(TMManagers, function (key, value) { $('select#ddlTMManagers').append( ''); }); – bladerunner Apr 26 '11 at 13:18
  • Now this is coming back with TM names but there are still some select one and some ids that i need to fix.. – bladerunner Apr 26 '11 at 13:19
  • After changing the script to $('select#ddlTMManagers').append(''); $.each(data, function (key, TMManagers) { $.each(TMManagers, function (key, value) { $('select#ddlTMManagers').append( ''); }); }); I get in my dropdownlist id, name, id, name...for example 34, Rob Smith, 45, Allen Border.... – bladerunner Apr 26 '11 at 13:30
  • after playing with the script, it looks like its fixed. i tweaked this code to success: function (data) { $('select#ddlTMManagers').append(''); $.each(data, function (val, TMManagers) { $('select#ddlTMManagers').append(''); }); }...now i see just the TM names in the dropdownlist..thanks a bunch for your help. I am going to tweak your code up above. – bladerunner Apr 26 '11 at 14:03
  • Hi BumbleB2na, is it possible to have couple more dropdowns and have the onchange event for them? So, in my scenario, i would probably have a dropdownlist for dealers that would be populated based on the value selected from the TMManagers dropdownlist. – bladerunner Apr 26 '11 at 21:19
  • Yes, you just have to duplicate exactly what you did for TMManagers dropdown. – BumbleB2na Apr 26 '11 at 22:30
1

Use the following code. It is used in my project. For Zone and Region I used two drop-down list. On change Zone data I loaded the Region drop-down.

In View page

 @Html.DropDownList("ddlZone", new SelectList(@ViewBag.Zone, "Zone_Code", "Zone_Name"), "--Select--", new { @class = "LoginDropDown" })

 @Html.DropDownList("ddlRegion", Enumerable.Empty<SelectListItem>(), new { @class = "LoginDropDown" })

The Zone need to load when the view page is load.

In the controller write this method for Region Load

 [WebMethod]
        public JsonResult LoadRegion(string zoneCode)
        {
            ArrayList arl = new ArrayList();

            RASolarERPData objDal = new RASolarERPData();
            List<tbl_Region> region = new List<tbl_Region>();

            region = erpDal.RegionByZoneCode(zoneCode);

            foreach (tbl_Region rg in region)
            {
                arl.Add(new { Value = rg.Reg_Code.ToString(), Display = rg.Reg_Name });
            }

            return new JsonResult { Data = arl };
        }

Then use the following JavaScript

<script type="text/javascript">

        $(document).ready(function () {

        $('#ddlZone').change(function () {
            LoadRegion(this.value);
        });

        function LoadRegion(zoneCode) {

            $.ajax({
                type: "POST",
                url: '@Url.Action("LoadRegion", "RSFSecurity")',
                data: "{'zoneCode':'" + zoneCode + "'}",
                contentType: "application/json; charset=utf-8",
                dataType: 'json',
                cache: false,
                success: function (data) {
                    $('#ddlRegion').get(0).options.length = 0;
                    $('#ddlRegion').get(0).options[0] = new Option("--Select--", "0");

                    $.map(data, function (item) {
                        $('#ddlRegion').get(0).options[$('#ddlRegion').get(0).options.length] = new Option(item.Display, item.Value);
                    });
                },
                error: function () {
                    alert("Failed to load Item");
                }
            });
        }

    });

</script>
Md. Nazrul Islam
  • 2,809
  • 26
  • 31
1

We can use the jquery to get and fill the dropdown like this:

<script>
  function FillCity() {
    var stateId = $('#State').val();
    $.ajax({
        url: '/Employees/FillCity',
        type: "GET",
        dataType: "JSON",
        data: { State: stateId},
        success: function (cities) {                    
            $("#City").html(""); // clear before appending new list 
            $.each(cities, function (i, city) {
                $("#City").append(
                    $('<option></option>').val(city.CityId).html(city.CityName));
            });
        }
    });
  }
</script>

For more detail see MVC DropDownListFor fill on selection change of another dropdown

Ali Adravi
  • 21,707
  • 9
  • 87
  • 85