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

发布于 2024-11-23 16:43:22 字数 5545 浏览 3 评论 0原文

我有一个带有一堆模板列的网格视图。其中一列是隐藏列,其值为 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 的行数据绑定事件中,我有以下代码片段:

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..可能是因为

@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">

也就是说,我像您一样静态设置值...我运行了我的项目,现在警报没有触发,因此没有< code>onchange,这可能就是您无法重现错误的原因。所以看起来是这样的:

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

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

编辑 4!!!

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

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

只要我消除了 calendarextender,它就可以正常工作...我是否提到过这个 gridview 位于 updatepanel 内?会是这个问题吗??问题是我不想删除日历扩展程序...我希望能够允许用户从中选择一个日期,而不是输入它。

I've got a gridview with a bunch of template columns. One of those columns is a hidden column that either has a value of 0 or 1. If a row in a grid view is changed I set the value to 1, otherwise I leave the default 0.

The templatefield is defined as:

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

My issue is (without too much details), I've got a field where I call a javascript function and do some validation on the client side. Inside of this function I'd like to be able to access this hidden field (rowIsChanged) for this specific row and set the value to 1 (in javascript). That way when I click my server side 'Update' button I can ensure the update occurs given I have a condition checken for rowIsChanged==1.

So my question, I have something to this effect right now:

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

And the javascript:

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

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

So how can I access this particular row's rowIsChanged field and set it to "1".

Edit

Here is more details:

The asp markup:

<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> 

The issue is when I first load the page and load the grid data the system automatically assumes a change was made to the date (value of hidden field is 1). But no changes were made it is just an initial load...So I dont know how to handle this.

In the gridview's row databound event I have the following snippet of code:

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")
 ....

So I've posted code for the rowdatabound event as well as the markup..but as soon as the page loads with NO edits done to the field txtMyDate and I click the "Update" button on my page which does something to this effect:

  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

Every row seems to have the value 1 as if the row was already updated (onchange got called...). But this is not the case. This works fine for any other field that is not using the calendar control. For instance, if I comment the line:

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

And just leave the onchange for all my other fields and then click the "Update" button it works as expected (that is if I change the value in the fields then the hidden field has the value 1 and if i dont change the values in the field they have the value 0). But the issue is just this one field...

Edit 2

Just for testing I even tried this:

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

All I did was add a js function called helloworld() that looks like this:

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

I run my project and right away it alerts out hello world (I have 2 rows in the grid so it alerts out hello world twice). This is without any change whatsoever to the data, the question is why is onchange called without any change? It must have to be with how it is setting the date from the the data returned from the database, is that considered an onchange event when it sees markup like so:

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

Specifically the DataBinder.Eval(Container, "DataItem.MyDate")...

Edit #3..Could be possible cause

@Tim

I decided to make a small change, you mentioned in your comments you filled in the txtMyDate statically by assigning a value to it (rather then pulling the value from the database like I did). So instead of this:

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

Just for giggles I changed it to this:

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

That is I set the value statically like you did...I run my project and now the alert doesn't fire, hence no onchange, this is probably why you could not reproduce the error. So it appears this:

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

Causes the onchange event to fire, which for me is not good :(...so question is how to still handle this??

Edit 4!!!

Wow sorry for all the edits, I am trying to eliminate possibilities here...
So now what I did was remove this line:

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

Meaning I removed the calendarextender from the markup and the onchange event no longer fires on the load event. Why would this be causing this to happen. Even If I leave this:

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

As long as I eliminate the calendarextender it works fine...Did I mention this gridview is inside an updatepanel? Could this be the issue?? The problem is I do not want to remove the calendarextender...I would like to be able to allow users to select a date from that rather then typing it in.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

征﹌骨岁月お 2024-11-30 16:43:22

您可以从代码隐藏添加 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 + "');";
    }
}

Edit:这是 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 之间的差异。

You could add the javascript onchange handler from codebehind:

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

Edit: here is the js-function, it works to set the value and read it after postback:

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

Edit2: added an additional check for a difference between the current textbox' value and it's defaultValue.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文