ASP.NET DropDownList Postback: The jQuery AJAX Replacement for MVC

It was handy in ASP.NET WebForms to have the AutoPostback property and use the SelectedIndexChanged event, to allow other parts of your WebForm to be updated depending on user selection!

With MVC and Razor you can achieve the same functionality, but it has to be done using some other way that fits in with a View. Recently I had a requirement to render a list of checkboxes on a user form; the catch was that the list of checkboxes to be rendered was dependant on a drop down list option the user selected on the same form...

With this senario, we have three main components to any solution:

1. We need to fire a method when the drop down list selection changes.
2. This method needs to take the value of the selected item in the drop down list and return output based on that value.
3. The returned output needs to be rendered in the view.

With the requirement I had, I needed to query a database to return the data needed to render the checkboxes. The solution I used utilised jQuery AJAX and JSON.

I had an MVC Web Application with the latest version of jQuery installed, however I also needed the json2 library from http://www.json.org/ (this can also be downloaded via NuGet).

With these libraries referenced, I needed to wire up a a method to fire on the change event of the dropdownlist using jQuery:


    $(document).ready(function () {

        $('#OrganisationId').change(getReceivers);

    });


My getReceivers method makes an ajax call using JSON data to a controller action in my MVC application:

function getReceivers() {
        $.ajax({
            url: '/Person/ListRecievers',
            data: "{'organisationId':'" + $('#OrganisationId').val() + "', 'personId':'@Model.Person.Id'}",
            type: 'POST',
            contentType: 'application/json; charset=utf-8',
            dataType: 'json',
            success: function (result) {
                $('#receiversResponse').empty();
                $.each(result, function (person) {
                    var isChecked;
                    if (this.selected) {
                        isChecked = 'checked=\'checked\'';
                    }
                    else {
                        isChecked = '';
                    }
                    $('#receiversResponse').append(
                            '   <label class=\'checkbox\'>'
                            + '     <input type=\'checkbox\' name=\'Receivers\' ' + isChecked + ' value=\'' + this.id + '\'>' + this.name + ' at ' + this.organisationName + ''
                            + ' </label>'
                        );
                });
            },
            error: function () {

            }
        });
    }


URL: the path to my controller action to get the data back for generating the checkbox HTML

Data: this is data I need to pass to my controller action. I have two inputs, organisationId and personId. It is important to remember that these are passed in the ajax call as strings - if the organisationId is a Guid (for example), you will need to convert this to a Guid once it is passed into your controller action

Success: This takes the returned data (in JSON) and iterates through to generate HTML for the checkboxes. The HTML is written to a div I have in my view with an ID of "receiversResponse".


My controller action that is called to return the data I need in JSON is:



        public ActionResult ListRecievers(string organisationId, string personId)
        {
            var selectedOrganisation = db.Organisations.Where(p => p.Id == new Guid(organisationId)).Single();
                var people = db.People.ToList();
                var peopleList = from p in people
                                 select (new {
                                     id = p.Id,
                                     name = p.Name,
                                     organisationName = p.Organisation.Name,
                                     selected = db.People.Include("Receivers").Where(n => n.Id == new Guid(personId) && n.Receivers.Any(r => r.Id == p.Id)).Count() == 1
                                 }
                                     );
                return Json(peopleList.ToList(), JsonRequestBehavior.AllowGet);  
        }



I hope the solution to this problem helps someone else to dynamically display HTML based on user selection of a dropdownlist option value. You don't have to just display checkboxes with this either!


Comments

Popular posts from this blog

Connecting to SQL Azure with Dynamic IP Addresses

HTML to PDF Conversion in MVC 4

WebAPI and Subscriber Authentication by Custom HTTP Headers