JQuery Show Hide Multiple Div Button - javascript

I need to develop a News page with 3 articles that can be hidden or showed one by one, by means of 2 buttons: "Show more news" and "Show less news"
Each article must be hidden/displayed by clicking the relevant button only once, starting from the last article (at the bottom page) to the first one (top of page). HTML:
<!-- Articles-->
<article id="art-1" class="row" >My first Art</article>
<article id="art-2" class="row art" >My second Art</article>
<article id="art-3" class="row art" >My last Art</article>
<!--Buttons-->
<button class="button-grey" id="show-less-news1">Show Less</button>
<button class="button-grey" id="show-less-news2">Show Less</button>
<button class="button-grey" id="show-less-news3">Show Less</button>
<button class="button-grey" id="show-more-news1">Show More</button>
<button class="button-grey" id="show-more-news2">Show More</button>
<button class="button-grey" id="show-more-news3">Show More</button>
I managed to do this with JQuery but the code is extremely verbose and I need 6 buttons instead of 2, but I believe there must be a simplier way to get the same result with a less complex code. This is the JQuery code:
$("#show-more-news1").css({display:'none'});
$("#show-more-news2").css({display:'none'});
$("#show-more-news3").css({display:'none'});
$("#show-less-news1").css({display:'none'});
$("#show-less-news2").css({display:'none'});
//function 1 less
$("#show-less-news3").click(function(){
$("#art-3").hide(400);
$("#show-less-news3").hide();
$("#show-more-news3").show();
$("#show-less-news2").show();
});
//function 2 less
$("#show-less-news2").click(function(){
$("#art-2").hide(400);
$("#show-less-news2").hide();
$("#show-more-news3").hide();
$("#show-less-news1").show();
$("#show-more-news2").show();
});
//function 3 more
$("#show-more-news3").click(function(){
$("#art-3").show(400);
$("#show-more-news3").hide();
$("#show-less-news2").hide();
$("#show-less-news3").show();
});
//function 3 less
$("#show-less-news1").click(function(){
$("#art-1").hide(400);
$("#show-less-news1").hide();
$("#show-more-news2").hide();
$("#show-more-news1").show();
});
//function 2 more
$("#show-more-news2").click(function(){
$("#art-2").show(400);
$("#show-more-news2").hide();
$("#show-less-news1").hide();
$("#show-less-news2").show();
$("#show-more-news3").show();
});
//function 1 more
$("#show-more-news1").click(function(){
$("#art-1").show(400);
$("#show-more-news1").hide();
$("#show-less-news1").show();
$("#show-more-news2").show();
});
Some CSS:
article {
position: realtive;
width: 100%;
height: 50px;
border: 1px solid red;
float:left;
background-color: yellow;
}
.button-grey {
display: block;
background-color: #cfcfcf;
width: 150px;
height: 30px;
float:right;
}
Here's a CodePen. Can someone help me to get the same result with a better code?
Thanks a lot!

Using your HTML with only two buttons and identical CSS
The following JS works for better for me:
Javascript:
var newsDepth = 3;
var maxNewsDepth = 3;
$('#show-more-news').hide();
$('#show-more-news').click( function () {
(newsDepth < maxNewsDepth ) && newsDepth++;
$('#art-' + newsDepth).show();
$('#show-less-news').show();
if (newsDepth == maxNewsDepth) $('#show-more-news').hide();
});
$('#show-less-news').click( function () {
( newsDepth > 1 ) && newsDepth--;
$('#art-' + (newsDepth + 1)).hide();
$('#show-more-news').show();
if (newsDepth == 1) $('#show-less-news').hide();
});
HTML
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<!-- Articles-->
<article id="art-1" class="row">My first Art</article>
<article id="art-2" class="row art">My second Art</article>
<article id="art-3" class="row art">My last Art</article>
<!--Buttons-->
<button class="button-grey" id="show-less-news">Show Less</button>
<button class="button-grey" id="show-more-news">Show More</button>
Here is a codepen for you

I've got a better version in this jsfiddle.
HTML:
<!-- Articles-->
<div id="articles">
<article id="art-1" class="row">My first Art</article>
<article id="art-2" class="row art">My second Art</article>
<article id="art-3" class="row art">My last Art</article>
</div>
<!--Buttons-->
<button class="button-grey" id="show-less">Show Less</button>
<button class="button-grey" id="show-more" style="display: none">Show More</button>
JS:
var allArticles = $('#articles article');
var visibleCount = 3;
$('#show-less').on('click', function() {
// no more articles to hide
if (visibleCount == 0) return;
// hide the previous one
$(allArticles[--visibleCount]).hide();
// Show the more button
$('#show-more').show();
// hide the less button
if (visibleCount == 0)
$('#show-less').hide();
});
$('#show-more').on('click', function() {
if (visibleCount == allArticles.length) return;
// show the next article
$(allArticles[visibleCount++]).show();
// Show the less button
$('#show-less').show();
// hide the more button
if (visibleCount == allArticles.length)
$('#show-more').hide();
});

Related

Two Column Accordion with Separate Full Width Divs

The intension is to have a two column accordion, without limiting the "expand" field to the left or right column. The catch is that there will be multiple on one page. This is already created, but only button 1 is working. With the way my JS is going, it will get very very repetitive - I am looking for assistance with re-writing the JS to be multiple click friendly. Fiddle: https://codepen.io/ttattini/pen/abLzaaY
EDIT: It would also be perfect if one dropdown would close as the next is opened
HTML
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="row">
<div id="column">
<button id="button">I am Button #1</button>
<button id="button">I am Button #3</button>
</div>
<div id="column">
<button id="button">I am Button #2</button>
<button id="button">I am Button #4</button>
</div>
</div>
<div id="hidden">
<p id="content"> So here I am #1</p>
</div>
<div id="hidden">
<p id="content"> So here I am #2</p>
</div>
<div id="hidden">
<p id="content"> So here I am #3</p>
</div>
<div id="hidden">
<p id="content"> So here I am #4</p>
</div>
CSS
#hidden {
background: #ccc;
margin-top: 2%;
overflow: hidden;
transition: height 200ms;
height: 0; /* <-- set this */
}
#button {
padding: 10px;
margin-top: 5px;
width:50%;
margin-left: 10%;
cursor: pointer;
}
#row {
display: flex;
}
#column {
flex: 50%;
}
JS
$(function() {
var b = $("#button");
var w = $("#hidden");
var l = $("#content");
b.click(function() {
if (w.hasClass('open')) {
w.removeClass('open');
w.height(0);
} else {
w.addClass('open');
w.height(l.outerHeight(true));
}
});
});
The biggest issue is that you're using IDs when you should be using classes. IDs must be unique to each element in a page. When you repeat an ID, JS will only target the first element using that ID. That's why only the first one is working.
The second issue is that, because of the way the script is written, it will only target a single element. What you need to do is get all the elements you want to target by something like their class name and then loop through them, applying the event listener to each one and its appropriate children.
EDIT: Here is an example from some code I wrote for a page with multiple accordions a few weeks ago in vanilla JS
//Below I establish a counting variable and find all the accordions on the page
const acc = document.getElementsByClassName( 'accordion' );
let i;
//Looping through each accordion
for ( i = 1; i <= acc.length; i++ ) {
//Identify target for the event listener. In this case, a heading for each accordion, which I've numbered e.g. "title-1"
const title = 'title-' + i;
const label = document.getElementById( title );
//Identify target content, in this case a list that has a unique ID e.g. "list-1"
const listNum = 'list-' + i;
const list = document.getElementById( listNum );
//Add event listener to heading that toggles the active classes
label.addEventListener( 'click', function() {
label.classList.toggle( 'accordion--active' );
});
}
Of course, there's more than one way to skin a cat, but this is a working example.
I have tracked the clicked event of each button and showed the corresponding hidden content with the use of data- attribute.
I have used vanilla JavaScipt instead of jQuery.
const buttons = document.querySelectorAll('.button');
const hiddens = document.querySelectorAll('.hidden');
buttons.forEach((btn) => {
btn.addEventListener('click', btnClicked)
function btnClicked(e) {
hiddens.forEach((hidden) => {
if(e.target.dataset.btn == hidden.dataset.content) {
hidden.classList.toggle('height')
} else {
hidden.classList.remove('height')
}
})
}
})
.hidden {
background: #ccc;
margin-top: 2%;
padding-left:2%;
overflow: hidden;
transition: height 200ms;
height: 0; /* <-- set this */
}
.hidden.height {
height: 50px;
}
.button {
padding: 10px;
color: white;
background-color: #2da6b5;
border: none;
margin-top: 5px;
width:90%;
margin-left: 5%;
cursor: pointer;
}
.button:hover {
filter: brightness(.9);
}
#row {
display: flex;
}
.column {
flex: 50%;
}
<div id="row">
<div class="column">
<button class="button" data-btn="one">I am Button #1</button>
<button class="button" data-btn="three">I am Button #3</button>
</div>
<div class="column">
<button class="button" data-btn="two">I am Button #2</button>
<button class="button" data-btn="four">I am Button #4</button>
</div>
</div>
<div class="hidden" data-content="one">
<p class="content"> So here I am #1</p>
</div>
<div class="hidden" data-content="two">
<p class="content"> So here I am #2</p>
</div>
<div class="hidden" data-content="three">
<p class="content"> So here I am #3</p>
</div>
<div class="hidden" data-content="four">
<p class="content"> So here I am #4</p>
</div>
Also, please do not use the same ID at multiple elements.

Get the value of checkboxes in a specific section using javascipt

I have a page that contain different section these section appear when the user click on li an active class is added to the section and then this section appear
each section contain a box with checkboxes and a link to another page when i click on this link i should store the value of the checkboxes for the section active only to print them later
all the code work fine but my problem is that i only can have the checkbox value for the first section that contain active class by defaul
how can i solve that please?
/*Put active class on li click for section*/
let tabs = document.querySelectorAll(".nav li");
let tabsArray = Array.from(tabs);
let section = document.querySelectorAll(".section");
let sectionArray = Array.from(section);
tabsArray.forEach((ele) => {
ele.addEventListener("click", function (e) {
tabsArray.forEach((ele) => {
ele.classList.remove("active");
});
e.currentTarget.classList.add("active");
sectionArray.forEach((sec) => {
sec.classList.remove("active");
});
document.querySelector('#' + e.currentTarget.dataset.cont).classList.add("active");
});
});
/*put the check box value in localstorage to print them later*/
let printBtn = document.querySelector(".active .btn-print");
let terms = document.querySelectorAll(".active input[type='checkbox']");
let termsValChecked = [];
let termsValUnChecked = [];
printBtn.addEventListener("click", function (e) {
localStorage.removeItem("termschecked");
localStorage.removeItem("termsunchecked");
for (let i = 0; i < terms.length; i++) {
if (terms[i].checked == true) {
termsValChecked.push(terms[i].value);
} else {
termsValUnChecked.push(terms[i].value);
}
}
window.localStorage.setItem("termschecked", JSON.stringify(termsValChecked));
window.localStorage.setItem("termsunchecked", JSON.stringify(termsValUnChecked));
});
.box {
display: flex;
align-items: center;
}
section {
display: none;
}
section.active {
display: block;
}
.nav {
list-style:none;
display: flex;
align-items: center;
}
.nav li {
padding: 20px;
background-color: #ccc;
margin-left: 2px;
cursor: pointer;
}
<ul class="nav">
<li data-cont="r1">1</li>
<li data-cont="r2">2</li>
<li data-cont="r3">3</li>
</ul>
<section class="section section-one active" id="r1">
<h3>Section 1</h3>
<div class="box">
<input type="checkbox" value="test1">
<p>test1</p>
</div>
<div class="box">
<input type="checkbox" value="test2">
<p>test2</p>
</div>
<div class="print">
Print
</div>
</section>
<section class="section section-two" id="r2">
<h3>Section 2</h3>
<div class="box">
<input type="checkbox" value="test3">
<p>test3</p>
</div>
<div class="box">
<input type="checkbox" value="test4">
<p>test4</p>
</div>
<div class="print">
Print
</div>
</section>
<section class="section section-three" id="r3">
<h3>Section 3</h3>
<div class="box">
<input type="checkbox" value="test5">
<p>test5</p>
</div>
<div class="box">
<input type="checkbox" value="test6">
<p>test6</p>
</div>
<div class="print">
Print
</div>
</section>
querySelectorAll returns a static NodeList, i.e. the list will reflect the state at invocation and won't update if the page later changes.
The following line runs when you initialize your page:
let terms = document.querySelectorAll(".active input[type='checkbox']");
And that's why you always capture the first section in local storage.
You need to move this line inside your click handler so that you enumerate the checkboxes inside the .active section at that time.
Remove the Attribute ".change" from your selector on line 23
simply change
let terms = document.querySelectorAll(".active input[type='checkbox']");
to
let terms = document.querySelectorAll("input[type='checkbox']");

Add or Remove class on click - Javascript

I am trying to add a class when you click on a box then remove the class when you click the button. But no class os added or removed.
var leftBox = document.getElementsByClassName("left");
var rightBox = document.getElementsByClassName("right");
function expandLeft() {
leftBox.className = leftBox.className + "zero-width";
rightBox.className = rightBox.className + "full-width";
}
function expandRight() {
leftBox.className = leftBox.className + "full-width";
rightBox.className = rightBox.className + "zero-width";
}
function originalLeft(){
leftBox.removeClass(leftBox, "zero-width");
rightBox.removeClass(rightBox, "full-width");
}
function originalRight(){
leftBox.removeClass(rightBox, "full-width");
rightBox.removeClass(leftBox, "zero-width");
}
<div class="row">
<div class="wrapper flex full-width">
<div class="form_wrapper flex full-width">
<div class="left">
<div class="form_wrapper--left" onclick="expandRight()">
<div><button id="shrink" onclick="originalLeft()">click here</button> .
</div>
</div>
</div>
<!-- END OR RIGHT BOX --
<!-- START OR RIGHT BOX -->
<div class="right">
<div class="form_wrapper--right" onclick="expandLeft()">
<div>
<button id="shrink" onclick="originalLeft()">click here</button>
</div>
</div>
</div>
<!--- END of Right Box --->
</div>
</div>
</div>
The effect should be that when you click one box it expands left and you can click a button and it returns. Vice versa for the other side.
You can use .toggleClass() in jQuery.
maybe this link helps:
https://api.jquery.com/toggleclass/
try this:
document.getElementById("test").addEventListener("click", enlarge);
document.getElementById("btn").addEventListener("click", resume);
function enlarge() {
document.getElementById("test").classList.add("enlarge");
}
function resume() {
document.getElementById("test").classList.remove("enlarge");
}
#test {
width: 100px;
height: 100px;
background-color: green;
margin-bottom: 20px;
}
.enlarge {
transform: scaleX(2);
}
<div id="test"></div>
<button id="btn">
Resume
</button>

Select next div with jquery?

//$(document).ready(function(){
$('.next').click(function(){
$('.box').fadeOut();
$('.box').next().fadeIn();
});
//});
.box{
border:solid 1px #ccc;
padding: 20px;
width:10%;
display:none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<a class="next" style="cursor:pointer;">next</a> <br><br>
<div class="box" style="display:block;">
1
</div>
<div class="box">
2
</div>
<div class="box">
3
</div>
<div class="box">
4
</div>
I have a div .box, and the next button. I need to select the next div if i click the next button but only the first div not all. For example if i click next button while it shown box 1 then the next box that should be appear is 2 and so on. But now it shown 2 3 4. How to do this ?
you can get the first visible div using $(.box:visible) and then fadeIn next div to it. you can also add a check for last element, in which case you can fadeIn the first element. something like this:
//$(document).ready(function(){
$('.next').click(function(){
var visibleBox = $('.box:visible');
$(visibleBox).fadeOut();
if(!$(visibleBox).next('div').length)
$('.box').first().fadeIn();
else
$(visibleBox).next().fadeIn();
});
//});
.box{
border:solid 1px #ccc;
padding: 20px;
width:10%;
display:none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<a class="next" style="cursor:pointer;">next</a> <br><br>
<div class="box" style="display:block;">
1
</div>
<div class="box">
2
</div>
<div class="box">
3
</div>
<div class="box">
4
</div>
It's showing 2 3 4 because you ares selecting ALL .box elements, i.e. 1 2 3 4
.next() of 1 = 2
.next() of 2 = 3
.next() of 3 = 4
.next() of 4 = nothing
You should find the box that is currently being shown, and then find it's next sibling.
// Filter by CSS rule
var $showing = $('.box').filter(function() {
return $(this).css('display') === 'block';
}).fadeOut();
// or using :visible
$showing = $('.box:visible').fadeOut();
$showing.next().fadeIn();
you can use another class to labeled, which div is on the display. for example, you add a class display. then you put that class, on the first box. when you click next, you can remove the class display from the current one, and move it into the next one.
HTML
<a class="next" style="cursor:pointer;">next</a> <br><br>
<div class="box display">
1
</div>
<div class="box">
2
</div>
<div class="box">
3
</div>
<div class="box">
4
</div>
CSS
.box{
border:solid 1px #ccc;
padding: 20px;
width:10%;
display:none;
}
.display{
display:block
}
JQuery
$('.next').click(function(){
var current = $('.box.display');
current.fadeOut().removeClass('display').next().fadeIn().addClass('display');
});
Demo : https://jsfiddle.net/dfaLnsmo/
If I understand your requirement this will work
$(document).ready(function(){
var i = 1;
$('.next').click(function(){
$('.box').fadeOut();
$('.box:nth-child(i)').fadeIn();
if(i >= $('.box').length)
i++;
else
i=1;
});
});
Try the following Jquery
var curr = 1;
$('.next').click(function(){
if(curr < $( ".box" ).length) {
$('.box').hide();
$( ".box" )[curr].style.display= "block";
curr += 1;
}
});
Here is the working jsfiddel : https://jsfiddle.net/Lv7yr820/1/

Creating a filter bar with Javascript [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
I am new to Javascript and only have very basic knowledge of it at this stage.
I am trying to create a filter bar that, when clicked, would set the opacity of the non-matched items to 0.2 and the matched item would remain at full opacity.
I have uploaded the html/css to show an example on jsfiddle: https://jsfiddle.net/rebeccasmith1301/zw2aozff/
<div id="filter-bar">
<button onclick="findShoes()">Shoes</button>
<button onclick="findTops()">Tops</button>
<button onclick="findSkirts()">Skirts</button>
</div>
<div class="product-item">
<p>Shoes</p>
</div>
<div class="product-item">
<p>Tops</p>
</div>
Skirts
I have been experimenting with javascript written on a previous post that I found very helpful but due to my basic knowledge I have been unable to solve how to achieve the results I am aiming for.
I basically would like the user to be able to click on the button shoes (for example) and all of the divs that contain the word shoes to remain with full opacity and all other divs to have the class un-selected which lowers the opacity to 0.2. The divs that contain the products can be a class only, not an id as well.
Would anyone be able to help? This would be using mainly vanilla javascript.
Many thanks,
Becky
Fiddle with multiple words: https://jsfiddle.net/qucwvqfr/1/
Fiddle with white space removal: https://jsfiddle.net/d15v3x0w/1/
Don't make a function for each possible variation of content, just make one function and give that a parameter. This javascript would check the textContent of the items, strip the whitespace from them, and change classes accordingly. The hasClass, addClass, and removeClass are helpers, focus on the highlightItems function.
function hasClass(ele,cls) {
return !!ele.className.match(new RegExp('(\\s|^)'+cls+'(\\s|$)'));
}
function addClass(ele,cls) {
if (!hasClass(ele,cls)) ele.className += " "+cls;
}
function removeClass(ele,cls) {
if (hasClass(ele,cls)) {
var reg = new RegExp('(\\s|^)'+cls+'(\\s|$)');
ele.className=ele.className.replace(reg,' ');
}
}
var highlightItems = function(itemName) {
var p = document.getElementsByClassName("product-item");
for (var i = 0; i < p.length; i++) {
itemText = p[i].textContent.replace(/^\s+|\s+$/g,''); // you don't need the .replace() part if you don't add extra white space in the HTML
if ( !(itemText == itemName) ) {
addClass(p[i], "un-selected");
} else {
removeClass(p[i], "un-selected");
}
}
}
And you would use it like this:
<div id="filter-bar">
<button onclick="highlightItems('Shoes')">Shoes</button>
<button onclick="highlightItems('Tops')">Tops</button>
<button onclick="highlightItems('Skirts')">Skirts</button>
</div>
Note:
If you want to have multiple words inside the box, don't add any unnecessary white space inside the div tags. (You probably shouldn't do it anyway.) So the HTML usage would be like this:
<div class="product-item">Shoes and socks</div>
<div class="product-item">Tops</div>
<div class="product-item">Skirts</div>
Credits for the class-changing functions go to http://jaketrent.com/post/addremove-classes-raw-javascript/
There needs to be a reliable way to select the specified items. I propose that you add a class shoes, tops and skirts to their respective elements:
<div class="product-item shoes">
Shoes
</div>
<div class="product-item tops">
Tops
</div>
<div class="product-item skirts">
Skirts
</div>
Now, to select all elements that got shoes it's really easy:
var shoes = document.getElementsByClassName('shoes');
Selecting elements that don't have a class shoes is another story. Let say we start by collecting out all product-item elements, like so:
var products = document.getElementsByClassName('product-item');
From here on, you need to iterate all the elements inside the returned nodeList and check if they got a shoes class. A helper function that can help you with that:
function not(nodeList, cls){
var reg = new RegExp('\\b' + cls + '\\b');
return Array.prototype.reduce.call(nodeList, function(acc, el){
console.log(el, el.className.search(reg))
if(el.className.match(reg) === null){
acc.push(el);
}
return acc;
}, []);
}
So now, to get products that aren't shoes:
var notShoes = not(products, 'shoes');
To change the opacity of all the elements inside a nodeList we could use another helper function:
function changeOpacity(nodeList, opacity){
Array.prototype.forEach.call(nodeList, function(el){
el.style.opacity = opacity;
});
}
And to use it:
changeOpacity(shoes, 1.0);
changeOpacity(notShoes, 0.2);
All together in this snippet:
function find(cls) {
var clsList = document.getElementsByClassName(cls);
var products = document.getElementsByClassName('product-item');
var notCls = not(products, cls);
changeOpacity(clsList, 1.0);
changeOpacity(notCls, 0.2);
}
function not(nodeList, cls){
var reg = new RegExp('\\b' + cls + '\\b');
return Array.prototype.reduce.call(nodeList, function(acc, el){
console.log(el, el.className.search(reg))
if(el.className.match(reg) === null){
acc.push(el);
}
return acc;
}, []);
}
function changeOpacity(nodeList, opacity){
Array.prototype.forEach.call(nodeList, function(el){
el.style.opacity = opacity;
});
}
/* Styling for filter bar*/
#filter-bar{
width: 100%
}
#filter-bar button{
width: 30%
float: left;
margin: 0.5%;
}
/* Styling for products*/
.product-item{
width: 24%;
float: left;
margin: 0.5%;
background-color: red;
height: 80px;
box-sizing: border-box;
padding: 10px;
}
/* Different options for products with button click*/
.un-selected{
opacity: 0.2;
}
<div id="filter-bar">
<button onclick="find('shoes')">Shoes</button>
<button onclick="find('tops')">Tops</button>
<button onclick="find('skirts')">Skirts</button>
</div>
<div class="product-item shoes">
Shoes
</div>
<div class="product-item tops">
Tops
</div>
<div class="product-item skirts">
Skirts
</div>
<div class="product-item skirts">
Skirts
</div>
<div class="product-item shoes">
Shoes
</div>
<div class="product-item tops">
Tops
</div>
<div class="product-item skirts">
Skirts
</div>
<div class="product-item skirts">
Skirts
</div>
I have a solution with jquery:
HTML
<button class="active btn" id="all">Show All</button>
<button class="btn" id="a">Tops</button>
<button class="btn" id="b">Skirts</button>
<button class="btn" id="c">Shoes</button>
<!-- An element with an id is needed for the jQuery -->
<div id="parent">
<!-- The base class is the box. Categories are then given as accessory classes. Any div can be in more than one category -->
<div class="box product-item a b">Shoes & Tops</div>
<div class="box product-item a">Tops</div>
<div class="box product-item b">Skirts</div>
<div class="box product-item c">Shoes</div>
</div>
CSS
/* Styling for filter bar*/
#filter-bar{
width: 100%
}
#filter-bar button{
width: 30%
float: left;
margin: 0.5%;
}
/* Styling for products*/
.product-item{
width: 24%;
float: left;
margin: 0.5%;
background-color: red;
height: 80px;
box-sizing: border-box;
padding: 10px;
}
/* Different options for products with button click*/
.un-selected{
opacity: 0.2;
}
jQuery
var $btns = $('.btn').click(function() {
if (this.id == 'all') {
$('#parent > div').fadeIn(450);
} else {
var $el = $('.' + this.id).fadeIn(450);
$('#parent > div').not($el).hide();
}
$btns.removeClass('active');
$(this).addClass('active');
})
jsfiddle
function filter(me) {
var items = document.getElementsByClassName("product-item");
console.log(me.textContent);
for (var i = 0; i < items.length; i++) {
var item = items[i];
item.style.display = "";
if (item.textContent.trim() !== me.textContent.trim() && me.textContent.trim() !== "All") {
item.style.display = "none";
}
}
}
/* Styling for filter bar*/
#filter-bar{
width: 100%
}
#filter-bar button{
width: 30%
float: left;
margin: 0.5%;
}
/* Styling for products*/
.product-item{
width: 24%;
float: left;
margin: 0.5%;
background-color: red;
height: 80px;
box-sizing: border-box;
padding: 10px;
}
/* Different options for products with button click*/
.un-selected{
opacity: 0.2;
}
<div id="filter-bar">
<button onclick="filter(this)">Shoes</button>
<button onclick="filter(this)">Tops</button>
<button onclick="filter(this)">Skirts</button>
<button onclick="filter(this)">All</button>
</div>
<div class="product-item">
Shoes
</div>
<div class="product-item">
Tops
</div>
<div class="product-item">
Skirts
</div>
<div class="product-item">
Skirts
</div>
<div class="product-item">
Shoes
</div>
<div class="product-item">
Tops
</div>
<div class="product-item">
Skirts
</div>
<div class="product-item">
Skirts
</div>

Categories