Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

HTML Simplest hide/show and class filter

I have searched far and wide for this but can't quite find what I need. I have a list as such:

<ul>
    <li class="a b c">Apple</li>
    <li class="a">Banana</li>
    <li class="b">Carrot</li>
    <li class="b c">Drink</li>
</ul>

All I need is 3 buttons that toggle variables true and false that will show/hide the list items with the corresponding class for each variable. Then a search box that will filter out the list items without the (not case sensitive) string in them. For instance checking the box labelled "a" will only show "Apple" and "Banana" but typing in "b" into the search box will only show "Banana".

This is what I have tried so far:

<button onClick="toggle(a)">A</button>
<button onClick="toggle(b)">B</button>
<button onClick="toggle(c)">C</button>
<ul>
    <li class="a b c">Apple</li>
    <li class="a">Banana</li>
    <li class="b">Carrot</li>
    <li class="b c">Drink</li>
</ul>

Then the Javascript:

var a, b, c;
function toggle(i) {
    if (i) {i = false
    }else {i = true};
};

if (a) {
    document.getElementsByClassName('a').style.visibility='shown';
}else {
    document.getElementsByClassName('a').style.visibility='hidden';
};

if (b) {
    document.getElementsByClassName('b').style.visibility='shown';
}else {
    document.getElementsByClassName('b').style.visibility='hidden';
};

if (c) {
    document.getElementsByClassName('c').style.visibility='shown';
}else {
    document.getElementsByClassName('c').style.visibility='hidden';
};

I have not yet figured out how to take a string from a text box.

How would I do this as simply as possible. "Simplest" being with the least code and vanilla javascript with no surplus features. I do not need animation or fancy graphics, just a show and hide based on the criteria. I will also note I'm reasonably new to JS and just cannot understand JQuery at all.

Thanks in advance.

Olie.

Also: If I have missed another question requesting the same info then do tell me.


1 Answers

I have created toggle buttons for your three classes, and an input that sets visibility based on the content of your list items.

Javascript

var hiddenClass = [];
var buttons = document.getElementsByClassName('toggleBtn');
for(var i = 0; i < buttons.length; i++){
  buttons[i].addEventListener('click', function(){
    var self = this;
    var elements = document.getElementsByClassName(self.value);
    toggleButtonState(self);
    for(var i = 0; i < elements.length; i++) {
      var element = elements[i];

      var isHidden = false;
      var classes = element.className.split(' ');
      for(var j = 0; j < classes.length; j++){
        if(hiddenClass.indexOf(classes[j]) !== -1) isHidden = true;
      }

      var vis = elements[i].style.visibility;
      if(vis === 'hidden' && !isHidden){
        setVisibility(element, 'visible');
      } else {
        setVisibility(element, 'hidden');
      }
    }
  });  
}

var input = document.getElementById('classFilter');

input.addEventListener('input', function(){
  var food = document.getElementsByClassName('food');
  for(var i = 0; i < food.length; i++){
    var ele = food[i];
    if(ele.innerHTML.toLowerCase().indexOf(input.value.toLowerCase()) === -1) {
      setVisibility(ele, 'hidden');
    }else {
      isHidden = false;
      var classes = ele.className.split(' ');
      for(var j = 0; j < classes.length; j++){
        if(hiddenClass.indexOf(classes[j]) !== -1) isHidden = true;
      }

      if(!isHidden) setVisibility(ele, 'visible');
    }
  }
});

function setVisibility(element, visibility){
  element.style.visibility = visibility;
}

function setVisibilityByClass(name, visibility) {
  var elements = document.getElementsByClassName(name);
  for(var i = 0; i < elements.length; i++){
    setVisibility(elements[i], visibility);
  }
}

function toggleButtonState(element){
  var on = element.className.indexOf('on') !== -1;
  if(on){
    element.className = 'toggleBtn off';
    if(hiddenClass.indexOf(element.value) === -1) hiddenClass.push(element.value);
  }
  if(!on){
    element.className = 'toggleBtn on';
    hiddenClass = hiddenClass.filter(function(x) { return x !== element.value });
  }  
}

Html

<div id="buttons">
  <input type="button" class="toggleBtn on" value="a" />
  <input type="button" class="toggleBtn on" value="b"   />
  <input type="button" class="toggleBtn on" value="c"   />

  <input type="text" id="classFilter"  />
</div>

<ul>
    <li class="food a b c">Apple</li>
    <li class="food a">Banana</li>
    <li class="food b">Carrot</li>
    <li class="food b c">Drink</li>
</ul>

CSS

  .off {
    background-color: grey;
  }

Got a fiddle working, had to change the listeners a bit to work in their environment: https://jsfiddle.net/b9jp7m1g/1/

like image 59
IrkenInvader Avatar answered May 19 '26 10:05

IrkenInvader