Saturday 13 August 2011

Is accessing the ClientID pointless until DataBind complete?

I have a tricky situation:

I am using CustomTemplates to render the contents of a Repeater control which is bound to a custom entity collection.

Some such controls are a pair of Input + TextBox controls.

The requirement is that the TextBox should not be enabled until the Input is selected/checked.

To do this, i was planning on defining a client side event and event handler such as:

EnableTextBox(int txtBoxId)

Which would take the ID of the text box control and then enable it.

This function would then be bound to the Input controls 'onclick' event.

(I would also need a DisableTextBox() function bound to the Input controls 'onchange' event to handle the situation when the user choose a different option and therefore the Textbox should be cleared and disabled)

PROBLEM:

In order to do the above, during the DataBind of the Repeater, whilst the control collection is being built, i was hoping to 'hardcode' the ID of the TextBox into the call to the EnableTextBox function within the 'onclick' event of the Input control such that the markup would look like this:

<input onclick="EnableTextBox('ContentPlaceHolder_rptrQuestions_txt136_18') type="checkbox" />

However, because all this is happening during the Repeater.DataBind event, and since ASP.Net prefixes the IDs of controls with their container names, it is not good enough to simply put the server side ID of the TextBox control in the EnableTextBox() function call...

This means that my input element in the final rendering looks like:

<input onclick="EnableTextBox('txt136') type="checkbox" />
 

...and my EnableTextBox function will never find such a TextBox with ID 'txt136' because it doesn't exist!!!

Ah, but what about the ClientID property you say???

Well folks, the problem there is, the ClientID property, up until the DataBind event is complete, simply contains the server side ID value!!! The prefixing appears to occur AFTER the DataBind is complete...thereby rending my approach useless (it would appear!)

So, what is the solution???

3 comments:

  1. NOTE: This problem may well be solved with the introdcution of the ClientIDMode attribute in .Net 4.

    When you set this to 'Static', the ID of the Rendered control will actually be the same as the Server Side ID - hallelujah!

    ReplyDelete
  2. Furthermore: You can include the ClientIDMode property in the control, the container control, or the user control.

    ReplyDelete
  3. Here is a good explanation of the ClientIDMode attribute and how to use it:

    http://beyondrelational.com/blogs/hima/archive/2010/07/16/all-about-client-id-mode-in-asp-net-4.aspx

    ReplyDelete