ASP.NET: AJAX Cascading Dropdownlist with Autosuggest using Jquery




Cascading dropdownlists are a set of dropdownlist controls in which each dropdownlist is populated based on another dropdownlist's selected item and the best approach to implement this is without refreshing the whole page in AJAX way. There are several ways in which we can achieve this such as using AJAX Toolkit's CascadingDropdown extender along with ASP.NET dropdownlist, using dropdownlist in an UpdatePanel and using jquery to make AJAX calls to populate dropdownlist. One more feature that is desirable in a dropdownlist is the autocomplete functionality, that can help the user to get to the right option without scrolling much especially when there are lot of items in the dropdownlist.

In this post, I am going to explain with an example on how to implement cascading dropdownlist using jquery and apply autocomplete feature using Select2 jquery plugin in the client side. We are going to populate the dropdownlists by making jquery ajax calls to server side method(WebMethod) and enable autocomplete feature in client side using Select2 jquery plugin.
1.  First of all let us download all the required libraries,

a. jQuery
b. Select2

2. Place the above downloaded libraries inside your asp.net project folder.


3. Let us now create two model classes, that would serve the data required for the dropdownlists. The first dropdownlist will contain items that are departments and the other will contain items that are subjects corresponding to the department that is selected in the first dropdownlist. Department dropdownlist will be populated on page load and subjects dropdownlist will be populated whenever an item is selected in the department dropdownlist by making ajax calls to the server.

Department.cs

namespace CascadingAutoCompleteSample
{
    public class Department
    {
        public string dptName { get; set; }
        public string dptAliasName { get; set; }

        public List<Department> GetDepartment()
        {
            return new List<Department>
            {
                new Department {
                    dptName = "Aeronautical Engineering",
                    dptAliasName = "AE"
                },
                new Department {
                    dptName = "Biomedical Engineering",
                    dptAliasName = "BME"
                },
                new Department {
                    dptName = "Computer Science Engineering",
                    dptAliasName = "CSE"
                },
                new Department{
                    dptName = "Information Technology",
                    dptAliasName = "IT"
                },
                 new Department{
                    dptName = "Mechanical Engineering",
                    dptAliasName = "MECH"
                },
                 new Department{
                    dptName = "Electronics and Communication Engineering",
                    dptAliasName = "ECE"
                }
            }.ToList();
        }
    }
}

Subjects.cs

namespace CascadingAutoCompleteSample
{
    public class Subjects
    {
        public string deptAliasName { get; set; }
        public string subName { get; set; }
        public string subAliasName { get; set; }

        public List<Subjects> GetSubjects()
        {
            return new List<Subjects>
            {
                new Subjects {
                    deptAliasName="AE",
                    subName = "Fluid Mechanics",
                    subAliasName = "FM"
                },
                new Subjects {
                    deptAliasName="AE",
                    subName = "Aircraft System",
                    subAliasName = "AS"
                },
                new Subjects {
                    deptAliasName="AE",
                    subName = "Helicopter Theory",
                    subAliasName = "HT"
                },
                new Subjects {
                    deptAliasName="BME",
                    subName = "Bio Analytical Techniques",
                    subAliasName = "BAT"
                },
                new Subjects {
                    deptAliasName="BME",
                    subName = "Bio Signal Processing",
                    subAliasName = "BSP"
                },
                new Subjects {
                    deptAliasName="CSE",
                    subName = "Data Structures & Algorithms",
                    subAliasName = "DSA"
                },
                new Subjects{
                    deptAliasName="CSE",
                    subName = "Computer Architecture",
                    subAliasName = "CO"
                },
                 new Subjects{
                    deptAliasName="CSE",
                    subName = "Artificial Intelligence",
                    subAliasName = "AI"
                },
                 new Subjects{
                     deptAliasName="CSE",
                    subName = "Fundamentals of Computing",
                    subAliasName = "FOC"
                },
                new Subjects{
                     deptAliasName="IT",
                    subName = "Numerical Methods",
                    subAliasName = "NM"
                },
                new Subjects{
                     deptAliasName="IT",
                    subName = "Fundamentals of Computing",
                    subAliasName = "FOC"
                },
                new Subjects{
                    deptAliasName="IT",
                    subName="Priciples of Communication",
                    subAliasName="POC"
                },
                new Subjects{
                     deptAliasName="MECH",
                    subName = "Measurements and Controls",
                    subAliasName = "MC"
                },
                new Subjects{
                     deptAliasName="MECH",
                    subName = "Machine Tools",
                    subAliasName = "MT"
                },
                new Subjects{
                     deptAliasName="ECE",
                    subName = "Electronic Devices & Circuits",
                    subAliasName = "EDC"
                },
                new Subjects{
                     deptAliasName="ECE",
                    subName = "Electro Magnetic Theory",
                    subAliasName = "EMT"
                }
                
            }.ToList();
        }
    }
}

Data is hard coded in these classes, you can also modify this to fetch items from a database if you prefer.

4. Let us create an aspx page with two dropdownlists and script to make ajax calls to server to populate one of it based on the other. The script will also convert these dropdownlists in to rich dropdownlists that enables the user to search for an item in it.

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>Cascading AutoComplete DropDownlist using jQuery</title>
    <link href="Styles/select2.css" rel="stylesheet" />
    <script src="Scripts/jquery-1.9.1.js"></script>
    <script src="Scripts/select2.js"></script>
    <script type="text/javascript">
        $(function () {
            var $ddl = $("select[name$=ddlDepartment]");
            $ddl.select2();
            var $ddlSub = $("select[name$=ddlSubject]");            
            $ddl.focus();
            $ddl.bind("change keyup", function () {
                loadSubjects($("select option:selected").val());
                $ddlSub.fadeIn("slow");


            });
        });
        function loadSubjects(selectedItem) {
            $.ajax({
                type: "POST",
                url: "CascadingAutocomplete.aspx/GetSubjectList",
                data: "{deptAliasName:'" + selectedItem + "'}",
                contentType: "application/json; charset=utf-8",
                dataType: "json",
                async: true,
                success: function (data) {
                    printSub(data.d);

                },
                error: function (xhr, status, err) {
                    var err = eval("(" + xhr.responseText + ")");
                    alert(err.Message);

                }
            });
        }
        function printSub(data) {
            $("select[name*=ddlSubject] > option").remove();
            $("select[name*=ddlSubject]").append(
                $("<option></option>").val("Select Subject").html("Select Subject")
                );
            for (var i = 0; i < data.length; i++) {
                $("select[name*=ddlSubject]").append(
                    $("<option></option>").val(data[i].subAliasName).html(data[i].subName)
                );
            }           
            $("#subjectdiv").css("display","block");
            $("select[name$=ddlSubject]").select2();
        }

    </script>
</head>
<body>
    <form id="form1" runat="server">
    <div style="text-align:center">
         <h1>Cascading AutoComplete in ASP.NET using jQuery</h1>
        Select Department : 
        <asp:DropDownList ID="ddlDepartment" runat="server" Width="280px">
        </asp:DropDownList>
        <br/>
        Select Subject :
      <asp:DropDownList ID="ddlSubject" runat="server" Width="280px" >           
        </asp:DropDownList>
       
    </div>       
    </form>
</body>
</html>

Let us take a close look on the jquery script that makes ajax calls to populate the second dropdownlist. The loadSubjects method is fired whenever an user selects or changes value in the first dropdownlist and makes ajax call to method that is declared as WebMethod in the code behind page(CascadingAutocomplete.aspx/GetSubjectList). Once the data is fetched from server side, printSub method in the above script updates user interface in this case the second dropdownlist with the response. Both the dropdownlists are enabled with autosuggest feature using select2 plugin.

5. Now in the code behind page let us write code that is called by the jquery script to fetch data for the Subjects dropdownlist. Note that to call a server side method, the method should be declared as a WebMethod.

using System.Web.Services;
using System.Web.Script.Services;


namespace CascadingAutoCompleteSample
{
    public partial class CascadingAutocomplete : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            Department dept = new Department();
            List<Department> lstDept = dept.GetDepartment();
            ddlDepartment.DataSource = lstDept;
            ddlDepartment.DataTextField = "dptName";
            ddlDepartment.DataValueField = "dptAliasName";
            ddlDepartment.DataBind();
            ddlDepartment.Items.Insert(0, new ListItem("Select Department", "Select Department"));
            ddlDepartment.SelectedItem.Text = "Select Department";


        }


        [WebMethod]
        [ScriptMethod(UseHttpGet = false, ResponseFormat = ResponseFormat.Json)]
        public static List<Subjects> GetSubjectList(string deptAliasName)
        {
            Subjects sub = new Subjects();
            List<Subjects> lstSubs = sub.GetSubjects().Where(x => x.deptAliasName == deptAliasName).ToList();
            return lstSubs;
        }

    }
}

That is all. See below screenshots or try the live demo to know how the outcome of the above implementation will look like,




Please leave your comments and queries about this post in the comment sections in order for me to improve my writing skills and to showcase more useful posts. Thanks for reading!!
 
>

Subscribe to GET LATEST ARTICLES!


Related

Jquery 7915741274987572667

Post a Comment

  1. Very Nice and useful article.Keep going

    ReplyDelete
  2. very good initiative from you.

    ReplyDelete
  3. Hi Priya
    I try to used the above in of my page which included in master page, In that I am using jquery treeview plugin, I am facing some problems while implementing the selects().
    Can you please help regarding this.

    Thanks
    Prakash

    ReplyDelete
    Replies
    1. Please explain your problem and post your code at http://forums.asp.net for immediate help on this by experts.

      Delete
  4. Hi Priya- if I like to capture my selection i.e. Department and the Subject after user has chosen both, how can I do that? I am trying to implement this example but the issue I am having is to bind the capture the change keyup (user's selection) for the last dropdown list.

    Thanks for your help in advance !

    ReplyDelete
  5. Or to put it simply, how should I print (alert) chosen Department and Subject on the screen every time I change the department and/or subject.

    ReplyDelete
    Replies
    1. Hi,

      You can edit the script in this example like this to throw an alert when the user selects a department or subject,

      <script type="text/javascript">
      $(function () {
      var $ddl = $("select[name$=ddlDepartment]");
      $ddl.select2();
      var $ddlSub = $("select[name$=ddlSubject]");
      $ddl.focus();
      $ddl.bind("change keyup", function () {
      loadSubjects($("select option:selected").val());
      $ddlSub.fadeIn("slow");
      });
      //this alerts the selected subject
      $ddlSub.bind("change keyup", function () {
      alert($("select option:selected").val());
      });
      });
      function loadSubjects(selectedItem) {
      alert(selecteditem);// This alerts the selected department
      $.ajax({
      type: "POST",
      url: "CascadingAutocomplete.aspx/GetSubjectList",
      data: "{deptAliasName:'" + selectedItem + "'}",
      contentType: "application/json; charset=utf-8",
      dataType: "json",
      async: true,
      success: function (data) {
      printSub(data.d);

      },
      error: function (xhr, status, err) {
      var err = eval("(" + xhr.responseText + ")");
      alert(err.Message);

      }
      });
      }
      function printSub(data) {
      $("select[name*=ddlSubject] > option").remove();
      $("select[name*=ddlSubject]").append(
      $("<option></option>").val("Select Subject").html("Select Subject")
      );
      for (var i = 0; i < data.length; i++) {
      $("select[name*=ddlSubject]").append(
      $("<option></option>").val(data[i].subAliasName).html(data[i].subName)
      );
      }
      $("#subjectdiv").css("display","block");
      $("select[name$=ddlSubject]").select2();
      }
      </script>


      Hope this helps!

      Thanks,
      Priya

      Delete
  6. Thanks for the quick response. I'll try it and let you know.

    ReplyDelete
  7. //added these variables for lower levels criteria //
    var selectedDeptNbr;
    var selectedSubDeptNbr;
    var selectedClassNbr;
    var selectedSubClassNbr;
    $(function () {
    var $ddlDeptLst = $("select[name$=ddlDepartment]"); //dept
    var $ddlSubDeptLst = $("select[name$=ddlSubDepartment]"); //subdept
    var $ddlClassLst = $("select[name$=ddlClass]"); //class
    var $ddlSubClassLst = $("select[names$=ddlSubClass]"); //subclass
    $ddlDeptLst.select2();
    $ddlDeptLst.focus();
    $ddlDeptLst.bind("change keyup", function () {
    $("#classdiv").css("display", "none");
    $("#subclassdiv").css("display", "none");
    selectedDeptNbr = $('#deptdiv option:selected').val();
    loadSubDepts($('#deptdiv option:selected').val());
    $ddlSubDeptLst.fadeIn("slow");
    $ddlSubDeptLst.focus();
    });

    $ddlSubDeptLst.bind("change keyup", function () {
    $("#subclassdiv").css("display", "none");
    selectedSubDeptNbr = $('#subdeptdiv option:selected').val();
    loadClasses($("#subdeptdiv option:selected").val());
    $ddlClassLst.fadeIn("slow");
    });

    $ddlClassLst.bind("change keyup", function () {
    selectedClassNbr = $('#classdiv option:selected').val();
    loadSubClasses($("#classdiv option:selected").val());
    alert("Your selection is :" + selectedDeptNbr + "-" + selectedSubDeptNbr + "-" + selectedClassNbr);
    $ddlSubClassLst.fadeIn("slow");

    });
    $ddlSubClassLst.bind("change keyup", function () {
    alert("Your selection is :" + selectedDeptNbr + "-" + selectedSubDeptNbr + "-" + selectedClassNbr + "-" + selectedSubClassNbr);
    });
    });

    ReplyDelete
  8. in the above example,everything works just fine but the last bind i.e. $ddlSubClassLst.bind does not even get called and it does not even reach to alert() call either.

    But my alert one step above i.e.

    alert("Your selection is :" + selectedDeptNbr + "-" + selectedSubDeptNbr + "-" + selectedClassNbr);

    works just find returned the value for dept,subdept and as well as selected class

    ReplyDelete
  9. $ddlSub.bind("change keyup", function () {
    alert($("select option:selected").val());
    });
    });

    I think this bind never gets executed in your example or at least for me.

    ReplyDelete
  10. Its great. work fine for me. very very useful article.

    ReplyDelete
  11. in case of cascading dropdown the result is populating in 2 dropdowns instead of 1

    ReplyDelete
  12. Please Help How can i include this dropdownlist to my project

    ReplyDelete

emo-but-icon

SUBSCRIBE


item