izag
May 16, 2020, 11:44pm
1
Hi all,
i am trying to retain the first selected parameter when filtering on a page - with the current solution the hole url changes. I just need the tag to add another parameter to the URL.
<ul class="tags">
<?php foreach($farben as $farbe): ?>
<li>
<a href="<?= url('home', ['params' => ['farbe' => $farbe]]) ?>">
<?= html($farbe) ?>
</a>
</li>
<?php endforeach ?>
</ul>
<ul class="tags">
<?php foreach($geschlechter as $geschlecht): ?>
<li>
<a href="<?= url(Url::current(), ['params' => ['geschlecht' => $geschlecht]]) ?>">
<?= html($geschlecht) ?>
</a>
</li>
<?php endforeach ?>
</ul>
You would have to merge the parameters
['params' => array_merge(params(),['geschlecht' => $geschlecht])])
But. what if someone selects the second choice first? You don’t get to the same URL with what you are doing there…
1 Like
izag
May 17, 2020, 8:01am
3
Do i have to create the URL always as whole, can’t i separate the page->url() from the parameters that are to be added after the URL? - this was it wont matter which is first?
izag:
url('home',
If you use url('home',
in both instances, you won’t have this problem either, if the home page is the target page.
You would have to do the merging for both types of links…
izag
May 17, 2020, 8:17am
5
Thanks a lot texnixe - just adding the array merge worked!!
> // fetch all tags
> $farben = page('masken')->children()->listed()->pluck('farbe', ',', true);
> $brands = page('masken')->children()->listed()->pluck('brand', ',', true);
> $prices = page('masken')->children()->listed()->pluck('price', ',', true);
> ?>
>
> <button class="accordion">Farben</button>
> <div class="panel">
> <ul class="tags autogridtag">
> <li>
> <a href="/">
> Alle Masken
> </a>
> </li>
> <?php foreach($farben as $farbe): ?>
> <li>
> <a <?php if( param('farbe') === $farbe ) { echo('class="aktiv"'); } ?> href="<?= url($page->url(), ['params' => array_merge(params(),['farbe' => $farbe])]) ?>">
> <?= html($farbe) ?>
> </a>
> </li>
> <?php endforeach ?>
> </ul>
> </div>
>
>
> <button class="accordion">Brands</button>
> <div class="panel">
>
> <ul class="tags autogridtag">
> <li>
> <a href="/">
> Alle Masken
> </a>
> </li>
> <?php foreach($brands as $brand): ?>
> <li>
> <a <?php if( param('brand') === $brand ) { echo('class="aktiv"'); } ?> href="<?= url($page->url(), ['params' => array_merge(params(),['brand' => $brand])]) ?>">
> <?= html($brand) ?>
> </a>
> </li>
> <?php endforeach ?>
> </ul>
izag
May 17, 2020, 8:21am
6
it would be really awesome if i could somehow check if there are any brands that are offered in this color, any ideas?=)
Do you mean, so that if a color is selected, only the brands in that color are shown and vice versa, if a brand is selected, only the remaining colors are shown?
Yes, that’s possible. You have to filter the brands by color. How do you get the colors/brands.
izag
May 17, 2020, 9:17am
8
Yep - i am plucking them here
<?php
// fetch all tags
$farben = page('masken')->children()->listed()->pluck('farbe', ',', true);
$brands = page('masken')->children()->listed()->pluck('brand', ',', true);
$prices = page('masken')->children()->listed()->pluck('price', ',', true);
?>
Then you have to filter the children if a parameter is set before you pluck
izag
May 17, 2020, 9:26am
10
So probably plug them again after a filter ?
You can use when()
: https://getkirby.com/docs/reference/objects/pages/when
Then pluck the tags after defining the list of children.
$brand = param('brand');
$color = param('farbe');
$price = param('price');
$products = $page->children()->listed()
->when($brand, function ($brand) {
return $this->filterBy('brand', $brand);
})
->when($color, function ($color) {
return $this->filterBy('farbe', $color);
})
->when($price, function ($price) {
return $this->filterBy('price', $price);
});
$farben = $products->pluck('farbe', ',', true);
// etc.
izag
May 17, 2020, 9:37am
12
Yep was using something similar:
<?php
return function ($site, $page) {
/* FILTERS */
$farbe =param('farbe');
$brand = param('brand');
$price = param('price');
$maskPages = page('masken')->children()->listed()->flip();
$ausgabeFiltered = $maskPages
->when($farbe, function ($farbe) {
return $this->filterBy('farbe', $farbe, ',');
$farben = page('masken')->children()->listed()->pluck('farbe', ',', true);
})
->when($brand, function ($brand) {
return $this->filterBy('brand', $brand,',');
})
->when($price, function ($price) {
return $this->filterBy('price', $price,',');
});
return $ausgabeFiltered->paginate(100);
};
I just tried your code but it still returns all of the children, not just the filtered ones:
<?php
return function ($site, $page) {
$brand = param('brand');
$color = param('farbe');
$price = param('price');
$products = $page->children()->listed()
->when($brand, function ($brand) {
return $this->filterBy('brand', $brand);
})
->when($color, function ($color) {
return $this->filterBy('farbe', $color);
})
->when($price, function ($price) {
return $this->filterBy('price', $price);
});
$farben = $products->children()->listed()->pluck('farbe', ',', true);
$brands = $products->children()->listed()->pluck('brand', ',', true);
$prices = $products->children()->listed()->pluck('price', ',', true);
}
You changed the code I provided and those lines don’t make sense, should be $products->pluck('farbe', ',', true)
etc., so using the filtered $products
, not the children.
Does your controller return the variables to the template?
What is in your template?
izag
June 25, 2020, 3:04pm
14
Thanks a lot that solved the problem!=)