'Filter button with Javascript & React
Good day! I am hoping to get some help with a project I am working on. I created a filter functionality so that when a user click on a button, they can filter my projects based on what type of project it is.
I was able to get the "ALL" button to work but the other buttons are not working. The expected output is when I click on the button it filters out the other projects and keeps the one that matches the category. However the current output is when I click on the button, the projects disappear.
This is my code:
import React, {useState} from "react";
import ReactDOM from "react-dom";
import styles from "./projects.module.scss";
import cards from "./allData";
function Projects() {
const [state, setState] = useState(cards);
const handleBtns = (e) => {
let word = e.target.value;
function isCardActive() {
for(const card of cards) {
if (cards.category === "FEATURED") {
return true;
} else if (cards.category === "WEB APP") {
return true;
} else if (cards.category === "MOBLE APP"){
return true
}
}
};
if(word === 'All') {
setState(cards)
} else if(word === 'Featured') {
const filtered = cards.filter(isCardActive);
setState(filtered);
} else if(word === 'webApp') {
const filtered = cards.filter(isCardActive);
setState(filtered);
} else if(word === 'mobileApp') {
const filtered = cards.filter(isCardActive);
setState(filtered);
}
}
return(
<div className={styles.projects} id="projectHash">
<section>
<h3>PROJECTS</h3>
</section>
<section id={styles.filterMain}>
<button className={`${styles.filterBox} ${styles.active}`} onClick={handleBtns} type="button" value="All" >VIEW ALL</button>
<button className={styles.filterBox} onClick={handleBtns} type="button" value="Featured" >FEATURED</button>
<button className={styles.filterBox} onClick={handleBtns} type="button" value="webApp" >WEB APP</button>
<button className={styles.filterBox} onClick={handleBtns} type="button" value="mobileApp" >MOBILE APP</button>
</section>
<section>
{state.map((cards) => (
<div className={styles.projectcard} key={cards.id} >
<h4>Project Name: {cards.title} </h4>
<br/>
<h4>{cards.image}</h4>
</div>
))}
</section>
</div>
)
};
export default Projects;
This is code for the file that contains the array of data
import card1 from "../../assets/card1.jpg";
import card2 from "../../assets/card2.jpg";
import card3 from "../../assets/card3.jpg";
import card4 from "../../assets/card4.jpg";
import card5 from "../../assets/card5.jpg";
import card6 from "../../assets/card6.jpg";
const cards = [
{
title: 'VICTORY FOLIO',
category: ['WEB APP', 'FEATURED'],
description: 'Lorem ipsum dolro sit amt, consestcuer elit',
image: card1,
id: 1
},
{
title: 'IN WHOLENESS PRACTICE',
category: 'WEB APP',
description: 'Lorem ipsum dolro sit amt, consestcuer elit',
image: card2,
id: 2
},
{
title: 'TRIBE HAIRCARE',
category: ['WEB APP', 'MOBILE APP', 'FEATURED'],
description: 'Lorem ipsum dolro sit amt, consestcuer elit',
image: card3,
id: 3
},
{
title: 'TRIBE SKINCARE',
category: ['WEB APP', 'MOBILE APP'],
description: 'Lorem ipsum dolro sit amt, consestcuer elit',
image: card4,
id: 4
},
{
title: 'BUG TRACKER',
category: 'WEB APP',
description: 'Lorem ipsum dolro sit amt, consestcuer elit',
image: card5,
id: 5
},
{
title: 'PATIENT PORTAL',
category: 'MOBILE APP',
description: 'Lorem ipsum dolro sit amt, consestcuer elit',
image: card6,
id: 6
}
];
export default cards;
Solution 1:[1]
You can use Array.filter() method, also change the inputs values to match categories as they are defined in cards with uppercase and spaces between
const handleBtns = (e) => {
const word = e.target.value;
if (word === "All") setState(cards);
else {
const filteredCards = cards.filter(({ category }) => {
return category.includes(word);
});
setState(filteredCards);
}
};
Solution 2:[2]
Here's a sandbox with my solution using the useState hook: codesandbox
I would note:
- When comparing string values, make sure that they use the same format/capitalization:
'Feature' === 'FEATURE' //false
'FEATURE' === 'FEATURE' //true
- Normalize data in your objects. JavaScript is dynamically typed, so it's ok to do this:
card.category = 'string'
card.category = ['STRING']
Making sure data types are the same removes the need to do extra checks in your filter function.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Rilind Nuha |
| Solution 2 | erica mitchell |
