Is it possible to build the following/is it the right way in Craft. Been through the docs and searched but stuck.

I just need to build a form on one page with a dropdown select for 2 categories;

  1. Location

  2. Type

That then takes the user to the results page and returns entries where the location and type match.

Can someone be so kind as to provide a sample to get me going please?

1 Answer 1


Building the form is pretty straightforward, you get the categories from your "locations" and "types" category groups using craft.categories and loop them to build your select options. I choose to pass the category's slug as the value to submit and /results as the URL to submit to.

<form action="{{ url('results') }}" method="get">

    <select name="location">
        <option value="">all locations</option>
        {% set categories = craft.categories.group('locations') %}
        {% for category in categories %}
            <option value="{{ category.slug }}">{{ category.title }}</option>
        {% endfor %}

    <select name="type">
        <option value="">all types</option>
        {% set categories = craft.categories.group('types') %}
        {% for category in categories %}
            <option value="{{ category.slug }}">{{ category.title }}</option>
        {% endfor %}

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


Getting the entries that are related to categories from both, one or non of your category groups is a little bit more tricky. In case a category in both select options is selected, you need to use the following syntax for your relatedTo parameter (see Craft docs: "The relatedTo Param - Passing Multiple Relation Criteria"):

{% set cocktails = craft.entries.section('cocktails').relatedTo('and',
    { sourceElement: currentUser, field: 'favoriteCocktails' },
    { targetElement: gin, field: 'ingredients' }
) %}

I suggest to compose the value for the relatedTo parameter starting with an array ['and'] and then build upon this array, conditionally adding array elements (relation conditions) using the merge filter.

{# Get the search data #}
{% set locationParam = craft.request.getParam('location') %}
{% set typeParam = craft.request.getParam('type') %}

{# Compose the relation param #}
{% set relationParam = ['and'] %}

{% if locationParam %}
    {% set location = craft.categories.group('locations').slug(locationParam).first() %}
    {% set relationParam = relationParam|merge([{ targetElement: location }]) %}
{% endif %}

{% if typeParam %}
    {% set type = craft.categories.group('types').slug(typeParam).first() %}
    {% set relationParam = relationParam|merge([{ targetElement: type }]) %}
{% endif %}

{# Avoid passing an array with `['and']` only #}
{% if relationParam|length < 2 %}
    {% set relationParam = '' %}
{% endif %}

{# Find and list matching entries #}
{% set entries = craft.entries.relatedTo(relationParam) %}

{% if entries|length %}
        {% for entry in entries %}
            <li>{{ entry.title }}</li>
        {% endfor %}
{% else %}
    No entries found.
{% endif %}
  • Thank you so much for taking the time, that really helps someone get their head around this for the first time. A scholar and a gent.
    – moondawg
    Commented Jan 28, 2015 at 13:03
  • Trying this today. Unfortunately it is returning results that it shouldn't. I have 2 entries only, as a test. 1.Type: Software Engineer Location:USA 2. Type: Engineer Location: Europe. Specific dropdown searches work fine. But if I choose Software Engineer, Europe - entry 2 still appears. Also, if nothing is chosen, ALL entries in Craft are returned. Any ideas?
    – moondawg
    Commented Jan 29, 2015 at 10:23
  • @moondawg what do you mean with choose nothing? With dropdown fields you always select something, but you probably mean choosing "all types + all locations"? Don't you want this selection to return all entries?
    – carlcs
    Commented Jan 29, 2015 at 15:14
  • @moondawg for that bug you noticed: I was using the wrong syntax to merge array elements. Updated the answer!
    – carlcs
    Commented Jan 29, 2015 at 15:47
  • thank you again so much, that is working now. Just one thing though. All locations and All types brings back ALL the entries in any section or single, not just the 'jobs' section.
    – moondawg
    Commented Jan 29, 2015 at 18:41

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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