Filter Entries by Category fields & refresh URL and list with AJAX 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? 

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=&amp;partnerCapabilities=

If anyone could share their filtering snippets, I would greatly appreciate it :)
First you need some HTML/Twig logic to display your categories

&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;


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-&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
    ]);
}