Answers.Body: <p>Before I answer your main question, I'm seeing a couple issues with what you’re currently doing that are worth correcting.</p>
  
  <p>First, this code:</p>
  
  <pre><code>{% set supplierCat = craft.categories.group('supplier').slug(supplier).first %}
  {% set productCat = craft.categories.group('product').slug(product).first %}
  {% set deliveryCat = craft.categories.group('delivery').slug(delivery).first %}
  </code></pre>
  
  <p>should be replaced with:</p>
  
  <pre><code>{% set supplierCat = supplier ? craft.categories.group('supplier').slug(supplier).first %}
  {% set productCat = product ? craft.categories.group('product').slug(product).first %}
  {% set deliveryCat = delivery ? craft.categories.group('delivery').slug(delivery).first %}
  </code></pre>
  
  <p>in case any of the <code>supplier</code>/<code>product</code>/<code>delivery</code> params are blank.</p>
  
  <p>Next, this code:</p>
  
  <pre><code>{% set supplierParam = supplier ? {targetElement: supplierCat} : '' %}
  {% set productParam = product ? {targetElement: productCat} : '' %}
  {% set deliveryParam = delivery ? {targetElement: deliveryCat} : '' %}
  </code></pre>
  
  <p>should be replaced with:</p>
  
  <pre><code>{% set supplierParam = supplierCat ? {targetElement: supplierCat} %}
  {% set productParam = productCat ? {targetElement: productCat} %}
  {% set deliveryParam = deliveryCat ? {targetElement: deliveryCat} %}
  </code></pre>
  
  <p>That way you will avoid unexpected behavior if a supplier/product/delivery was <em>posted</em>, but it had an invalid slug, and yielded no results. Also, the <code>: ''</code>s at the end are just not really necessary unless your <em>really</em> wanted them to be strings by default (no reason in this case though), as Twig will default the values to <code>null</code>, which is just as good.</p>
  
  <p>Also, you can’t chain multiple <code>relatedTo</code> params together like this:</p>
  
  
  
  <pre class="lang-twig prettyprint-override"><code>.relatedTo(productParam).relatedTo(deliveryParam)
  </code></pre>
  
  <p>When you do that, the second <code>relatedTo</code> param will just override the 1st one.</p>
  
  <p>Instead you’d need to do something like:</p>
  
  <pre class="lang-twig prettyprint-override"><code>{% set relationParams = [supplierParam, productParam, deliveryParam]|filter %}
  
  {% set entries = craft.entries({
      section: 'suppliers',
      relatedTo: relationParams ? ['and']|merge(relationParams) : null,
      search: query,
      homeGrown: homeGrownParam,
      preparedProduce: preparedProduceParam,
      redTractor: redTractorParam
  }) %}
  </code></pre>
  
  <p><em>(I’m using the <code>{p1: v1, p2: v2}</code> syntax for setting the criteria params here for clarity, but you can use the <code>p1(v1).p2(v2)</code> chaining syntax instead if you prefer it.)</em></p>
  
  <hr>
  
  <p>With that out of the way…</p>
  
  <p>To support searching for entries that are related to <em>multiple</em> suppliers/products/deliveries at the same time, the first thing you’ll need to do is update your search form. I know you said you want to go with checkboxes, but for simplicity’s sake I’ll demonstrate with multi-select boxes, since that’s closer to your original code and produces the same request param data.</p>
  
  <p>For each of your <code>&lt;select&gt;</code>s, just append a <code>[]</code> to the input name and add the <code>multiple</code> attribute:</p>
  
  <pre class="lang-twig prettyprint-override"><code>&lt;select name="supplier[]" multiple&gt;
  ...
  &lt;select name="product[]" multiple&gt;
  ...
  &lt;select name="delivery[]" multiple&gt;
  ...
  </code></pre>
  
  <p>In your search results template, change <code>.first</code> to <code>.find()</code> when fetching the categories:</p>
  
  <pre class="lang-twig prettyprint-override"><code>{% set supplierCat = supplier ? craft.categories.group('supplier').slug(supplier).find() %}
  {% set productCat = product ? craft.categories.group('product').slug(product).find() %}
  {% set deliveryCat = delivery ? craft.categories.group('delivery').slug(delivery).find() %}
  </code></pre>
  
  <p>And assuming you want this to be an <em>inclusive</em> search (where only results with <em>all</em> of the selected suppliers should be included, etc.), you’ll need to prepend <code>'and'</code> to each of the <code>targetElement</code> arrays:</p>
  
  <pre class="lang-twig prettyprint-override"><code>{% set supplierParam = supplierCat ? {targetElement: ['and']|merge(supplierCat)}l %}
  {% set productParam = productCat ? {targetElement: ['and']|merge(productCat)} %}
  {% set deliveryParam = deliveryCat ? {targetElement: ['and']|merge(deliveryCat)} %}
  </code></pre>
  
  <p>That’s it. The rest can stay the same.</p>
  
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2017-03-03T15:31:20.760Z
Answers.Text: There's a letter "l" at the end of this `{% set supplierParam = supplierCat ? {targetElement: supplierCat}l %}`, was that intended?
Answers.UserDisplayName: Jose
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2017-03-03T15:34:42.783Z
Answers.Text: Works great! I just had to add a `selected` attribute to the first option in the select dropdown block. So the code looks something like this: `<option value="" selected>All Products</option>`
Answers.UserDisplayName: Jose
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2017-03-03T16:12:38.447Z
Answers.Text: Interestingly, if I don't have the `selected` attribute on the first option of the three select boxes, it doesn't work? Why's that?
Answers.UserDisplayName: Jose
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2017-03-03T17:31:43.310Z
Answers.Text: @Jose Just [updated the answer](http://craftcms.stackexchange.com/posts/19258/revisions) to address the possibility of `supplier`/`product`/`delivery` params being blank.
Answers.UserDisplayName: Brandon Kelly
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2017-03-03T12:43:24.003Z
Answers.LastActivityDate: 2017-03-03T17:30:32.170Z
Answers.LastEditDate: 2017-03-03T17:30:32.170Z
Answers.UserDisplayName: Brandon Kelly
Body: <p>Been scratching my head for the past day on how to implement search with multiple categories. </p>
  
  <p>At the moment, I have product categories as a select dropdown which only allows to search in one category at a time. This is passing the value as a parameter. How do I go about searching with multiple categories (checkboxes) at once? Here's what I have so far. </p>
  
  <p>Any ideas?</p>
  
  <p><strong>search.html</strong></p>
  
  <pre><code>&lt;form action="{{ url('food-suppliers/results') }}"&gt;
      &lt;input type="search" name="query" placeholder="What are you looking for?" style="width: 100%;"&gt;
  
      &lt;select name="supplier"&gt;
        &lt;option value=""&gt;All Markets&lt;/option&gt;
        {% set suppliers = craft.categories.group('suppliers') %}
        {% for supplier in suppliers %}
        &lt;option value="{{ supplier.slug }}"&gt;{{ supplier.title }}&lt;/option&gt;
        {% endfor %}
      &lt;/select&gt;
  
      &lt;select name="product"&gt;
        &lt;option value=""&gt;All Products&lt;/option&gt;
        {% set products = craft.categories.group('product') %}
        {% for product in products %}
        &lt;option value="{{ product.slug }}"&gt;{{ product.title }}&lt;/option&gt;
        {% endfor %}
      &lt;/select&gt;
  
      &lt;select name="delivery"&gt;
        &lt;option value=""&gt;All Delivery&lt;/option&gt;
        {% set deliveries = craft.categories.group('delivery') %}
        {% for delivery in deliveries %}
        &lt;option value="{{ delivery.slug }}"&gt;{{ delivery.title }}&lt;/option&gt;
        {% endfor %}
      &lt;/select&gt;
  
      &lt;div class=""&gt;
        &lt;input type="checkbox" name="homeGrown" value="true"&gt;Home Grown&lt;br/&gt;
        &lt;input type="checkbox" name="preparedProduce" value="true"&gt;Prepared Produce&lt;br/&gt;
        &lt;input type="checkbox" name="redTractor" value="true"&gt;Red Tractor&lt;br/&gt;
      &lt;/div&gt;
  
      &lt;div class=""&gt;
        &lt;input type="submit" value="Search"&gt;
      &lt;/div&gt;
  
  &lt;/form&gt;
  </code></pre>
  
  <p><strong>results.html</strong></p>
  
  <pre><code>{% set query = craft.request.getParam('q') %}
  {% set supplier = craft.request.getParam('supplier') %}
  {% set product = craft.request.getParam('product') %}
  {% set delivery = craft.request.getParam('delivery') %}
  
  {% set homeGrownParam = craft.request.getParam('homeGrown') %}
  {% set preparedProduceParam = craft.request.getParam('preparedProduce') %}
  {% set redTractorParam = craft.request.getParam('redTractor') %}
  
  
  {% set supplierCat = craft.categories.group('supplier').slug(supplier).first %}
  {% set productCat = craft.categories.group('product').slug(product).first %}
  {% set deliveryCat = craft.categories.group('delivery').slug(delivery).first %}
  
  
  {% set supplierParam = supplier ? {targetElement: supplierCat} : '' %}
  {% set productParam = product ? {targetElement: productCat} : '' %}
  {% set deliveryParam = delivery ? {targetElement: deliveryCat} : '' %}
  
  
  {% set entries = craft.entries.section('suppliers').relatedTo(productParam).relatedTo(deliveryParam).search(query).homeGrown(homeGrownParam).preparedProduce(preparedProduceParam).redTractor(redTractorParam) %}
  </code></pre>
  
Tags: <search>
Title: Advanced Search with tags and categories
ThreadText: # Advanced Search with tags and categories
  
  (Asked by: username_0 on 2017-03-03)
  
  Been scratching my head for the past day on how to implement search with multiple categories.
  
  At the moment, I have product categories as a select dropdown which only allows to search in one category at a time. This is passing the value as a parameter. How do I go about searching with multiple categories (checkboxes) at once? Here's what I have so far.
  
  Any ideas?
  
  **search.html**
  
  ```
  <form action="{{ url('food-suppliers/results') }}">
      <input type="search" name="query" placeholder="What are you looking for?" style="width: 100%;">
  
      <select name="supplier">
        <option value="">All Markets</option>
        {% set suppliers = craft.categories.group('suppliers') %}
        {% for supplier in suppliers %}
        <option value="{{ supplier.slug }}">{{ supplier.title }}</option>
        {% endfor %}
      </select>
  
      <select name="product">
        <option value="">All Products</option>
        {% set products = craft.categories.group('product') %}
        {% for product in products %}
        <option value="{{ product.slug }}">{{ product.title }}</option>
        {% endfor %}
      </select>
  
      <select name="delivery">
        <option value="">All Delivery</option>
        {% set deliveries = craft.categories.group('delivery') %}
        {% for delivery in deliveries %}
        <option value="{{ delivery.slug }}">{{ delivery.title }}</option>
        {% endfor %}
      </select>
  
      <div class="">
        <input type="checkbox" name="homeGrown" value="true">Home Grown<br/>
        <input type="checkbox" name="preparedProduce" value="true">Prepared Produce<br/>
        <input type="checkbox" name="redTractor" value="true">Red Tractor<br/>
      </div>
  
      <div class="">
        <input type="submit" value="Search">
      </div>
  
  </form>
  
  ```
  
  **results.html**
  
  ```
  {% set query = craft.request.getParam('q') %}
  {% set supplier = craft.request.getParam('supplier') %}
  {% set product = craft.request.getParam('product') %}
  {% set delivery = craft.request.getParam('delivery') %}
  
  {% set homeGrownParam = craft.request.getParam('homeGrown') %}
  {% set preparedProduceParam = craft.request.getParam('preparedProduce') %}
  {% set redTractorParam = craft.request.getParam('redTractor') %}
  
  {% set supplierCat = craft.categories.group('supplier').slug(supplier).first %}
  {% set productCat = craft.categories.group('product').slug(product).first %}
  {% set deliveryCat = craft.categories.group('delivery').slug(delivery).first %}
  
  {% set supplierParam = supplier ? {targetElement: supplierCat} : '' %}
  {% set productParam = product ? {targetElement: productCat} : '' %}
  {% set deliveryParam = delivery ? {targetElement: deliveryCat} : '' %}
  
  {% set entries = craft.entries.section('suppliers').relatedTo(productParam).relatedTo(deliveryParam).search(query).homeGrown(homeGrownParam).preparedProduce(preparedProduceParam).redTractor(redTractorParam) %}
  
  ```
  
  **Tags:** search
  
  
  ---
  
  ## 1 answers
  
  ### Answer by username_1 on 2017-03-03. Score: 5 | Accepted answer
  
  Before I answer your main question, I'm seeing a couple issues with what you’re currently doing that are worth correcting.
  
  First, this code:
  
  ```
  {% set supplierCat = craft.categories.group('supplier').slug(supplier).first %}
  {% set productCat = craft.categories.group('product').slug(product).first %}
  {% set deliveryCat = craft.categories.group('delivery').slug(delivery).first %}
  
  ```
  
  should be replaced with:
  
  ```
  {% set supplierCat = supplier ? craft.categories.group('supplier').slug(supplier).first %}
  {% set productCat = product ? craft.categories.group('product').slug(product).first %}
  {% set deliveryCat = delivery ? craft.categories.group('delivery').slug(delivery).first %}
  
  ```
  
  in case any of the `supplier`/`product`/`delivery` params are blank.
  
  Next, this code:
  
  ```
  {% set supplierParam = supplier ? {targetElement: supplierCat} : '' %}
  {% set productParam = product ? {targetElement: productCat} : '' %}
  {% set deliveryParam = delivery ? {targetElement: deliveryCat} : '' %}
  
  ```
  
  should be replaced with:
  
  ```
  {% set supplierParam = supplierCat ? {targetElement: supplierCat} %}
  {% set productParam = productCat ? {targetElement: productCat} %}
  {% set deliveryParam = deliveryCat ? {targetElement: deliveryCat} %}
  
  ```
  
  That way you will avoid unexpected behavior if a supplier/product/delivery was *posted*, but it had an invalid slug, and yielded no results. Also, the `: ''`s at the end are just not really necessary unless your *really* wanted them to be strings by default (no reason in this case though), as Twig will default the values to `null`, which is just as good.
  
  Also, you can’t chain multiple `relatedTo` params together like this:
  
  ```twig
  .relatedTo(productParam).relatedTo(deliveryParam)
  
  ```
  
  When you do that, the second `relatedTo` param will just override the 1st one.
  
  Instead you’d need to do something like:
  
  ```twig
  {% set relationParams = [supplierParam, productParam, deliveryParam]|filter %}
  
  {% set entries = craft.entries({
      section: 'suppliers',
      relatedTo: relationParams ? ['and']|merge(relationParams) : null,
      search: query,
      homeGrown: homeGrownParam,
      preparedProduce: preparedProduceParam,
      redTractor: redTractorParam
  }) %}
  
  ```
  
  *(I’m using the `{p1: v1, p2: v2}` syntax for setting the criteria params here for clarity, but you can use the `p1(v1).p2(v2)` chaining syntax instead if you prefer it.)*
  
  ---
  
  With that out of the way…
  
  To support searching for entries that are related to *multiple* suppliers/products/deliveries at the same time, the first thing you’ll need to do is update your search form. I know you said you want to go with checkboxes, but for simplicity’s sake I’ll demonstrate with multi-select boxes, since that’s closer to your original code and produces the same request param data.
  
  For each of your `<select>`s, just append a `[]` to the input name and add the `multiple` attribute:
  
  ```twig
  <select name="supplier[]" multiple>
  ...
  <select name="product[]" multiple>
  ...
  <select name="delivery[]" multiple>
  ...
  
  ```
  
  In your search results template, change `.first` to `.find()` when fetching the categories:
  
  ```twig
  {% set supplierCat = supplier ? craft.categories.group('supplier').slug(supplier).find() %}
  {% set productCat = product ? craft.categories.group('product').slug(product).find() %}
  {% set deliveryCat = delivery ? craft.categories.group('delivery').slug(delivery).find() %}
  
  ```
  
  And assuming you want this to be an *inclusive* search (where only results with *all* of the selected suppliers should be included, etc.), you’ll need to prepend `'and'` to each of the `targetElement` arrays:
  
  ```twig
  {% set supplierParam = supplierCat ? {targetElement: ['and']|merge(supplierCat)}l %}
  {% set productParam = productCat ? {targetElement: ['and']|merge(productCat)} %}
  {% set deliveryParam = deliveryCat ? {targetElement: ['and']|merge(deliveryCat)} %}
  
  ```
  
  That’s it. The rest can stay the same.
  
  > **Comments:**
  > **username_0**: There's a letter "l" at the end of this `{% set supplierParam = supplierCat ? {targetElement: supplierCat}l %}`, was that intended?  
  > **username_0**: Works great! I just had to add a `selected` attribute to the first option in the select dropdown block. So the code looks something like this: `<option value="" selected>All Products</option>`  
  > **username_0**: Interestingly, if I don't have the `selected` attribute on the first option of the three select boxes, it doesn't work? Why's that?  
  > **username_1**: @username_0 Just [updated the answer](http://craftcms.stackexchange.com/posts/19258/revisions) to address the possibility of `supplier`/`product`/`delivery` params being blank.  
  
  ---
  
  