Filtering multiple values for the same parameter

Hello everyone!

I am currently trying to get some news filters done, but I struggle to filter for more than one value.
I do NOT want to filter multiple parameters (e.g. year, topic, author). Instead, I want to select several values that are tied to one parameter.

The URL Kirby provides for a single keyword looks like this in my case: www.mydomain.de/news/filter:unternehmer
What I want to achieve is to have a URL like this, that returns results for both values: www.mydomain.de/news/filter:unternehmer&filter:arbeitsrecht

As a reference, this is my frontend:

My approach so far was, to add the single keyword URL to the labels of the checkboxes as some kind of fallback if javascript cant be loaded for any reason. And then in a second step, disabling the href, but collecting the parameters of all the checked values and building a new link that is loaded when clicked on submit. And then seperate it again in the controller to get the values for my Kirby tags.
This seems incredible clunky and I was wondering if there is a better and maybe very different approach for this that I didn’t think of.

Thanks for reading, all suggestions are appreciated!

If you submit a form with the GET method, you automatically get the correct query string without having to build anything manually.

<form method="GET"> 
  <h3>What do you want for breakfast?</h3> 
  <fieldset>
    <ul>
      <li> 
        <label>
          <input type="checkbox" name="breakfast" value="coffee">
          Coffee
        </label>
      </li>
      <li> 
        <label>
           <input type="checkbox" name="breakfast" value="croissant">
           Croissant
        </label>
      </li>
      <li>  
        <label>
          <input type="checkbox" name="breakfast" value="nutella">
          Nutella
        </label>
      </li>
    </ul> 
  </fieldset>   <input type="submit" value="Absenden">
</form>
  <input type="submit" value="Absenden">
</form>

Once submitted, you will get a URL like this https://kirby.test/?breakfast=coffee&breakfast=croissant&breakfast=nutella

I’m doing something very similar to this but don’t know how to get multiple values for the same parameter. Here’s my controller:

  $query  = get('q');
  $type   = get('type');
  $tags   = get('tags');

  $places = $page->children()->listed()->flip()
    ->when($query, function ($query) {
        return $this->search($query, 'title|category|tags|locations');
    })
    ->when($type, function ($type) {
        if($type != 'all'){
          $return = $this->filterBy('type', $type);
        } else {
          $return = $this;
        }
        return $return;
    })
    ->when($tags, function ($tags) {
        return $this->filterBy('tags', $tags, ',');
    });

There can be more than one tag, so an example url would be:

/places?tags=Beef&tags=Curry

However get() only gets the last tag (so in this example, ‘Curry’). How do I get tags as an array?

To get an array, your query string should look like this:

tags[]=Beef&tags[]=Curry

Where does this come from? From a multiselect or checkboxes field?

With a checkboxes field like above, you have to modify the name a bit and add square brackets:

 <label>
          <input type="checkbox" name="breakfast[]" value="coffee">
          Coffee
 </label>

The values are coming from checkboxes, so name="tags[]" worked to pass them in an array. I’m having some problems using them as filters though.

$tags   = get('tags');
$places = $page->children()->listed()->flip()
->when($tags, function ($tags) {
    return $this->filterBy('tags', 'in', $tags);
});

This is returning no results, even when I pass just a single tag. What more do I need to do with the array before passing it to fliterBy?

For fields that contain a comma separated list of values, you have to pass the delimiter as last argument:

$tags   = get('tags');
$places = $page->children()->listed()->flip()
->when($tags, function ($tags) {
    return $this->filterBy('tags', 'in', $tags, ',');
});

Doh, of course! Thank you!

Is there a more intuitive way to have multiple values per parameter as of now (v3.5)? It seems such a common use case when filtering results …

What do you mean with more intuitive?

Primarily easier to read, like tags=beef,cereal instead of tags[]=beef&tags[]=cereal

This has nothing to do with Kirby. That’s the URL that is produced by the form, no matter if inside Kirby or a standard HTML page.

To create a comma separated list instead of repeating tags, you probably have to use some JavaScript, but when I google this, most of the stuff I find is ASP.net related.

The [] is PHP specific, to read the values into an array.

Thanks for the clarification - you (= I) never know if there’s a clever wrapper or utility function helping with this kind of stuff.

:+1: