I am fetching local data through json server. db.json is attached for your reference. When I search any text I want to filter products using heading and when I click on filter checkbox then also I want to filter products by category, size and packs. I have attached every component below for your reference which I am using in this project. Please help me I am using BOOTSTRAP 4.6.0 as UI.
CHECK CODESANDBOX LINK - https://xo6b9.codesandbox.io/product-listing FOR BETTER UNDERSTANDING.
PRODUCT LISTING COMPONENT
import React, { useState, useEffect } from "react";
import PageNotFound from "../other/PageNotFound";
import Loading from "../other/Loading";
import ProductView from "./ProductView";
import SearchResult from "./SearchResult";
import Filter from "./Filter";
const ProductsListing = () => {
const [loading, setLoading] = useState(true);
const [products, setProducts] = useState([]);
const [filters, setFilters] = useState([]);
const [typedValue, setTypedValue] = useState("");
useEffect(() => {
getProductListingData();
}, []);
const getProductListingData = async () => {
try {
const response = await fetch("http://localhost:8000/productListing");
const data = await response.json();
if (data) {
setLoading(false);
setProducts(data.products);
setFilters(data.filters);
} else {
setProducts("PRODUCT LISTING DATA NOT FOUND");
}
} catch (error) {
console.log(error);
}
};
if (loading) {
return <Loading loadingProductListing="Loading Product List" />;
}
const searchFilterFunction = (e) => {
setTypedValue(e);
console.log(typedValue);
if (typedValue !== "") {
const newArray = products.filter((item) => {
return item.heading.indexOf(typedValue) > -1;
});
console.log(newArray);
setProducts(newArray);
} else {
console.log("else block");
setProducts(products);
}
};
return (
<>
{products && filters ? (
<section className="dvMain">
<div className="container-fluid">
<div className="row">
<Filter filters={filters} />
<div className="dvProducts col-lg-6 col-xl-8">
<div className="row">
<SearchResult
searchFilterFunction={(e) => searchFilterFunction(e)}
/>
<div className="dvFilterMobile col-sm-3 col-md-2 d-lg-none text-center text-sm-right mb-3">
<a
href=""
className="btn bg-light w-100"
data-toggle="modal"
data-target="#mobileFiltersModal"
>
<i className="fa fa-filter"></i>Filter
</a>
</div>
</div>
<ProductView products={products} />
</div>
<div className="dvCart col-lg-3 col-xl-2 d-none d-lg-block">
<div className="sticky-top" style={{ top: "100px" }}>
<div className="row">
<div className="col-sm-12 mb-2">
<h5 className="d-inline-block">Cart</h5>
<span className="d-inline-block">106 items</span>
</div>
<div className="dvCartItems col-sm-12 mb-2">
<div className="row">
<div className="scrollbar mr-3">
<div className="item col-sm-12 mb-2 pr-0">
<div className="bg-light pt-2 pb-2">
<div className="col-12">
<h6>Pomegranate</h6>
<p className="f10 text-muted mb-1">250ml</p>
</div>
<div className="col-sm-12">
<div className="d-flex justify-content-between align-items-center">
<div className="addBtn d-flex justify-content-center align-items-center flex-1">
<div className="flex-1 text-center">
<i className="fa fa-minus"></i>
</div>
<div className="flex-3 text-center">
<input
type="text"
className="form-control text-center p-0"
/>
</div>
<div className="flex-1 text-center">
<i className="fa fa-plus"></i>
</div>
</div>
<div className="text-right">
<i className="fa fa-inr"></i>600
</div>
</div>
</div>
<button className="btn btnRemove absolute">
<i className="fa fa-close"></i>
</button>
</div>
</div>
<div className="item col-sm-12 mb-2 pr-0">
<div className="bg-light pt-2 pb-2">
<div className="col-12">
<h6>Coconut Water</h6>
<p className="f10 text-muted mb-1">200ml</p>
</div>
<div className="col-sm-12">
<div className="d-flex justify-content-between align-items-center">
<div className="addBtn d-flex justify-content-center align-items-center flex-1">
<div className="flex-1 text-center">
<i className="fa fa-minus"></i>
</div>
<div className="flex-3 text-center">
<input
type="text"
className="form-control text-center p-0"
/>
</div>
<div className="flex-1 text-center">
<i className="fa fa-plus"></i>
</div>
</div>
<div className="text-right">
<i className="fa fa-inr"></i>80
</div>
</div>
</div>
<button className="btn btnRemove absolute">
<i className="fa fa-close"></i>
</button>
</div>
</div>
<div className="item col-sm-12 mb-2 pr-0">
<div className="bg-light pt-2 pb-2">
<div className="col-12">
<h6>Mango</h6>
<p className="f10 text-muted mb-1">200ml</p>
</div>
<div className="col-sm-12">
<div className="d-flex justify-content-between align-items-center">
<div className="addBtn d-flex justify-content-center align-items-center flex-1">
<div className="flex-1 text-center">
<i className="fa fa-minus"></i>
</div>
<div className="flex-3 text-center">
<input
type="text"
className="form-control text-center p-0"
/>
</div>
<div className="flex-1 text-center">
<i className="fa fa-plus"></i>
</div>
</div>
<div className="text-right">
<i className="fa fa-inr"></i>48
</div>
</div>
</div>
<button className="btn btnRemove absolute">
<i className="fa fa-close"></i>
</button>
</div>
</div>
<div className="item col-sm-12 mb-2 pr-0">
<div className="bg-light pt-2 pb-2">
<div className="col-12">
<h6>Sugarcane</h6>
<p className="f10 text-muted mb-1">250ml</p>
</div>
<div className="col-sm-12">
<div className="d-flex justify-content-between align-items-center">
<div className="addBtn d-flex justify-content-center align-items-center flex-1">
<div className="flex-1 text-center">
<i className="fa fa-minus"></i>
</div>
<div className="flex-3 text-center">
<input
type="text"
className="form-control text-center p-0"
/>
</div>
<div className="flex-1 text-center">
<i className="fa fa-plus"></i>
</div>
</div>
<div className="text-right">
<i className="fa fa-inr"></i>64
</div>
</div>
</div>
<button className="btn btnRemove absolute">
<i className="fa fa-close"></i>
</button>
</div>
</div>
<div className="item col-sm-12 mb-2 pr-0">
<div className="bg-light pt-2 pb-2">
<div className="col-12">
<h6>Life</h6>
<p className="f10 text-muted mb-1">250ml</p>
</div>
<div className="col-sm-12">
<div className="d-flex justify-content-between align-items-center">
<div className="addBtn d-flex justify-content-center align-items-center flex-1">
<div className="flex-1 text-center">
<i className="fa fa-minus"></i>
</div>
<div className="flex-3 text-center">
<input
type="text"
className="form-control text-center p-0"
/>
</div>
<div className="flex-1 text-center">
<i className="fa fa-plus"></i>
</div>
</div>
<div className="text-right">
<i className="fa fa-inr"></i>120
</div>
</div>
</div>
<button className="btn btnRemove absolute">
<i className="fa fa-close"></i>
</button>
</div>
</div>
<div className="item col-sm-12 mb-2 pr-0">
<div className="bg-light pt-2 pb-2">
<div className="col-12">
<h6>Valencia Orange</h6>
<p className="f10 text-muted mb-1">1litre</p>
</div>
<div className="col-sm-12">
<div className="d-flex justify-content-between align-items-center">
<div className="addBtn d-flex justify-content-center align-items-center flex-1">
<div className="flex-1 text-center">
<i className="fa fa-minus"></i>
</div>
<div className="flex-3 text-center">
<input
type="text"
className="form-control text-center p-0"
/>
</div>
<div className="flex-1 text-center">
<i className="fa fa-plus"></i>
</div>
</div>
<div className="text-right">
<i className="fa fa-inr"></i>240
</div>
</div>
</div>
<button className="btn btnRemove absolute">
<i className="fa fa-close"></i>
</button>
</div>
</div>
<div className="item col-sm-12 mb-2 pr-0">
<div className="bg-light pt-2 pb-2">
<div className="col-12">
<h6>Trim</h6>
<p className="f10 text-muted mb-1">250ml</p>
</div>
<div className="col-sm-12">
<div className="d-flex justify-content-between align-items-center">
<div className="addBtn d-flex justify-content-center align-items-center flex-1">
<div className="flex-1 text-center">
<i className="fa fa-minus"></i>
</div>
<div className="flex-3 text-center">
<input
type="text"
className="form-control text-center p-0"
/>
</div>
<div className="flex-1 text-center">
<i className="fa fa-plus"></i>
</div>
</div>
<div className="text-right">
<i className="fa fa-inr"></i>120
</div>
</div>
</div>
<button className="btn btnRemove absolute">
<i className="fa fa-close"></i>
</button>
</div>
</div>
<div className="item col-sm-12 mb-2 pr-0">
<div className="bg-light pt-2 pb-2">
<div className="col-12">
<h6>Aloe Lemonade</h6>
<p className="f10 text-muted mb-1">250ml</p>
</div>
<div className="col-sm-12">
<div className="d-flex justify-content-between align-items-center">
<div className="addBtn d-flex justify-content-center align-items-center flex-1">
<div className="flex-1 text-center">
<i className="fa fa-minus"></i>
</div>
<div className="flex-3 text-center">
<input
type="text"
className="form-control text-center p-0"
/>
</div>
<div className="flex-1 text-center">
<i className="fa fa-plus"></i>
</div>
</div>
<div className="text-right">
<i className="fa fa-inr"></i>40
</div>
</div>
</div>
<button className="btn btnRemove absolute">
<i className="fa fa-close"></i>
</button>
</div>
</div>
</div>
</div>
</div>
<div className="dvCartEmpty col-12 d-none">
<h6>Cart is Empty.</h6>
<p className="f12">
All Good No Bad! Go ahead, order some items from the
menu.
</p>
<img
src="images/cart-empty.png"
className="img-fluid"
width="200"
alt=""
/>
</div>
<div className="col-sm-12 mb-2">
<div className="d-flex justify-content-between">
<div>
<h6>Subtotal</h6>
</div>
<div>
<p>
<i className="fa fa-inr"></i>1,312.00
</p>
</div>
</div>
<p className="f12">Extra charges may apply.</p>
</div>
<div className="col-sm-12 mb-2">
<a href="checkout.html" className="btn btnPrimary w-100">
Proceed
</a>
</div>
</div>
</div>
</div>
</div>
</div>
</section>
) : (
<PageNotFound />
)}
</>
);
};
export default ProductsListing;
PRODUCT VIEW COMPONENT
import React from "react";
const ProductView = ({ products }) => {
return (
<>
<div className="dvProductView row">
{products &&
products.map((product) => {
const {
id,
heading,
description,
detailsTable,
category,
img,
packs,
price,
size,
} = product;
return (
<div key={id} className="col-6 col-md-4 col-lg-6 col-xl-3 mb-4">
<div className="border border-light shadow-sm p-1 h-100">
<div>
<div className="bg-light text-center pt-2 pb-2 mb-1">
<a className="d-inline-block" href="">
<img src={img} className="img-fluid" alt={heading} />
</a>
</div>
<h6 className="text-center">{heading}</h6>
</div>
<div className="d-flex justify-content-between mb-1">
<div className="size">
<p>{size}</p>
</div>
<div className="discount-price mr-2">
<span>
<i className="fa fa-inr"></i>
<span>{price}</span>
</span>
</div>
</div>
<div className="text-center">
<button
className="btn btnSecondary w-100"
href="detail.html"
>
Add to Bag
</button>
</div>
</div>
</div>
);
})}
</div>
</>
);
};
export default ProductView;
SEARCH RESULT COMPONENT
import React, { useState } from "react";
const SearchResult = ({ searchFilterFunction }) => {
// console.log(searchFilterFunction);
// const [searchText, setSearchText] = useState("");
// console.log(searchText);
return (
<>
<div className="dvSearch col-sm-9 col-md-10 col-lg-12 mb-3">
<form className="position-relative">
<input
// value={searchText}
onChange={(e) => searchFilterFunction(e.target.value)}
type="text"
className="form-control"
placeholder="Search - orange, mango, etc."
/>
<button className="btn btnSearch position-absolute">
<i className="fa fa-search"></i>
</button>
</form>
</div>
</>
);
};
export default SearchResult;
FILTER COMPONENT
import React from "react";
const Filter = ({ filters }) => {
return (
<>
<div className="dvFilters col-lg-3 col-xl-2 d-none d-lg-block text-right">
<div className="sticky-top" style={{ top: "100px" }}>
{filters.map((item, index) => {
const { id, heading, submenu } = item;
return (
<div key={id} className="dvPackages row">
<div className="col-sm-12">
<h5 className={`${index === 0 ? "" : "mt-3"}`}>{heading}</h5>
</div>
{submenu.map((item) => {
const { id, name } = item;
return (
<div key={id} className="col-sm-12">
<label className="d-inline-block">
<span className="badge badge-light">05</span>
<span>{name}</span>
<input type="checkbox" />
</label>
</div>
);
})}
</div>
);
})}
</div>
</div>
</>
);
};
export default Filter;
DB.JSON
{
"productListing": {
"filters": [
{
"id": 1,
"heading": "Packages",
"submenu": [
{ "id": 1, "name": "Subscriptions" },
{ "id": 2, "name": "Value Packs" }
]
},
{
"id": 2,
"heading": "Categories",
"submenu": [
{ "id": 1, "name": "Juices" },
{ "id": 2, "name": "Cleanses" },
{ "id": 3, "name": "Almond Milk" },
{ "id": 4, "name": "protein MilkShake" }
]
},
{
"id": 3,
"heading": "Size",
"submenu": [
{ "id": 1, "name": "200ml" },
{ "id": 2, "name": "250ml" },
{ "id": 3, "name": "410ml" }
]
},
{
"id": 4,
"heading": "Packs",
"submenu": [
{ "id": 1, "name": "pack of 2" },
{ "id": 2, "name": "pack of 4" },
{ "id": 3, "name": "pack of 6" },
{ "id": 4, "name": "pack of 8" },
{ "id": 5, "name": "pack of 10" },
{ "id": 6, "name": "pack of 12" },
{ "id": 7, "name": "pack of 14" },
{ "id": 8, "name": "pack of 16" },
{ "id": 9, "name": "pack of 18" },
{ "id": 10, "name": "pack of 20" },
{ "id": 11, "name": "pack of 24" },
{ "id": 12, "name": "pack of 30" },
{ "id": 13, "name": "pack of 36" }
]
}
],
"products": [
{
"id": 1,
"description": "Valencia Orange Every athlete’s go to natural energy drink; Coconut Water is a complete win-win for your everyday rehydration needs. #iaminlovewiththecoco!",
"category": "juices",
"img": "https://static.wixstatic.com/media/2c0034_5b8e230643ee4b6cbb1ae55088b40d50~mv2.png",
"heading": "Valencia Orange",
"size": "250ml",
"packs": 0,
"price": 80
},
{
"id": 2,
"description": "Valencia Orange Every athlete’s go to natural energy drink; Coconut Water is a complete win-win for your everyday rehydration needs. #iaminlovewiththecoco!",
"category": "juices",
"img": "https://static.wixstatic.com/media/2c0034_e8d3fce1719f402797ddaaa555c094e4~mv2.png",
"heading": "Valencia Orange",
"size": "1litre",
"packs": 0,
"price": 240
},
{
"id": 3,
"description": "Trim Every athlete’s go to natural energy drink; Coconut Water is a complete win-win for your everyday rehydration needs. #iaminlovewiththecoco!",
"category": "juices",
"img": "https://static.wixstatic.com/media/2c0034_7534300a0eb04f75b0170b7eb8da71aa~mv2.png",
"heading": "Trim",
"size": "250ml",
"packs": 0,
"price": 120
}
]
}
}
IN THE PRODUCT LISTING COMPONENT Create a new state and name it allProducts as below :-
const [allProducts, setAllProducts] = useState([]);
and pass data from async function :-
const getProductListingData = async () => {
try {
const response = await fetch("http://localhost:8000/productListing");
const data = await response.json();
if (data) {
setLoading(false);
setProducts(data.products);
//send all the products
setAllProducts(data.products);
setFilters(data.filters);
} else {
setProducts("PRODUCT LISTING DATA NOT FOUND");
}
} catch (error) {
console.log(error);
}
};
and then set in else block
const searchFilterFunction = (e) => {
const inputValue = e;
console.log(inputValue);
if (inputValue !== "") {
console.log(inputValue);
const newArray = products.filter((item) => {
return item.heading.toLowerCase().match(inputValue);
});
console.log(inputValue);
setProducts(newArray);
} else {
// set allProducts here
setProducts(allProducts);
}
};