Question

So I have an issue with accessing the correct clientID attributes of an ASP.NET user control.

My main question is that I'm trying to return the full ClientID field of a control using VB code-behind. the expected value for my control (and what shows up in browser) is:

  • ctl00_ContentPlaceHolder1_ctl05_txtAnswer

But I'm only getting "txtAnswer" in code-behind.

I've found something similar on SO here:

ASP.Net: ClientID not correct in code-behind of a user control

This post suggests adding the onClick event during onPreRender or onPageLoad, etc, But I have other circumstances:

  • My user control (text box) is designed to 'pre-load' values from a database (if the same user has previously tried to access the form), or if isPostBack == true.

  • Because I'm reading from a DB for answers, and because there JS function (which uses the getElementByID() JS function) the control needs to access user data ...

  • Currently the control has a member function loadQuestions(key parameters) that loads specific questions from the database.

  • More context: I'm updating some older code that had hard-coded (in client ASPX file) control elements, but now the controls are being built dynamically at runtime (i.e., inserted into a placeholder in client page).

  • I've tried messing around with different ClientIDMode settings (per http://msdn.microsoft.com/en-us/library/system.web.ui.clientidmode.aspx) but no dice so far... I'm using .NET 4.0, so I understand I can directly edit the ClientID via "Static" clientIDmode, and I haven't tried that yet though...

Right now I'm thinking I should "front-load" all of the content-defining stuff into a constructor for the object, which would then apply all the content-defining stuff, and then establish the onClick attribute after the control's data have been populated?

For reference:

Here is the ASP markup for the Control:

<%@ Control Language="VB" AutoEventWireup="false" CodeFile="RBHorizWithText.ascx.vb" Inherits="Apps_Controls_RBHorizWithText" %>
<%@ Register Assembly="txtBoxLengthValidator" Namespace="txtBoxLengthValidator" TagPrefix="cc1" %>

<asp:Panel ID="pnlPreamble" runat="server">
    <div id="divPreamble" runat="server" style="padding-bottom:15px"></div>
</asp:Panel>

<asp:Panel ID="pnlQuestion" runat="server">
    <div id="divQuestion1" runat="server"></div>



    <div id="divRBL" runat="server"  style="padding-left: 20px"> 
      <asp:Table ID="tblAnswers" runat="server" CellPadding="0" CellSpacing="0">
      </asp:Table>
    </div>

    <div id="divQuestion2" runat="server" style="padding-left: 20px; padding-top: 10px"></div>
    <div id="divAnswer2" runat="server" style="padding-left:20px; padding-top: 5px; text-align: left" align="left">
        <div>
            <cc1:TextBoxLengthValidator 
                ID="tblvAnswer" 
                    ControlToValidate="txtAnswer" 
                    runat="server" 
                    ErrorMessage="Maximum length is 255 Characters" 
                    MaximumLength="255" 
                    Display="Dynamic"
                    ForeColor="Red">
            </cc1:TextBoxLengthValidator>    
        </div>

        <div><asp:TextBox ClientIDMode = "Predictable" ID = "txtAnswer" runat="server" Width="600px" Rows="3" TextMode="MultiLine"></asp:TextBox></div>

    </div>

</asp:Panel>

And here is the function from the VB Code-behind (edited for brevity) that calls the JS function...

Public Sub LoadQuestions(ByVal objQRBL As Question, ByVal objQText As Question, ByVal dicAnswers As Dictionary(Of Integer, QuestionAnswer), ByVal LoadAnswers As Boolean)
        'This is a function from RBHorizWithText user control that has two member controls: a radio button and a text box (first 2 params).
        'dicAnswers are the user's answers stored either in HttpContext.Current, or as global memory objects...


        _lstRadioButtons = New List(Of RadioButton)
        Me.tblAnswers.Rows.Clear()
        'txtAnswer is a member control of type textBox...
        Me.txtAnswer.Text = String.Empty

        '.
        'Stuff to build out <tr> and <td> question display elements to format/store control...
        '.


        Dim trw As New TableRow
        Dim iCount As Integer = 0

        For Each objA As QuestionAnswer In objQRBL.AnswerList           

            Dim objRB As New RadioButton

            objRB.ID = objA.QuestID & ";" & objA.AnswerID
            objRB.GroupName = "rb" & objA.QuestID
            objRB.Text = objA.AnswerText

            'This is the main area where I'm having trouble:  
            '   At runtime, Me.txtAnswer.ClientID should evaluate to: "ctl00_ContentPlaceHolder1_ctl05_txtAnswer"
            '   Instead I'm getting:    "txtAnswer"

            If objQText.ParentReqResponseCode.IndexOf(";" & objA.ResponseCode & ";") <> -1 Then
                objRB.Attributes.Add("onclick", "txtBoxEnable('" & Me.txtAnswer.ClientID & "');")
            Else
                objRB.Attributes.Add("onclick", "txtBoxDisable('" & Me.txtAnswer.ClientID & "','" & objQText.InnerText & "');")
            End If


            tcl.Controls.Add(objRB)
            trw.Cells.Add(tcl)

            _lstRadioButtons.Add(objRB)

            iCount += 1
        Next

        'Other stuff to handle formatting and behavior of other controls...

    End Sub

and here are the JS functions, which exist on the master page for the project:

function txtBoxEnable(elID) {                     
    var el = document.getElementById(elID);
    el.style.backgroundColor = '#f4df8d';
    el.value = '';
    el.disabled = '';           
}

function txtBoxDisable(elID, innerText) {
    var el = document.getElementById(elID);
    el.value = innerText;
    el.style.backgroundColor = '#ffffff';
    el.disabled = 'disabled';
}

Thanks Very Much! -Lewis

Was it helpful?

Solution

I've tried messing around with different ClientIDMode settings (per http://msdn.microsoft.com/en-us/library/system.web.ui.clientidmode.aspx) but no dice so far... I'm using .NET 4.0, so I understand I can directly edit the ClientID via "Static" clientIDmode, and I haven't tried that yet though...

Try it, it will solve your issue completely. Whatever ID you assign it on the markup will be the ID you retrieve on the server side. No extra garbage prepended to the ID.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top