2

I am working on a site that requires a filter option based on tags. Each entry will have two sets of tags (e.g., colors and shapes)

{% for tag in craft.tags.group('colorTag') %}
{% for tag in craft.tags.group('shapeTag') %}

How can I create a filter that allows you to check boxes for those tags and display the results that match ANY of the selected tags?

enter image description here

The results will show entries with the Blue tag, entries with the Yellow tag and entries with the Triangle tag.

Thanks so much!

  • You're specifically looking for entries where any of those tags match, correct? i.e. "blue or yellow or triangle". Or is it "(blue or yellow) AND triangle"? – Brad Bell Jan 10 '17 at 0:41
  • Yes, where ANY of the tags match, so any entry with a blue, or a yellow or a triangle tag. – Ricardo Henriquez Jan 10 '17 at 14:43
  • The filtering is from within the CMS right? Not user-based from the page – Jan_dh Jan 17 '17 at 20:17
  • @Jan_dh User based from the front-end. – Ricardo Henriquez Jan 17 '17 at 20:24
5
+50

You can combine multiple relationship criteria by passing an array to the relatedTo parameter with the keyword 'and' or 'or' as the first array element. You want your entries to be related to any of the tags, so this should work for you:

{% set query = craft.request.getQuery() %}

{# Make sure selectedTagIds is an array #}
{% set selectedTagIds = query.tags ?? [] %}

<form action="">
    {% for tag in craft.tags.group('colorTag') %}
        {% set checkedAttr = tag.id in selectedTagIds ? 'checked' : '' %}
        <input type="checkbox" name="tags[]" value="{{ tag.id }}" {{ checkedAttr }}>{{ tag.name }}</input>
    {% endfor %}

    {% for tag in craft.tags.group('shapeTag') %}
        {% set checkedAttr = tag.id in selectedTagIds ? 'checked' : '' %}
        <input type="checkbox" name="tags[]" value="{{ tag.id }}" {{ checkedAttr }}>{{ tag.name }}</input>
    {% endfor %}

    <button type="submit">Search</button>
</form>

{# Prepare our relatedTo parameter #}
{% set relatedToParam = ['or'] %}

{% for id in selectedTagIds %}
    {% set relatedToParam = relatedToParam|merge([{
        targetElement: id
    }]) %}
{% endfor %}

{# Make sure to not pass the param with just the 'or' in the array #}
{% set relatedToParam = relatedToParam|length > 1 ? relatedToParam : null %}

{% set entries = craft.entries({
    section: 'foo',
    relatedTo: relatedToParam,
}) %}

{# Query for the entries and return them #}
{% for entry in entries %}
{% endfor %}
|improve this answer|||||
  • Can you explain where to include the tags name and how to construct the form?. Thanks! – Ricardo Henriquez Jan 17 '17 at 19:41
  • I’d rather go with the tags’s IDs instead of the names, saves us some work to query for the tags by their names. Updated the answer and added the form to make it complete. – carlcs Jan 17 '17 at 22:48
2

I think what you are trying to achieve here has little to do with the actual templating itself. You can add your tags as data-attributes like so

{% set entries = craft.entries.section('yoursection') %}
<ul>
{% for entry in entries %)
   <li data-tag={% for tags in entry.tagsFieldHandle %){{tag.title}}{% endfor %}>{{entry.title}}</li>
{% endfor %}
</ul>

You set the tags for each entry, so you'll be able to hide/show entries with the right tags.

Then you can simply use javascript on the checkboxes to match for one of these tags in the data attributes.

|improve this answer|||||

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.