Previous
Multiple choices filters
import { MultipleFilters } from "@overdog/fn"
new MultipleFilters("#filter-wrapper-multiple-dropdown", {
divIds: ["listing"]
}).init()
{# --------------------- 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 %}
{# --------------------- MERGE THE CATEGORIES FOR THE RELATEDTO #}
{% if relatedTo|length > 1 %}
{% set relatedTo = ['and']|merge(relatedTo) %}
{% endif %}
{# --------------------- MAIN QUERY - with eager loading the categories #}
{% set foodQuery = craft.entries()
.section('structureFood')
.orderBy('title')
.relatedTo(relatedTo ? relatedTo : null)
.with(['structureFoodColors', 'structureFoodTypes'])
.all()
%}
{# --------------------- FETCH CATEGORIES GROUP TO POPULATE FILTERS #}
{# categories group #}
{% set typesCatGroup = craft.categories().group('groupFoodTypes').all() %}
{% set colorsCatGroup = craft.categories().group('groupFoodColors').all() %}
{# --------------------- FILTERS LAYOUT #}
{# ID is used by Javascript #}
<div id="filter-wrapper-multiple-dropdown" class="grid grid-cols-1 md:grid-cols-3 gap-half mb-half">
{# TYPES FORM - Dropdown filter multiple choices #}
{% if typesCatGroup|length %}
<div class="filter-dropdown relative">
<button
class="flex items-center border-b border-[#a5adb9] h-[50px] justify-between text-left w-full"
aria-expanded="false"
aria-controls="form-type"
>
<span>{{ 'Filter by type'|t }}</span>
{# caret #}
<span class="
border-b-0 border-x-transparent border-x-[0.3em] border-t-[0.3em] border-t-slate-600
transition-all ease-linear duration-200
parent-is-open:rotate-180
">
</span>
</button>
<div
id="form-types" {# only for aria-controls - not used by JS #}
class="absolute hidden left-0 p-4 bg-white rounded-b-md shadow-md overflow-hidden w-full z-10
parent-is-open:block"
>
<form data-fn-filter-group="{{ typesUrlQueryName }}">
<fieldset>
<legend class="sr-only">{{ 'Filter by type'|t }}</legend>
{% for category in typesCatGroup %}
<div class="flex items-center relative py-1">
<input
id="{{ category.slug }}"
class="inset-0 opacity-0 absolute -z-1 peer"
type="checkbox"
name="{{ category.slug }}"
value="{{ category.slug }}" {{(category.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="{{ category.slug }}"
>
{{ category.title }}
</label>
</div>
{% endfor %}
</fieldset>
</form>
</div>
</div>
{% endif %}
{# COLORS FORMS - Dropdown filter fake select single choice #}
{% if colorsCatGroup|length %}
<div class="filter-dropdown relative">
<button
class="flex items-center border-b border-[#a5adb9] h-[50px] justify-between text-left w-full"
aria-expanded="false"
aria-controls="form-colors"
>
<span data-fn-dropdown-text>{{ 'Filter by colors'|t }}</span>
{# caret #}
<span class="
border-b-0 border-x-transparent border-x-[0.3em] border-t-[0.3em] border-t-slate-600
transition-all ease-linear duration-200
parent-is-open:rotate-180
">
</span>
</button>
<div
id="form-colors" {# only for aria-controls - not used by JS #}
class="absolute hidden left-0 bg-white rounded-b-md shadow-md overflow-hidden w-full z-10
parent-is-open:block"
>
<form data-fn-filter-group="{{ colorsUrlQueryName }}">
<fieldset>
<legend class="sr-only">{{ 'Filter by colors'|t }}</legend>
<div>
<input
id="all"
class="absolute inset-0 opacity-0 -z-1"
type="radio"
name="cat-radio"
value=""
/>
<label class="cursor-pointer block px-3.5 py-1.5 w-full hover:bg-[#e7edee]" for="all">{{ 'All colors'|t }}</label>
</div>
{% for category in colorsCatGroup %}
{# name must be the same for radio button #}
<div>
<input
id="{{ category.slug }}"
class="absolute inset-0 opacity-0 -z-1"
type="radio"
name="cat-radio"
value="{{ category.slug }}" {{(category.slug in colorsUrlQueryValue) ? 'checked' }}
/>
<label class="cursor-pointer block px-3.5 py-1.5 w-full hover:bg-[#e7edee]" for="{{ category.slug }}">{{ category.title }}</label>
</div>
{% endfor %}
</fieldset>
</form>
</div>
</div>
{% 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 opacity-1 is-loading:opacity-40 transition-opacity">
{% 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>