<p>I had to get this working just the other day. Here is what I did:</p>

<pre><code>{# Get the relevant entries #}
{% set categoryQuery = craft.request.getParam('category') %}
{% set categories = craft.categories.group('sectionName').slug(categoryQuery) %}

{# Set the search parameters #} 
{% set searchParams = {
    relatedTo: categories,
    section: 'sectionName'
} %}

{# Get the relevant entries #}
{% set relevantEntries = craft.entries(searchParams) %}
</code></pre>

<p>In the form I have:</p>

<pre><code>&lt;form action=""&gt;

{% for category in craft.categories.group('services') %}
    &lt;input id="{{category.slug}}" type="checkbox" name="category[]"  value="{{ category.slug }}" {{ category.slug in categoryQuery or categoryQuery == null  ? 'checked'}}&gt;
    &lt;label for="{{ category.slug }}" &gt;{{ category.title }}&lt;/label&gt;
{% endfor %}

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

<p>This seems to work for me.</p>

CC BY-SA 3.0
2015-04-30T10:16:00.553Z
Thank you Dave, that's very helpful. Good to see that getting the categories and entries based on the query is as easy as that. It appears that the crux of my problem lies with the fact that I am unable to get the form to submit a comma separated list of categories. I have copied your code and that gives me a query string that looks like this: `?category%5B%5D=managing-waste-recycling&category%5B%5D=working-with-communities`. And that's just not right. No idea why that is and how to fix it. Stuck on this one.
Katrin
CC BY-SA 3.0
2015-04-30T11:28:32.930Z
[Turns out](https://twitter.com/katrinkerber/status/593721413925806080) my knowledge about query strings was non-existent and what I was getting in the URL was correct. I just needed to fix up a couple of `array to string conversion` template errors somewhere else and all is now working as expected.
Katrin
CC BY-SA 3.0
2015-04-29T16:44:38.103Z
2015-04-29T16:44:38.103Z
Dave Coggins
<p>If multiple are passed <code>subcategoryParam</code> should be an array. So I believe you will need to process the data differently to get the categories. If you pass the id instead of the slug you could do this: </p>

<pre><code>targetElement: subcategoryParam|join(',')
</code></pre>

CC BY-SA 3.0
2015-04-29T09:27:55.160Z
Thanks Aran. For this I would have to have a comma separated list in the URL query string, like `?subcategory=11,12`, yes? How do I get to that stage in the first place?
Katrin
CC BY-SA 3.0
2015-04-29T14:52:48.463Z
Change the value of `subcategory.slug` to `subcategory.id`.  Then just use the code I posted earlier which will join each of those categories together. `{% set entries = craft.entries({
  section: listingType,
  relatedTo: {
    targetElement: subcategoryParam|join(','),
    field: 'involvementAreas.area'
  }
}) %}`
a-am
CC BY-SA 3.0
2015-04-29T15:15:29.940Z
That doesn't solve the main issue, which is that I am not getting a **comma separated list** for the subcategory parameter, which is what I need for this to work.
Katrin
CC BY-SA 3.0
2015-04-29T15:38:38.203Z
Sorry I had another look at your code.  You need to add a name to your checkbox with brackets  `name="subcategory[]"` this will submit the checkboxes as an array.
a-am
CC BY-SA 3.0
2015-04-29T15:58:49.833Z
Nope, it doesn't. I have tried that. I have detailed what I am getting instead in the question.
Katrin
CC BY-SA 3.0
2015-04-28T22:35:59.163Z
2015-04-28T22:35:59.163Z
a-am
<p>I hijacked the form submission and generated the URL based on all the checkboxes they checked. </p>

<p>Creating a URL like: /results?category=green,red,blue&amp;number=one,two,three</p>

<p>The input names were not category[], but category and number.</p>

<p>Then in the results template, I grabbed the parameters (just displaying one in this example):</p>

<pre><code>{% set number = craft.request.getParam('number') %}

{% if number %}
    {% for item in mealType|split(',') %}
        {% set numberCategories = craft.categories.group('number').slug(item) %}
        {% set relationParam = relationParam|merge([{ targetElement: numberCategories }]) %}
    {% endfor %}
{% endif %}

{# setup your search parameters #}
{% set searchParams = {
    section: 'news',
    relatedTo: relationParam
} %}

{# Find your entries #}
{# {% set entries = craft.entries(searchParams).order('score') %} #}
{% if relationParam|length &gt; 1 %}
    {% paginate craft.entries(searchParams).order('score').limit(12) as pageInfo, pageEntries %}
{% endif %}
</code></pre>

<p>The JS for getting the values from each checkbox, I set the checkboxes all to have the same class. I looped thru those checkboxes and built an array to of checkbox input names and the values.</p>

<pre><code>$("#news-form").submit(function(e) {
    e.preventDefault();
    var query_string = '';
    var categories = [];
    var i = 0;

    $('.category-checkbox').each(function (index, value) {
        var checkboxName = $(this).attr('name');
        var checkboxValue = $(this).val();

        // if checkbox is checked
        if ($(this).is(':checked'))
        {
            categories[checkboxName] = categories[checkboxName] || [];
            categories[checkboxName].push(checkboxValue);
        }

    });

    var cat_index = 0;

    for(var key in categories)
    {
        console.log(key);

        if(cat_index &gt; 0)
        {
            query_string += '&amp;' + key + '=' + categories[key];
        } else {
            query_string += key + '=' + categories[key];
        }

        cat_index++;
    }

    if( query_string != '')
    {
        window.location = '/news/results?' + query_string;
    }
});
</code></pre>

<p>Hopefully this helps someone out.</p>

CC BY-SA 3.0
2016-04-13T18:36:57.953Z
"hijacked the form submission". I assume this means this approach wouldn't work when JS fails/isn't enabled?
Katrin
CC BY-SA 3.0
2016-04-13T20:02:07.323Z
Correct. I think most users have JS enabled. As long as you can get it to go to a URL like: project.com/news/filtered?category1=green,blue&category2=up,down then you're good to go w/ the rest of the code.
Brad
CC BY-SA 3.0
2016-04-14T12:08:46.033Z
You are certainly not alone with that approach to web development, but I would urge you to [reconsider](http://dsgnwrks.pro/resources/why-you-we-should-care-about-disabled-javascript/).
Katrin
CC BY-SA 3.0
2016-04-12T15:06:15.400Z
2016-04-12T15:06:15.400Z
Brad
<p>I am trying to set up a form with checkboxes that allows users to filter entries by selecting multiple categories, but I am not quite getting it right.</p>

<p>Currently this is my form:</p>

<pre><code>{% set subcategoryParam = craft.request.getParam('subcategory') %}
{% set subcategories = craft.categories.group('partnerAreas').find() %}

&lt;form action="{{ craft.request.url }}"&gt;

  {% for subcategory in subcategories %}
    &lt;input type="checkbox" value="{{ subcategory.slug }}" id="{{ subcategory.slug }}" name="subcategory" {{ subcategory.slug in subcategoryParam ? 'checked'}}&gt;
    &lt;label class="label__checkbox" for="{{ subcategory.slug }}"&gt;
      {{ subcategory.title }}
    &lt;/label&gt;
  {% endfor %}

  &lt;button type="submit"&gt;
    Search
  &lt;/button&gt;
&lt;/form&gt;
</code></pre>

<p>Submitting this form gets me URL query strings like this:</p>

<p><code>?subcategory=sourcing-local-products&amp;subcategory=communication</code></p>

<p>When I am using <code>craft.request.getParam('subcategory')</code>, only the last selected subcategory gets picked up (as you would expect).</p>

<p>I've tried setting the name on the checkbox field to <code>subcategory[]</code>, but that gets me an <code>array to string conversion</code> template error and the URL query string then looks like this:</p>

<p><code>?subcategory%5B%5D=sourcing-local-products&amp;subcategory%5B%5D=communication</code></p>

<p>What do I need to do to get a comma separated list for the subcategory parameter like this:</p>

<p><code>?subcategory=sourcing-local-products,communication</code></p>

<p>And once that is working, how do I then get all the entries that have <strong>any</strong> of the selected categories assigned via a Matrix field?</p>

<p>This is what I've currently got:</p>

<pre><code>{% set subcategoryParam = craft.request.getParam('subcategory') %}
{% set selectedSubcategories = craft.categories.slug(subcategoryParam) %}
{% set entries = craft.entries({
  section: listingType,
  relatedTo: {
    targetElement: selectedSubcategories,
    field: 'involvementAreas.area'
  }
}) %}
</code></pre>

<p>But I imagine that's not quite right if I want to account for an array of selected categories...</p>

<categories><filter>
Filter entries by multiple categories
# Filter entries by multiple categories

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

I am trying to set up a form with checkboxes that allows users to filter entries by selecting multiple categories, but I am not quite getting it right.
Currently this is my form:
{% set subcategoryParam = craft.request.getParam('subcategory') %}
{% set subcategories = craft.categories.group('partnerAreas').find() %}



  {% for subcategory in subcategories %}
    
    
      {{ subcategory.title }}
    
  {% endfor %}

  
    Search
  


Submitting this form gets me URL query strings like this:
?subcategory=sourcing-local-products&subcategory=communication
When I am using craft.request.getParam('subcategory'), only the last selected subcategory gets picked up (as you would expect).
I've tried setting the name on the checkbox field to subcategory[], but that gets me an array to string conversion template error and the URL query string then looks like this:
?subcategory%5B%5D=sourcing-local-products&subcategory%5B%5D=communication
What do I need to do to get a comma separated list for the subcategory parameter like this:
?subcategory=sourcing-local-products,communication
And once that is working, how do I then get all the entries that have any of the selected categories assigned via a Matrix field?
This is what I've currently got:
{% set subcategoryParam = craft.request.getParam('subcategory') %}
{% set selectedSubcategories = craft.categories.slug(subcategoryParam) %}
{% set entries = craft.entries({
  section: listingType,
  relatedTo: {
    targetElement: selectedSubcategories,
    field: 'involvementAreas.area'
  }
}) %}

But I imagine that's not quite right if I want to account for an array of selected categories...

**Tags:** categories, filter

---

## 3 answers

### Answer by username_1 on 2015-04-29. Score: 4 | Accepted answer

I had to get this working just the other day. Here is what I did:
{# Get the relevant entries #}
{% set categoryQuery = craft.request.getParam('category') %}
{% set categories = craft.categories.group('sectionName').slug(categoryQuery) %}

{# Set the search parameters #} 
{% set searchParams = {
    relatedTo: categories,
    section: 'sectionName'
} %}

{# Get the relevant entries #}
{% set relevantEntries = craft.entries(searchParams) %}

In the form I have:


{% for category in craft.categories.group('services') %}
    
    {{ category.title }}
{% endfor %}



This seems to work for me.

> **Comments:**
> **username_0**: Thank you Dave, that's very helpful. Good to see that getting the categories and entries based on the query is as easy as that. It appears that the crux of my problem lies with the fact that I am unable to get the form to submit a comma separated list of categories. I have copied your code and that gives me a query string that looks like this: `?category%5B%5D=managing-waste-recycling&category%5B%5D=working-with-communities`. And that's just not right. No idea why that is and how to fix it. Stuck on this one.  
> **username_0**: [Turns out](https://twitter.com/katrinkerber/status/593721413925806080) my knowledge about query strings was non-existent and what I was getting in the URL was correct. I just needed to fix up a couple of `array to string conversion` template errors somewhere else and all is now working as expected.  

---

### Answer by username_2 on 2015-04-28. Score: 2

If multiple are passed subcategoryParam should be an array. So I believe you will need to process the data differently to get the categories. If you pass the id instead of the slug you could do this: 
targetElement: subcategoryParam|join(',')

> **Comments:**
> **username_0**: Thanks Aran. For this I would have to have a comma separated list in the URL query string, like `?subcategory=11,12`, yes? How do I get to that stage in the first place?  
> **username_2**: Change the value of `subcategory.slug` to `subcategory.id`.  Then just use the code I posted earlier which will join each of those categories together. `{% set entries = craft.entries({   section: listingType,   relatedTo: {     targetElement: subcategoryParam|join(','),     field: 'involvementAreas.area'   } }) %}`  
> **username_0**: That doesn't solve the main issue, which is that I am not getting a **comma separated list** for the subcategory parameter, which is what I need for this to work.  
> **username_2**: Sorry I had another look at your code.  You need to add a name to your checkbox with brackets  `name="subcategory[]"` this will submit the checkboxes as an array.  
> **username_0**: Nope, it doesn't. I have tried that. I have detailed what I am getting instead in the question.  

---

### Answer by username_3 on 2016-04-12. Score: 0

I hijacked the form submission and generated the URL based on all the checkboxes they checked. 
Creating a URL like: /results?category=green,red,blue&number=one,two,three
The input names were not category[], but category and number.
Then in the results template, I grabbed the parameters (just displaying one in this example):
{% set number = craft.request.getParam('number') %}

{% if number %}
    {% for item in mealType|split(',') %}
        {% set numberCategories = craft.categories.group('number').slug(item) %}
        {% set relationParam = relationParam|merge([{ targetElement: numberCategories }]) %}
    {% endfor %}
{% endif %}

{# setup your search parameters #}
{% set searchParams = {
    section: 'news',
    relatedTo: relationParam
} %}

{# Find your entries #}
{# {% set entries = craft.entries(searchParams).order('score') %} #}
{% if relationParam|length > 1 %}
    {% paginate craft.entries(searchParams).order('score').limit(12) as pageInfo, pageEntries %}
{% endif %}

The JS for getting the values from each checkbox, I set the checkboxes all to have the same class. I looped thru those checkboxes and built an array to of checkbox input names and the values.
$("#news-form").submit(function(e) {
    e.preventDefault();
    var query_string = '';
    var categories = [];
    var i = 0;

    $('.category-checkbox').each(function (index, value) {
        var checkboxName = $(this).attr('name');
        var checkboxValue = $(this).val();

        // if checkbox is checked
        if ($(this).is(':checked'))
        {
            categories[checkboxName] = categories[checkboxName] || [];
            categories[checkboxName].push(checkboxValue);
        }

    });

    var cat_index = 0;

    for(var key in categories)
    {
        console.log(key);

        if(cat_index > 0)
        {
            query_string += '&' + key + '=' + categories[key];
        } else {
            query_string += key + '=' + categories[key];
        }

        cat_index++;
    }

    if( query_string != '')
    {
        window.location = '/news/results?' + query_string;
    }
});

Hopefully this helps someone out.

> **Comments:**
> **username_0**: "hijacked the form submission". I assume this means this approach wouldn't work when JS fails/isn't enabled?  
> **username_3**: Correct. I think most users have JS enabled. As long as you can get it to go to a URL like: project.com/news/filtered?category1=green,blue&category2=up,down then you're good to go w/ the rest of the code.  
> **username_0**: You are certainly not alone with that approach to web development, but I would urge you to [reconsider](http://dsgnwrks.pro/resources/why-you-we-should-care-about-disabled-javascript/).  

---

