Skip to content

Instantly share code, notes, and snippets.

@janparkio
Last active March 18, 2024 11:12
Show Gist options
  • Save janparkio/c3e09f9149bd6b3f9620e36edb091b89 to your computer and use it in GitHub Desktop.
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
{{# 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