title: Returning "full" clientID in code behind (asp.net VB)
body: <p>So I have an issue with accessing the correct clientID attributes of an ASP.NET user control. </p>
  
  <p>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:</p>
  
  <ul>
  <li>ctl00_ContentPlaceHolder1_ctl05_txtAnswer</li>
  </ul>
  
  <p>But I'm only getting "txtAnswer" in code-behind.</p>
  
  <p>I've found something similar on SO here: </p>
  
  <p><a href="https://stackoverflow.com/questions/3562198/asp-net-clientid-not-correct-in-code-behind-of-a-user-control">ASP.Net: ClientID not correct in code-behind of a user control</a></p>
  
  <p>This post suggests adding the onClick event during onPreRender or onPageLoad, etc, But I have other circumstances:</p>
  
  <ul>
  <li><p>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. </p></li>
  <li><p>Because I'm reading from a DB for answers, and because there JS function (which uses the <em>getElementByID()</em> JS function) the control needs to access user data ... </p></li>
  <li><p>Currently the control has a member function <em>loadQuestions(key parameters)</em> that loads specific questions from the database.  </p></li>
  <li><p>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).  </p></li>
  <li><p>I've tried messing around with different ClientIDMode settings (per <a href="http://msdn.microsoft.com/en-us/library/system.web.ui.clientidmode.aspx" rel="nofollow noreferrer">http://msdn.microsoft.com/en-us/library/system.web.ui.clientidmode.aspx</a>) 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...</p></li>
  </ul>
  
  <p>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?</p>
  
  <p>For reference:</p>
  
  <p>Here is the ASP markup for the Control:</p>
  
  <pre><code>&lt;%@ Control Language="VB" AutoEventWireup="false" CodeFile="RBHorizWithText.ascx.vb" Inherits="Apps_Controls_RBHorizWithText" %&gt;
  &lt;%@ Register Assembly="txtBoxLengthValidator" Namespace="txtBoxLengthValidator" TagPrefix="cc1" %&gt;
  
  &lt;asp:Panel ID="pnlPreamble" runat="server"&gt;
      &lt;div id="divPreamble" runat="server" style="padding-bottom:15px"&gt;&lt;/div&gt;
  &lt;/asp:Panel&gt;
  
  &lt;asp:Panel ID="pnlQuestion" runat="server"&gt;
      &lt;div id="divQuestion1" runat="server"&gt;&lt;/div&gt;
  
  
  
      &lt;div id="divRBL" runat="server"  style="padding-left: 20px"&gt; 
        &lt;asp:Table ID="tblAnswers" runat="server" CellPadding="0" CellSpacing="0"&gt;
        &lt;/asp:Table&gt;
      &lt;/div&gt;
  
      &lt;div id="divQuestion2" runat="server" style="padding-left: 20px; padding-top: 10px"&gt;&lt;/div&gt;
      &lt;div id="divAnswer2" runat="server" style="padding-left:20px; padding-top: 5px; text-align: left" align="left"&gt;
          &lt;div&gt;
              &lt;cc1:TextBoxLengthValidator 
                  ID="tblvAnswer" 
                      ControlToValidate="txtAnswer" 
                      runat="server" 
                      ErrorMessage="Maximum length is 255 Characters" 
                      MaximumLength="255" 
                      Display="Dynamic"
                      ForeColor="Red"&gt;
              &lt;/cc1:TextBoxLengthValidator&gt;    
          &lt;/div&gt;
  
          &lt;div&gt;&lt;asp:TextBox ClientIDMode = "Predictable" ID = "txtAnswer" runat="server" Width="600px" Rows="3" TextMode="MultiLine"&gt;&lt;/asp:TextBox&gt;&lt;/div&gt;
  
      &lt;/div&gt;
  
  &lt;/asp:Panel&gt;
  </code></pre>
  
  <p>And here is the function from the VB Code-behind (edited for brevity) that calls the JS function...</p>
  
  <pre><code>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 &lt;tr&gt; and &lt;td&gt; 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 &amp; ";" &amp; objA.AnswerID
              objRB.GroupName = "rb" &amp; 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(";" &amp; objA.ResponseCode &amp; ";") &lt;&gt; -1 Then
                  objRB.Attributes.Add("onclick", "txtBoxEnable('" &amp; Me.txtAnswer.ClientID &amp; "');")
              Else
                  objRB.Attributes.Add("onclick", "txtBoxDisable('" &amp; Me.txtAnswer.ClientID &amp; "','" &amp; objQText.InnerText &amp; "');")
              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
  </code></pre>
  
  <p></p>
  
  <p>and here are the JS functions, which exist on the master page for the project:</p>
  
  <pre><code>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';
  }
  </code></pre>
  
  <p>Thanks Very Much!
  -Lewis</p>