Click here to Skip to main content
Click here to Skip to main content

Using AJAX to populate a drop-down list in ASP.NET

, 26 Jul 2007
Rate this:
Please Sign up or sign in to vote.
An article on how to populate a drop-down list using AJAX in ASP.NET

Introduction

This article is aimed at those who are new to AJAX and who are willing to implement their code using AJAX in the classic way with JavaScript and XML.

Using the code

This article will help a person who knows what AJAX is and wants to implement it in a simple way using JavaScript and XML. This article will show how to implement AJAX technology in a simple way in ASP.NET and will not go in-depth into explaining what the technology is. I have used two drop-down lists (DDLs) to implement AJAX. The first drop-down list contains alphabets. On selecting a particular alphabet from the first DDL, the second DDL will populate with names starting with the selected alphabet, assuming that the browser is IE.

What do we need?

  1. Two DDLs: ddl_alphabets and ddl_users
  2. Two XML files: alphabets.xml and users.xml
  3. Two ASPX web forms: Client.aspx and Remote.aspx
  4. Include the System.xml namespace in your CS files

The XML files are in the downloadable version. In the Page_Load event of Client.aspx.cs, add the following code for populating the two DDLs from the alphabets.xml and users.xml files.

protected void Page_Load(object sender, EventArgs e)
{
    if (!Page.IsPostBack)
    {
        DataSet ds = new DataSet();
        ds.ReadXml(Server.MapPath("~\\alphabets.xml"));
        XMLDataDocument XMLDoc = new XMLDataDocument(ds);
        //for populating the ddl_alphabets          
        foreach (
            XmlNode XMLNodes in XMLDoc.SelectNodes("/alphabets/alphabet"))
        {
            ddl_alphabets.Items.Add(
                new ListItem(xmlNodes.ChildNodes[0].InnerText.ToString()));
        }
        ds = new DataSet();
        ds.ReadXml(Server.MapPath("~\\users.xml"));
        XMLDoc = new XMLDataDocument(ds);
        //for populating the ddl_users          
        foreach (XmlNode XMLNodes in XMLDoc.SelectNodes("/Users/User"))
        {
            ddl_users.Items.Add(
                new ListItem(xmlNodes.ChildNodes[0].InnerText.ToString()));
        }
        //fires the onchange event and calls a javascript 
        //function when the user selects an alphabet from  ddl_alphabets
        ddl_alphabets.Attributes.Add("onChange", "getUsers(this.value)");
    }
}

Now let's get to the interesting stuff, the JavaScript functions! In the head section of the Client.aspx source page, add the following under the script tag.

var requestURL = window.document.location.toString();
var start = 0
var end = requestURL.lastIndexOf("/") + 1;
var remotePage = 'Remote.aspx?alphabet=';
//for getting the current  url dynamically 
requestURL = requestURL.substring(start,end) + remotePage;       
var XMLHttp;        
var is_ie = (navigator.userAgent.indexOf('MSIE') >= 0) ? 1 : 0; 
var is_ie5 = (navigator.appVersion.indexOf("MSIE 5.5")!=-1) ? 1 : 0; 

The JavaScript function getUsers is called when the user selects an item from ddl_alphabets.

function getUsers(alphabet)
{  
    var ddl=document.getElementById("ddl_alphabets");        
    if (ddl.selectedIndex==0)
    {
        alert("please select item");
        alphabet="FetchEmAll";
    }
               
    if (alphabet.length > 0)
    { 
        //Append the name to search for to the requestURL 
        var url = requestURL + alphabet;
                                 
        //Create the XMLHttp object to use in the request 
        //stateChangeHandler will fire when the state has 
        //changed, i.e. data is received back.This is 
        //non-blocking (asynchronous)                  
        XMLHttp = GetXmlHttpObject(stateChangeHandler);
                             
        //Send the XMLHttp get to the specified url                
        XMLHttp_Get(xmlHttp, url);                
    } 
}

stateChangeHandler will fire when the state has changed, i.e. data is received back. This is non-blocking (asynchronous).

function stateChangeHandler() 
{ 
    //readyState of 4 or 'complete' represents that data has been returned
    if (xmlHttp.readyState == 4 || XMLHttp.readyState == 'complete')
    { 
        //Gather the results from the callback          
        var str = XMLHttp.responseText;    
                
        // for populating  ddl_users
        if (xmlHttp.responseXML.documentElement != null)
        {
            ClearUsersAndSetUsers(xmlHttp.responseXML.documentElement);
        }
        else
        {
            alert("No Match");
        }                         
    }   
} 

The GetXmlHttpObject JavaScript function creates a new browser object.

function GetXmlHttpObject(handler)
{ 
    var objXmlHttp = null;    //Holds the local XMLHTTP object instance
    if (is_ie)
    { 
        //The object to create depends on version of IE 
        //If it isn't ie5, then default to the Msxml2.XMLHTTP object 
        var strObjName = (is_ie5) ? 'Microsoft.XMLHTTP' : 'Msxml2.XMLHTTP';
             
        //Attempt to create the object 
        try
        { 
            objXmlHttp = new ActiveXObject(strObjName);
            objXmlHttp.onreadystatechange = handler; 
        } 
        catch(e)
        { 
            //Object creation errored 
            alert('Object could not be created'); 
            return; 
        }    
    } 
    return objXmlHttp; 
} 

The XMLHttp_Get function sends the GET request to the specified URL for response from the remote page.

function XMLHttp_Get(xmlhttp, url)
{                     
    XMLhttp.open('GET', url, true);             
    XMLhttp.send(null); 
}

The ClearUsersAndSetUsers function gets the XML document sent from Remote.aspx. It clears and sets ddl_users with new items.

//Clears the contents of ddl_users dropdown list and 
//sets the names that start with the selected alphabet
function ClearUsersAndSetUsers(userNodes)
{
    var usersList = document.getElementById("ddl_users"); 
    var userNameNodes = userNodes.getElementsByTagName('name'); 
    var textValueName; 
    var optionItemName;
      
    //Clears the ddl_users dropdown list                   
    for (var count = usersList.options.length-1; count >-1; count--)
    {
        usersList.options[count] = null;            
    }        
    //Add new users list to the users ddl_users
    for (var count = 0; count < userNameNodes.length; count++)
    {
        textValueName = GetInnerText(userNameNodes[count]);  
        optionItemName = new Option( textValueName, 
            textValueName,  false, false);
        usersList.options[usersList.length] = optionItemName;  
    }           
}

//Returns the node text value 
function GetInnerText (node)
{
    return (node.textContent || node.innerText || node.text) ;
}

Next let's see the Remote.aspx web form. In Page_Load of Remote.aspx, add the following.

protected void Page_Load(object sender, EventArgs e)
{
    //Get the request query 
    string strAlphabet = Request["alphabet"].ToString();
    int nameFound = 0;

    //Create the XML-like string to be sent back to the request 
    string strXmlNames = "";        
    int i = 0;
    ArrayList users = new ArrayList();        
    DataSet ds = new DataSet();
    ds.ReadXml(Server.MapPath("~\\users.xml"));
    XMLDataDocument XMLDoc = new XMLDataDocument(ds);
    foreach (XmlNode XMLNodes in XMLDoc.SelectNodes("/Users/User"))
    {
        users.Add(xmlNodes.ChildNodes[0].InnerText.ToString());
    }

    foreach (string strName in users)
    {
        //If the request matches the beginning of a name, 
        //then add it to the string 
        // otherwise it shouldn't be a valid match
        if (strAlphabet == "FetchEmAll")
        {
            strXmlNames += "<user><name>" + strName + "</name></user>";
            nameFound = 1;
        }

        else if (strName.Length > strAlphabet.Length)
        {
            if (strName.ToLower().Substring(0, 
                strAlphabet.Length) == strAlphabet.ToLower())
            {
                nameFound = 1;
                strXmlNames += "<user><name>" + strName + "</name></user>";
            }
        }

        else if (strName.Length == strAlphabet.Length)
        {
            if (strName == strAlphabet)
            {
                nameFound = 1;
                strXmlNames += "<user><name>" + strName + "</name></user>";
            }
        }
        i += 1;
    }
    //Prepend and append the parent element 
    //for populating the DDL

    if (nameFound == 1)
    {
        strXmlNames = 
            "<?xml version=\"1.0\" ?><users>" + strXmlNames + "</users>";
    }
    else
    {
        strXmlNames = "";
    }
    Response.Clear();
    Response.ContentType = "text/xml";
    Response.Write(strXmlNames);
    //this sends the XML data to the requesting page(Client.aspx)
    Response.End();
}

Simply download the working version of this AJAX implementation using Classic.

History

  • 25 July, 2007 -- Original version posted

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

About the Author

jithucpillai

India India
No Biography provided

Comments and Discussions

 
Generalfilter listbox based on the text entered in the textbox Pinmemberelizabethsheeba16-Apr-08 9:32 
GeneralRe: filter listbox based on the text entered in the textbox Pinmemberbond_00313-Jul-09 5:45 
GeneralAdding cross-browser-functionality PinmemberIlTrips26-Jul-07 22:38 
It's easy, really. First of all, get rid of your is_ie variables, you don't need them.
Second, change your XmlHttpRequest-Creation to:
function GetXmlHttpObject(handler)
{
var objXmlHttp = null; //Holds the local xmlHTTP object instance
try
{
objXmlHttp = new XMLHttpRequest(); // Opera, MSIE 7, Mozilla
}
catch (e)
{
try
{
objXmlHttp = new ActiveXObject("Msxml2.XMLHTTP"); // IE 5.5+
}
catch (e)
{
objXmlHttp = new ActiveXObject("Microsoft.XMLHTTP"); // IE 5.x
}
}
 
if(objXmlHttp != null)
objXmlHttp.onreadystatechange = handler;

return objXmlHttp;
}
 
That's all there is to it. Remember not to use ActiveXObject whenever there's an alternative.
 
So, good start, but you're not done yet Big Grin | :-D .
 
Now go back and do the same with ONE page handling the initialising AND the javascript callback (thus, getting rid of the hard-coded callback address in your javascript). After that, try and create a custom control (dll) which encapsulates all the needed ASP.net methods and embeds and registers the needed javascript to the page as well.
 
Have fun Smile | :) .
Generalgood one - would like to know abt your opinion on this Pinmemberrilov26-Jul-07 14:40 
GeneralRe: good one - would like to know abt your opinion on this Pinmemberjithucpillai26-Jul-07 19:40 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web02 | 2.8.140721.1 | Last Updated 26 Jul 2007
Article Copyright 2007 by jithucpillai
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid