【问题标题】:Multiple instances of usercontrol in asp.netasp.net中用户控件的多个实例
【发布时间】:2013-09-17 02:44:55
【问题描述】:

我有一个带有文本框的用户控件。 onclick 的文本框打开一个 popupcontrolExtender,上面有几个复选框。当一个复选框被选中时,它将复选框值写入文本框。

这是我的 java 脚本:

<script type = "text/javascript">

    function CheckItem(checkBoxList) {
        var options = checkBoxList.getElementsByTagName('input');
        var arrayOfCheckBoxLabels = checkBoxList.getElementsByTagName("label");
        var s = "";

        for (i = 0; i < options.length; i++) {
            var opt = options[i];
            if (opt.checked) {
                s = s + "," + arrayOfCheckBoxLabels[i].innerText;
            }
        }
        if (s.length > 0) {
            s = s.substring(2, s.length); 
        }
        var TxtBox = document.getElementById("<%=txtCombo.ClientID%>");
    TxtBox.value = s;
    document.getElementById('<%=hidVal.ClientID %>').value = s;
    }

</script>

在上面的 js 中,这段代码 var TxtBox = document.getElementById("&lt;%=txtCombo.ClientID%&gt;"); 获取文本框并写入它。

当我在我的 aspx 页面中使用 UserControl 时,如果我的用户控件只有一个实例,它可以正常工作。但是当我添加用户控件的第二个实例时,文本只写入文本框的第二个实例。如果我在用户控件的第一个实例中选中/取消选中第一个复选框,文本仍会添加到 altest 复选框。

有人可以帮我解决这个问题吗?如何获取复选框的每个实例以便我可以修改我的 java 脚本?

编辑

添加完整代码

<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="MultiSelectDropDown.ascx.cs" Inherits="MenuTest.MultiSelectDropDown" %>
<%@ Register Assembly="AjaxControlToolkit" Namespace="AjaxControlToolkit" TagPrefix="cc1" %>

<script type = "text/javascript">

    function CheckItem(checkBoxList) {
        var options = checkBoxList.getElementsByTagName('input');
        var arrayOfCheckBoxLabels = checkBoxList.getElementsByTagName("label");
        var s = "";

        for (i = 0; i < options.length; i++) {
            var opt = options[i];
            if (opt.checked) {
                s = s + "," + arrayOfCheckBoxLabels[i].innerText;
            }
        }
        if (s.length > 0) {
            s = s.substring(2, s.length); //sacar la primer 'coma'
        }
        var TxtBox = document.getElementById("<%=txtCombo.ClientID%>");
    TxtBox.value = s;
    document.getElementById('<%=hidVal.ClientID %>').value = s;
    }

</script>


<asp:TextBox ID="txtCombo" runat="server" ReadOnly="true" Width="150" Font-Size="X-Small"></asp:TextBox>
<cc1:PopupControlExtender ID="PopupControlExtender111" runat="server" 
    TargetControlID="txtCombo" PopupControlID="Panel111" Position="Bottom"
     >
</cc1:PopupControlExtender>

<input type="hidden" name="hidVal" id="hidVal" runat="server" />

<asp:Panel ID="Panel111" runat="server" ScrollBars="Vertical" Width="150" Height="110" BackColor="AliceBlue" BorderColor="Gray" BorderWidth="1">

    <asp:CheckBoxList ID="chkList" 
        runat="server" 
        Height="80" onclick="CheckItem(this)">      
        <asp:ListItem Text="Contains" Value="Contains"/>
        <asp:ListItem Text="Related" Value="Related"/>
        <asp:ListItem Text="Exact" Value="Exact"/>
    </asp:CheckBoxList>
</asp:Panel>

【问题讨论】:

  • 您确认他们获得了不同的 ID 吗?
  • 我已经习惯了开发者工具,并且看到他们拥有不同的 ID
  • 对,所以也许你必须再次执行 getElementsByTagName。
  • 感谢@HanletEscaño,如果我按标签使用get 元素,是否确保它将写入相应的用户控件文本框?
  • 不完全是。让我们解决这个问题:chat.stackoverflow.com/rooms/37269/lets-solve-this

标签: c# javascript asp.net ajax


【解决方案1】:

每次您拥有 UserControl 的实例时,您都在重新添加 javascript 函数。您应该添加一次 javascript 函数,因此将其从 UserControl 中删除并将其添加到您的主 .aspx 页面中,并将其更改为如下内容:

function CheckItem(chk, txt, hid) {
    var tbl = chk.parentNode.parentNode.parentNode; //table with checkboxes

    var options = tbl.getElementsByTagName('input'); //checkboxes
    var arrItems = new Array(); //array for selected items

    for (i = 0; i < options.length; i++) {
        var opt = options[i];
        if (opt.checked) {
            arrItems.push(opt.value); //if checked, push it in array
        }
    }

    txt.value = arrItems.join(", "); //use join to comma separate them
    hid.value = arrItems.join(); //comma separated without extra space
}

现在让我们从每个 Checkbox 调用该函数,而不是从 CheckBoxList 调用。为此,我们在每次用户单击复选框项时添加一个属性,而不是整个控件,我们将其放在后面的代码中:

protected void Page_Load(object sender, EventArgs e)
{
    if (!Page.IsPostBack)
    {
        foreach (ListItem li in this.chkList.Items)
        {
            li.Attributes.Add("onclick", "CheckItem(this, document.getElementById('" + txtCombo.ClientID + "'), document.getElementById('" + hidVal.ClientID + "'))");
        }
    }
}

最后,从 CheckBoxList 中删除所有 javascript 事件,因为我们在后面的代码中这样做了:

<asp:CheckBoxList ID="chkList" runat="server" Height="80">
    <asp:ListItem Text="Contains" Value="Contains" />
    <asp:ListItem Text="Related" Value="Related" />
    <asp:ListItem Text="Exact" Value="Exact" />
</asp:CheckBoxList>

【讨论】:

    【解决方案2】:

    另一种方法是使 javascript 函数名称对用户控件的每个实例都是唯一的。您可以通过将用户控件客户端 ID 附加到函数名称来做到这一点。

    function CheckItem<%=ClientID %>(checkBoxList) {
    

    确保在调用函数时还包括客户端 ID。

    Height="80" onclick="CheckItem<%=ClientID %>(this)">
    

    【讨论】:

    • onclick="CheckItem(this)" 语法无效。我收到以下错误:这不是 scriptlet。将作为纯文本输出。
    • @SteveStaple 当您尝试在服务器端标记(其中包含 runat="server" 的任何内容)中使用 标签。
    • 我喜欢,这让我发疯了
    【解决方案3】:

    包含您的 ASP 和完整的 JavaScript 将有助于我更清楚地了解您的挑战。或者至少了解 CheckItem() 调用的来源。

    话虽如此..我正在对这个提议做出假设:

    您能否修改 CheckItem() 的调用者,使其包含 txtCombo.ClientID 和 hidVal.ClientID?类似这样:

    <script type = "text/javascript">
    
        function CheckItem(checkBoxList, txtClientId, hidClientId) {
            var options = checkBoxList.getElementsByTagName('input');
            var arrayOfCheckBoxLabels = checkBoxList.getElementsByTagName("label");
            var s = "";
    
            for (i = 0; i < options.length; i++) {
                var opt = options[i];
                if (opt.checked) {
                    s = s + "," + arrayOfCheckBoxLabels[i].innerText;
                }
            }
            if (s.length > 0) {
                s = s.substring(2, s.length); //sacar la primer 'coma'
            }
            var TxtBox = document.getElementById(txtClientId);
        TxtBox.value = s;
        document.getElementById(hidClientId).value = s;
        }
    
    </script>
    

    你的电话会是这样的:

    CheckItem(checkBoxList, '<%=txtCombo.ClientID%>', '<%=hidVal.ClientID %>');
    

    【讨论】:

    • forums.asp.net/p/1935248/…可以在上面的链接中看到完整的代码
    • 好的,感谢您发布整个控件。要么使用我上面的解决方案,要么更改您的代码隐藏,以便您的代码为每个用户控件创建一个唯一的 JavaScript 函数名称。
    • 我已经使用了你的解决方案,但它似乎仍然不起作用,CheckItem(checkBoxList, '', '');无法将 txtcombo id 发送到 java 脚本功能。执行 java 脚本时,它的 id 为空
    • 我有机会访问您的网页吗?只是为了确定..您将函数签名更改为: function CheckItem(checkBoxList, txtClientId, hidClientId) { 并将 onClick 更改为 onclick="CheckItem(this, '', '')
    【解决方案4】:

    尝试添加类似 jQuery 的选择器: $( "input[id*='man']" ) 将找到 'bigman' 和 'littleman'

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多