<section class="facets facets-advanced" id="facets" role="navigation">
    <h1 class="facets__title">Filter results</h1>
    <div class="facets__facets">
    </div>
</section>

<script id="facets-advanced-group-template" type="text/template">
    <div class="facets__group">
        <button class="facets__group-button">
            <h2 class="facets__group-title"></h2>
        </button>
        <ul class="facets__list">
        </ul>
    </div>
</script>

<script id="facets-advanced-item-template" type="text/template">
    <li class="facets__item">
        <a class="facets__link" href=""></a>
    </li>
</script>

<script id="facets-advanced-item-checkbox-template" type="text/template">
    <li class="facets__item">
        <input type="checkbox" class="facets__checkbox form-check-input">
        <label for="" class="facets__label form-check-label"></label>
    </li>
</script>

Advanced facets

This component will show the facets of search results, with tailored search filters.

Note

  • In the example the facet is rendered in a column. You should do this yourself when implementing the facets.
  • The titles in this component are rendered via h1 and h2 elements, every heading (h1 - h6) will work so choose your own heading according the structure of the page.

Using

To start using this component, some JavaScript is needed to initialize it.
Underneath a jQuery example on how to initialize the facets and the facets script itself. Both scripts be placed in the Additional component(s) script section as documented in How to use.

Look at the example to see how the data needs to be formatted that you can feed the facets script:

[
    {
        title: 'Document type',
        expanded: 'true',
        facets: [
            { title: 'PDF document (10)', url: '#pdf', active: true, type: checkbox },
            { title: 'Webpage (5)', callback: callbackFunction, type: checkbox}
        ]
    },
    {
        title: 'Date',
        facets: [
            { title: 'Last week (7)' },
            { title: 'This week (3)' },
            { title: 'Today (5)' }
        ]
    }
]

Example on how to implement:

<script>
    var facets = new FacetsAdvanced();

    function facetClickHandler(event, $facetItem, facetItem) {
        if (facetItem.type == 'checkbox') {
            var isChecked = $('.facets__checkbox', $facetItem).prop('checked');
            console.log(facetItem.title + ' is ' + (isChecked ? 'checked' : 'unchecked'));
            return;
        }
        if ($facetItem.hasClass('active')) {
            $('#facets .facets__item').removeClass('active');
            console.log(facetItem.title + ' is deselected');
            event.preventDefault();
            return;
        }
        $('#facets .facets__item').removeClass('active');
        console.log(facetItem.title + ' is selected');
        $facetItem.addClass('active');
        event.preventDefault();
    }

    $(document).ready(function () {
        var facetData = [
            {
                title: 'Document type',
                expanded: true,
                facets: [
                    { title: 'Webpagina (5)', type: "checkbox", active: true },
                    { title: 'PDF document (10)', type: "checkbox" }
                ]
            },
            {
                title: 'Datum',
                facets: [
                    { title: 'Vandaag (5)' },
                    { title: 'Deze week (3)' },
                    { title: 'Afgelopen week (7)' }
                ]
            }
        ];

        facets.init('#facets', facetClickHandler);
        facets.show(facetData);
    });
</script>

Advanced Facets script:

<script>
    function FacetsAdvanced() {
        this.$facets = null;
        this.$facetsContainer = null;
        this.facetGroupTemplate = null;
        this.facetItemTemplate = null;
        this.globalCallback = null;
    }

    FacetsAdvanced.prototype.init = function (selector, globalCallback) {
        this.$facets = $(selector);
        this.$facetsContainer = $('.facets__facets', this.$facets);
        this.$facetsContainer.addClass('hide');

        this.globalCallback = globalCallback;
        this.facetGroupTemplate = $.parseHTML($('#facets-advanced-group-template').html());
        this.facetItemTemplate = $.parseHTML($('#facets-advanced-item-template').html());
        this.facetItemCheckboxTemplate = $.parseHTML($('#facets-advanced-item-checkbox-template').html());

        $('.facets__title', this.$facets).click(this.clickHandler.bind(this));
    };

    FacetsAdvanced.prototype.clickHandler = function () {
        var $title = $('.facets__title', this.$facets);
        if ($title.hasClass('expanded')) {
            $title.removeClass('expanded');
            this.$facetsContainer.removeClass('expanded');
        } else {
            $title.addClass('expanded');
            this.$facetsContainer.addClass('expanded');
        }
    };

    FacetsAdvanced.prototype.createGroup = function (facetGroup, id) {
        var $facetGroup = $(this.facetGroupTemplate).clone();
        if (facetGroup.expanded) {
            $facetGroup.addClass('expanded');
        }
        $('.facets__group-title', $facetGroup)
            .html(facetGroup.title);
        $('.facets__group-button', $facetGroup)
            .click(function () {
                var $facetGroup = $(this).parent();
                if ($facetGroup.hasClass('expanded')) {
                    $facetGroup.removeClass('expanded');
                    $(this).attr('aria-expanded', 'false');
                } else {
                    $facetGroup.addClass('expanded');
                    $(this).attr('aria-expanded', 'true');
                }
            })
            .attr('aria-expanded', facetGroup.expanded ? 'true' : 'false')
            .attr('aria-controls', 'facet-group-list-' + id);

        $('.facets__list', $facetGroup).attr('id', 'facet-group-list-' + id);
        return $facetGroup;
    };

    FacetsAdvanced.prototype.createItem = function (facetItem, id) {
        var $facetItem = $(this.facetItemTemplate).clone();

        $('.facets__link', $facetItem).html(facetItem.title);
        if (facetItem.url) {
            $('.facets__link', $facetItem).attr('href', facetItem.url);
        }
        if (facetItem.callback || this.globalCallback) {
            var callback = facetItem.callback ? facetItem.callback : this.globalCallback;
            $('.facets__link', $facetItem).click(
                (function ($facetItem, facetItem) {
                    return function (event) {
                        callback(event, $facetItem, facetItem);
                    };
                })($facetItem, facetItem)
            );
        }
        if (facetItem.active) {
            $facetItem.addClass('active');
        }
        return $facetItem;
    };

    FacetsAdvanced.prototype.createItemCheckbox = function (facetItem, id) {
        var $facetItem = $(this.facetItemCheckboxTemplate).clone();
        var namedId = facetItem.id ? facetItem.id : 'facet-item-checkbox-' + id;
        var callback = facetItem.callback ? facetItem.callback : this.globalCallback;
        $('.facets__checkbox', $facetItem)
            .attr('id', namedId)
            .change((function ($facetItem, facetItem) {
                return function (event) {
                    callback(event, $facetItem, facetItem);
                };
            })($facetItem, facetItem));
        if (facetItem.active) {
            $('.facets__checkbox', $facetItem).prop('checked', true);
        }
        $('.facets__label', $facetItem).html(facetItem.title).attr('for', namedId);
        return $facetItem;
    };

    FacetsAdvanced.prototype.show = function (facets) {
        this.$facetsContainer.html('');
        if (facets && facets.length) {
            this.$facets.removeClass('facets--hide');
        } else {
            this.$facets.addClass('facets--hide');
        }
        for (var groupKey in facets) {
            var facetGroup = facets[groupKey];
            var $facetGroup = this.createGroup(facetGroup, groupKey);

            for (var itemKey in facetGroup.facets) {
                var facetItem = facetGroup.facets[itemKey];
                var $facetItem = null;
                if (facetItem.type == 'checkbox') {
                    $facetItem = this.createItemCheckbox(facetItem, itemKey);
                }
                else {
                    $facetItem = this.createItem(facetItem, itemKey);
                }

                $('.facets__list', $facetGroup).append($facetItem);
            }

            this.$facetsContainer.append($facetGroup);
        }
    };
</script>