Reputation:
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.
Upvotes: 3
Views: 4965
Reputation: 4050
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/
Upvotes: 1
Reputation: 3308
Here is an example of how you can do this cleanly in an HTML 5 way, using only native JavaScript. This doesn't use class names, but keys off the actual lowercased data. It will also shows a basic example of how jQuery uses the $ as a function name, plus how it works from a native JS POV. Here is my jsfiddle for this demo.
HTML:
<button data-key="a">A</button>
<button data-key="b">B</button>
<button data-key="c">C</button>
<button data-key="d">D</button>
<button data-key="all">Show All</button>
<ul>
<li>Apple</li>
<li>Banana</li>
<li>Carrot</li>
<li>Drink</li>
</ul>
JavaScript:
/* This is a basic example of how jQuery works,
* but with native JavaScript & without jQuery:
*/
function $(str) {
if (str.indexOf(' ') > -1) {
var results = document.querySelectorAll(str);
} else if (str[0] === '#') {
var results = document.getElementById(str.replace('#',''));
} else if (str[0] === '.') {
var results = document.getElementsByClassName(str.replace('.',''));
} else {
var results = document.getElementsByTagName(str);
}
return results;
}
// So you can use dollar sign function names, as shortcuts, as shown below:
function showAll(liTags) { // This is useful for the next button click.
if (!liTags) {
liTags = $('li');
}
for (var i=0; i<liTags.length; i++) {
var liTag = liTags[i];
liTag.style.visibility = 'visible';
}
}
function clickHandler() {
var key = this.dataset.key; // Gets the data-key attribute.
var liTags = $('li');
showAll(liTags);
if (key !== 'all') {
// Hide all but current one.
for (var i=0; i<liTags.length; i++) {
var liTag = liTags[i];
var text = liTag.innerText.toLowerCase();
if (text.indexOf(key) > -1) {
liTag.style.visibility = 'visible';
} else {
liTag.style.visibility = 'hidden';
}
}
}
}
(function init() {
var results = $('button');
for (var i=0; i<results.length; i++) {
results[i].addEventListener("click", clickHandler);
}
})(); // Self-loading function, which runs only 1x on Page Load.
Upvotes: 0
Reputation: 323
Hope this helps. How I hide and show DOM elements that can be or impact several different areas is as follows: 1) I create a CSS as follow:
.hideDom {
display: none;
}
2) Then within the code area I toggle that css "on" and "off" to hide and show the DOM element(s) as follows:
$('someSelector').removeClass("hideDom");
to hide and
$('someSelector').addClass("hideDom");
to show. So for example, if I wanted to hide several DOM elements when "condition1" occurs, else show the elements. I would put a class on all those elements say 'cssCondition1' and perform the following:
switch(condition){
case "condition1":
$('.cssCondition').addClass("hideDom");
break;
default:
$('.cssCondition').removeClass("hideDom");
break;
}
In your specific example, if you wanted to hide everything but the banana:
$('.b').addClass("hideDom");
Upvotes: 0