Click here to Skip to main content
Click here to Skip to main content
Technical Blog

Finding Controls in a Master Page with jQuery

, 28 Nov 2010 CPOL
Rate this:
Please Sign up or sign in to vote.
Finding Controls in a Master Page with jQuery

This question popped up on the ASP.NET forums where I moderate:

"How do I find an HTML element on a Master Page, from a child page, using jQuery?"

I licked my chops. I like questions like this because when I don't know the answer, it gives me an excuse to explore and learn.

The problem is that element ids on Master Pages get mangled, or decorated, to prevent duplicate ids on the final rendered HTML.

For instance, a textbox with an id like this: MasterPageTextBox ends up with an id like this: ctl00$MasterPageTextBox.

Solution 1

We could hard code the mangled id into the jQuery search criteria and it would work. But what a maintenance nightmare, in the future, the mangled id might change: Not acceptable. When people pay you money to write code, you should write good code.

Solution 2

If you are using ASP.NET 4, you have control over the generated ids and can make them predictable. Then you can hard code the generated id into the CSS selector. However, that isn't the case for most sites at this time.

Solution 3

After Googling and Binging around a bit, I came up with this approach to use in the Master Page:

protected void Page_Load(object sender, EventArgs e)    
{
    Page.ClientScript.RegisterHiddenField
	("HiddenFieldClientID", this.MasterPageTextBox.ClientID);     
}

The code above takes the generated ClientID and puts it in a HiddenField that gets sent to the browser. The jQuery code in the child page can then get the value in the HiddenField and use it to search for the element. I thought this was pretty cool but…the jQuery code wouldn't compile because the HiddenField wasn't on its page. So an empty HiddenField control has to be placed on the page. It's messy, but it works! Here is how the jQuery on the child page accesses the hidden field and then accesses the textbox on the Master Page:

// ---- SetMasterPageTextBox ---------------------------
// write hello in a textbox field on the master page

function SetMasterPageTextBox()
{
    // Get the hidden field         
    var HidField = $("#HiddenFieldClientID");
    if (HidField.length == 1)
    {
        // get the contents of the hidden field
        var ClientID = HidField[0].value;
        // use it as the ID of the TextBox control
        $("#" + ClientID).val("Hello");
    }
}

I went to post my 'brilliant' answer, but in the meantime another forum member posted an answer which was far superior to mine.

Frank Hong suggested wrapping the element with a span tag.

Solution 4

Two things make this next solution work.

  1. Span tag IDs are NOT mangled or decorated.
  2. CSS selectors are cool, really cool…quick review:

div, p

The comma (,) operator means AND. All divs and paragraphs on the page will be selected.

div > p

The greater than (>) operator means direct parent of. Any paragraphs directly inside of any divs are selected

div p

The space ( ) operator means ancestor of. Any paragraphs inside a div are selected, even if they are inside of other elements within the div.

In the Master Page, wrap the textbox with a span element:

<%-- Span is to allow child page to jQuery select textbox--%>     
<span id="SpanMyTextBox">         
    <asp:TextBox ID="MyTextBox" runat="server"></asp:TextBox>     
</span>  

Here's what it looks like rendered, note the TextBox id got mangled but the span id remains unscathed:

<span id="SpanMyTextBox">        
    <input name="ctl00$MyTextBox" type="text" id="ctl00_MyTextBox" />  
</span>  

In the Child Page, we can use the greater than or the space operator. The greater than operator is more explicit as to our intent. We use 'input' because textboxes render as HTML input elements.

So the CSS selector is: #SpanMyTextBox > input.

// ---- SetMasterPageTextBox ---------------------------    
// write hello in a textbox field on the master page             

function SetMasterPageTextBox()    
{        
    //Textbox is wrapped in span element        
    $("#SpanMyTextBox > input").val("Hello");    
}

Now, isn't that better? Of course, it's up to the developer to ensure duplicate span ids are not used.

[Update:]

Solution 5 (from the comments)

You can also use a wild card CSS selector.

input[id$=MyTextBox]

The above line matches all HTML input elements with an id attribute that ends with "MyTextBox".

It will match:

<asp:TextBox ID="ctl00$MyTextBox" runat="server"...
<asp:TextBox ID="LaLaLaMyTextBox" runat="server"...
<asp:TextBox ID="abc123MyTextBox" runat="server"...

I hope someone finds this useful.

Steve Wellens

License

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

Share

About the Author

Steve Wellens
EndWell Software, Inc.
United States United States
I am an independent contractor/consultant working in the Twin Cities area in Minnesota. I work in .Net, Asp.Net, C#, C++, XML, SQL, Windows Forms, HTML, CSS, etc., etc., etc.

Comments and Discussions

 
QuestionHow to populate data in child page using json & master pages PinmemberRohit_daga9-Jun-13 21:56 
AnswerRe: How to populate data in child page using json & master pages PinmemberSteve Wellens10-Jun-13 3:53 
Generalnice PinmemberPranay Rana5-Jan-11 22:33 
GeneralUsing JQuery and arrays for element IDs [modified] PinmemberGary Noter1-Dec-10 9:59 
GeneralMy vote of 4 PinmemberShahriar Iqbal Chowdhury30-Nov-10 10:19 
Generalgood tip PinmemberFabio Barbieri29-Nov-10 23:11 

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 | Terms of Use | Mobile
Web03 | 2.8.141216.1 | Last Updated 28 Nov 2010
Article Copyright 2010 by Steve Wellens
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid