访问gridview控件中的隐藏字段以在javascript中设置值?

时间:2011-07-13 21:29:49

标签: javascript asp.net hidden-field

我有一组带有一堆模板列的gridview。其中一列是隐藏列,其值为0或1.如果网格视图中的行更改,我将值设置为1,否则保留默认值0.

模板字段定义为:

<asp:TemplateField>
      <ItemTemplate>
          <input type="hidden" id="rowIsChanged" runat="server" />
      </ItemTemplate>
 </asp:TemplateField>

我的问题是(没有太多细节),我有一个字段,我调用javascript函数并在客户端进行一些验证。在这个函数里面,我希望能够访问这个特定行的隐藏字段(rowIsChanged)并将值设置为1(在javascript中)。这样当我点击我的服务器端“更新”按钮时,我可以确保更新发生,因为我已经检查了rowIsChanged==1

所以我的问题,我现在有一些效果:

<asp:TemplateField>
  <ItemTemplate>
    <asp:TextBox id="txtMyDate" runat="server" onchange="DoSomeValidation(this)" />
  </ItemTemplate>
<asp:TemplateField>

和javascript:

function DoSomeValidation(myParam)
 {
   //do some validation...

   //here is where I need to access the hidden field 'rowIsChanged' and set the value to "1"
 }

那么如何访问这个特定行的rowIsChanged字段并将其设置为“1”。

修改

以下是更多详情:

asp标记:

<asp:TemplateField HeaderText="Date" SortExpression="LineItemDate">
      <ItemTemplate>
        <ajaxToolkit:CalendarExtender TargetControlID="txtMyDate" ID="CalendarExtender3" runat="server"></ajaxToolkit:CalendarExtender>
        <asp:TextBox ToolTip="Line Item Date"  Width="60px"  ID="txtMyDate" runat="server" Text='<%# DataBinder.Eval(Container, "DataItem.MyDate") %>'></asp:TextBox>
      </ItemTemplate>
   </asp:TemplateField> 

问题是当我第一次加载页面并加载网格数据时,系统会自动假设对日期进行了更改(隐藏字段的值为1)。但是没有改变它只是一个初始负载...所以我不知道如何处理这个。

在gridview的row databound事件中,我有以下代码片段:

If e.Row.RowType = DataControlRowType.DataRow Then
            Dim hiddenField As HtmlInputHidden = DirectCast(e.Row.FindControl("rowIsChanged"), HtmlInputHidden)

            Dim tLID As TextBox = CType(e.Row.FindControl("txtMyDate"), TextBox)

            tLID.Attributes.Add("onchange", "document.getElementById('" + hiddenField.ClientID + "').value=1")
 ....

所以我发布了rowdatabound事件和标记的代码。但是一旦页面加载 NO 对字段txtMyDate进行了编辑,我点击了我的页面上的“更新”按钮有效:

  For Each Row As GridViewRow In Me.gvLineItems.Rows
            Dim hiddenField As HtmlInputHidden = DirectCast(Row.FindControl("rowIsChanged"), HtmlInputHidden)
            'only update rows that have been edited / update IsDirty=1 :)
            If (hiddenField.Value = "1") Then

每一行似乎都有值1,好像该行已经更新(onchange被调用...)。但这种情况并非如此。这适用于未使用日历控件的任何其他字段。例如,如果我评论该行:

tLID.Attributes.Add("onchange", "document.getElementById('" + hiddenField.ClientID + "').value=1")

然后离开我所有其他字段的onchange,然后单击它按预期工作的“更新”按钮(即如果我更改字段中的值,则隐藏字段的值为1,如果我不更改在字段中的值,它们具有值0)。但问题只是这一个领域......

编辑2

只是为了测试我甚至试过这个:

Protected Sub gvLineItems_RowDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewRowEventArgs) Handles gvLineItems.RowDataBound
        If e.Row.RowType = DataControlRowType.DataRow Then
            'this is used to add a trigger to the <TRIGGERS> tag for the update panel
            'I could not do it in the HTML / ASP code because the button is inside of a gridview control
            Dim hiddenField As HtmlInputHidden = DirectCast(e.Row.FindControl("hdnIsChanged"), HtmlInputHidden)

            'the line item date
            Dim tLID As TextBox = CType(e.Row.FindControl("txtMyDate"), TextBox)

            'just a test...
            tLID.Attributes("onchange") = "helloworld();"

我所做的只是添加一个名为helloworld()的js函数,如下所示:

 function helloworld()
   {
   alert ("hello world");
   }

我运行我的项目并立即发出警告世界(我在网格中有2行,因此它会两次警告你好的世界)。这对数据没有任何改变,问题是为什么onchange被调用而没有任何改变?它必须与从数据库返回的数据设置日期的方式一样,当它看到标记时,它被视为onchange事件:

<asp:TextBox ToolTip="Line Item Date" ID="txtMyDate" runat="server" Text='<%# DataBinder.Eval(Container, "DataItem.MyDate") %>' />

特别是DataBinder.Eval(Container, "DataItem.MyDate")...

编辑#3 ..可能原因

@Tim

我决定做一个小改动,你在评论中提到你通过为它分配一个值来静态填充txtMyDate(而不是像我一样从数据库中提取值)。所以不要这样:

<asp:TextBox ToolTip="Line Item Date" ID="txtMyDate" runat="server" Text='<%# DataBinder.Eval(Container, "DataItem.MyDate") %>'

只是为了咯咯笑,我把它改成了这个:

<asp:TextBox ToolTip="Line Item Date"  Width="60px"  ID="txtMyDate" runat="server" Text="1/1/2011">

那就是我像你一样设置值静态 ...我运行我的项目,现在警报不会触发,因此没有onchange,这可能就是为什么你可以不重现错误。所以看来这个:

<asp:TextBox ToolTip="Line Item Date" ID="txtMyDate" runat="server" Text='<%# DataBinder.Eval(Container, "DataItem.MyDate") %>'

导致onchange事件触发,这对我来说不好:( ...所以问题是如何处理这个?

编辑4 !!!

对不起所有的编辑,我试图消除这里的可能性...... 所以我现在所做的就是删除这一行:

<ajaxToolkit:CalendarExtender TargetControlID="txtMyDate" ID="CalendarExtender3" runat="server"></ajaxToolkit:CalendarExtender>

含义我从标记中删除了calendarextender,并且onchange事件不再在load事件上触发。为什么会导致这种情况发生。即使我离开了这个:

<asp:TextBox ToolTip="Line Item Date" ID="txtMyDate" runat="server" Text='<%# DataBinder.Eval(Container, "DataItem.MyDate") %>'>

只要我消除了calendarextender它就可以正常工作......我是否提到过这个gridview是在更新面板内?这可能是问题吗?问题是我不想删除calendarextender ...我希望能够允许用户从中选择日期而不是输入日期。

1 个答案:

答案 0 :(得分:2)

您可以从codebehind添加javascript onchange处理程序:

Protected Sub GridView1_RowDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewRowEventArgs)
    If e.Row.RowType = DataControlRowType.DataRow Then
        Dim hidden = DirectCast(e.Row.FindControl("rowIsChanged"), HtmlInputHidden)
        Dim txtMyDate = DirectCast(e.Row.FindControl("txtMyDate"), TextBox)
        txtMyDate.Attributes("onchange") = "DoSomeValidation(this,'" & hidden.ClientID & "');"
    End If
End Sub

C#

protected void GridView1_RowDataBound(object sender, System.Web.UI.WebControls.GridViewRowEventArgs e)
{
    if (e.Row.RowType == DataControlRowType.DataRow) {
        var hidden = (HtmlInputHidden)e.Row.FindControl("rowIsChanged");
        var txtMyDate = (TextBox)e.Row.FindControl("txtMyDate");
        txtMyDate.Attributes("onchange") = "DoSomeValidation(this,'" + hidden.ClientID + "');";
    }
}

编辑:这里是js-function,它可以设置值并在回发后读取它:

 <script type="text/javascript">
     function DoSomeValidation(ctrl, hiddenID) {
        var hidden = document.getElementById(hiddenID);
        if(ctrl.defaultValue != ctrl.value)
            hidden.value = "1";
     }
 </script>

Edit2 :添加了对当前文本框值与defaultValue之间差异的额外检查。