Saturday, September 18, 2010

How to dynamically load a DropDownList using jQuery and JSON


Demo:

If you want to load dropdownlist on the spot, you can use onmouseover and onfocus events to respond both mouse and keyboard. I would use jQuery + JSON to load dropdownlists dynamically which will be the ideal case. I have used GenericHander.ashx to servie all the dropdownlist data.

But the problem is when you add/change dropdown list items in the client side using JavaScripts, in the very next postback, it fails the EventValidation I am not going to discuss about this issue here. But I have a seperate article with detailed information how to overcome this issue. So I have used used AddableDropDownList for this example.

Other key point is, you have to remember load items to the list only the first page load inside the JavaScript. Because once you added items to the list they will get listed in AddableDropDownList.Items collection and they will be in ViewState for subsequent postbacks. So no need to load on each postback.

Markup - Test Page
<%@ Register Assembly="ActiveTest" Namespace="ActiveTest" TagPrefix="asp" %>
<%@ Page Language="C#" %>
<html>
<head runat="server">
    <style type="text/css">
        .countries { width:150px; }
    </style>        
    <script src="Scripts/jquery-1.4.1.min.js" type="text/javascript"></script>
    <script language="javascript" type="text/javascript">
        var countriesLoaded = false;
        function load(key) {
            if ('<%=this.IsPostBack %>' != 'True') {
                if (key == 'countries' && countriesLoaded) return;
                var target = $("." + key);
                target.attr("disabled""disabled");
                $.getJSON('GenericHandler.ashx?q=' + key, function (data) {
                    for (i = 0; i < data.length; i++)
                        AddListItem(data[i].value, data[i].text, '<%=AddableDropDownList1.ClientID %>');
                    countriesLoaded = true;
                    target.removeAttr("disabled");
                });
            }
        }
    </script>
    <script runat="server">
        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);
            if (this.IsPostBack)
                this.lblLstPostBackTime.Text = 
                    string.Format("Last posted pack at: {0}"DateTime.Now.ToString("hh:mm:ss"));
        }
    </script>
</head>
<body>
    <form id="form1" runat="server">
        <asp:AddableDropDownList
            ID="AddableDropDownList1" 
            runat="server" 
            CssClass="countries" 
            onmouseover="javascript:load('countries')" 
            onfocus="javascript:load('countries')">
            <asp:ListItem>Please Select</asp:ListItem>
        </asp:AddableDropDownList>
        <hr />
        <p>Event validation enabled </p>   
        <asp:Button runat="server" ID="btnSave" Text="Save" /> 
        | <asp:Label runat="server" ID="lblLstPostBackTime" />
    </form>
</body>
</html>

Generic Handler:
public class GenericHandler : IHttpHandlerIRequiresSessionState
{
    public void ProcessRequest(HttpContext context)
    {
        StringBuilder data = new StringBuilder();
        context.Response.ClearHeaders();
        context.Response.ClearContent();
        context.Response.Clear();
        data.Append("[");
        string q = context.Request.QueryString.Get("q");
        switch(q)
        {
            case "countries":
                for (int i = 0; i < 1000; i++)
                    data.AppendFormat("{{\"value\":\"Value{0}\", \"text\":\"Text{0}\"}},", i);
                break;
        }
        data.Append("]");            
        string json = data.ToString();
        if (json.EndsWith(",]")) json = json.Remove(json.Length - 2, 1);
        context.Response.ContentType = "application/json";
        context.Response.ContentEncoding = Encoding.UTF8;
        context.Response.Write(json);
        context.Response.Flush();
        context.ApplicationInstance.CompleteRequest();
    }
    public bool IsReusable
    {
        get
        {
            return false;
        }
    }
}

No comments:

iPhone Launch Screen Sizes

iPhone Portrait iOS 8 Retina HT 5.5 = 1242 X 2208 Retna HD 4.7 = 750 X 1134 iPhone Landscape iOS 8 Retina HD 5.5  2208 X 1242 iPho...