Add searchbox to filter recipes

This commit is contained in:
2018-11-19 10:16:53 +05:30
parent 2e88121020
commit fadf9b69f1
8 changed files with 104 additions and 8 deletions
+6 -1
View File
@@ -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
View File
@@ -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 -1
View File
@@ -1,3 +1,3 @@
.recipes-wrapper { #recipes-wrapper {
margin: 12px; margin: 12px;
} }
+1 -1
View File
@@ -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({
+3
View File
@@ -0,0 +1,3 @@
import SearchBox from './searchbox';
export default SearchBox;
+17
View File
@@ -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);
}
+72
View File
@@ -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>
`
);
}
+4
View File
@@ -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;