Add option to search recipes by tag, tweak UI of search results
This commit is contained in:
parent
6b2d108c3d
commit
3c9e10dca1
|
|
@ -4,7 +4,8 @@
|
||||||
"author": "John Doe",
|
"author": "John Doe",
|
||||||
"primaryColor": "#ffdb70",
|
"primaryColor": "#ffdb70",
|
||||||
"secondaryColor": "#32816e",
|
"secondaryColor": "#32816e",
|
||||||
"searchLabel": "Find recipes by name or ingredients",
|
"searchLabel": "Find recipes by name, tag or ingredients",
|
||||||
|
"searchContainsLabel": "Contains",
|
||||||
"servingsLabel": "servings",
|
"servingsLabel": "servings",
|
||||||
"ingredientsLabel": "Ingredients"
|
"ingredientsLabel": "Ingredients"
|
||||||
}
|
}
|
||||||
|
|
@ -2,25 +2,15 @@
|
||||||
<label for="{{ 'search-home' if homeSearch else 'search' }}" class="c-search__label {{ 'c-search__label--home' if homeSearch }}">{{ site.searchLabel }} :</label>
|
<label for="{{ 'search-home' if homeSearch else 'search' }}" class="c-search__label {{ 'c-search__label--home' if homeSearch }}">{{ site.searchLabel }} :</label>
|
||||||
<div class="c-search__input-wrapper {{ 'c-search__input-wrapper--home' if homeSearch }}">
|
<div class="c-search__input-wrapper {{ 'c-search__input-wrapper--home' if homeSearch }}">
|
||||||
<input type="text" id="{{ 'search-home' if homeSearch else 'search' }}" class="c-search__input {{ 'c-search__input--home' if homeSearch }}" x-model="searchInput" @focus="
|
<input type="text" id="{{ 'search-home' if homeSearch else 'search' }}" class="c-search__input {{ 'c-search__input--home' if homeSearch }}" x-model="searchInput" @focus="
|
||||||
if (!window.searchResults) {
|
|
||||||
fetch('/search.json').then(res => res.json()).then(res => {
|
|
||||||
window.searchResults = res;
|
|
||||||
searchResults = window.searchResults;
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
searchResults = window.searchResults;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sessionStorage.getItem('searchResults')) {
|
if (sessionStorage.getItem('searchResults')) {
|
||||||
searchResults = JSON.parse(sessionStorage.getItem('searchResults'));
|
searchResults = JSON.parse(sessionStorage.getItem('searchResults'));
|
||||||
} else {
|
} else {
|
||||||
fetch('/search.json').then(res => res.json()).then(res => {
|
fetch('/search.json').then(res => res.json()).then(res => {
|
||||||
sessionStorage.setItem('searchResults', JSON.stringify(res));
|
sessionStorage.setItem('searchResults', JSON.stringify(res));
|
||||||
searchResults = random(res);
|
searchResults = JSON.stringify(res);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
" @input="
|
" @input="
|
||||||
console.log(searchInput);
|
|
||||||
matches = [];
|
matches = [];
|
||||||
|
|
||||||
if (searchInput.length < 3) { return };
|
if (searchInput.length < 3) { return };
|
||||||
|
|
@ -28,12 +18,14 @@
|
||||||
searchResults.forEach(recipe => {
|
searchResults.forEach(recipe => {
|
||||||
const matchTitle = recipe.title.toLowerCase().includes(searchInput);
|
const matchTitle = recipe.title.toLowerCase().includes(searchInput);
|
||||||
const matchIngredient = recipe.ingredients.find(ingredient => ingredient.toLowerCase().includes(searchInput));
|
const matchIngredient = recipe.ingredients.find(ingredient => ingredient.toLowerCase().includes(searchInput));
|
||||||
|
const matchTag = recipe.tags.find(tag => tag.toLowerCase().includes(searchInput));
|
||||||
|
|
||||||
if (!matchTitle && !matchIngredient) { return };
|
if (!matchTitle && !matchIngredient && !matchTag) { return };
|
||||||
|
|
||||||
const match = {...recipe};
|
const match = {...recipe};
|
||||||
if (matchTitle) { match.matchTitle = matchTitle };
|
if (matchTitle) { match.matchTitle = matchTitle };
|
||||||
if (matchIngredient) { match.matchIngredient = matchIngredient };
|
if (matchIngredient) { match.matchIngredient = matchIngredient };
|
||||||
|
if (matchTag) { match.matchTag = matchTag };
|
||||||
|
|
||||||
matches.push(match)
|
matches.push(match)
|
||||||
});
|
});
|
||||||
|
|
@ -49,18 +41,25 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<template x-if="matches.length">
|
<template x-if="matches.length">
|
||||||
<ul class="c-search__search-results">
|
<div class="c-search__results-wrapper">
|
||||||
<template x-for="(match, index) in matches" :key="index">
|
<ul class="c-search__results {{ 'c-search__results--home' if homeSearch }}">
|
||||||
<li>
|
<template x-for="(match, index) in matches" :key="index">
|
||||||
<a x-bind:href="match.url" x-html="highlightText(match.title, searchInput)" class="c-search__search-result-link {{ 'c-search__search-result-link--home' if homeSearch }}"></a>
|
<li>
|
||||||
<template x-if="match.matchIngredient">
|
<div class="c-search__result-link {{ 'c-search__result-link--home' if homeSearch }}">
|
||||||
<p class="c-search__search-result-ingredients {{ 'c-search__search-result-ingredients--home' if homeSearch }}" >
|
<a x-bind:href="match.url" x-html="highlightText(match.title, searchInput)"></a>
|
||||||
Contains: <span x-html="highlightText(match.matchIngredient, searchInput)"></span>
|
<template x-if="match.matchTag">
|
||||||
</p>
|
<div class="c-tags__tag c-tag__tag--selected" x-html="highlightText(match.matchTag, searchInput)"></div>
|
||||||
</template>
|
</template>
|
||||||
</li>
|
</div>
|
||||||
</template>
|
<template x-if="match.matchIngredient">
|
||||||
</ul>
|
<p class="c-search__result-ingredients {{ 'c-search__result-ingredients--home' if homeSearch }}" >
|
||||||
|
{{ site.searchContainsLabel }}: <span x-html="highlightText(match.matchIngredient, searchInput)"></span>
|
||||||
|
</p>
|
||||||
|
</template>
|
||||||
|
</li>
|
||||||
|
</template>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -42,6 +42,7 @@ collections:
|
||||||
- {label: "Primary color", name: "primaryColor", widget: "color", hint: "make sure to choose a color that is light enough to display as a background behind dark text"}
|
- {label: "Primary color", name: "primaryColor", widget: "color", hint: "make sure to choose a color that is light enough to display as a background behind dark text"}
|
||||||
- {label: "Secondary color", name: "secondaryColor", widget: "color", hint: "used for links and focus styles"}
|
- {label: "Secondary color", name: "secondaryColor", widget: "color", hint: "used for links and focus styles"}
|
||||||
- {label: "Search (label)", name: "searchLabel", widget: "string"}
|
- {label: "Search (label)", name: "searchLabel", widget: "string"}
|
||||||
|
- {label: "Search \"contains\" (label)", name: "searchContainsLabel", widget: "string"}
|
||||||
- {label: "Servings (label)", name: "servingsLabel", widget: "string"}
|
- {label: "Servings (label)", name: "servingsLabel", widget: "string"}
|
||||||
- {label: "Ingredients (label)", name: "ingredientsLabel", widget: "string"}
|
- {label: "Ingredients (label)", name: "ingredientsLabel", widget: "string"}
|
||||||
- name: "nav"
|
- name: "nav"
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@
|
||||||
background-color: var(--color-white);
|
background-color: var(--color-white);
|
||||||
padding: 24px;
|
padding: 24px;
|
||||||
border: 1px solid var(--color-grey-300);
|
border: 1px solid var(--color-grey-300);
|
||||||
border-radius: 6px;
|
border-radius: 10px;
|
||||||
box-shadow: var(--shadow-xl);
|
box-shadow: var(--shadow-xl);
|
||||||
font-size: 1rem;
|
font-size: 1rem;
|
||||||
|
|
||||||
|
|
@ -101,24 +101,46 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.c-search__search-results {
|
.c-search__results-wrapper {
|
||||||
|
position: relative;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.c-search__results {
|
||||||
> * + * {
|
> * + * {
|
||||||
margin-top: 10px;
|
margin-top: 10px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.c-search__search-results {
|
.c-search__results.c-search__results--home {
|
||||||
margin-top: 30px;
|
position: absolute;
|
||||||
|
z-index: 10;
|
||||||
|
top: 10px;
|
||||||
|
left: 50%;
|
||||||
|
transform: translateX(-50%);
|
||||||
|
width: 100%;
|
||||||
|
max-width: 500px;
|
||||||
|
padding: 24px;
|
||||||
|
background-color: var(--color-white);
|
||||||
|
border: 1px solid var(--color-grey-300);
|
||||||
|
box-shadow: var(--shadow-xl);
|
||||||
|
border-radius: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.c-search__search-result-link--home {
|
.c-search__result-link {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.c-search__result-link--home {
|
||||||
font-size: 1.2rem;
|
font-size: 1.2rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.c-search__search-result-ingredients {
|
.c-search__result-ingredients {
|
||||||
font-style: italic;
|
font-style: italic;
|
||||||
}
|
}
|
||||||
|
|
||||||
.c-search__search-result-ingredients--home {
|
.c-search__result-ingredients--home {
|
||||||
font-size: 1rem;
|
font-size: 1rem;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,8 @@ permalink: search.json
|
||||||
{
|
{
|
||||||
"title" : "{{ recipe.data.title }}",
|
"title" : "{{ recipe.data.title }}",
|
||||||
"url" : "{{ recipe.url }}",
|
"url" : "{{ recipe.url }}",
|
||||||
"ingredients" : [{% for ingredient in recipe.data.ingredients %}"{{ingredient}}"{% if not loop.last %},{% endif %}{% endfor %}]
|
"ingredients" : [{% for ingredient in recipe.data.ingredients %}"{{ingredient}}"{% if not loop.last %},{% endif %}{% endfor %}],
|
||||||
|
"tags" : [{% for tag in recipe.data.tags %}"{{tag}}"{% if not loop.last %},{% endif %}{% endfor %}]
|
||||||
}{% if not loop.last %},{% endif %}
|
}{% if not loop.last %},{% endif %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
]
|
]
|
||||||
Loading…
Reference in a new issue