Is possible to set up a default value for the facet results? Even with custom code?
I'm on Drupal 9 and I have an ajax view with a page display and an exposed filter block and a single filter exposed, "Search: Fulltext search".
The search api is configured to search inside 3 different content type: products, articles and authors.
I've also configured a facet to filter on the content type, using a widget type "links", that let filter one content type at time
So, initially, the search page shows the results of all 3 content type. After a user filters a content type - e.g. articles - he can switch only to another and never return to the "no content type chosen" situation.
What I need to do is that the results are listed by default with one specific content type - e.g. product.
If that content type yield no results, the following content type should be used as filter. If there are no result, just "no result" should be shown.
In other words, the "no content type chosen" situation should be never available.
I've already tried to see if I can alter the query\options inside a hook_views_pre_view or SearchApiEvents::QUERY_PRE_EXECUTE, but with no success.
Comments
Comment #2
giuseppe87 commentedInitially I tried some different approach:
* extending
SearchApiString* an event subscriber of
KernelEvents::REQUESTaltering the incoming urlbecause by default facets\search api rely on the query_params of the url and the "values" of the relative facets various objects of the modules.
Both of those those approaches kinda failed, because the first didn't update the query params of the request, while the second caused some bugs that I couldn't manage to solve.
The working approach was to extending the default url_processor
QueryString- which both initialises the active facets filters and build the url after a search.Injecting the logic when the class is created allowed to do a minor modification without breaking all the standard functionality.
Comment #3
mpotter commented@Giuseppe87 how did you override the default querystring plugin for facets to use the above code? Is there something in a services.yml file somewhere? I didn't see anything in the Facet config to select the new processor.
Comment #4
mpotter commentedOh, nevermind, found the answer. For others: Go to the Configure link for your Facet Source and there will be a radio selector for the url processor.
Comment #5
giuseppe87 commented@mpotter: Sorry I've read now your question. Yes it is done as you've explained, via the config of the Facet Source
Comment #6
nicolas bouteille commentedThanks a lot for sharing this Giuseppe87!
Creating a custom URL Processor in order to pre-fill / force a value on a facet served for us as a workaround to the facet + contextual filter problem.
Indeed, on each node of type School, we are displaying the list of all trainings related to that specific School.
At first, we obviously used Views' Contextual filter for that.
However, we also had some facet filters with search API for the Level of the training for example.
Unfortunately, facets are not aware of the data transmitted to the view through contextual filters. So they were not properly restricting the available options regarding to the currently viewed School page.
In the end, we removed the contextual filter and replaced it with an additional facet "School" which value is pre-filled / forced with the current School (retrieved form canonical url) in a custom URL Processor, following code at #2.
Comment #7
brolad commented#2 Thanks for your solution but it works when we have only one search page. In another case we'll apply the default value for all pages as alterRequest() will be called each time where we're rendering facet even when the facet related to default value is not expected to be displayed.
I got the same result with the next code:
mb it'll be helpful for someone
Comment #8
mfrosch commented#7 did not work for me. Despite the facet had a default value, the results were not filtered.
#2 worked for me. The facet had a default value as well the results were filtered.
Comment #9
anybodyShould this perhaps be changed to a feature request to allow defining default values in facets? Might be a relevant feature?
We should ensure that not only a single value, but always a list of values is allowed to be defined per facet.
Comment #10
alorencApproach #7 allows me to set default filter value but please dont forget to set processor for the facet source configuration.
Comment #11
shiraz dindarFor me,
#7 sets the default facet value in the facet field, but the results are not actually filtered accordingly.
#2 works for me. However, since then a new argument ($urlGenerator) was added to the url_processor constructor (the one we are extending), so I had to add it here as well, as follows:
That said, I agree with #9 -- this should be something that we can set in the facet config.
Thanks all!
Comment #12
reszli$query->get('f') will not work anymore since it's not a scalar value but an array
I used $query->all()['f'] ?? [] instead
problem with this approach is that you can't even intentionally reset the filter to "any" since then the value is not in the URL and it will force the default
Comment #13
vensiresBased on the previous comments of this thread, I was able to build the following URL processor.
In my case, I wanted that in some views only the values from user fields became the default values for facets when entering the page. In some other views though, the default query_string plugin is what I needed. Read the inline comments if you intend to use it. Might require some refactoring for your case.
Comment #14
ludo.rIt seems, my custom URL processor is being called event when the facet source is set to use the default one.
Anyone encountered this issue?
EDIT: nevermind, it seems another facet source is being triggered on the same page, I just have to find out why.