0

What I am trying to achieve: What I am trying to achieve is very simple I have a table with 2 table body tags. The first one gets shown as its just the main content. The last td element has an anchor tag, this anchor tag when clicked should show the next tbody tag using the jQuery method slideToggle().

Problem: The problem I am having is these are dynamically made tables using Angular.js. So if there are 5 items then there are 5 div elements each with a table that all have the same class for each tbody within the div. This makes sense as for each I would like the click function to show that specific tables second div if the user wants to see additional content related to that item.

Things tried:

  1. $(this).next('.test').slideToggle();
  2. $(this).closest('tbody').find('.test').slideToggle();
  3. $(this).closest('.test').slideToggle();
  4. $(this).closest('tr').find('.test').slideToggle();

Posts look into on StackOverflow for similar issue:

  1. affect only the clicked element in jquery for multiple elements with same class
  2. Using a class name in jQuery's .closest()
  3. jQuery closest(); not working

  4. Jquery adding click function to several spans with the same Class

Non Stack Overflow sites:

  1. https://www.sitepoint.com/jquerys-closest-parents/

HTML:

<div class="productsList" ng-repeat="products in productListing.products">
    <div class="productSection">
        <div class="figureDiv">
            <figure class="img">
                <img ng-src="{{products.image}}" />
            </figure>
        </div>
        <div class="description">
            <h2 ng-bind="products.summary"></h2>
            <summary ng-bind="products.description"></summary>
        </div>
        <table class="productTable">
            <tbody>
                <tr><td><b>Product Name</b></td><td ng-bind="product.merchantName"></td></tr>
                <tr><td><b>Valid:</b></td><td>{{products.validityStart}} to {{products.valididtyEnd}}</td></tr>
                <tr><td><b>Product Type:</b></td><td>Appliance</td></tr>
                <tr><td><b>Testing:</b></td><td>Yes<a class="testLink" href="">Show More &gt;</a></td></tr>
            </tbody>
            <tbody class="test">
                <tr><td><b>Extra</b></td><td>Extra</td></tr>
                <tr><td><b>Extra</b></td><td>Extra</td></tr>
                <tr><td><b>Extra</b></td><td>Extra</td></tr>
                <tr><td><b>Extra</b></td><td>Extra</td></tr>
            </tbody>
        </table>
    </div>
</div>

jQuery (current implementation):

function init() {
    jQuery(document).ready(function(){

        $(document).on("click", ".productTable .testLink", function (ev) {

        ev.stopImmediatePropagation();
        $(this).closest('tr').find('.test').slideToggle();
        $(".test").slideToggle();
   });
}

Visually from Dynamic content (3 items):

Table  class="productTable"
  tbody
      anchor tag  class="testLink"
  tbody  class="test"

Table  class="productTable"
  tbody
      anchor tag  class="testLink"
  tbody  class="test"

Table  class="productTable"
  tbody
      anchor tag  class="testLink"
  tbody  class="test"

Ending As you can see visually there are 3 tables created each having same classes. So for the first table if the user clicks the anchor tag then the body tag right after in that specific table will be displayed with toggle. Only that one should be shown not all of them which is the current problem.

I tried many solutions however nothing is working, every implementation is making all of them toggle which is horrible.

halfer
  • 19,824
  • 17
  • 99
  • 186
L1ghtk3ira
  • 3,021
  • 6
  • 31
  • 70

3 Answers3

1

I think something like this.

  $(".productTable .testLink").on("click", function() {
    $(this).parents('.productTable').children('.test').slideToggle();
  });
.testLink {
  color: blue;
  text-decoration: underline;
}
.test {
  display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table class="productTable">
  <tbody>
    <tr>
      <td><b>Product Name</b>
      </td>
      <td ng-bind="product.merchantName"></td>
    </tr>
    <tr>
      <td><b>Valid:</b>
      </td>
      <td>{{products.validityStart}} to {{products.valididtyEnd}}</td>
    </tr>
    <tr>
      <td><b>Product Type:</b>
      </td>
      <td>Appliance</td>
    </tr>
    <tr>
      <td><b>Testing:</b>
      </td>
      <td>Yes<span class="testLink">Show More &gt;</span>
      </td>
    </tr>
  </tbody>
  <tbody class="test">
    <tr>
      <td><b>Extra</b>
      </td>
      <td>Extra</td>
    </tr>
    <tr>
      <td><b>Extra</b>
      </td>
      <td>Extra</td>
    </tr>
    <tr>
      <td><b>Extra</b>
      </td>
      <td>Extra</td>
    </tr>
    <tr>
      <td><b>Extra</b>
      </td>
      <td>Extra</td>
    </tr>
  </tbody>
</table>
Will
  • 3,201
  • 1
  • 19
  • 17
  • No that is not correct, The table has two tbody's. When the last TD element in the first tbody is clicked the second tbody wich is hidden with display:none: will now be shown, When the user clicks it again it will disappear again – L1ghtk3ira Aug 19 '16 at 16:56
  • THANK YOU. finally it is working the way I expected :). Now I just need a nice transition to it. Thanks a lot. I never thought their might be a class to go to that parent specifically and then the class. Excellent – L1ghtk3ira Aug 21 '16 at 16:57
0

I think the problem is in this line of your jQuery $(".test").slideToggle(); as it will execute slideToggle on all .test try removing it. Also update.closest('tr'); to .closest('table'); as the .test is in the table tag not the tr

Abdullah Razzaki
  • 972
  • 8
  • 16
0

From what I make out, you are looking for JQuery's .next() method. Just for the parent tbody and call .next()

Example would be

$('.testLink').parentsUntil('tbody').next().show();
Saksham
  • 9,037
  • 7
  • 45
  • 73