英文:
ASP NET Label Get Dynamic Value using Javascript
问题
以下是您提供的内容的翻译:
我有4个学生姓名的示例记录:
- John Doe
- Jane Smith
- Alice Johnson
- Bob Anderson
我有以下的HTML代码,用于从数据库中获取并存储记录列表:
<asp:TemplateField HeaderText="StudentName" ItemStyle-HorizontalAlign="Center" HeaderStyle-Width="10%" ItemStyle-Width="10%">
<ItemTemplate>
<asp:Label ID="lblStudentName" runat="server" Text='<%# Bind("StudentName") %>' Visible="true"></asp:Label>
<img src="../Images/copy.png" alt="Printer" onclick="copyLabelValue('lblStudentName')" class="col-2" style="cursor: pointer; width: 30px; height: 30px;" />
</ItemTemplate>
</asp:TemplateField>
以及一个JavaScript函数:
function copyLabelValue(label) {
var value = document.getElementById(label).innerText;
navigator.clipboard.writeText(value);
}
但无论我触发第三/第四个复制图像,该值始终返回给我第一个姓名“John Doe”。尝试了其他一些方法,但仍然无法获得我想要的,即如果我点击第三个复制图像,它能够返回给我第三个值,反之亦然。
尝试的方法:
document.getElementById(label).innerText 返回 "John Doe";
document.getElementById('<%=lblStudentName.ClientID%>').innerText 返回 "John Doe";
$('#<%=lblStudentName.ClientID%>').html() 返回 "John Doe";
document.getElementById(label).innerHtml 返回 undefined;
document.getElementById('<%=lblStudentName.ClientID%>').innerHtml 返回 undefined。
英文:
I have a sample records of 4 student names:
- John Doe
- Jane Smith
- Alice Johnson
- Bob Anderson
I am having below html code which take a list of records from db and store:
<asp:TemplateField HeaderText="StudentName" ItemStyle-HorizontalAlign="Center" HeaderStyle-Width="10%" ItemStyle-Width="10%">
<ItemTemplate>
<asp:Label ID="lblStudentName" runat="server" Text='<%# Bind("StudentName") %>' Visible="true"></asp:Label>
<img src="../Images/copy.png" alt="Printer" onclick="copyLabelValue('lblStudentName')" class="col-2" style="cursor: pointer; width: 30px; height: 30px;" />
</ItemTemplate>
</asp:TemplateField>
and a javascript of
function copyLabelValue(label) {
var value = document.getElementById(label).innerText;
navigator.clipboard.writeText(value);
}
but the value keeps returning the first name "John Doe" to me even when i trigerred the third/forth copy image. Tried some other ways but still couldnt get what i want which able to return me the third value if i pressed on the third copy image and vice versa.
Ways:
document.getElementById(label).innerText returns "John Doe"
document.getElementById('<%=lblStudentName.ClientID%>').innerText returns "John Doe"
$('#<%=lblStudentName.ClientID%>').html() returns "John Doe"
document.getElementById(label).innerHtml returns undefined
document.getElementById('<%=lblStudentName.ClientID%>').innerHtml returns undefined
答案1
得分: 1
OK,以下是翻译的部分:
“好的,你不显示这是一个重复器、gridview,甚至是详细视图。
然而,这可能并不重要。
问题当然是,你不只有一个标签的实例,或者图像或其他什么。因此,每一行都“重复”了很多次,实际上标签和图像按钮也都“重复”了很多次。
因此,每一行的控件实际上都是“生成”的,并分配了特定的行 ID。查看这是如何工作的一个好方法是按下 F12(浏览器调试工具),选择“元素”,然后单击“指针”,然后单击页面上的一个元素 - 你会看到每一行的控件都被赋予了一个特定的名称(通常由控件名称,如 gridview,然后是控件名称,然后是行号来前缀)。
所以,有几种方法可以做到这一点。其中一种简单的方法是传递行值,这可能是最简单的方法。
所以,假设这个标记:
<div style="float:left">
<asp:GridView ID="GridView1" runat="server" ShowHeaderWhenEmpty="true"
AutoGenerateColumns="False" DataKeyNames="ID" CssClass="table table-hover"
Width="55em">
<Columns>
<asp:BoundField DataField="FirstName" HeaderText="FirstName" />
<asp:BoundField DataField="LastName" HeaderText="LastName" />
<asp:BoundField DataField="HotelName" HeaderText="HotelName" />
<asp:BoundField DataField="City" HeaderText="City" />
<asp:BoundField DataField="Province" HeaderText="Province" />
<asp:BoundField DataField="Description" HeaderText="Description" />
<asp:TemplateField>
<ItemTemplate>
<img src="../Content/copy.png"
onclick="copyLabelValue('<%# Eval("HotelName") %>')"
style="width:48px;height:48px"
/>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
</div>
<div style="float:left;margin-left:40px">
<h4>粘贴测试区域</h4>
<asp:TextBox ID="TextBox1" runat="server"
TextMode="MultiLine" Height="117px" Width="304px"></asp:TextBox>
</div>
<script>
function copyLabelValue(cText) {
navigator.clipboard.writeText(cText);
}
</script>
在上述代码中,我只是将“表达式”传递给了 JavaScript 代码。
因此,加载的代码如下:
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If Not IsPostBack Then
LoadGrid
End If
End Sub
Sub LoadGrid()
GridView1.DataSource =
MyRst("SELECT * FROM tblHotelsA ORDER BY HotelName")
GridView1.DataBind()
End Sub
结果如下:
但是,假设我们想要获取该网格行上的控件。
所以,假设这个标记:
<asp:TemplateField>
<ItemTemplate>
<asp:Label ID="lblHotelName" runat="server"
Text='<%# Eval("HotelName") %>' style="display:none"></asp:Label>
<img src="../Content/copy.png" id="myimagebtn" runat="server"
onclick="copyLabelValue2(this.id,'myimagebtn')"
style="width:48px;height:48px"
/>
</ItemTemplate>
</asp:TemplateField>
然后是这个:
function copyLabelValue2(btn, cText) {
var tlbl = btn.replace(cText, 'lblHotelName')
var HotelText = document.getElementById(tlbl).innerText
navigator.clipboard.writeText(HotelText);
}
还有其他方法。我认为通常只需使用服务器端表达式传递值效果很好。但是,如果该值包含单引号(或双引号),则代码可能会失败。
因此,最好传递当前控件的“id”(确保有 runat="server",以便为重复器/gridview/listview(实际上是任何数据重复控件)的每一行自动进行服务器端控件重命名)。
另一个可能的技巧?我经常只是为相关控件编写自定义属性。这允许传递多个值!
比如这样:
<asp:TemplateField>
<ItemTemplate>
<img src="../Content/copy.png" id="myimagebtn" runat="server"
onclick="copyLabelValue3(this)"
style="width:48px;height:48px"
myHotel='<%# Eval("HotelName") %>'
/>
</ItemTemplate>
</asp:TemplateField>
然后是这段代码:
function copyLabelValue3(btn) {
var HotelText = btn
英文:
OK, you don't show if this is a repeater, gridview, or even a details view.
However, it probably does not matter.
The issue of course is that you don't have JUST ONE instance of the label, or the image or whatever. As a result each row is "repeated" many times , and in fact both the label, and your image button is ALSO repeated many times.
As a result, then each row of controls are actually "generated" and given a specific row ID. A great way to see how this works is to hit f12 (browser debug tools), select "elements", and then click on the "pointer" and now click on a element in the page - you see that EACH ROW of controls is given a specific name (usually prefixed by the control such as gridview, then the control name, and then a row number!).
So, there are several ways to do this. One simple way is to PASS the row value, and that's probably the most simple.
So, say this markup:
<div style="float:left">
<asp:GridView ID="GridView1" runat="server" ShowHeaderWhenEmpty="true"
AutoGenerateColumns="False" DataKeyNames="ID" CssClass="table table-hover"
Width="55em">
<Columns>
<asp:BoundField DataField="FirstName" HeaderText="FirstName" />
<asp:BoundField DataField="LastName" HeaderText="LastName" />
<asp:BoundField DataField="HotelName" HeaderText="HotelName" />
<asp:BoundField DataField="City" HeaderText="City" />
<asp:BoundField DataField="Province" HeaderText="Province" />
<asp:BoundField DataField="Description" HeaderText="Description" />
<asp:TemplateField>
<ItemTemplate>
<img src="../Content/copy.png"
onclick="copyLabelValue('<%# Eval("HotelName") %>')"
style="width:48px;height:48px"
/>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
</div>
<div style="float:left;margin-left:40px">
<h4>Paste test area</h4>
<asp:TextBox ID="TextBox1" runat="server"
TextMode="MultiLine" Height="117px" Width="304px"></asp:TextBox>
</div>
<script>
function copyLabelValue(cText) {
navigator.clipboard.writeText(cText);
}
</script>
In above, I just pass the "expression" to the js code.
So, code to load is this:
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If Not IsPostBack Then
LoadGrid
End If
End Sub
Sub LoadGrid()
GridView1.DataSource =
MyRst("SELECT * FROM tblHotelsA ORDER BY HotelName")
GridView1.DataBind()
End Sub
And the result is thus this:
However, let's say we want to grab the control on that grid row.
So, say this markup:
<asp:TemplateField>
<ItemTemplate>
<asp:Label ID="lblHotelName" runat="server"
Text='<%# Eval("HotelName") %>' style="display:none"></asp:Label>
<img src="../Content/copy.png" id="myimagebtn" runat="server"
onclick="copyLabelValue2(this.id,'myimagebtn')"
style="width:48px;height:48px"
/>
</ItemTemplate>
</asp:TemplateField>
And then this:
function copyLabelValue2(btn, cText) {
var tlbl = btn.replace(cText, 'lblHotelName')
var HotelText = document.getElementById(tlbl).innerText
navigator.clipboard.writeText(HotelText);
}
There are other ways. I think often just passing the value using a server side expression works quite well. However, if the value has single (or double) quotes, then the code can fail.
As a result, it probably better to pass the "id" of the current control (make sure there is a runat="server", so the server side automatic control re-name occurs for each row of the repeater/gridview/listview (in fact any data repeating control).
Another possible trick? I often just make up a custom attribute for the control in question. This allows MULTIPLE values to be passed!
Say like this:
<asp:TemplateField>
<ItemTemplate>
<img src="../Content/copy.png" id="myimagebtn" runat="server"
onclick="copyLabelValue3(this)"
style="width:48px;height:48px"
myHotel='<%# Eval("HotelName") %>'
/>
</ItemTemplate>
</asp:TemplateField>
And then this code:
function copyLabelValue3(btn) {
var HotelText = btn.getAttribute("myHotel")
alert(HotelText)
navigator.clipboard.writeText(HotelText);
}
but, note that I could say pass Hotel and City by just adding another "made up" attribute
eg:
<img src="../Content/copy.png" id="myimagebtn" runat="server"
onclick="copyLabelValue3(this)"
style="width:48px;height:48px"
myHotel='<%# Eval("HotelName") %>'
myCity='<%# Eval("City") %>'
/>
However, since this means the data is being repeated (sent) to the browser 2 times, then with a large page, this would start to add additional payload to the web page. However, for a few extra values here and there, then adding "made up" attributes works rather well.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论