Click here to Skip to main content
Email Password   helpLost your password?

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.

// 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.

// 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:

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.

You must Sign In to use this message board.
 
 
Per page   
 FirstPrevNext
GeneralMy vote of 1
Syed Javed
4:14 6 Dec '09  
Poor
GeneralThanks !! It works excellently
Shariq Misbahi
21:00 23 Jul '09  
It works excellently
QuestionNice But could use a little more Help on getting values back from a secoundary window.
Kevin Lyons
4:11 15 Jan '09  
Thanks for the great code it has gotten me much closer to my goal.

I am communicating with my Parent VIA a child window. using
window.opener.parent.form1['txt1'].value=lsString; at the child.

Now this works really well if I am not using a master or even a bit deeper a WebControl.
What happens is when I put a master on this, or deploy as a WebControl the referance is lost.
that the Window.Opener cannot find the control... no object is found?



So... this is were I found your code, however I am not able to get the value from the child to the parent.. cant seem to overcome the object not being found?
Can you provide any help?
Thank you for your time.



// here is working Code without a master
//PARENT


<script language="javascript">
function popWin(llInp)
{
window.open("webform2.aspx","aa","width=300,height=300");
return false;
}
</script>

//PARENTS ASP CONTROLS

<asp:textbox id="txtParent" runat="server" width="176px" xmlns:asp="#unknown">
<asp:button id="Button1" runat="server" width="80px" text="Button" xmlns:asp="#unknown">


//PARENTS CODE BEHIND On load event to register Click Event
Button1.Attributes.Add("onClick", "return popWin('" + txtParent.ID + "');");


// CHILD Java Script
<script language="javascript">

function mainValues()
{
var lsString;
lsString=window.document.form1['TextBox1'].value;
window.opener.parent.form1['txtParent'].value=lsString;
window.close();
}
</script>

// CHILD ASP

<asp:textbox id="TextBox1" runat="server" width="144px" xmlns:asp="#unknown">
<asp:button id="Button1" server=" Width=" 72px=" Text=" return="></asp:Button><br mode=" hold=" /><br mode=" onclick=", " xmlns:asp="#unknown">
QuestionThe name 'txtTest' does not exist in the current context
HuntTheShuntHTS
2:09 15 Jan '09  
Good article.

Can you help with a problem I have with the code
RenderJSArrayWithCliendIds(txtTest);
has an error "The name 'txtTest' does not exist in the current context"

If I ignore the error the code works ok!
How can I tell RenderJSArrayWithCliendIds the object I want without the error?

Thanks.
AnswerEasier solution
Corne.duplooy
3:53 21 Oct '08  
Hi Rajganesh,

An simpler solution to this problem is to just use:
document.getElementById("<%= ServerSideControlID.ClientID %>");

from the JavaScript where ServerSideControlID is the ID of the control.
GeneralRe: Easier solution
Rajganesh Mountbatton
4:10 21 Oct '08  
Yes, that is much easier. But it works only with the case of inline JavaScript code Frown


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


Please check the third paragraph in the Background section of the article.

Rajganesh

Meet me in my blog : Rajganesh Writes

GeneralAwesome!
cwellis
9:21 24 Sep '08  
I have been looking for this functionality for a couple of weeks now. Your code is concise and very easy to follow. Thanks!
GeneralThanks!
trujello
5:38 7 Sep '08  
Rajganesh,

Thank you SO MUCH for your clear example! Big Grin I made it work in my 2 deep nested master pages and with my Menu control. It's great!

-- Jerry
GeneralPlease additional explenation
Daniel_Moreshet
2:22 25 Jun '08  
You started with a problem that we can't get the client id from an external file, so I don't get what is the solution. Where you intend to register the 2 arrays and "GetClientId()" method,
and how can I call this method from another file?
Please your help, since I am in that problem that I need to get to the client id of a page from the popup window this page opened.
Thanks, Daniel.
AnswerRe: Please additional explenation [modified]
Rajganesh Mountbatton
19:52 29 Jul '08  
Apologies for late response. In external JavaScript files we would not be able to access the server side code like '<%= Control.ClientID %>'.

So on these cases, solution i propose is to "Have a mapping between ClientId and the ServerID in an array, and push that array to your page every time it loads. Also write your own function to get the mapping id's by passing any one of them"

In my case, the client and server ids are maintained in two arrays in the same order. Then these arrays are pushed to the page by using the page's client script manager's RegisterArrayDeclaration method. This registration can be done in your page load event.

To get the mapping ClientId for a ServeId, the function used is

function GetClientId(serverId)
{
for(i=0; i<myserverid.length;> {
if ( MyServerID[i] == serverId )
{
return MyClientID[i];
break;
}
}
}


This function should be there in all of your pages where you need to get the ClientId by its ServerId. You can have it in common script or you can register this function also in your page load.

Rajganesh

Meet me in my blog : Rajganesh Writes

modified on Thursday, July 31, 2008 11:15 PM

GeneralHow can I get PopWindow page value back to Parent which in using Master Page.
Member 1934494
6:14 21 Apr '08  
This is good but I want to know How can I pass values from Child PopMenu Page to Parent page which is Using MasterPage.
Can you tell me this. Smile
Generalthank you
kevinduk
7:39 11 Mar '08  
I've spent a couple of days trying to solve this problem. works great. many thanks.

kevd
GeneralNice
unknownunknown
1:28 18 Feb '08  
Very useful - thanks
GeneralThanks
Gfw
6:36 27 Dec '07  
It does exaclt what I needed it to do!
GeneralWrong name
dennisbetten
11:31 17 Dec '07  
Should be called Javascript on ContentPage... The real challenge is to activate javascript on the real masterpage. If you find that one out, let me know!


Last Updated 14 Dec 2007 | Advertise | Privacy | Terms of Use | Copyright © CodeProject, 1999-2010