【问题标题】:Retrieving Client side ID in asp.net for javascript code is not working在 asp.net 中为 javascript 代码检索客户端 ID 不起作用
【发布时间】:2014-08-05 10:29:56
【问题描述】:

对于网站 已定义用户控件 (ascx) 来为用户提供计算帮助。 该控件在另一个 ascx 控件中多次实现,该控件是 umbraco 网站的一部分。

用户控件中的某些面板已被隐藏,我正在尝试通过使用 java 脚本来显示它们。

选择要显示的面板的asp代码:

<asp:Panel ID="firstpanel" runat="server">
  <asp:RadioButtonList ID="rblSelect" runat="server" RepeatDirection="Vertical" >
     <asp:ListItem Text="Show hidden" Value="0" onclick="ShowMe('<%= hiddenPan.ClientID %>');" ></asp:ListItem>
     <asp:ListItem Text="Show other" Value="1" onclick="ShowMe('<%= otherPan.ClientID %>');" ></asp:ListItem>
  </asp:RadioButtonList>
</asp:Panel>

<asp:Panel ID="hiddenPan" runat="server" style="display:none">
  <!-- stuff to work with -->
</asp:Panel>

javascript代码如下:

function ShowMe(showPanel) {
    console.log(showPanel);
    $('#' + showPanel).show();
}

此方法无效。控制台日志返回值 而不是我期望的 clientID。

我尝试过的解决方案: 实现静态客户端 ID -> 因为 ascx 控件被实现了多次,这将导致 javascript 显示和隐藏它找到的第一个控件,而不是活动控件。

我已经尝试过Link 中的解决方案,但它对我不起作用。

我的问题是如何在示例中切换面板的显示。也欢迎一个好的解决方法。

【问题讨论】:

  • 这很奇怪。能否检查一下这段代码是否在IIS下动态运行?
  • 我能在 IIS 中看到吗?
  • 如果这段代码在ASPX 页面中运行,并且该页面在定义为应用程序的虚拟目录中,那么可以。
  • 我查过,是的,它是动态运行的
  • 这是我问的一个愚蠢的问题!打扰一下。我正在寻找一种方法

标签: javascript asp.net


【解决方案1】:

您可以使用JQuery 使用其他解决方法:

<asp:Panel ID="firstpanel" runat="server">
  <asp:RadioButtonList ID="rblSelect" runat="server" RepeatDirection="Vertical" >
     <asp:ListItem Text="Show hidden" Value="0"   ></asp:ListItem>
     <asp:ListItem Text="Show other" Value="1"   ></asp:ListItem>
  </asp:RadioButtonList>
</asp:Panel>

<asp:Panel ID="hiddenPan" runat="server" style="display:none">
  <!-- stuff to work with -->here some content
</asp:Panel>

    <asp:Panel ID="otherPan" runat="server" style="display:none">
  <!-- stuff to work with -->here some more content
</asp:Panel>

在 jQuery 方面:

/// $("[id*=rblSelect] input").live("click", function () { -- old jquery way

// new version of Jquery uses 'on' instead of 'live'
$("[id*=rblSelect]").on("click", "input", function () 
{ 
     var selectedValue = $(this).val();
     if (selectedValue == "0") // IF first item is clicked
     {
          $('#' + '<%=hiddenPan.ClientID %>').show();
     } else {
         $('#' + '<%=otherPan.ClientID %>').show();
     }
 });

【讨论】:

  • 发生了什么?你能详细说明一下吗?因为我在这里做了一个样本并且运行良好
  • 我将代码添加到 Javascript 页面。我添加了一些控制台日志记录,但它们没有显示在 firebug 上。
【解决方案2】:

目前我已经在客户端通过 javascript 进行了以下修改:

<div id="containerDiv">
  <asp:Panel ID="firstpanel" runat="server">
    <asp:RadioButtonList ID="rblSelect" runat="server" RepeatDirection="Vertical" >
       <asp:ListItem Text="Show hidden" Value="0" onclick="ShowMe($$(this, 'hiddenPan'));" ></asp:ListItem>
       <asp:ListItem Text="Show other" Value="1" onclick="ShowMe($$(this, 'otherPan'));" ></asp:ListItem>
    </asp:RadioButtonList>
  </asp:Panel>

  <asp:Panel ID="hiddenPan" runat="server" style="display:none">
    <!-- stuff to work with -->
  </asp:Panel>
</div>

javascript/客户端函数:

function ShowMe(showPanel) {
   showPanel.show();
}

function $$(target, id) {

    var t = $(target);
    var con = t.closest("#containerDiv");
    var el = $("#" + id, con);
    if (el.length < 1)
        el = $("[id$=_" + id + "]", con);

    return el;
}

下面的link是用来解决的。

【讨论】:

    【解决方案3】:

    **已编辑**

    我不确定,但可能是因为 ListItem 属性将所有值转换为字符串,请检查:

    <asp:ListItem Text="<%= hiddenPan.ClientID %>" Value="0"></asp:ListItem>
    

    你可以看到Text也显示为&lt;%= hiddenPan.ClientID %&gt;

    如果与实际项目不冲突,你可以试试这个,这完全符合你的要求:

    <div class="divUserControlContainer">
        <asp:Panel ID="firstpanel" runat="server">
          <asp:RadioButtonList ID="rblSelect" runat="server" RepeatDirection="Vertical" >
             <asp:ListItem Text="Show hidden" Value="0" onclick="ShowMe(this.id,'hiddenPan');" ></asp:ListItem>
             <asp:ListItem Text="Show other" Value="1" onclick="ShowMe(this.id,'otherPan');" ></asp:ListItem>
          </asp:RadioButtonList>
        </asp:Panel>
    
        <asp:Panel ID="hiddenPan" runat="server" style="display:none">
            <!-- stuff to work with -->
        </asp:Panel>
        <asp:Panel ID="otherPan" runat="server" style="display:none">
            <!-- stuff to work with -->
        </asp:Panel>
    </div>
    

    Javascript:

    function ShowMe(thisId, showPanel) {
        console.log(showPanel);
        $('#' + showPanel).show();
        $('#' + thisId).closest('.divUserControlContainer').find("div[id*='" + showPanel + "']").show();
    }
    

    唯一的一点是,每个 PanelID 不应作为另一个 PanelID 的子字符串,并且还应使用 div 用此类将每个 UserControl 包装起来:divUserControlContainer

    【讨论】:

    • 这仅在客户端 ID 模式设置为静态时有效。 ClientIDMode ="static",并且只用于第一个控件。第二个控件不起作用。
    • 不,不是,您不需要设置ClientIDMode ="static",它也可以用于第二个控制,请在编写cmets之前检查答案的代码。
    • 它适用于所有面板,而不仅仅是一个。我正在处理同一个用户控件的多个实例,这会取消隐藏每个实例中的面板。
    • 在您上次发表评论后,我完全理解您的问题,我编辑答案,您可以检查新答案,在编辑后的代码中每个用户控件单独工作,当您单击 ListItemjquery 搜索他的divUserControlContainer 容器,当找到它时,只在同一个divUserControlContainer 中显示选定的面板,不要更改其他divUserControlContainers(阅读其他UserControls)。
    【解决方案4】:

    显然,如果在某些属性(如 ListItem 的“onclick”属性)中使用引号,则 ASP.NET 解析器会将引号编码为其等效的 HTML。 (我不完全了解这种行为,但这是一种情况)。

    为了解决您的问题,我建议使用以下解决方法:仅将控件的名称放在 onclick 属性中,然后在控件的 OnPreRender 方法中找到该控件并使用其客户端 ID 创建一个变量。我选择了PreRender,因为客户端 ID 都是在此之前分配的。

    在控件的标记中,只需输入面板的服务器端Id:

    <asp:ListItem Text="Show hidden" Value="0" onclick="hiddenPan"></asp:ListItem>
    <asp:ListItem Text="Show other" Value="1" onclick="otherPan" ></asp:ListItem>
    

    Control的代码后面:

    public partial class WebUserControl1 : System.Web.UI.UserControl
    {
        protected override void OnPreRender(EventArgs e)
        {
            System.Text.StringBuilder sb = new System.Text.StringBuilder("<script type='text/javascript'>");
            foreach (ListItem i in rblSelect.Items)
            {
                string relatedControlId = i.Attributes["onclick"];
    
                Control relatedControl = null;
                if (!string.IsNullOrEmpty(relatedControlId) && (relatedControl = FindControl(relatedControlId)) != null)
                {
                    sb.AppendFormat("var {0}_id = '{0}';", relatedControl.ClientID);
                    i.Attributes["onclick"] = string.Format("ShowMe({0}_id)", relatedControl.ClientID);
                }
            }
            sb.Append("</script>");
            this.Page.ClientScript.RegisterClientScriptBlock(this.GetType(), string.Format("ids{0}", this.ID) , sb.ToString());
    
            base.OnPreRender(e);
        }
    

    这将添加到呈现的输出 HTML 中,每个 ListItems 的变量如下:

    <script type='text/javascript'>var uc1_hiddenPan_id = 'uc1_hiddenPan';</script>
    

    并将该列表项的每个 onclick 属性更改为如下内容:

     onclick="ShowMe(uc1_hiddenPan_id);"
    

    更新:我已根据 OP 的要求编辑了答案以使用多个控件。

    【讨论】:

    • 不幸的是,此方法将始终显示和隐藏页面的第一个用户控件上的面板,而不是第二个。
    • 我终于明白了问题所在。您应该将代码移至控件的PreRender 事件。在我从理发店回来之前你会测试它吗?
    • @martijn 我已经更新了答案。它可以按您的意愿工作。祝你好运
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-19
    • 2021-09-24
    • 2013-01-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多