2

This question is very similar to the question posted here I have asked in the comments but my requirements are slightly different. I am trying to filter search results by categories in more than one category group and use both an exclusive search (category AND category) and a non exclusive search (category OR category).

My use case is this: the parks category wants to filter using the OR filter so Park A OR Park B and so does the price filter so Price A OR Price B but when they are combined Park A AND Price B only show parks in the Price A category.

2

After a lot of back and forth and reading various posts on this I thought I would submit my answer. There maybe better ways of doing what I ended up doing but hopefully this will provide a start for someone wanting to do the same.

First here are a few posts and questions that helped:

My Solution

First I created a search form that had the checkboxes for the search, each checkbox name when posted would form the get variable for the filter. A check is done to see if there are categories, if there are then I loop through and add them. There is also a check done to see if you are on the filter results page, if you are then set the relevant checkboxes to checked on the form.

The Search Form Code

<form action="{{ url('homes-for-sale/filter') }}" method="get">

  {# check if there are any park categories if there are then show them as checkboxes #}

  {% if parkCategories|length %}

    {% for category in parkCategories %}
      {% set loopIndex = 'park' ~ loop.index %}
      <label class="checkbox-inline">

        {# if you are on the filter results page then set the results to checked #}

        {% if template is defined and template == 'filter' %}
          <input type="checkbox" name="{{ loopIndex }}" value="{{ category.slug }}"{% if category.slug == park1 or category.slug == park2 or category.slug == park3 or category.slug == park4 or category.slug == park5 %} checked{% endif %}>
        {% else %}
          <input type="checkbox" name="{{ loopIndex }}" value="{{ category.slug }}">
        {% endif %}
        {{ category.navTitle }}
      </label>
    {% endfor %}
  {% endif %}

  {# check if there are any price categories if there are then show them as checkboxes #}

  {% if priceCategories|length %}
    {% for category in priceCategories %}
      {% set loopIndex = 'price' ~ loop.index %}
      <label class="checkbox-inline">

        {# if you are on the filter results page then set the results to checked #}

        {% if template is defined and template == 'filter' %}
          <input type="checkbox" name="{{ loopIndex }}" value="{{ category.slug }}"{% if category.slug == price1 or category.slug == price2 or category.slug == price3 or category.slug == price4 or category.slug == price5 or category.slug == price6 %} checked{% endif %}>
        {% else %}
          <input type="checkbox" name="{{ loopIndex }}" value="{{ category.slug }}">
        {% endif %}
        {{ category.title }}
      </label>
    {% endfor %}
  {% endif %}

  <button type="submit">Submit</button>

</form>

The Filter Results Page

On the results page you need to check which filter variables have been set via the get request and then display the appropriate related entries.

{# set park search parameters #}
{% set park1 = craft.request.getParam('park1') %}
{% set park2 = craft.request.getParam('park2') %}
{% set park3 = craft.request.getParam('park3') %}
{% set park4 = craft.request.getParam('park4') %}
{% set park5 = craft.request.getParam('park5') %}

{# set price search parameters #}
{% set price1 = craft.request.getParam('price1') %}
{% set price2 = craft.request.getParam('price2') %}
{% set price3 = craft.request.getParam('price3') %}
{% set price4 = craft.request.getParam('price4') %}
{% set price5 = craft.request.getParam('price5') %}
{% set price6 = craft.request.getParam('price6') %}

{# set park category model if it is in the search query #}
{% set parkCategory1 = park1|length ? craft.categories.slug(park1).first().id %}
{% set parkCategory2 = park2|length ? craft.categories.slug(park2).first().id %}
{% set parkCategory3 = park3|length ? craft.categories.slug(park3).first().id %}
{% set parkCategory4 = park4|length ? craft.categories.slug(park4).first().id %}
{% set parkCategory5 = park5|length ? craft.categories.slug(park5).first().id %}

{# create an array of park categories #}
{% set parks = [
  parkCategory1,
  parkCategory2,
  parkCategory3,
  parkCategory4,
  parkCategory5,
] %}

{# create a park array and trim blank strings #}
{% set trimParks = [] %}

{% for park in parks %}
  {% if park|length %}
    {% set trimParks = trimParks|merge({ (loop.index0): park}) %}
  {% endif %}
{% endfor %}

{# set price category model if it is in the search query #}
{% set priceCategory1 = price1|length ? craft.categories.slug(price1).first().id %}
{% set priceCategory2 = price2|length ? craft.categories.slug(price2).first().id %}
{% set priceCategory3 = price3|length ? craft.categories.slug(price3).first().id %}
{% set priceCategory4 = price4|length ? craft.categories.slug(price4).first().id %}
{% set priceCategory5 = price5|length ? craft.categories.slug(price5).first().id %}
{% set priceCategory6 = price6|length ? craft.categories.slug(price6).first().id %}

{# create an array of price categories #}
{% set prices = [
  priceCategory1,
  priceCategory2,
  priceCategory3,
  priceCategory4,
  priceCategory5,
  priceCategory6,
] %}

{# create a price array and trim blank strings #}
{% set trimPrices = [] %}

{% for price in prices %}
  {% if price|length %}
    {% set trimPrices = trimPrices|merge({ (loop.index0): price}) %}
  {% endif %}
{% endfor %}

{% if trimParks|length and trimPrices|length %}
  {% set entries = craft.entries.section('homesForSale').relatedTo('and',
    {targetElement:parks},
    {targetElement:prices}
  ) %}
{% endif %}

{% if trimParks|length and not trimPrices|length %}
  {% set entries = craft.entries.section('homesForSale').relatedTo('or',
    {targetElement:parks}
  ) %}
{% endif %}

{% if trimPrices|length and not trimParks|length %}
  {% set entries = craft.entries.section('homesForSale').relatedTo('or',
    {targetElement:prices}
  ) %}
{% endif %}

<h1>Filter Results</h1>

{% if entries|length %}
    <p>{{ entries|length }} results:</p>
    <ul>
        {% for entry in entries %}
          {% set park = entry.park.first() %}
          {% set price = entry.parkPriceCategory.first() %}
          <li><a href="{{ entry.url }}">{{ entry.title }} :: <b>{{ park }}</b> :: <b>{{ price }}</b></a></li>
        {% endfor %}
    </ul>
{% else %}
    <p>Your search didn't return any results.</p>
{% endif %}

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.