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">
<label>Location</label>
<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>
<label>Type</label>
<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 %}
</select>
<button type="submit">Search</button>
</form>
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 %}
<ul>
{% for entry in entries %}
<li>{{ entry.title }}</li>
{% endfor %}
</ul>
{% else %}
No entries found.
{% endif %}