Extension de la classe MultipleChoicesFilters. Cette extension vous permet de facilement ajouter des tags pour les options sélectionnées de vos filtres. Vous pouvez décider de placer les tags où vous voulez. Ils peuvent être sous chaque filtre ou dans un même div. L'attribut data-tags-row, que vous ajoutez sur chaque input spécifie le id du div où vous souhaitez afficher le tag.
Le template de votre tag est tiré d'une balise <template>. Cela vous permet de modifier facilement la structure html de votre tag sans toucher à la fonction JavaScript.
Demo
Ananas
Brun
Jaune
Fruits
Avocat
Vert
Fruits
Banane
Jaune
Fruits
Brocoli
Vert
Légumes
Celeri
Vert
Légumes
Citron
Jaune
Fruits
Filet mignon
Gris
Viande
Lime
Vert
Fruits
Patate
Brun
Jaune
Légumes
Pomme
Rouge
Fruits
Salade
Vert
Légumes
Steak
Rouge
Viande
Installation
Importez la fonction dans votre projet
import { MultipleFiltersWithTags } from "@overdog/fn"
Instance et initialisation
new MultipleFiltersWithTags("#filter-wrapper-tags", {
divIds: ["listing"]
}).init()
Cet élément utilise les mêmes options et arguments que le Multiple choices filters.
Twig template Code
{# --------------------- SET RELATEDTO ARRAY #}
{% set relatedTo = [] %}
{# --------------------- CATEGORY GROUP 1 - COLORS #}
{% set colorsUrlQueryName = 'colors'|t %} {# variable also used in the form name #}
{% set colorsUrlQueryValue = craft.app.request.getQueryParam(colorsUrlQueryName)|split(',')|filter %}
{% if colorsUrlQueryValue %}
{% set relatedTo = relatedTo|merge([{
targetElement: craft.categories({ group: 'groupFoodColors', slug: colorsUrlQueryValue }).ids()
}]) %}
{% endif %}
{# --------------------- CATEGORY GROUP 2 - TYPES #}
{% set typesUrlQueryName = 'types'|t %} {# variable also used in the form name #}
{% set typesUrlQueryValue = craft.app.request.getQueryParam(typesUrlQueryName)|split(',')|filter %}
{% if typesUrlQueryValue %}
{% set relatedTo = relatedTo|merge([{
targetElement: craft.categories({ group: 'groupFoodTypes', slug: typesUrlQueryValue }).ids()
}]) %}
{% endif %}
{% if relatedTo|length > 1 %}
{% set relatedTo = ['and']|merge(relatedTo) %}
{% endif %}
{# --------------------- MAIN QUERY #}
{% set foodQuery = craft.entries()
.section('structureFood')
.orderBy('title')
.relatedTo(relatedTo ? relatedTo : null)
.with(['structureFoodColors', 'structureFoodTypes'])
.all()
%}
{# --------------------- FETCH CATEGORIES GROUP AND RADIO BUTTON FIELD TO POPULATE FILTERS #}
{# categories group - example #}
{% set colorsCatGroup = craft.categories().group('groupFoodColors').select(['title', 'slug']).asArray().all() %}
{% set typesCatGroup = craft.categories().group('groupFoodTypes').select(['title', 'slug']).asArray().all() %}
{# --------------------- FILTER LAYOUT #}
{# ID is used by Javascript - a wrapper around your form is necessary as elem for your instance #}
<div id="filter-wrapper-tags" class="border border-gray-300 p-8 grid grid-cols-1 md:grid-cols-3 gap-half mb-half">
{# MACRO TAGS SECTION #}
{% macro tag(id = "", content = "Category Name") %}
<div
class="inline-flex items-center bg-[#c4cad2] rounded-xl cursor-pointer text-0.6em px-3 py-1"
data-fn-tag-id="{{ id }}"
>
{# you can replace the SVG with one from your SVG Sprite #}
<svg class="h-2 w-2 mr-4px shrink-0" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" aria-hidden="true">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" />
</svg>
<div data-fn-tag-content>{{ content }}</div>
</div>
{% endmacro %}
{# IMPORTANT : HTML TEMPLATE FOR THE TAGS SECTION #}
{# template for tags - used by JS - not rendered by the browser #}
<template data-fn-tag-template>
{{ _self.tag() }}
</template>
{# COLORS FILTER #}
{% if colorsCatGroup|length %}
<form data-fn-filter-group="{{ colorsUrlQueryName }}">
<fieldset>
<legend class="font-bold mb-quarter">{{ 'Colors'|t }}</legend>
{% for cat in colorsCatGroup %}
<div class="flex items-center relative py-1">
<input
id="{{ cat.slug }}"
class="inset-0 opacity-0 absolute -z-1 peer"
data-fn-tag-row="tag-row-colors"
type="checkbox"
name="{{ cat.slug }}"
value="{{ cat.slug }}"
{{(cat.slug in colorsUrlQueryValue) ? 'checked' }}
/>
<label
class="cursor-pointer flex items-center w-full
peer-checked:before:bg-black
before:bg-[#c4cad2] before:cursor-pointer before:inline-block before:h-4 before:w-4 before:mr-4 before:shrink-0"
for="{{ cat.slug }}"
>{{ cat.title }}
</label>
</div>
{% endfor %}
</fieldset>
{# TAGS ROW with initial content to show tags on page load #}
<div id="tag-row-colors" class="flex flex-wrap mt-3 gap-2">
{% if colorsUrlQueryValue|length %}
{% for cat in colorsCatGroup|filter(cat => cat.slug in colorsUrlQueryValue) %}
{{ _self.tag(cat.slug, cat.title) }}
{% endfor %}
{% endif %}
</div>
</form>
{% endif %}
{# TYPES FILTER #}
{% if typesCatGroup|length %}
<form data-fn-filter-group="{{ typesUrlQueryName }}">
<fieldset>
<legend class="font-bold mb-quarter">{{ 'Types'|t }}</legend>
{% for cat in typesCatGroup %}
<div class="flex items-center relative py-1">
<input
id="{{ cat.slug }}"
class="inset-0 opacity-0 absolute -z-1 peer"
data-fn-tag-row="tag-row-types"
type="checkbox"
name="{{ cat.slug }}"
value="{{ cat.slug }}"
{{(cat.slug in typesUrlQueryValue) ? 'checked' }}
/>
<label
class="cursor-pointer flex items-center w-full
peer-checked:before:bg-black
before:bg-[#c4cad2] before:cursor-pointer before:inline-block before:h-4 before:w-4 before:mr-4 before:shrink-0"
for="{{ cat.slug }}"
>{{ cat.title }}</label>
</div>
{% endfor %}
</fieldset>
{# TAGS ROW with initial content to show tags on page load #}
<div id="tag-row-types" class="flex flex-wrap mt-3 gap-2">
{% if typesUrlQueryValue|length %}
{% for cat in typesCatGroup|filter(cat => cat.slug in typesUrlQueryValue) %}
{{ _self.tag(cat.slug, cat.title) }}
{% endfor %}
{% endif %}
</div>
</form>
{% endif %}
</div>
{# --------------------- LAYOUT WIH LOOP FOR CARDS #}
{# ID is used by Javascript #}
<div id="listing" class="grid grid-col-1 md:grid-cols-3 gap-third">
{% if foodQuery|length %}
{{ include('_lib-fn/_card', { queryName: foodQuery }, ignore_missing = true )}}
{% else %}
<div>{{ ('There is no content matching your criteria.')|t }}</div>
{% endif %}
</div>