How to highlight an active filter?

Hi there,
I’ve followed your amazing youtube course building a portfolio website, and I would like to add a CSS class to an active filter. I’m an absolute beginner, so I don’t really understand how to do that.

In the youtube comments, you said to ‘in the foreach loop for the filter buttons you can compare $filter with $filterBy and then add a css class or an aria-current attribute if they are the same’

but I can’t seem to make it work. I guess it should go somewhere here, but I’m not sure.

  <nav class="filter">
    <a href="<?= $page->url() ?>">All</a>
  <?php foreach ($filters as $filter): ?>
    <a href="<?= $page->url() ?>?filter=<?= $filter ?>"><?= $filter ?></a>
  <?php endforeach ?>
  </nav>

Thank you so much!

Hey, welcome to our forum. Assuming you are using this code: kirbycasts/projects.php at main · getkirby/kirbycasts · GitHub

<nav class="filter">
      <a href="<?= $page->url() ?>">All</a>
      <?php foreach ($filters as $filter): ?>
      <a href="<?= $page->url() ?>?filter=<?= $filter ?>" class="<?= $filterBy === $filter ? 'active' : '' ?>"><?= $filter ?></a>
      <?php endforeach ?>
    </nav>

Great, thank you! I would like to highlight the “All” Link if no Filter is active. Is there a possibility to check if no filter is selected to add the “active” class to this Link?
Thank you!

1 Like

Hi, have you found a way to do this?
I’m also wondering if there is way to get the filters/links in the order I want them to be in

Hi, you can use param('filter') to check if a filter parameter is set in the url and if not, you can highlight the ‘All’ link. You can read more e.g. here: Filter collections by tags | Kirby CMS

If you want a custom sorting of the filters that is not alphabetic, then you would have to use something like usort: usort

Sigi

Hey! I’m also struggling with this. The code snippet here is only applying the filtername as class name to the <a> element - but not a class named “active” or the :active for a class with the filter name?

This is what I’d get for all, no matter which one is active:
<a href="http://localhost:8080/projects?filter=Work" class="">Work</a>

and this is what I’d want to achieve:

if not selected:
<a href="http://localhost:8080/projects?filter=Work" class="inactive">Work</a>

if selected:
<a href="http://localhost:8080/projects?filter=Work" class="active">Work</a>

Any help is highlgy appreciated, thanks!

Could you please post the code you are using?

Sure! I’m using this one here:

Is the $filterBy variable defined and if so, how?

Yes, should be! I use this snippet from one of the youtube tutorials:

    <?php snippet('nav') ?>
    <?php snippet('header') ?>
    <?php 
        $filterBy = get('filter');
        $unfiltered = $page->children()->listed();
        $projects = $unfiltered
        ->when($filterBy, function($filterBy) {
            return $this->filterBy('category',$filterBy);
        })
        ->paginate(10);
        $pagination = $projects->pagination();
        $filters = $unfiltered->pluck('category', null, true);
    ?>

Sorry, I’m very new to php/kirby and might have mixed things up… Thank you!

But the filter itself works as expected? On a side note, you only need the active class, not an inactive class?

Yes, the filter works perfect!

I know what the problem is.

This line of code doesn’t return a simple array, but an array of field objects. Therefore the strict comparison

$filterBy === $filter 

Does not work.

You have two options:

Use

$filterBy == $filter 

or, in my opinion the better option, pass a comma as separator in the pluck method even if your field does not contain a comma separated list of value (which makes sure you get a simple indexed array)

$filters = $unfiltered->pluck('category', ',', true);
1 Like

Amazing!! I have implemented the second method and it works great. Thank you so much and have a nice rest of the weekend! :slight_smile:

Hey,

I’m new in Kirby and I’ve got a problem with the ‘active’ css class on my filters. I created the filter system with this code:

<?php

$filterBy = get('filter');

$unfilterd = $page->children()->listed();

 $page = $unfilterd
 ->when ($filterBy, function($filterBy){
  return $this->filterBy('Tags', $filterBy, ',');
})
?>

<?php
$filters = $unfilterd->pluck('Tags', ',', true);
  ?>

  <nav class="filter">
  <li <?='class="active"'?>>Alle<a href="<?= $page->url() ?>?filter="></li>


  <?php foreach ($filters as $filter): ?>
    <li <?= $filter === $filterBy ? 'class="active"' : ''?>><a href="<?= $page->url() ?>?filter=<?= $filter ?>"><?= $filter ?></a></li>
  <?php endforeach ?>

The filter system works. But there’s a problem with the ‘active’ css class on the “alle” function:

Is there any easy solution for this problem?

Don’t store your filtered collection in the $page variable. $page should never be redefined, it is a global variable that refers to the current page.

<?php
 $filtered = $unfilterd
 ->when ($filterBy, function($filterBy){
  return $this->filterBy('Tags', $filterBy, ',');
})

?>
  <ul>
  <li <?='class="active"'?>>Alle<a href="<?= $page->url() ?>?filter="></li>
 <?php foreach ($filters as $filter): ?>
    <li <?= $filter === $filterBy ? 'class="active"' : ''?>><a href="<?= $page->url() ?>?filter=<?= $filter ?>"><?= $filter ?></a></li>
  <?php endforeach ?>
  </ul>

<?php foreach ($filtered as $p): ?>
  <!-- do stuff -->
<?php endforeach ?>

Also, don’t use li elements without an ul wrapper.

1 Like

Hi there! Thank you for all the helpful replies.
I’ve added an active class to the filters, but I’m wondering how to highlight ‘All’ when no filter is selected? Do I need to use the param() method, and if so, how? I’m still using the same code as in the YouTube tutorial. Thanks in advance!

all is active when `param(‘paramname’) is null.

Thank you for your reply! I’m unsure if I understand correctly what paramname should be entered there.

Right now, I have this, but it doesn’t work.

<a <?= param('filter') === null ? 'class="active"' : '' ?> href="<?= $page->url() ?>">All</a>

Do I need to specify the categories instead of writing ‘filter’?
Thank you in advance!

I don’t know what your parameter name is that you are filtering by. What appears in the url when you have the parameter is set?