Edit: Found the solution, and posted the answer below.

In my ASP.NET c# project, I have a ListView (ParentList) bound to a DataSource. Within the ParentList, inside the ItemTemplate, I have another Repeater (ChildList) bound to an attribute of each ListViewDataItem.

<asp:ListView ID="ParentList" runat="server" DataSourceID="objectDataSourceID" DataKeyNames="ID">                    
    <ItemTemplate>
        <tr>
            <td>
                <asp:Label ID="Label1" runat="server" Text='<%# Eval("Attribute1") %>' />
            </td>
            <td valign="top">
                <asp:Repeater ID="ChildList" runat="server" DataSource='<%# Eval("Attribute2ReturnsAnotherList") %>'>
                    <HeaderTemplate>
                        <ul>
                    </HeaderTemplate>
                    <ItemTemplate>
                        <li>
                            <%# DataBinder.Eval(Container.DataItem, "childAttribute") %> 
                        </li>
                    </ItemTemplate>
                    <FooterTemplate>
                        </ul>
                    </FooterTemplate>
                </asp:Repeater>
            </td>
        </tr>
    </ItemTemplate>
    <LayoutTemplate>
        ...
    </LayoutTemplate>
</asp:ListView>

The code above works just fine, everything renders great. Now I want to add a link that will show/hide the ChildList. Something like the below:

<td valign="top">
    <a href="javascript:ToggleListVisibility()" >Show/Hide</a>
    <asp:Repeater ID="ChildList" runat="server" DataSource='<%# Eval("Attribute2ReturnsAnotherList") %>'>
    </asp:Repeater>
</td>

How can I achieve this? I can't just use getElementById as I normally would, as the ul lists are within a Repeater nested inside the ListView. I tried obtaining the parentNode, then accessing the children and toggling the visibility of the ul element within:

function ToggleListVisibility(source) {
    var childrenlist = source.parentNode.children;
    for (var i = 0; i < childrenlist.length; i++) {
        if (childrenlist[i].tagName == 'ul') {
            if (childrenlist.style.display == "none") {
                childrenlist.style.display = "block";
            } else {
                childrenlist.style.display = "none";
            }                    
        }
    }            
}

<a href="javascript:ToggleListVisibility(this)" >Show/Hide</a>

but that didn't work. IE's 'error on page' gave me this error:

The parentNode is null or not an object.

I also tried setting the a runat="server" attribute to my ul element, then using <%# ulID.ClientID %> to pass the ul id to the Js function, but visual studio complained:

Server elements cannot span templates.

Finally, I tried just passing the ul object into the Js function, like this:

function ToggleListVisibility(src) {
    if (src.style.display == "none") {
        src.style.display = "block";
    } else {
        src.style.display = "none";
    }                              
}

<a href="javascript:ToggleListVisibility(ulID)" >Show/Hide</a>
...
<ul id="ulID">

which works, but it toggles the visibility for the ChildList in all rows within my ParentList. I want it to only toggle the visibility for the ChildList in its own row.

I'm at a loss of what to do. JavaScript is not my forte, and I would appreciate if someone can provide some pointers. Thanks in advance.

有帮助吗?

解决方案 2

I found the painfully simple answer that makes me feel like a doofus. All I needed to do is wrap my Repeater in a <div> element, then show/hide the entire thing.

<a href="javascript:ToggleListVisibility('<%# Container.FindControl("divWrapper").ClientID %>')" >Show/Hide</a>
<div id="divWrapper" runat="server">                                
<asp:Repeater ID="ChildList" runat="server">
</asp:Repeater>
</div>

function ToggleListVisibility(id) {
    var wrapper = document.getElementById(id);
    if (wrapper.style.display == "none") {
        wrapper.style.display = "block";
    } else {
        wrapper.style.display = "none";
    }
}

Hooray for overthinking!

其他提示

Ok hopefully this will get you going - it worked for me in hiding a list. My source HTML looks like this:

<table>
  <tbody>
  ...
    <tr>
      <td>
         <a href="#" onclick="javascript:toggleListVisibility(this);">Hide</a>
         <ul>
           <li>One</li>
           <li>Two</li>
           <li>Three</li>
         </ul>
      </td>
    </tr>
  ...
  </tbody>
</table>

<script type="text/javascript">
  function toggleListVisibility(src) {
    var childrenList = src.nextSibling.nextSibling;
    childrenList.style.display = "none";
  }
</script>

Note I had to use two "nextSibling"'s due to a text node that is created right after the "hide" anchor. Depending on how you structure your HTML, that bit will be different.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top