1
votes

I am trying to implement a nested repeater with outer repeater showing categories (initially collapsed) and when user clicks + or - inner repeater expands/collapses.

I have the repeaters but when I clicked on + both inner repeaters expanded. I tried to set the class name dynamically so only one would expand but now it sees I broke it.

This is what I have and what I have tried (minus irrelevant stuff):

<asp:Repeater runat="server" ID="rptCategoryList" OnItemDataBound="rptCategoryList_ItemDataBound">
    <ItemTemplate>
        <div style="font-size: 120%">
            <%# Eval("CourseCategory")%>
            <i id="br-plus" class="fa fa-plus-circle" style="color: #3697EA; margin-left: 1%; margin-top: 60px;" data-cat="<%# Eval("Abbrev")%>"></i>
            <i id="br-minus" class="fa fa-minus-circle" style="color: #3697EA; margin-left: 1%; margin-top: 60px; display: none;"></i>

        </div>
        <div class="row">
            <asp:Repeater runat="server" ID="rptCourses" OnItemDataBound="rptCourses_ItemDataBound" OnItemCommand="rptCourses_ItemCommand">
                <HeaderTemplate>
                    <table class='<%# Eval("Abbrev")%>' style="display: none; margin-top: 10px; font-size: 26px; width: 90%;">
                </HeaderTemplate>
                <ItemTemplate>
                    <tr style="border-top: 1px solid #000;">
                        <td style="padding-top: 30px;">
                        </td>
                        ...
                        <td style="padding-top: 30px;">
                        </td>
                    </tr>
                </ItemTemplate>
                <FooterTemplate>
                    </table>
                </FooterTemplate>
            </asp:Repeater>            
        </div>
    </ItemTemplate>
</asp:Repeater>

I tried adding a data attribute to + and - icons (data-cat), use the same value of category for the table in inner repeater (set its class to be the category name), and in jQuery expand and collapse based on which plus/minus was clicked.

When I view source, icons have correct data attribute (correct category abbreviation) but table's class name is blank.

$(function () {
    $('#br-plus').on('click', function () {debugger
        var cat = $('#br-plus').data("cat")
        //var catID = $('#hfCategoryID').val();
        $('.' + cat).toggle();
        $(this).hide();
        $('#br-minus').show();
    });

    $('#br-minus').on('click', function () {debugger
        //var catID = $('#hfCategoryID').val();
        var cat = $('#br-minus').data("cat")
        $('.' + cat).toggle();
        $(this).hide();
        $('#br-plus').show();
    });

Update - result of View Source

$(function() {
  //$('.courses').hide();

  $('#br-plus').on('click', function() {
    debugger
    var cat = $(this).data("cat")
    //var catID = $('#hfCategoryID').val();
    $('.' + cat).toggle();
    $(this).hide();
    $('#br-minus').show();
    $(this).siblings().show();
  });

  $('#br-minus').on('click', function() {
    debugger
    //var catID = $('#hfCategoryID').val();
    var cat = $(this).data("cat")
    $('.' + cat).toggle();
    $(this).hide();
    $('#br-plus').show();
    $(this).siblings().hide();
  });

  $('#net-plus').on('click', function() {
    $('.courses-net').toggle();
    $(this).hide();
    $('#net-minus').show();

  });

  $('#net-minus').on('click', function() {
    $('.courses-net').toggle();
    $(this).hide();
    $('#net-plus').show();
  });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<body>
  <div style="font-size: 120%">
    Delivery Operations
    <i id="br-plus" class="fa fa-plus-circle" style="color: #3697EA; margin-left: 1%; margin-top: 60px;" data-cat="DelOps">+</i>
    <i id="br-minus" class="fa fa-minus-circle" style="color: #3697EA; margin-left: 1%; margin-top: 60px; display: none;" data-cat="DelOps">-</i>
  </div>
  <div class="row">
    <!-- This is where the content of inner repeater is; note emply class name -->
    <table class='' style="display: none; margin-top: 10px; font-size: 26px; width: 90%;">

      <tr style="border-top: 1px solid #000;">
        <td style="padding-top: 30px;">
        </td>
        <td style="text-align: center;">
        </td>
      </tr>

      <tr style="border-top: 1px solid #000;">
        <td style="padding-top: 30px;">
        </td>
        <td style="text-align: center;">
        </td>
      </tr>
    </table>

  </div>

  <div style="font-size: 120%">
    Network Operations
    <i id="br-plus" class="fa fa-plus-circle" style="color: #3697EA; margin-left: 1%; margin-top: 60px;" data-cat="NetOps">+</i>
    <i id="br-minus" class="fa fa-minus-circle" style="color: #3697EA; margin-left: 1%; margin-top: 60px; display: none;" data-cat="NetOps">-</i>
  </div>
  <div class="row">

    <table class='' style="display: none; margin-top: 10px; font-size: 26px; width: 90%;">

      <tr style="border-top: 1px solid #000;">
        <td style="padding-top: 30px;">
        </td>
        <td style="text-align: center;">
        </td>
      </tr>

      <tr style="border-top: 1px solid #000;">
        <td style="padding-top: 30px;">
        </td>
        <td style="text-align: center;">
        </td>
      </tr>
    </table>

  </div>


</body>
1
Try var cat = $(this).data("cat") so you get the cat of what just got clicked. If that doesn't fix your problem, please post the source of the web page as well, so we can see exactly what the javascript is working with. - Ruzihm
Also you probably want to use $(this).siblings().show(); so you only show the sibling of what just got clicked. - Ruzihm
I tried both suggestions and it is not working. The + in first item in top repeater changes to - and back to +, but nothing is expanded or collapsed. The second item (category) in top repeater does not respond to clicks on +. Please see update for "View Source" of the page. - NoBullMan

1 Answers

0
votes

You still need to change $(this).siblings().hide(); to $(this).siblings().show();. This lets you get rid of $('#br-plus').show(); $('#br-minus').show();

Also, since you have multiple br-plus/br-minus elements, you can't use an id to select on them, you'll want to use it as a class instead:

$('.br-minus').on('click', function() {
    debugger
    //var catID = $('#hfCategoryID').val();
    var cat = $(this).data("cat")
    $('.' + cat).toggle();
    $(this).hide();
    $(this).siblings().show();
  });

Edit: I found a solution for the blank class at Accessing parent data in nested repeater, in the HeaderTemplate. In order to get the Abbrev from the inner repeater, you need to reference the parent of the container you're in.

...

<div class="row">
    <asp:Repeater runat="server" ID="rptCourses" OnItemDataBound="rptCourses_ItemDataBound" OnItemCommand="rptCourses_ItemCommand">
        <HeaderTemplate>
            <table class='<%# ((RepeaterItem)Container.Parent).Abbrev %>' style="display: none; margin-top: 10px; font-size: 26px; width: 90%;">
        </HeaderTemplate>

...

Once you get the class working, it should look like this:

$(function() {
  //$('.courses').hide();

  $('.br-plus').on('click', function() {
    debugger
    var cat = $(this).data("cat")
    //var catID = $('#hfCategoryID').val();
    $('.' + cat).toggle();
    $(this).hide();
    $(this).siblings().show();
  });

  $('.br-minus').on('click', function() {
    debugger
    //var catID = $('#hfCategoryID').val();
    var cat = $(this).data("cat")
    $('.' + cat).toggle();
    $(this).hide();
    $(this).siblings().show();
  });

  $('#net-plus').on('click', function() {
    $('.courses-net').toggle();
    $(this).hide();
    $('#net-minus').show();

  });

  $('#net-minus').on('click', function() {
    $('.courses-net').toggle();
    $(this).hide();
    $('#net-plus').show();
  });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<body>
  <div style="font-size: 120%">
    Delivery Operations
    <i class="br-plus" class="fa fa-plus-circle" style="color: #3697EA; margin-left: 1%; margin-top: 60px;" data-cat="DelOps">+</i>
    <i class="br-minus" class="fa fa-minus-circle" style="color: #3697EA; margin-left: 1%; margin-top: 60px; display: none;" data-cat="DelOps">-</i>
  </div>
  <div class="row">
    <!-- This is where the content of inner repeater is; note emply class name -->
    <table class='DelOps' style="display: none; margin-top: 10px; font-size: 26px; width: 90%;">

      <tr style="border-top: 1px solid #000;">
        <td style="padding-top: 30px;">
          td 1.1.1
        </td>
        <td style="text-align: center;">
          td 1.1.2
        </td>
      </tr>

      <tr style="border-top: 1px solid #000;">
        <td style="padding-top: 30px;">
          td 1.2.1
        </td>
        <td style="text-align: center;">
          td 1.2.2
        </td>
      </tr>
    </table>

  </div>

  <div style="font-size: 120%">
    Network Operations
    <i class="br-plus" class="fa fa-plus-circle" style="color: #3697EA; margin-left: 1%; margin-top: 60px;" data-cat="NetOps">+</i>
    <i class="br-minus" class="fa fa-minus-circle" style="color: #3697EA; margin-left: 1%; margin-top: 60px; display: none;" data-cat="NetOps">-</i>
  </div>
  <div class="row">

    <table class='NetOps' style="display: none; margin-top: 10px; font-size: 26px; width: 90%;">

      <tr style="border-top: 1px solid #000;">
        <td style="padding-top: 30px;">
          td 2.1.1
        </td>
        <td style="text-align: center;">
          td 2.1.2
        </td>
      </tr>

      <tr style="border-top: 1px solid #000;">
        <td style="padding-top: 30px;">
          td 2.2.1
        </td>
        <td style="text-align: center;">
          td 2.2.2
        </td>
      </tr>
    </table>

  </div>


</body>