3

I have a list of people (entries) who are related to Categories.

I would like to create select menu which will change (filter) the people (entries) shown on the page depending on which category (option) is selected from the select menu. I would like the default option to show everyone.

I don't mind if this is done on page reload or via ajax but I really don't know where to start with this one :/

Thanks again

Martin

  • 1
    As far as I understand, this select menu would be on the frontend. You could also do it with a frontend filter plugin like isotope: isotope.metafizzy.co using the category id's as filter options – KSPR Oct 7 '15 at 12:55
  • Hi Kaspar, I gave this method a shot and it does work :) However, I would rather stay with the loaded page actually being a category page, rather than just showing and hiding. Many thanks! – Martin Oct 8 '15 at 8:36
3

You can do this using the relatedTo param.

{# Get the selected category ID from a 'catId' query string param #}
{% set catId = craft.request.getQuery('catId') %}

{# Define the 'relatedTo' param value, depending on if there is a category #}
{% if catId %}
    {% set relatedToParam = {
        targetElement: catId,
        field: 'categoriesFieldHandle'
    } %}
{% else %}
    {% set relatedToParam = null %}
{% endif %}

{# Define the ElementCriteriaModel for people #}
{% set people = craft.entries({
    section: 'people',
    relatedTo: relatedToParam,
    limit: null,
    order: 'title asc'
}) %}

{# Output the people #}
{% for person in people %}
    <li>{{ person.title }}</li>
{% endfor %}

With this code in place, you just need to update your view so that when a category is selected, this template is re-loaded with a ?catId=X query string, where X is the selected category ID.

The simplest example of that would be with a list of category links:

{% for cat in craft.categories.group('myGroupHandle') %}
    {% set url = url(craft.request.path, { catId: cat.id }) %}
    <li><a href="{{ url }}">{{ cat.title }}</a></li>
{% endfor %}
  • Hi Brandon, when I add the template code verbatim it gives me the error "Unexpected tag name "catId" (expecting closing tag for the "block" tag defined near line 5)" - There is a closing block tag. – Martin Oct 7 '15 at 14:55
  • @Martin Sorry, typo. Forgot the set in that {% set catId = ... line. – Brandon Kelly Oct 7 '15 at 17:03
  • Sorry, one last thing... how do I display the title of the category currently being shown? – Martin Oct 8 '15 at 8:32
  • @Martin Can you post that as a new question please? – Brandon Kelly Oct 8 '15 at 13:17
  • Hi Brandon - thanks, i've posted the question - craftcms.stackexchange.com/questions/11812/… – Martin Oct 8 '15 at 13:47
2

Like you mention there are really two ways of going about it.

For both ways, you'll want to populate a select dropdown with the value of an individual option being the category name you want to filter by.

The first way you could do it is loading all of the people entries onto the page. Using craft tags spit out all of your people onto the page, and make sure you're giving each "person" an attribute (or class) that lets you show/hide them based on their category

eg:

<div class="person" data-category="{{ entry.categoryName }}">
<h3>Persons Name</h3>
</div>

Within your javascript code, write an event handler that will fire when you change the select dropdown, and then show/hide the people based on the value selected:

$(".people-category-dropdown").change(function(){

  var categoryName = $(this).val();

  $(".person").hide(); 
  $(".person").is("[data-category='"+ categoryName +"']").show();

});

The second way of doing it is to initially only load one category of people onto the page, and when someone updates the dropdown, fire off an ajax request that fetches all of the people from that category. When that response is sent back, swap out all the old people with the new ones.

Those code examples above are by no means all the code you'll need to get things implemented, but hopefully that at least points you in the right direction!

  • Or by using the option Brandon listed above :) – Bryant Oct 7 '15 at 14:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.