Last active
March 18, 2024 11:12
-
-
Save janparkio/c3e09f9149bd6b3f9620e36edb091b89 to your computer and use it in GitHub Desktop.
[Collection with filter using AlpineJS] A simpler way to implement search filters with AlpineJS #alpinejs #statamic #antlers #tailwind
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{{# The outer wrapper grid as defined in tailwind.config.js. It makes sure all | |
blocks on a page get evenly spaced without having to worry about margins or | |
paddings. #}} {{ if page_builder }} {{ page_builder scope="block" }} {{ partial | |
src="page_builder/{type}" }} {{ /page_builder }} {{ /if }} | |
<div class="bg-accent-300 pb-14"> | |
<div | |
id="content" | |
class="container px-8 pt-12 mx-auto md:px-12" | |
x-data="loadCollection()" | |
> | |
{{# <p | |
class="mb-4 text-sm font-semibold tracking-wider uppercase text-primary-default" | |
> | |
Busca un curso | |
</p> #}} | |
<label for="search" class="flex"> </label> | |
<div class="flex p-2 bg-white rounded-full shadow-lg"> | |
<span | |
class="flex items-center justify-end w-auto p-2 text-gray-500" | |
> | |
<svg | |
class="w-6 h-6 font-medium text-primary-default" | |
width="20" | |
height="20" | |
xmlns="http://www.w3.org/2000/svg" | |
fill="none" | |
viewBox="0 0 24 24" | |
stroke="currentColor" | |
> | |
<path | |
stroke-linecap="round" | |
stroke-linejoin="round" | |
stroke-width="2" | |
d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" | |
/> | |
Buscar | |
</svg> | |
</span> | |
<input | |
class="w-full px-6 py-4 leading-tight text-gray-700 border-white rounded-full focus:outline-none" | |
x-ref="searchField" | |
x-model="search" | |
@keydown.window.prevent.slash="$refs.searchField.focus()" | |
placeholder="Buscar receta, categoría o descripción..." | |
type="search" | |
/> | |
</div> | |
<div | |
class="grid max-w-lg gap-5 mx-auto mt-10 mb-10 lg:grid-cols-3 lg:max-w-none" | |
> | |
<template x-for="item in filteredCourses" :key="item"> | |
<div class="flex flex-col overflow-hidden rounded-lg shadow-lg"> | |
<div class="flex-shrink-0"> | |
<img | |
class="object-cover w-full h-48 cursor-pointer" | |
:src="`${item.feature_image.url}`" | |
:alt="`${item.feature_image.alt}`" | |
@click="window.location.href = `${item.url}`" | |
/> | |
</div> | |
<div | |
class="flex flex-col justify-between flex-1 p-6 bg-white" | |
> | |
<div class="flex-1"> | |
<p class="text-sm font-medium text-primary-900"> | |
<template x-for="category in item.recetas"> | |
<a | |
:href="`${category.url}`" | |
class="p-1 px-2 rounded-md bg-accent-500" | |
x-text="category.title" | |
> | |
</a> | |
</template> | |
</p> | |
<a :href="`${item.url}`" class="block mt-2"> | |
<p | |
class="text-xl font-semibold text-primary-default" | |
x-text="item.title" | |
></p> | |
<p | |
class="mt-3 text-base text-primary-800" | |
x-text="item.summary" | |
></p> | |
</a> | |
</div> | |
<div class="flex items-center mt-6"> | |
{{# | |
<div class="flex-shrink-0"> | |
<a href="#"> | |
<span class="sr-only">Roel Aufderehar</span> | |
<img | |
class="w-10 h-10 rounded-full" | |
src="https://images.unsplash.com/photo-1472099645785-5658abf4ff4e?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2&w=256&h=256&q=80" | |
alt="" | |
/> | |
</a> | |
</div> | |
<div class="ml-3"> | |
<p class="text-sm font-medium text-neutral-900"> | |
<a href="#" class="hover:underline"> | |
Roel Aufderehar | |
</a> | |
</p> | |
#}} | |
<div | |
class="flex content-center space-x-1 text-sm text-primary-800" | |
> | |
<svg | |
class="w-4 mt-px text-primary-500" | |
xmlns="http://www.w3.org/2000/svg" | |
fill="none" | |
viewBox="0 0 24 24" | |
stroke="currentColor" | |
> | |
<path | |
stroke-linecap="round" | |
stroke-linejoin="round" | |
stroke-width="2" | |
d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z" | |
/> | |
</svg> | |
<span | |
x-text="item.preparation_time != null ? item.preparation_time + ' min.' : 'En pocos minutos.' " | |
></span> | |
</div> | |
</div> | |
</div> | |
</div> | |
</div> | |
</template> | |
</div> | |
<template x-if="filteredCourses <= 0 || filteredCourses === null"> | |
<div class="max-w-lg mx-auto mt-10 mb-10"> | |
<p class="text-neutral-600"> | |
<span>No se encontraron resultados con la palabra:</span> | |
"<span class="font-medium" x-text="search"></span>" | |
<span class="block mt-4" | |
>Por favor prueba con otra palabra o borra tu | |
búsqueda.</span | |
> | |
</p> | |
</div> | |
</template> | |
</div> | |
</div> | |
<script> | |
function loadCollection() { | |
return loadCourses ( | |
{{ collection:escuela as="cursos" }}{{ cursos | to_json }}{{ /collection:escuela }} | |
); | |
} | |
function loadCourses(courses) { | |
return { | |
search: "", | |
myCourses: courses, | |
get filteredCourses() { | |
if (this.search === "") { | |
return this.myCourses; | |
} | |
const filteredItem = this.myCourses.filter((item) => { | |
return ( | |
item.title | |
+ item.summary | |
+ (item.recetas[0] ? item.recetas[0].title:'') | |
+ (item.recetas[1] ? item.recetas[1].title:'') | |
+ (item.recetas[2] ? item.recetas[2].title:'') | |
+ (item.recetas[3] ? item.recetas[3].title:'') | |
+ (item.recetas[4] ? item.recetas[4].title:'') | |
) | |
.toLowerCase() | |
.includes(this.search.toLowerCase()) | |
}) | |
return filteredItem; | |
} | |
}; | |
} | |
</script> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment