2

I have 2 buttons in a column of my GridView control.

<asp:TemplateField ItemStyle-CssClass="minPadding">
    <ItemTemplate>
        <input  id="btnDateRange" type="button" value="Date Range" class="JQDatePicker SmallText FloatRight WrapButtonText" onclick="javascript:document.getElementById('hdnImpressionTagID').value = '<%# Eval("ImpressionTagID") %>'"/>
        <asp:Button ID="btnShowImpressions" CommandArgument='<%# Eval("ImpressionTagID") %>' CommandName="ShowImpressions" Text="Total Impressions" runat="server" UseSubmitBehavior="false" CssClass="SmallText FloatLeft WrapButtonText" Width="80px" />
    </ItemTemplate>
</asp:TemplateField>

The reason the first button is an HTML control is because when I try to use an asp:button - the onclick event doesn't work (note the #Eval statement inside the javascript call) Using a server control gives me the error : 'Server tag is not well formed'

I want to change the text of these buttons from my code behind. (I'm using c#)

I find the correct row index and I know they are in cell 5.

I can set the asp:Button control's text like so...

Button btn = ((Button)gridImpressionTags.Rows[i].Cells[5].FindControl("btnDateRange")); btn.Text = "This Text has changed!";

The problem is: The Web control btnDateRange appears as a DataBoundLiteralControl when referenced from code behind & I am unable to cast it as a button.

I am also unable to cast it as a literal. Unable to cast object of type 'System.Web.UI.DataBoundLiteralControl' to type 'System.Web.UI.WebControls.Literal'.

And casting it as a DataBoundLiteralControl works, but then doesn't allow me to change the text: System.Web.UI.DataBoundLiteralControl.Text' cannot be assigned to -- it is read only

Does anyone know why my HTML button is being rendered as a DataBoundLiteralControl ? Does anyone have any ideas for me to try for me at all ?

Any suggestions are appreciated!

wotney
  • 1,039
  • 3
  • 21
  • 34

2 Answers2

3

1) You can take the button back to asp:button and use OnClientClick instead of OnClick. In this context the OnClick is for server event handling instead of javascript. To use the javascript, use OnClientClick

2) Add runat="server" to your html button

Update: I was focusing on accessing the control from codebehind. Try this javascript

<input type="button" onclick='<%# String.Format("javascript:document.getElementById('hdnImpressionTagID').value = '{0}'", Eval("ImpressionTagID")) %>' />

Update

I agree with you that it is not that easy. You can move the assigning the onclick to code-behind and take care of the mismatching quotes

1) <asp:Button runat="server ID="btnDateRange" Text="Date Range" />

2) assign the onclick in the rowdatabound

protected void GridView_OnRowDataBound(object sender, GridViewRowEventArgs e)
{
      Button btnDateRange = e.Row.FindControl("btnDateRange") As Button; //if you used Asp:Button
      btnDateRange.Attributes["onclick"] = "javascript:document.getElementById('hdnImpressionTagID').value = '"+e.Row.DataItem("ImpressionTagID")+"'";
}
codingbiz
  • 26,179
  • 8
  • 59
  • 96
  • I wish it was that easy, I've already tried that... "the server tag is not well formed." – wotney Dec 10 '12 at 14:24
  • I think you might be getting wires crossed... The input button works fine, but I can't access it from code behind. The asp:button can be accessed from code behind, but returns: "the server tag is not well formed" - even when I apply your updated 'onclick' suggestion to the asp style button. – wotney Dec 10 '12 at 14:56
  • don't mind me. it worked because I removed the runat="server". To access your control from codebebind, you need to have runat="server" – codingbiz Dec 10 '12 at 15:30
  • Cheers CodingBiz - I think we're getting closer (with assigning the onclick on the RowDataBound) but ... I can't access e.Item - GridViewRowEventArgs doesn't contain Item. I can get to e.Row, but it can't find `Button btnDateRange = e.Row.FindControl("btnDateRange") as Button;` – wotney Dec 10 '12 at 16:06
  • ` = Button` and ` = HtmlInputButton` - obey that logic. Make sure thay match – codingbiz Dec 10 '12 at 17:02
2

Firstly - I couldn't have answered this without the help of codingBiz, so thanks dude !!

The trick was to ditch the <input type="button"> type button and go for a server control, which adds the onclick event on the RowDataBound.

The reason I couldn't go for this the first time round was because I needed to add some javascript to the onclick event, and while this would work on a standard HTML button control, it wouldn't work on the asp:button. CodingBiz pointed me towards adding the onclick event at RowDataBound. With a few code changes to be able to access the correct row and datakey data, I got it working...

ASPX page :

<asp:TemplateField>
    <ItemTemplate>
        <asp:Button runat="server" ID="btnDateRange" Text="asp Date Range" CssClass="JQDatePicker SmallText FloatRight WrapButtonText" />
        <asp:Button ID="btnShowImpressions" CommandArgument='<%# Eval("ImpressionTagID") %>' CommandName="ShowImpressions" Text="Total Impressions" runat="server" UseSubmitBehavior="false" CssClass="SmallText FloatLeft WrapButtonText" Width="80px" />
    </ItemTemplate>
</asp:TemplateField>

Code behind :

        protected void gridImpressionTags_OnRowDataBound(object sender, GridViewRowEventArgs e)
    {
        Button btnDateRange = e.Row.FindControl("btnDateRange") as Button;

         if (e.Row.RowType == DataControlRowType.DataRow)
        {
            Button btn = e.Row.Cells[5].Controls[1] as Button;
            string datakey = gridImpressionTags.DataKeys[e.Row.RowIndex].Value.ToString();

             btn.Attributes["onclick"] = "javascript:document.getElementById('hdnImpressionTagID').value = '" + datakey + "'";
         }
    }
codingbiz
  • 26,179
  • 8
  • 59
  • 96
wotney
  • 1,039
  • 3
  • 21
  • 34