65.9K
CodeProject is changing. Read more.
Home

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

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.08/5 (7 votes)

Jul 26, 2007

2 min read

viewsIcon

104835

downloadIcon

932

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