Search code examples
c#linq-to-sqlasp.net-mvc-3jquerycascadingdropdown

3 Dropdown List cascade using MVC3 & LinqSql


I have 3 dropdownlist i wanna make 3 dropdownlist with cascade. I am using LinqSql for database..

I have 3 tables Product(id,name), Design(id,master_id,name), Model(id,design_id,name) master_id bound to Product(id), design_id bound to Design(id)..

I want to create one dropdown which is gonna show Products and than when i choose a product its gonna make Design dropdown enabled else it will stay disabled.. also here is the tricky part that i couldnt solve and i need great explanation in here creating 3rd dropdown which is gonna be disabled normally till a Design is chosen.

Each of them gonna populate a lower dropdownlist bound to them.Its like; Product gonna enable and populate Design, Design gonna enable and populate Model. I can do it with 2 dropdowns but when it comes to 3 dropdown i stuck really badly im on (brain-freeze)..

I already checked the other questions couldnt find any solution for my self. As i said im using LinqSql i need a solution about 3 cascadingdropdown list for this type of data reach.

thanks already for anything u can do! and if u can explain Model-View-Controller partials and the parameters and why you use them that would be awesome. Iam kinda beginner at this MVC3.


Solution

  • I would approach the problem something like this:

    First, in the controller, we'll set up have the following methods:

    public JsonResult GetDesignsForProduct(int productId)
    {
      // Instantiate our context and do whatever goo we need to select the objects we want
      using (MyDatabaseContext ctx = new MyDatabaseContext())
      {
         return Json(ctx.Designs.Where(d => d.master_id == productId).ToList(), JsonRequestBehavior.AllowGet);
      }
    }
    
    public JsonResult GetModelsForDesign(int designId)
    {
      // Instantiate our context and do whatever goo we need to select the objects we want
      using (MyDatabaseContext ctx = new MyDatabaseContext())
      {
         return Json(ctx.Models.Where(d => d.design_id == designId).ToList(), JsonRequestBehavior.AllowGet);
      }
    }
    

    I've turned on "get" here; if your data contains sensitive information - user names/e-mail addresses, other proprietary or legally protected data, etc. - you can change this to only allow "post", and modify your Javascript accordingly. See Phil Haack's article.

    Also, if you expect this data to change frequently, these methods will cache it by default according to your application's cache settings. You can add an OutputCache attribute on the method to alter this behavior.

    Then, in the view you'll have some AJAX plumbing, something like this:

    function LoadDesigns() {
        // Get the currently-selected value in our Product dropdown
        var prod = $("#Product").val();
    
        // Call our controller method and process the list of Design objects
        $.getJSON('@Url.Content("~/ControllerName/GetDesignsForProduct")', { productId: prod },
            function (designs) {
                $("#Design").empty();
                $.each(designs, function (i, c) {
                    $("#Design").append(
                        $('<option></option>').val(c.id).html(c.name)
                    );
                });
        });
    }
    
    function LoadModels() {
        // Get the currently-selected value in our Design dropdown
        var des = $("#Design").val();
    
        // Call our controller method and process the list of Model objects
        $.getJSON('@Url.Content("~/ControllerName/GetModelsForDesign")', { designId: des },
            function (models) {
                $("#Model").empty();
                $.each(models, function (i, c) {
                    $("#Model").append(
                        $('<option></option>').val(c.id).html(c.name)
                    );
                });
        });
    }
    

    Finally, define all three drop-downs as follows:

    @Html.DropDownList("Product", productSelectList, new { onchange = "LoadDesigns()" })
    @Html.DropDownList("Design", null, new { onchange = "LoadModels()" })
    @Html.DropDownList("Model")
    

    Don't forget that the HTML helpers are really just shortcuts to generate the underlying HTML, and in Razor you frequently just go straight to HTML instead of messing with the helpers. So you could just as easily write these as:

    <select id="Product" onchange="LoadDesigns()">
      @foreach (var prod in products) {
        <option value="@prod.id">@prod.name</option>
      }
    </select>
    
    <select id="Design" onchange="LoadModels()"></select>
    
    <select id="Model"></select>