访问 gridview 控件中的隐藏字段以在 javascript 中设置值?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6685939/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
access hidden field within gridview control to set a value in javascript?
提问by JonH
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.
我有一个带有一堆模板列的 gridview。其中一列是隐藏列,其值为 0 或 1。如果更改了网格视图中的一行,我会将值设置为 1,否则保留默认值 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
.
我的问题是(没有太多细节),我有一个字段,我可以在其中调用 javascript 函数并在客户端进行一些验证。在此函数内部,我希望能够访问此特定行的隐藏字段 (rowIsChanged) 并将值设置为 1(在 javascript 中)。这样,当我单击服务器端的“更新”按钮时,我可以确保更新发生,因为我已经检查了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:
和 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".
那么如何访问该特定行的 rowIsChanged 字段并将其设置为“1”。
Edit
编辑
Here is more details:
以下是更多详细信息:
The asp markup:
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>
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.
问题是当我第一次加载页面并加载网格数据时,系统会自动假定对日期进行了更改(隐藏字段的值为 1)。但是没有进行任何更改,这只是初始加载...所以我不知道如何处理。
In the gridview's row databound event I have the following snippet of code:
在 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")
....
So I've posted code for the rowdatabound event as well as the markup..but as soon as the page loads with NOedits done to the field txtMyDate
and I click the "Update" button on my page which does something to this effect:
所以我已经发布了 rowdatabound 事件和标记的代码..但是一旦页面加载时没有对字段进行任何编辑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
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:
每一行似乎都有值 1,就好像该行已经更新(onchange 被调用......)。但这种情况并非如此。这适用于不使用日历控件的任何其他字段。例如,如果我评论该行:
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...
只需为我的所有其他字段保留 onchange,然后单击它按预期工作的“更新”按钮(也就是说,如果我更改字段中的值,则隐藏字段的值为 1,如果我不更改中的值字段,它们的值为 0)。但问题只是这一领域......
Edit 2
编辑 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:
我所做的只是添加一个名为 helloworld() 的 js 函数,如下所示:
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:
我运行我的项目并立即发出 hello world 警报(我在网格中有 2 行,因此它两次向 hello world 发出警报)。这对数据没有任何改变,问题是为什么在没有任何改变的情况下调用onchange?它必须与它如何设置从数据库返回的数据中的日期有关,当它看到这样的标记时,它是否被认为是一个 onchange 事件:
<asp:TextBox ToolTip="Line Item Date" ID="txtMyDate" runat="server" Text='<%# DataBinder.Eval(Container, "DataItem.MyDate") %>' />
Specifically the DataBinder.Eval(Container, "DataItem.MyDate")...
具体来说 DataBinder.Eval(Container, "DataItem.MyDate")...
Edit #3..Could be possible cause
编辑 #3 .. 可能是原因
@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:
我决定做一个小的改变,你在评论中提到你通过为它分配一个值来静态填充 txtMyDate (而不是像我一样从数据库中提取值)。所以而不是这个:
<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 staticallylike 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:
那就是我像你一样静态设置值......我运行我的项目,现在警报没有触发,因此没有onchange
,这可能是你无法重现错误的原因。所以看起来是这样的:
<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??
导致onchange
事件触发,这对我来说并不好:(...所以问题是如何仍然处理这个??
Edit 4!!!
编辑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>
<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:
这意味着我从标记中删除了 calendarextender,并且 onchange 事件不再在加载事件上触发。为什么这会导致这种情况发生。即使我离开这个:
<asp:TextBox ToolTip="Line Item Date" ID="txtMyDate" runat="server" Text='<%# DataBinder.Eval(Container, "DataItem.MyDate") %>'>
<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.
只要我消除了日历扩展器,它就可以正常工作......我有没有提到这个 gridview 是在一个更新面板内?会不会是这个问题??问题是我不想删除日历扩展器......我希望能够允许用户从中选择一个日期而不是输入它。
采纳答案by Tim Schmelter
You could add the javascript onchange handler from 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#
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:
编辑:这是 js 函数,它可以设置值并在回发后读取它:
<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.
Edit2:添加了对当前文本框值与其defaultValue之间差异的额外检查。