1

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>
Ruzihm
  • 16,769
  • 3
  • 27
  • 40
NoBullMan
  • 1,761
  • 5
  • 30
  • 65
  • 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 Oct 02 '18 at 16:30
  • Also you probably want to use `$(this).siblings().show();` so you only show the sibling of what just got clicked. – Ruzihm Oct 02 '18 at 16:32
  • 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 Oct 02 '18 at 18:38

1 Answers1

0

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>
Ruzihm
  • 16,769
  • 3
  • 27
  • 40
  • Thank you Ruzihm. But how do I set Abbrev in code behind, in order to call GetAbbrev, when it depends on repeater item? How do I make sure each repeater item gets the correct Abbrev? – NoBullMan Oct 02 '18 at 20:41
  • @NoBullMan I found a solution for that problem and edited my answer to include it instead of the old one. – Ruzihm Oct 03 '18 at 02:01
  • Thank you. In VS when I add this, it says: 'RepeaterItem' does not contain a definition for 'Abbrev' and no extension method 'Abbrev' accepting a first argument of type repeaterItem' could be found ....' – NoBullMan Oct 03 '18 at 12:20
  • I also tried adding public string Abbrev {get {return "Abbrev"}} in code behind and then in repeater use <... ...="" class="<%= Abbrev %>"> – NoBullMan Oct 03 '18 at 12:31
  • 1
    This worked:
    – NoBullMan Oct 03 '18 at 13:31