Home > Blockchain >  jQuery - show list items that match data-attribute
jQuery - show list items that match data-attribute

Time:03-10

The function for finding the active menu option and showing the li with the matching data-type only works if the active class is on the first or second li. If I put the active class on the third or fourth li, no items show for either table.

How do I show all of the items with the data-type that matches the data-related value with the active class?

Note the click function works fine, the issue is showing the li for the active selection on load.

$(document).ready(function() {
  //Retreive active list on load:::::::::::::::::::::::::::::::
  $("[data-section='table']").each(function() {
    var $container = $(this);
    var item = $container.find(".billing__item");
    var active = $container.find(".ladder__ul li.active");
    var $id = item.attr("data-type");
    var datarel = active.attr("data-related");

    item.hide();
    // Find out what Li has the active class, then return matching items on load:
    if (datarel == "all") {
      item.css("display", "flex");
    }
    if (datarel == $id) {
      $(".billing__item[data-type='"   $id   "']").css("display", "flex");
    }
  });
  //Retreive active list on Click:::::::::::::::::::::::::::::::
  $(".ladder__ul li").on("click", function(e) {
    e.preventDefault();
    var $li = $(this);
    var $table = $li.closest("[data-section='table']");
    var $id = $li.attr("data-related");

    $(".ladder__ul li.active").removeClass("active");
    $(this).addClass("active");

    $table.find(".billing__item").each(function() {
      var $item = $(this);
      var $type = $item.attr("data-type");
      //Hide every list on load::
      $item.hide();
      if ($li.attr("data-related") == "all") {
        $item.css("display", "flex");
      }
      if ($li.attr("data-related") == $type) {
        $item.css("display", "flex");
      }
    });
  });
});
li {
  padding: .9rem;
  border: 1px solid;
  cursor: pointer
}

.active {
  background: blue
}

[data-section='table'] {
  border: 2px solid;
  pading: 1.3rem
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div data-section="table">
  <ul >
    <li data-related="all">All</li>
    <li data-related="one" >One</li>
    <li data-related="two">two</li>
    <li data-related="three">three</li>
  </ul>

  <div >
    <div  data-type="one">One</div>
    <div  data-type="two">Two</div>
    <div  data-type="one">One</div>
    <div  data-type="three">Three</div>
  </div>
</div>

<div data-section="table">
  <ul >
    <li data-related="all">All</li>
    <li data-related="a">a</li>
    <li data-related="b" >b</li>
  </ul>

  <div >
    <div  data-type="a">a</div>
    <div  data-type="b">b</div>
    <div  data-type="a">a</div>
    <div  data-type="b">b</div>
  </div>
</div>

CodePudding user response:

I think the problem is because $id is not equal to datarel
The .attr() method gets the attribute value for only the first element in the matched set.
ref: https://api.jquery.com/attr/
So your $id variable is always one because that's how you layout your elements in the html and One is the value of the first element with attribute data-type

<div  data-type="one">One</div>
<div  data-type="two">Two</div>
<div  data-type="one">One</div>
<div  data-type="three">Three</div>

I believe you are complicating things with the $id, you don't need it

$("[data-section='table']").each(function () {
    var $container = $(this);
    var item = $container.find(".billing__item");
    var active = $container.find(".ladder__ul li.active");
    var datarel = active.attr("data-related");
    item.hide();
    // Find out what Li has the active class, then return matching items on load:
    if (datarel == "all") {
        item.css("display", "flex");
    }
    $(".billing__item[data-type='"   datarel   "']").css("display", "flex");
});

Using datarel directly should suffice.

CodePudding user response:

The problem from id. Because you get $id from item.attr("data-type") but the item is multiple element so it alway to get the first item data. That why at first section it work, but the second section work incorrect.

So you need to change your code like this:

//Retreive active list on load:::::::::::::::::::::::::::::::
$("[data-section='table']").each(function() {
  var $container = $(this);
  var item = $container.find(".billing__item");
  var active = $container.find(".ladder__ul li.active");

  var datarel = active.attr("data-related");

  item.hide();
  // Find out what Li has the active class, then return matching items on load:
  if (datarel == "all") {
    item.css("display", "flex");
  } else {
    $(".billing__item[data-type='"   datarel   "']", $container).css("display", "flex");
  }
});
  • Related