views:

1074

answers:

3

i have a repeater than creates a table:

<itemtemplate>
   <tr id="theTableRow" runat="server">
      <td>
         <asp:LinkButton runat="server"
            OnClientClick="todo"
            Text="Do Something" />
      </td>
   </tr>
</itemtemplate>

Note: the OnClientClick="todo" line.

In the final rendered code, i want the todo to contain a call to a javascript function, passing:

  • the ID of the generated table row, and
  • the Eval of a property of the currently bound object

And now for some pseudo-code:

Pseudocode 1:

OnClientClick="DoSomething(theTableRow, CromulentGuid); return false;"

Pseudocode 2

OnClientClick="javascript:DoSomething(theTableRow, CromulentGuid); return false;"

Pseudocode 3

OnClientClick="javascript:DoSomething(theTableRow, <%# Eval("CromulentGuid") %>); return false;"

Pseudocode 4

OnClientClick="javascript:DoSomething(<%= theTableRow %>, <%# Eval("CromulentGuid") %>); return false;"

Pseudocode 5

OnClientClick='javascript:DoSomething(<%= Eval(theTableRow) %>, <%# Eval("CromulentGuid") %>); return false;'

Whatever the ASP.NET code used, i want the rendered HTML to be:

<tr id="ctl00__itemRepeater_ctl01_theTableRow">
   <td>
      <a 
            onclick="DoSomething('ctl00__itemRepeater_ctl01_theTableRow', '19a149db-5675-4eee-835d-3d78372ca6f9'); return false;"
            href="javascript:__doPostBack('ctl00$itemRepeater$ctl01$ctl04','')">
         Do Something
      </a>
   </td>
</tr>

i would also be okay with:

<tr id="ctl00__itemRepeater_ctl01_theTableRow">
   <td>
      <a 
            onclick='DoSomething(&quot;ctl00__itemRepeater_ctl01_theTableRow&quot;, &quot;19a149db-5675-4eee-835d-3d78372ca6f9&quot;); return false;'
            href="javascript:__doPostBack('ctl00$itemRepeater$ctl01$ctl04','')">
         Do Something
      </a>
   </td>
</tr>

Note: i'm okay with the 2nd form since i know it is functionally identical, and ASP.NET code cannot generate the former, even if the latter is less readable.


Related questions:

ASP.NET: How to access repeater generated elements from javascript?

A: 

You can use the OnItemDataBound event to alter each element in your code. Since you're particular about the HTML I might also recommend using hybrid controls rather than asp controls. For example:

<itemtemplate>
   <tr id="theTableRow" runat="server">
      <td>
         <a runat="server"
            onclick="todo(this.parent.parent, '<%# Eval("Property") %>');return false;" >
            Do Something
         </a>
      </td>
   </tr>
</itemtemplate>

This probably isn't 100% perfect, as I just typed it directly in the reply window and I always screw up the Eval() syntax on my first go, but it should help some.

Joel Coehoorn
i can't use a pure <A>, since i need the fallback to the asp.net/postback/onClick behaviour when scripting isn't there.
Ian Boyd
Notice that the href property of the link button renders as javascript: so the fallback doesn't really work.
Joel Coehoorn
A: 

Why not put the JS on the table row?

<tr onClick="DoSomething(this, '<%# Eval("GUIDColumn") %>')"; ><td>
<%# Eval("ColumnText") %>
</td></tr>

This gets you a reference to the table row, and the data that you're needing. It does break downlevel support, so browsers under IE6 won't really work as expected, but that's pretty much par for the course these days.

Two other possibilities are to utilize the Datagrid/Gridview object and the OnItemDatabound aspects or to build the table in code utilizing the ASP.NET TABLE control, and iterating through your datasource manually.

Stephen Wrighton
Because there's other things in the table cell besides the one link; they were omitted for clarity as they are irrelavent to the question.
Ian Boyd
+1  A: 

The better solution is to put the presentation logic in the business layer:

Presentation:

<asp:LinkButton runat="server"
     OnClientClick="<%# GetItemClientClick((MySomething)Container.DataItem) %>"
     Text="Do stuff" />

Business Logic

protected string GetItemClientClick(MySomething item)
{
   ...   
   String szOnClientClick = 
      "return DeleteItem(this, "+
          Toolkit.QuotedStr(item.NodeGUID.ToString()) + ", "+
          Toolkit.QuotedStr(GetItemText(item))+");";

   return szOnClientClick;
}

Much cleaner. Much more readable. Much more maintainable.

Ian Boyd