<p>First you need some HTML/Twig logic to display your categories</p>

<pre class="lang-TWIG prettyprint-override"><code>&lt;div&gt;
    {% for category in categories %}
        &lt;input data-id="{{ category.id }}" data-slug="{{ category.slug }}" type="checkbox" class="category-filter"&gt;{{ category.title }}
    {% endfor %}

    &lt;a href="" id="submit"&gt;Submit&lt;/a&gt;
&lt;/div&gt;
</code></pre>

<p>Then some Javascript logic to make an ajax request, keep in mind you need some variables for csrf protection</p>

<pre class="lang-JS prettyprint-override"><code>window.csrfTokenName = "{{ craft.app.config.general.csrfTokenName|e('js') }}"
window.csrfTokenValue = "{{ craft.app.request.csrfToken|e('js') }}";
window.siteUrl = '{{ entry.getUrl() }}';
</code></pre>



<pre><code>$(document).ready(function () {
    $('#submit').click(function (e) {
        e.preventDefault();
        var checked = $('.category-filter:checked');
        var ids = [];
        var slugs = [];
        $.each(checked, function (index, item) {
            ids.push(item.dataset.id);
            slugs.push(item.dataset.slug);
        });

        var data = {
            action: 'plugin-id/controller-id/action-id',
            ids: ids
        }
        data[window.csrfTokenName] = window.csrfTokenValue

        var newUrl = siteUrl + '?location=' + slugs.join();
        $.ajax({
            url: '/',
            data: data,
            type: 'POST',
            dataType: 'json',
            success: function (response) {
                console.log(response);
                history.replaceState({}, '', newUrl);
            }
        });
    })
});
</code></pre>

<p>And finally your Controller</p>

<pre class="lang-PHP prettyprint-override"><code>public function actionIndex()
{
    $ids = Craft::$app-&gt;getRequest()-&gt;getBodyParam('ids');
    $entries = Entry::find()
        -&gt;relatedTo($ids)
        -&gt;asArray()
        -&gt;select(['elements.id', 'title'])
        -&gt;all();

    return $this-&gt;asJson([
        'entries' =&gt; $entries
    ]);
}
</code></pre>

CC BY-SA 4.0
2019-02-21T19:40:09.333Z
Is this to create a plugin? I've never dealt with a controller before, I really just need to filter some entries based on category field relations, similar to https://craftcms.com/partners/ I'm currently doing it using mixitup.js but I want to learn how to do it with craft and AJAX.
mateostabio
CC BY-SA 4.0
2019-02-21T19:43:36.337Z
You can't really perform a secure and good ajax request without a controller via plugin. I feel like you don't really know what ajax means. Because it sounds you just want to use it in sake for being able to say "I use ajax". Because doing it means to create a plugin and PHP. If you don't need the complex functionality then let it be
Robin Schambach
CC BY-SA 4.0
2019-02-22T01:50:55.953Z
Yep, never worked with ajax really. But all I know is that without it, the page would refresh. That's the only reason why I wanted to use it, but thanks for the answer and going through all the trouble.
mateostabio
CC BY-SA 4.0
2019-02-22T06:13:39.117Z
If you don't want to create a controller you can just hide your results with Javascript. That's what I mean
Robin Schambach
CC BY-SA 4.0
2019-02-20T07:34:55.133Z
2019-02-20T07:34:55.133Z
Robin Schambach
<p>I'm finding myself stuck with filtering entries that are related to categories using a category field. I'm looking to build a sub-navigation on a page, where I can select from a select field or from a dropdown nav. </p>

<p>I tried following this but no luck. It doesn't work for me. 
<a href="https://craftcms.stackexchange.com/questions/15218/how-to-load-entries-via-ajax-when-a-filter-is-clicked?rq=1">How to load entries via ajax when a filter is clicked?</a> </p>

<p>I also would love to have 2 or 3 category fields. In the end, I am trying to create something very similar to crafts partner page filtering.
<a href="https://craftcms.com/partners/category?locations=&amp;partnerCapabilities=" rel="nofollow noreferrer">https://craftcms.com/partners/category?locations=&amp;partnerCapabilities=</a></p>

<p>If anyone could share their filtering snippets, I would greatly appreciate it :)</p>

<categories><ajax><filter><filtering>
Filter Entries by Category fields & refresh URL and list with AJAX
# Filter Entries by Category fields & refresh URL and list with AJAX

(Asked by: username_0 on 2019-02-19)

I'm finding myself stuck with filtering entries that are related to categories using a category field. I'm looking to build a sub-navigation on a page, where I can select from a select field or from a dropdown nav.

I tried following this but no luck. It doesn't work for me.
[How to load entries via ajax when a filter is clicked?](https://craftcms.stackexchange.com/questions/15218/how-to-load-entries-via-ajax-when-a-filter-is-clicked?rq=1)

I also would love to have 2 or 3 category fields. In the end, I am trying to create something very similar to crafts partner page filtering.
<https://craftcms.com/partners/category?locations=&partnerCapabilities=>

If anyone could share their filtering snippets, I would greatly appreciate it :)

**Tags:** categories, ajax, filter, filtering

---

## 1 answers

### Answer by username_1 on 2019-02-20. Score: 2 | Accepted answer

First you need some HTML/Twig logic to display your categories

    {% for category in categories %}
        {{ category.title }}
    {% endfor %}

    Submit


Then some Javascript logic to make an ajax request, keep in mind you need some variables for csrf protection
window.csrfTokenName = "{{ craft.app.config.general.csrfTokenName|e('js') }}"
window.csrfTokenValue = "{{ craft.app.request.csrfToken|e('js') }}";
window.siteUrl = '{{ entry.getUrl() }}';

$(document).ready(function () {
    $('#submit').click(function (e) {
        e.preventDefault();
        var checked = $('.category-filter:checked');
        var ids = [];
        var slugs = [];
        $.each(checked, function (index, item) {
            ids.push(item.dataset.id);
            slugs.push(item.dataset.slug);
        });

        var data = {
            action: 'plugin-id/controller-id/action-id',
            ids: ids
        }
        data[window.csrfTokenName] = window.csrfTokenValue

        var newUrl = siteUrl + '?location=' + slugs.join();
        $.ajax({
            url: '/',
            data: data,
            type: 'POST',
            dataType: 'json',
            success: function (response) {
                console.log(response);
                history.replaceState({}, '', newUrl);
            }
        });
    })
});

And finally your Controller
public function actionIndex()
{
    $ids = Craft::$app->getRequest()->getBodyParam('ids');
    $entries = Entry::find()
        ->relatedTo($ids)
        ->asArray()
        ->select(['elements.id', 'title'])
        ->all();

    return $this->asJson([
        'entries' => $entries
    ]);
}

> **Comments:**
> **username_0**: Is this to create a plugin? I've never dealt with a controller before, I really just need to filter some entries based on category field relations, similar to https://craftcms.com/partners/ I'm currently doing it using mixitup.js but I want to learn how to do it with craft and AJAX.  
> **username_1**: You can't really perform a secure and good ajax request without a controller via plugin. I feel like you don't really know what ajax means. Because it sounds you just want to use it in sake for being able to say "I use ajax". Because doing it means to create a plugin and PHP. If you don't need the complex functionality then let it be  
> **username_0**: Yep, never worked with ajax really. But all I know is that without it, the page would refresh. That's the only reason why I wanted to use it, but thanks for the answer and going through all the trouble.  
> **username_1**: If you don't want to create a controller you can just hide your results with Javascript. That's what I mean  

---

