Emilie Hepburn
Emilie Hepburn

Reputation: 33

Sorting With JS/jQuery Show() + Hide() if id has specific class?

I'm trying to make a code that sorts divs based on their class names, with buttons that toggle show(); if the class exists but hide(); if the class does not exist. I'm not getting any errors but the code doesn't want to work the way I think I've told it to? When you click the button in my preview it hides the id that has the class name and does nothing to the ones that don't.

CSS

<html>
<head>
<title>Sorting</title>
<link rel="stylesheet" type="text/css" href="assets/css/style.css">
<script type="text/javascript" src="assets/js/jquery.js"></script>
<script type="text/javascript" src="assets/js/jquery-ui.js"></script>
</head>

<body>
<div id="sort-box"><div id="button-wrap">
<button id="everyone" class="sort-button active">everyone</button>
<button id="lions" class="sort-button">lions</button>
<button id="tigers" class="sort-button">tigers</button>
<button id="bears" class="sort-button">bears</button>
<textarea id="search" class="sort-button" placeholder="search"></textarea></div>

<div class="sort-hold">
    <div id="member" class="lions all">member name - lion</div>
    <div id="member" class="tigers all">member name - tiger</div>
    <div id="member" class="bears all">member name - bear</div>
</div>
</div>
    <script type="text/javascript" src="assets/js/main.js"></script>
</body>

</html>

JS

var btnWrap = document.getElementById("button-wrap");

// Get all buttons with class="btn" inside the container
var btns = btnWrap.getElementsByClassName("sort-button");

// Loop through the buttons and add the active class to the current/clicked button
for (var i = 0; i < btns.length; i++) {
  btns[i].addEventListener("click", function() {
    var current = document.getElementsByClassName("active");
    current[0].className = current[0].className.replace(" active", "");
    this.className += " active";
  });
}


$("#everyone").click(sortEveryone);
function sortEveryone() { 
    console.log("button clicked!")
    $("#member").show();
  };

  $("#lions").click(sortOne);
function sortOne() { 
    console.log("button clicked!")
    if($("#member").hasClass(".lions")){
        $("#member").show();
    } else {
        $("#member").hide();
    }
  };

Upvotes: 2

Views: 786

Answers (2)

Budi Salah
Budi Salah

Reputation: 333

Here is my solution.

Add class everyone to everyone btn and replace sort-hold member to class name instead of id

<div id="sort-box"><div id="button-wrap">
<button id="everyone" class="sort-button everyone active">everyone</button>
<button id="lions" class="sort-button">lions</button>
<button id="tigers" class="sort-button">tigers</button>
<button id="bears" class="sort-button">bears</button>
<textarea id="search" class="sort-button" placeholder="search"></textarea></div>

<div class="sort-hold">
    <div class="lions all member">member name - lion</div>
    <div class="tigers all member">member name - tiger</div>
    <div class="bears all member">member name - bear</div>
</div>
</div>


    <script type="text/javascript" src="https://files.jcink.net/uploads2/colourcoded/jquery.js"></script>
    <script type="text/javascript" src="https://files.jcink.net/uploads2/colourcoded/jquery_ui.js"></script>

Fix #member to be .member

.member {
  margin: 10px;
  width: calc(100% - 70px);
  height: 50px;
  line-height: 50px;
  padding: 0px 25px;
  text-transform: uppercase;
  font-family: arial;
  background: #fff;
  font-size: 10px;
  outline: 1px solid #ddd;
  outline-offset: -1px;
}
// Get the container element
var btnWrap = document.getElementById("button-wrap");

// Get all buttons with class="btn" inside the container
var btns = btnWrap.getElementsByClassName("sort-button");

// Loop through the buttons and add the active class to the current/clicked button
for (var i = 0; i < btns.length; i++) {
  btns[i].addEventListener("click", function() {
    var current = document.getElementsByClassName("active");
    current[0].className = current[0].className.replace(" active", "");
    this.className += " active";
  });
}


$("#everyone").click(sortEveryone);
function sortEveryone() { 
    console.log("button clicked!")
    $(".member").show();
}

// add activeBtn function for all btns except .everyone
for (var btn of btns) {
    $(btn).hasClass("everyone") == false ? btn.addEventListener("click", activeBtn) : "";
}

function activeBtn(e) {
  let targetId = e.target.id;
  let members = $(".member");

  // if the member class has the same name as the btn id, show it else hide it
  for (var member of members) {
    $(member).hasClass(targetId) ? $(member).show() : $(member).hide();
  }
}

I have changed the #member to .member, It's not a good approach to have more than one element with the same id.

And I have added .everyone for everyone btn to make it more easier to handle.

Upvotes: 0

charlietfl
charlietfl

Reputation: 171698

You can do this with a more generic approach using one click listener for all the buttons and checking the id of the one the event occurred on and reacting accordingly

const $items = $('.sort-hold').children()

$('.sort-button').click(function(){
   // remove active class from other buttons
   $('.sort-button.active').removeClass('active');
   // make this button active
   $(this).addClass('active');
   // hide/show logic
   if(this.id === 'everyone'){
      $items.show()
   }else{
      $items.hide().filter('.' + this.id).show();   
   }

})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="sort-box"><div id="button-wrap">
<button id="everyone" class="sort-button active">everyone</button>
<button id="lions" class="sort-button">lions</button>
<button id="tigers" class="sort-button">tigers</button>
<button id="bears" class="sort-button">bears</button>
</div>

<div class="sort-hold">
    <div  class="lions all">member name - lion</div>
    <div  class="tigers all">member name - tiger</div>
    <div  class="bears all">member name - bear</div>
</div>
</div>

Upvotes: 2

Related Questions