Overview
Create a react application that displays a list of products and add a search filter to search for specific products by name.
Requirements
The search filter should be implemented as a separate React component.
The search filter component should have an input field and a button.
When the user types a search term into the input field and clicks the button, the filter should be applied to the list of items to display only the items that match the search term.
The filter should be case-insensitive so that "apple" and "Apple" would be considered a match.
The filter should match items that contain the search term, not just items that start with the search term.
The filter should not modify the original list of items. Instead, it should create a new list that contains only the matching items.
If the search term is empty, the full list of items should be displayed.
The filtered list of items should be passed down as props to the component that renders the list of items.
The component that renders the list of items should be responsible for displaying the filtered list.
The search filter should update the filtered list in real time as the user types in the input field.
The search filter should be styled using CSS.
The filtered list of items should be sorted in a specific order (e.g., alphabetical order or by price) if requested by the user.
Instructions
Create a new React component called
ProductList
renders a list of products. Each product should have a name, description, and price.Create a new React component called
SearchFilter
allows users to search for products by name. The search filter should have an input field and a button.When the user types a search term into the input field and clicks the button, the
ProductList
component should update to display only the products that match the search term.If the search term matches any part of a product's name, that product should be included in the filtered list. For example, if the user searches for "apple", products with names like "Red Apple", "Green Apple", and "Apple Pie" should all be included.
If the search term is empty, the
ProductList
component should display all products.Use React state and props to pass data between the
ProductList
andSearchFilter
components.Use CSS to style the search filter and product list components.
Bonus Requirements
Add additional search filters to allow users to search for products by price, category, or any other attribute.
Add sorting functionality to allow users to sort the product list by name, price, or any other attribute.
Before you dive into the final output, I want to encourage you to take some time to work through the exercise yourself. I believe that active learning is the most effective way to learn and grow as a developer.
So, grab a pen and paper, fire up your code editor, and get ready to dive into the React search filter exercise. Once you have completed the exercise, feel free to return to this blog post to compare your solution to mine.
Output for the Search filter exercise
// App.js
import React, { useState } from 'react';
import ProductList from './ProductList';
import './App.css';
const products = [
{ id: 1, name: 'Red Apple', description: 'A delicious red apple', category: 'Fruit', price: 0.99 },
{ id: 2, name: 'Green Apple', description: 'A crunchy green apple', category: 'Fruit', price: 1.49 },
{ id: 3, name: 'Apple Pie', description: 'A sweet apple pie', category: 'Dessert', price: 5.99 },
{ id: 4, name: 'Banana', description: 'A ripe banana', category: 'Fruit', price: 0.49 },
{ id: 5, name: 'Orange', description: 'A juicy orange', category: 'Fruit', price: 0.79 },
];
const App = () => {
const [searchTerm, setSearchTerm] = useState('');
const [category, setCategory] = useState('');
const [minPrice, setMinPrice] = useState(0);
const [maxPrice, setMaxPrice] = useState(10);
const [sortBy, setSortBy] = useState('name');
const handleSearch = (event) => {
setSearchTerm(event.target.value);
};
const handleCategory = (event) => {
setCategory(event.target.value);
};
const handleMinPrice = (event) => {
setMinPrice(Number(event.target.value));
};
const handleMaxPrice = (event) => {
setMaxPrice(Number(event.target.value));
};
const handleSort = (event) => {
setSortBy(event.target.value);
};
const filteredProducts = products
.filter((product) => {
return product.name.toLowerCase().includes(searchTerm.toLowerCase());
})
.filter((product) => {
return category ? product.category === category : true;
})
.filter((product) => {
return product.price >= minPrice && product.price <= maxPrice;
})
.sort((a, b) => {
if (sortBy === 'name') {
return a.name.localeCompare(b.name);
} else {
return a.price - b.price;
}
});
return (
<div className="container">
<h1>Product Search</h1>
<div className="search-container">
<input type="text" value={searchTerm} onChange={handleSearch} placeholder="Search Products" />
<select value={category} onChange={handleCategory}>
<option value="">All Categories</option>
<option value="Fruit">Fruit</option>
<option value="Dessert">Dessert</option>
</select>
<div className="price-filter">
<label htmlFor="min-price">Min Price:</label>
<input id="min-price" type="number" value={minPrice} onChange={handleMinPrice} />
<label htmlFor="max-price">Max Price:</label>
<input id="max-price" type="number" value={maxPrice} onChange={handleMaxPrice} />
</div>
<select value={sortBy} onChange={handleSort}>
<option value="name">Sort By Name</option>
<option value="price">Sort By Price</option>
</select>
</div>
<ProductList products={filteredProducts} />
</div>
);
};
export default App;
// ProductList.js
import React from 'react';
import Product from './Product';
const ProductList = ({ products }) => {
return (
<div className="product-list">
{products.map((product) => (
<Product key={product.id} product={product} />
))}
</div>
);
};
export default ProductList;
// Product.js
import React from 'react';
const Product = ({ product }) => {
return (
<div className="product">
<h2>{product.name}</h2>
<p>{product.description}</p>
<p>Category: {product.category}</p>
<p>Price: ${product.price.toFixed(2)}</p>
</div>
);
};
export default Product;
.container {
max-width: 800px;
margin: 0 auto;
padding: 20px;
}
h1 {
font-size: 32px;
margin-bottom: 20px;
}
.search-container {
display: flex;
justify-content: space-between;
margin-bottom: 20px;
}
input[type='text'],
select,
input[type='number'] {
padding: 10px;
font-size: 16px;
border: 1px solid #ccc;
border-radius: 5px;
margin-right: 10px;
}
.price-filter {
display: flex;
align-items: center;
margin-right: 10px;
}
.price-filter label {
margin-right: 10px;
}
.product-list {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 20px;
}
.product {
background-color: #f9f9f9;
padding: 20px;
border: 1px solid #ccc;
border-radius: 5px;
box-shadow: 2px 2px 5px rgba(0, 0, 0, 0.1);
}
.product h2 {
font-size: 24px;
margin-bottom: 10px;
}
.product p {
font-size: 16px;
margin-bottom: 5px;
}
.product p:last-of-type {
font-weight: bold;
}
Potential use cases for this search filter
A customer visits an e-commerce website and wants to find products that match a specific price range. They use the search and filter form to narrow down the list of products to only those that meet their criteria.
An online store manager needs to update the pricing information for a subset of products. They use the search and filter form to find relevant products quickly and easily.
A sales team member wants to generate a list of products to pitch to a potential customer. They use the search and filter form to find products that match the customer's interests and budget.
A website user wants to browse products by category. They use the category filter dropdown to view products only in the categories they're interested in.
An inventory manager needs to keep track of the quantity of products in stock. They use the search and filter form to find products with low stock levels or those that are out of stock.
The search and filter functionality is a powerful tool that can help users find the products they need quickly and easily. By implementing a simple search and filter form, you can enhance the usability and functionality of your website or application.
Thanks for taking this JavaScript exercise!
By following the steps outlined in this exercise, you should now have a good understanding of how to implement a search and filter component in React. With some additional styling and customization, you can easily adapt this component to fit your specific needs and design requirements.
If you have any questions or comments, feel free to reach out to me on Twitter(@rajeshtomjoe), or follow me for more updates.
And if you'd like to receive more exercise on JavaScript, be sure to subscribe to my blog.