Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / web / XHTML

Master Pages and JavaScript document.getElementById

4.66/5 (34 votes)
14 Dec 2007CPOL3 min read 1   2.1K  
This article talks about the issues faced in accessing controls inside a Master Page from JavaScript, and points a quick solution.

Introduction

Master Pages is one of the best features of ASP.NET 2.0. But, if you are a beginner in .NET 2.0 and Master Pages, you would get stuck in accessing controls placed inside a Master Page using JavaScript. Whenever a control is placed inside a Master Page, its client ID would be changed. As the client ID is changes, the document.getElementById(serverID) of the control in JavaScript won't work. In this article, I will discuss about one of the simplest solutions to get the client ID of a control in a Master Page for use in JavaScript.

Background

Whenever a control is inside a Master Page, the client ID of the control would get appended with its content placeholder ID. So, for an element with an ID “txtTest”, the new client ID would look something like “ctl00_ContentPlaceHolder1_ txtTest”.

So, when you try to use document.getElementById(‘txtTest’), you will not get access to the txtTest textbox in JavaScript. You need to access it by calling document.getElementById(‘ctl00_ContentPlaceHolder1_ txtTest’).

To avoid hard coding of very long client IDs, we can access the control by using document.getElementById('<%=txtTest.ClientID%>'). This will give us access to txtTest. Now, this will work fine until and unless the script is inline with the ASPX page, i.e., if the script is included as part of the ASPX page. But, the same won’t work if you have the script in a separate .js file and add it to the ASPX page by specifying its location.

So, in this scenario, to get access to the control, we have to hard code the control’s ID. But hard coding is not the ideal way of coding. To avoid this situation, what we can do is maintain a mapping between the client ID and the server ID. In the JavaScript code, we can get the client ID of the control by giving its server ID. This can be achieved as shown below.

Using the code

The above said can be achieved as shown here. First, we need to declare two arrays; the first array will have the server IDs of the required controls, and the second array will have the client IDs of the server controls in the same order. Register these two arrays at the client side. Now, create a JavaScript function which will accept the server ID and will compare the server ID with the available server IDs in the array and will give its position in the array. Then, the same function would return you the matching client ID from the same location in the client IDs array. I feel this is one of the simplest ways of maintaining a mapping between client and server IDs.

The code below shows the declaration of the array, and the declaration of the JavaScript function in the code-behind.

C#
// This is the method used to register the array
// of the clientid's as well as the serverid's 
// Also this method registers the function GetClientId, which is used
// to get the client id provided server id is supplied


public void RenderJSArrayWithCliendIds(params Control[] wc)
{
    if (wc.Length > 0)
    {
        StringBuilder arrClientIDValue = new StringBuilder();
        StringBuilder arrServerIDValue = new StringBuilder();

        // Get a ClientScriptManager reference from the Page class.
        ClientScriptManager cs = Page.ClientScript;

        // Now loop through the controls and build the client and server id's
        for (int i = 0; i < wc.Length; i++)
        {
            arrClientIDValue.Append("\"" + 
                             wc[i].ClientID + "\",");
            arrServerIDValue.Append("\"" + 
                             wc[i].ID + "\",");
        }

        // Register the array of client and server id to the client
        cs.RegisterArrayDeclaration("MyClientID",
           arrClientIDValue.ToString().Remove(arrClientIDValue.ToString().Length - 1, 1));
        cs.RegisterArrayDeclaration("MyServerID",
           arrServerIDValue.ToString().Remove(arrServerIDValue.ToString().Length - 1, 1));

        // Now register the method GetClientId, used to get the client id of tthe control
        cs.RegisterStartupScript(this.Page.GetType(), "key", 
           "\nfunction GetClientId(serverId)\n{\nfor(i=0; i<MyServerID.length; i++)" + 
           "\n{\nif ( MyServerID[i] == serverId )\n" + 
           "{\nreturn MyClientID[i];\nbreak;\n}\n}\n}", true);
        }
    }

We can make this code a part of a common class for all UI pages like a page base, so that in every page we need to access a control in JavaScript, we can simply call the function with the control to be accessed as the parameter.

C#
// Here we need to register the client ids to the client,
// so that the same can be used in the javascript
// If there are nultiple controls make it by comma seperated..
RenderJSArrayWithCliendIds(txtTest);

This is one of the simplest ways to have a mapping between client and server IDs. Here, there is no need to worry about accessing a control inside a Master Page from an external JavaScript file.

Now, we can access the elements which are given in the RenderJSArrayWithCliendIds function in the JavaScript as shown below:

JavaScript
var TextBox = document.getElementById(GetClientId("txtTest"));

This will solve any issue arising due to changes in the client IDs of controls placed inside a Master Page.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)