I have a problem with filtering elements. I have a product catalog and have an item filter. The filter has a set of checkboxes. The number of products corresponding to the property is indicated in parentheses in the filter. Visually it looks like this:
It looks like everything is fine, but there is a problem. If I check the box in the "genre" section for "horror", and in the "specials" section I check the box for "multiplayer". That's what I see:
This is the wrong logic. It displays a list of products that have genre = horror AND specials = multiplayer, while I'm looking to display products according to the logic of genre = horror OR specials = multiplayer. According to the logic I need, not one game should be displayed, but four games!
This is how the records I need are being pulled out now:
{% set games = craft.entries().section('games') %}
{% set genreGet = craft.app.request.getQueryParam('genre') %}
{% if genreGet %}
{% do games.genreGame(genreGet|split(',')).all() %}
{% endif %}
{% set specialsGet = craft.app.request.getQueryParam('specials') %}
{% if specialsGet %}
{% do games.specialsGame(specialsGet|split(',')).all() %}
{% endif %}
Is there any way to make this work on the OR principle?
FINAL! Thanks to the guys Moritz Lost and Mats Mikkel Rummelhoff. They suggested how to do it better. Here is the final solution:
{% set games = craft.entries().section('games') %}
{% set elements = [] %}
{% set fields = [] %}
{% set genres = craft.app.request.getQueryParam('genres') %}
{% if genres %}
{% set elements = elements|merge(genres|split(','))%}
{% set fields = fields|merge(['genreEntriesGame'])%}
{% endif %}
{% set specials = craft.app.request.getQueryParam('specials') %}
{% if specials %}
{% set elements = elements|merge(specials|split(','))%}
{% set fields = fields|merge(['specialsEntriesGame'])%}
{% endif %}
{% if elements|length > 0 and fields|length > 0 %}
{% do games.relatedTo({
element: elements,
field: fields
}) %}
{% endif %}
{% set games = games.all() %}
The only thing I did not use the array syntax (genre[], specials[])
syntax as MoritzLost advised. When I use array syntax (genre[], specials[])
in input fields, my URL becomes very long. The names of the parameters in the url are repeated very many times then. Therefore, I used JS to process the selected checkboxes, took their id and wrote them in a separate input field, thereby getting something like this genre=4536,1457
in my URL. So I used |split(',')
split
and change your inputs as mentioned in my answer. The|split
filter always returns an array, which will be empty if the query param doesn't exist. So[genres, special]
will result in[[], []]
– an array with two empty arrays. This is not falsy, so therelatedTo
is always applied. So you're asking Craft for all games related to nothing, which matches nothing.genre[]
,specials[]
) and use the second code example in my answer.