【问题标题】:access hidden field within gridview control to set a value in javascript?访问gridview 控件中的隐藏字段以在javascript 中设置值?
【发布时间】:2011-07-13 21:29:48
【问题描述】:

我有一个带有一堆模板列的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 的行数据绑定事件中,我有以下 sn-p 代码:

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");
   }

我运行我的项目并立即发出 hello world 警报(我在网格中有 2 行,因此它会发出 hello world 两次警报)。这对数据没有任何改变,问题是为什么在没有任何改变的情况下调用 onchange?它必须与它如何从数据库返回的数据中设置日期有关,当它看到这样的标记时被认为是一个 onchange 事件:

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

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

编辑#3..可能是原因

@蒂姆

我决定做一个小改动,你在你的 cmets 中提到你通过为其分配一个值来静态填写 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!!!

对于所有的编辑,我很抱歉,我正在努力消除这里的可能性...... 所以现在我所做的就是删除这一行:

&lt;ajaxToolkit:CalendarExtender TargetControlID="txtMyDate" ID="CalendarExtender3" runat="server"&gt;&lt;/ajaxToolkit:CalendarExtender&gt;

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

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

只要我消除了 calendarextender,它就可以正常工作...我有没有提到这个 gridview 在更新面板中?会不会是这个问题??问题是我不想删除日历扩展器...我希望能够允许用户从中选择一个日期而不是输入它。

【问题讨论】:

    标签: javascript asp.net hidden-field


    【解决方案1】:

    您可以从代码隐藏中添加 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函数,它可以设置值并在回发后读取:

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

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

    【讨论】:

    • 我尝试过类似的方法,您能否在您的帖子中发布更新,显示 DoSomeValidation 的 javascript 实际访问该隐藏字段并设置一个值?
    • Tim 我明天会告诉你这是否有效。谢谢你的手
    • 我过去也遇到过同样的问题...问题是文本框 txtMyDate 有一个与之关联的日历扩展器。不知何故,当我最初用值(包括 txtMyDate 的值)填充我的网格时,它似乎已经调用了 onchange 事件......所以我的问题是我无法在这里设置hidden.value=1,因为没有任何更改只是加载数据。现在恐怕我不知道该如何处理?
    • @JonH:抱歉,我无法重现此问题。我已经在 TextBox txtMyDate 正下方的 ItemTemplate 中添加了一个 CalendarExtender,并且仅当我从 CalendarExtender 或手动(onblur)中选择一个日期时才会触发 onchange 事件。我在加载时静态设置了文本。
    • @JonH:编辑:也使用数据绑定日期值进行了测试,结果相同。 DoSomeValidation-函数仅在用户更改日期时调用,而不是在初始加载时调用。
    猜你喜欢
    • 2012-11-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多