mirror of
https://github.com/bendtherules/food-app.git
synced 2026-08-18 13:52:09 +00:00
Add searchbox to filter recipes
This commit is contained in:
+6
-1
@@ -1,7 +1,7 @@
|
|||||||
import Header from './components/Header/header';
|
import Header from './components/Header/header';
|
||||||
import Categories from './components/Categories';
|
import Categories from './components/Categories';
|
||||||
import Recipes from './components/Recipes';
|
import Recipes from './components/Recipes';
|
||||||
|
import SearchBox from './components/SearchBox';
|
||||||
|
|
||||||
import './App.css';
|
import './App.css';
|
||||||
|
|
||||||
@@ -39,6 +39,11 @@ class App {
|
|||||||
${
|
${
|
||||||
Header()
|
Header()
|
||||||
}
|
}
|
||||||
|
${
|
||||||
|
SearchBox({
|
||||||
|
recipes: this.data.recipes,
|
||||||
|
})
|
||||||
|
}
|
||||||
${
|
${
|
||||||
Categories({
|
Categories({
|
||||||
categories: this.data.categories,
|
categories: this.data.categories,
|
||||||
|
|||||||
@@ -5,11 +5,6 @@ export default function Header() {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
`
|
`
|
||||||
<style type="text/css" scoped>
|
|
||||||
${
|
|
||||||
headerCSS
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
<div class="header-row">
|
<div class="header-row">
|
||||||
<div class="header-text">
|
<div class="header-text">
|
||||||
What would you like to eat?
|
What would you like to eat?
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
.recipes-wrapper {
|
#recipes-wrapper {
|
||||||
margin: 12px;
|
margin: 12px;
|
||||||
}
|
}
|
||||||
@@ -5,7 +5,7 @@ import './recipes.css';
|
|||||||
function Recipes(props) {
|
function Recipes(props) {
|
||||||
return (
|
return (
|
||||||
`
|
`
|
||||||
<div class="recipes-wrapper">
|
<div id="recipes-wrapper">
|
||||||
${
|
${
|
||||||
props.recipes.map((recipe) => (
|
props.recipes.map((recipe) => (
|
||||||
RecipeCard({
|
RecipeCard({
|
||||||
|
|||||||
@@ -0,0 +1,3 @@
|
|||||||
|
import SearchBox from './searchbox';
|
||||||
|
|
||||||
|
export default SearchBox;
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
.search-box {
|
||||||
|
font-size: 18px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
margin: 12px;
|
||||||
|
border-bottom: 1px solid lightgray;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-box-icon {
|
||||||
|
width: 32px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#search-input {
|
||||||
|
border: none;
|
||||||
|
width: calc(100% - 32px);
|
||||||
|
}
|
||||||
@@ -0,0 +1,72 @@
|
|||||||
|
import './searchbox.css';
|
||||||
|
|
||||||
|
function debounce(func, timeOut) {
|
||||||
|
var timeout;
|
||||||
|
return function () {
|
||||||
|
var context = this, args = arguments;
|
||||||
|
var later = function () {
|
||||||
|
timeout = undefined;
|
||||||
|
func.apply(context, args);
|
||||||
|
};
|
||||||
|
|
||||||
|
clearTimeout(timeout);
|
||||||
|
timeout = setTimeout(later, timeOut);
|
||||||
|
|
||||||
|
var callNow = (timeout === undefined);
|
||||||
|
if (callNow) func.apply(context, args);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export default function SearchBox(props) {
|
||||||
|
setTimeout(function () {
|
||||||
|
const recipesData = props.recipes;
|
||||||
|
|
||||||
|
const searchInput = document.getElementById("search-input");
|
||||||
|
const recipesWrapper = document.getElementById("recipes-wrapper");
|
||||||
|
const allRecipeCards = [...document.getElementsByClassName("recipe-card")];
|
||||||
|
|
||||||
|
let lastFilteredRecipeCards = [...allRecipeCards];
|
||||||
|
|
||||||
|
function inputEventHandler(ev) {
|
||||||
|
ev.preventDefault();
|
||||||
|
|
||||||
|
const searchValue = searchInput.value.toLowerCase();
|
||||||
|
|
||||||
|
const filteredRecipeIndexes = recipesData.map((recipe, index) => {
|
||||||
|
const recipeName = recipe.name.toLowerCase();
|
||||||
|
if (recipeName.indexOf(searchValue) > -1) {
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
}).filter((value) => value !== undefined);
|
||||||
|
|
||||||
|
const filteredRecipeCards = filteredRecipeIndexes.map((recipeIndex) => {
|
||||||
|
return allRecipeCards[recipeIndex];
|
||||||
|
});
|
||||||
|
|
||||||
|
lastFilteredRecipeCards.forEach(recipeCard => {
|
||||||
|
recipesWrapper.removeChild(recipeCard);
|
||||||
|
});
|
||||||
|
|
||||||
|
filteredRecipeCards.forEach(recipeCard => {
|
||||||
|
recipesWrapper.appendChild(recipeCard);
|
||||||
|
});
|
||||||
|
|
||||||
|
lastFilteredRecipeCards = filteredRecipeCards;
|
||||||
|
}
|
||||||
|
|
||||||
|
searchInput.addEventListener('input', debounce(inputEventHandler, 500));
|
||||||
|
},
|
||||||
|
100
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
`
|
||||||
|
<div class="search-box">
|
||||||
|
<span class="search-box-icon mdi mdi-magnify">
|
||||||
|
</span>
|
||||||
|
<input type="search" id="search-input">
|
||||||
|
</div>
|
||||||
|
`
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -8,6 +8,10 @@ body {
|
|||||||
-moz-osx-font-smoothing: grayscale;
|
-moz-osx-font-smoothing: grayscale;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
input:focus {
|
||||||
|
outline: none
|
||||||
|
}
|
||||||
|
|
||||||
code {
|
code {
|
||||||
font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New",
|
font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New",
|
||||||
monospace;
|
monospace;
|
||||||
|
|||||||
Reference in New Issue
Block a user