Sunday, April 27, 2014

Step by Step how to create a Cascading DropDownList with Ajax functionality

        By Carmel Shvartzman


In this tutorial we'll learn how to create two Cascading DropDownLists with Ajax functionality. The  two Cascading DropDownLists will update its items dynamically Ajax-loading data from database, according to the user's selections.

We'll design a web site using a free CSS Template, as explained in a former tutorial,  and a JQuery UI Theme that we imported in this tutorial. They are short step by step begginer's guides, so if you like the look-and-feel of this web site, follow those 10 minutes tutorials to make this same site.

We'll want to create two Cascading DropDownLists with Ajax functionality , showing as follows:

The <select> tags will be loaded with data from the following related entities:


First, create a new Controller and create a Repository instance (provided you have one):


Add a new View for the Index Action method, and create two <select> as follows:

<div class="ui-widget-content ui-corner-all divselect">
    <div class="float-left">
        Select a Blog Post
        <br />
        <select id="Posts">
            <option value="-1">Select a Post</option>
        </select>
    </div>
    <div class="float-right">
        Select a Post Comment<br />
        <select id="Comments">
            <option value="-1">Select a Comment</option>
        </select>
    </div>
    <div id="txtComment" class="ui-widget-content ui-corner-all divselect float-left"></div>
</div>

Notice we're using the JQueryUI theme CSS classes.
Now add a <script> and an Ajax $.getJSON() call which executes right after the HTML document is loaded. This call will populate the FIRST <select>  control:


<script>$(function () {
    $.getJSON("CascadingDDL/Blogs/", function (data) {
        var list = "<option value='-1'>Select a Post</option>";
        $.each(data, function (i, post) {
            list += "<option value='" + post.Value + "'>" + post.Text + "</option>";
        });
        $("#Posts").html(list);
    });

The function makes a HTTP_GET call to the following Action method, which returns all the Blog posts in JSON notation:


public ActionResult Blogs()
        {
            List<Blog> posts = Rep.RetrieveBlog(null).ToList();
            if (HttpContext.Request.IsAjaxRequest())
            {
                SelectList select = new SelectList(posts, "BlogID", "Title");
                return Json(select, JsonRequestBehavior.AllowGet);
            }
            return View(posts);
        }

This Action method uses the RetrieveBlog method on the Repository:

       public IEnumerable<Blog> RetrieveBlog(int? Id)
        {
            List<Blog> list = new List<Blog>();
            if (Id.HasValue)
            {
                list.Add(Context.Blogs.Find(Id));
            }
            else
            {
                list = Context.Blogs.ToList();
            }
            return list;
        }

It's a generic method which works with or without a parameter.
Next, add an event handler for the 1st <select> CHANGE event at the <script>:


 $("#Posts").change(function () {
        var PostId = $("#Posts > option:selected").attr("value");
        $.getJSON("CascadingDDL/Comments/" + PostId, function (data) {
            var list = "<option value='-1'>Select a Comment</option>";
            $.each(data, function (k, comment) {
                list += "<option value='" + comment.Value + "'>" + comment.Text + "</option>";
            });
            $("#Comments").html(list);
        });
    });

This sends an Ajax HTTP_GET request to populate the 2nd <select> with the data corresponding to the SELECTED value at the 1st <select> control. This $.getJSON calls another Action method :



 public ActionResult Comments(int? Id)
        {
            List<Comment> comments = Rep.RetrieveBlogComments(Id).ToList();
            if (HttpContext.Request.IsAjaxRequest())
            {
                SelectList select = new SelectList(comments, "CommentID", "Title");
                return Json(select, JsonRequestBehavior.AllowGet);
            }
            return View(comments);
        }

This method uses another Repository function as follows:

 public IEnumerable<Comment> RetrieveBlogComments(int? Id)
        {
            List<Comment> list = new List<Comment>();
            if (Id.HasValue)
            {
                list = Context.Comments.Where(c => c.BlogID == Id).ToList();
            }
            else
            {
                list = Context.Comments.ToList();
            }
            return list;
        }


This fetchs only the Comments corresponding to the selected Blog post.
Finally, append a last $.ajax HTTP_POST function to the <script>, in order to get the text of the selected Comment:

$("#Comments").change(function () {
        var Id = $("#Comments > option:selected").attr("value");
        if (Id >= 0) {
            $.ajax("CascadingDDL/CommentText/", {
                data: { "CommentId": Id }, type: "POST", success: function (txt) {
                    $("#txtComment").html("<i>" + txt + "</i>");
                }
            });
        }
    });

This $.ajax calls the following Action method:


 public JsonResult CommentText(int? CommentId)
        {
            if (HttpContext.Request.IsAjaxRequest())
            {
                string comment = Rep.RetrieveComment(CommentId).Text;
                return Json(comment);
            }
            return Json("");
        }

This Action method uses a Repository function to fetch the Comment's text::


 public Comment RetrieveComment(int? Id)
        {
            Comment comment = null;
            if (Id.HasValue)
            {
                comment = Context.Comments.Where(c => c.CommentID == Id).FirstOrDefault();
            }          
            return comment;
        }
Build and run the app:


When the user selects a Post, the list of Comments is refreshed:



And when a Comment is selected, its text is Ajax displayed below:



That's all!! 
In this tutorial we've learn how to create two Cascading DropDownLists with Ajax functionality.  

Happy programming.....


כתב: כרמל שוורצמן