<p>Building the form is pretty straightforward, you get the categories from your "locations" and "types" <a href="http://buildwithcraft.com/docs/categories#category-groups">category groups</a> using <a href="http://buildwithcraft.com/docs/templating/craft.categories"><code>craft.categories</code></a>
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. </p>

<pre><code>&lt;form action="{{ url('results') }}" method="get"&gt;

    &lt;label&gt;Location&lt;/label&gt;
    &lt;select name="location"&gt;
        &lt;option value=""&gt;all locations&lt;/option&gt;
        {% set categories = craft.categories.group('locations') %}
        {% for category in categories %}
            &lt;option value="{{ category.slug }}"&gt;{{ category.title }}&lt;/option&gt;
        {% endfor %}
    &lt;/select&gt;

    &lt;label&gt;Type&lt;/label&gt;
    &lt;select name="type"&gt;
        &lt;option value=""&gt;all types&lt;/option&gt;
        {% set categories = craft.categories.group('types') %}
        {% for category in categories %}
            &lt;option value="{{ category.slug }}"&gt;{{ category.title }}&lt;/option&gt;
        {% endfor %}
    &lt;/select&gt;

    &lt;button type="submit"&gt;Search&lt;/button&gt;

&lt;/form&gt;
</code></pre>

<p>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 <a href="http://buildwithcraft.com/docs/relations#the-relatedTo-param"><code>relatedTo</code></a> parameter
(see Craft docs: <a href="http://buildwithcraft.com/docs/relations#the-relatedTo-param">"The relatedTo Param - Passing Multiple Relation Criteria"</a>):</p>

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

<p>I suggest to compose the value for the <code>relatedTo</code> parameter starting with an array <code>['and']</code> and then build upon this array,
conditionally adding array elements (relation conditions) using the <a href="http://twig.sensiolabs.org/doc/filters/merge.html"><code>merge</code></a> filter.</p>

<pre><code>{# 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 &lt; 2 %}
    {% set relationParam = '' %}
{% endif %}

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

{% if entries|length %}
    &lt;ul&gt;
        {% for entry in entries %}
            &lt;li&gt;{{ entry.title }}&lt;/li&gt;
        {% endfor %}
    &lt;/ul&gt;
{% else %}
    No entries found.
{% endif %}
</code></pre>

CC BY-SA 3.0
2015-01-28T13:03:36.650Z
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
CC BY-SA 3.0
2015-01-29T10:23:20.957Z
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
CC BY-SA 3.0
2015-01-29T15:14:56.273Z
@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
CC BY-SA 3.0
2015-01-29T15:47:12.820Z
@moondawg for that bug you noticed: I was using the wrong syntax to merge array elements. Updated the answer!
carlcs
CC BY-SA 3.0
2015-01-29T18:41:41.270Z
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
CC BY-SA 3.0
2015-01-29T18:45:11.923Z
Sorry, I amended it myself and it works!! I amended it to: {# Find and list matching entries #}
{% set entries = craft.entries.relatedTo(relationParam).section('jobs') %}
moondawg
CC BY-SA 3.0
2015-01-28T11:54:26.267Z
2015-01-29T15:42:46.980Z
2015-01-29T15:42:46.980Z
carlcs
<p>Is it possible to build the following/is it the right way in Craft. Been through the docs and searched but stuck.</p>

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

<ol>
<li><p>Location</p></li>
<li><p>Type</p></li>
</ol>

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

<p>Can someone be so kind as to provide a sample to get me going please?</p>

<categories><search>
Building a simple search by multiple categories
# Building a simple search by multiple categories

(Asked by: username_0 on 2015-01-28)

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?

**Tags:** categories, search

---

## 1 answers

### Answer by username_1 on 2015-01-28. Score: 8 | Accepted answer

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. 


    Location
    
        all locations
        {% set categories = craft.categories.group('locations') %}
        {% for category in categories %}
            {{ category.title }}
        {% endfor %}
    

    Type
    
        all types
        {% set categories = craft.categories.group('types') %}
        {% for category in categories %}
            {{ category.title }}
        {% endfor %}
    

    Search



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 %}
            {{ entry.title }}
        {% endfor %}
    
{% else %}
    No entries found.
{% endif %}

> **Comments:**
> **username_0**: 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.  
> **username_0**: 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?  
> **username_1**: @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?  
> **username_1**: @moondawg for that bug you noticed: I was using the wrong syntax to merge array elements. Updated the answer!  
> **username_0**: 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.  
> **username_0**: Sorry, I amended it myself and it works!! I amended it to: {# Find and list matching entries #} {% set entries = craft.entries.relatedTo(relationParam).section('jobs') %}  

---

