What this patch does:

  • Add a views filter which can render facets for that view (1)
  • Add a views area which can render facets
  • Support AJAX, also in combination with views ajax get module
  • Add a summary area
  • Add a summary filter (1)
  • Remove the current AJAX support on blocks
  • Provide an upgrade path for this

(1) Exposed filter block then renders the facets or summary and knows about the context.

------ original summary ----

This is a wild idea, and I'm not 100% sure if it's possible at all, but here's the idea.

Create a views filter field so that facets can be rendered in the exposed form:

  • You don't need to expose the facet blocks in a specific region on the page
  • Theming is consistent and bit easier since it all lives inside the view's exposed form block
  • When using views AJAX, there's only one request to update the view and facets instead of the current facets AJAX implementation which means there's two calls when nothing is cached. We also use views_ajax_get which is far more performant as caching can actually work nicely here
  • This probably fixes a couple issues with the current implementation (although I can't tell which exactly). Basically, any problem that this one gives with ajax, is probably a views issue ;)

Would this be something you'd be willing to commit, if so, I will start working on it. Won't be a funny one I'm afraid, but I'm willing to dive deep here as we're experiencing some minor performance issues right now on a project because of the two requests.

Dont' forget to credit the people in #2957950: Add views area plugin - most of the area code comes from there.

CommentFileSizeAuthor
#170 facets-create-views-plugins-3073444-170.patch49.44 KBroman.haluska
#169 facets-create-views-plugins-3073444-169.patch17.94 KBroman.haluska
#168 facets-create-views-plugins-3073444-168.patch44.64 KBhswong3i
#166 facets-create-views-plugins-3073444-166.patch44.79 KBhswong3i
#153 facets-2.0.x-2939710-31+3073444-153.patch100.5 KBFarnoosh
#152 facets-2.0.x-2939710-31+3073444-152.patch42.88 KBFarnoosh
#151 facets-2.0.x-2939710-31+3073444-150.patch100.19 KBhswong3i
#150 facets-2.0.x-allow-facets-as-filters-in-view-3073444-150.patch43.85 KBhswong3i
#149 facets-2.0.x-2939710-31+3073444-147.patch138.34 KBhswong3i
#148 facets-2.0.x-2939710-30+3073444-147.patch117.07 KBhswong3i
#147 facets-allow-facets-as-filters-in-view-3073444-147.patch44.19 KBFarnoosh
#146 facets-2.0.x-2939710-30+3073444-145.patch138.19 KBhswong3i
#145 facets-allow-facets-as-filters-in-view-3073444-145.patch44.04 KB3li
#122 3073444-122.patch66.93 KBSiegrist
#121 3073444-121.patch66.93 KBSiegrist
#114 facet-3073444-114-Allow-facets-filter-in-views.patch64.3 KBbgilhome
#105 interdiff_103_104.txt1.39 KBoxyc
#105 facet-3073444-104-Allow-facets-filter-in-views.patch62.92 KBoxyc
#103 interdiff_89_103.txt2.65 KBoxyc
#103 facet-3073444-103-Allow-facets-filter-in-views.patch72.1 KBoxyc
#89 interdiff-88-89.txt634 bytesvasi1186
#89 facet-3073444-89-Allow-facets-filter-in-views.patch66.64 KBvasi1186
#88 facet-3073444-88-Allow-facets-filter-in-views.patch66.62 KBayalon
#82 facets-n3073444-82.interdiff.txt643 bytesDamienMcKenna
#76 facets-n3073444-76.patch61.3 KBDamienMcKenna
#76 facets-n3073444-76.interdiff.txt822 bytesDamienMcKenna
#75 facets-n3073444-75.interdiff.txt3.1 KBDamienMcKenna
#75 facets-n3073444-75.patch61.25 KBDamienMcKenna
#71 facets-n3073444-71.patch59.78 KBDamienMcKenna
#71 facets-n3073444-71.interdiff.txt1.51 KBDamienMcKenna
#66 facets-3073444-66.patch59.95 KBmirom
#66 interdiff-65-66.txt1.57 KBmirom
#65 interdiff-61-65.txt1.21 KBmirom
#65 facets-3073444-65.patch59.48 KBmirom
#61 facets-n3073444-61.patch58 KBDamienMcKenna
#61 facets-n3073444-61.interdiff.txt2.13 KBDamienMcKenna
#60 facets-n3073444-60.interdiff.txt10.93 KBDamienMcKenna
#60 facets-n3073444-60.patch57.87 KBDamienMcKenna
#56 3073444-56.patch55.82 KBswentel
#55 3073444-55.patch45.43 KBswentel
#54 3073444-54.patch46.07 KBswentel
#52 3073444-52.patch43.86 KBswentel
#51 3073444-51.patch43.09 KBswentel
#44 3073444-44.patch34.05 KBswentel
#37 3073444-37.patch33.3 KBswentel
#34 Schermopname 2019-10-30 om 15.50.40.mov218.97 KBStryKaizer
#26 3073444-26.patch29.31 KBswentel
#24 3073444-23.patch12.64 KBswentel
#23 3073444-23.patch12.64 KBswentel
#8 3073444-8-no-ajax.patch5.32 KBswentel
#21 3073444-21.patch11.7 KBswentel

Issue fork facets-3073444

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

swentel created an issue. See original summary.

swentel’s picture

Issue summary: View changes
geek-merlin’s picture

+1000 for this. See related issue.

geek-merlin’s picture

geek-merlin’s picture

@swentel: I'd say pursuing this makes sense anyway, if this views plugin will be committed to facets, or if the maintaimer feels like this should live in a separate module. I have no doubt that @borisson_ will cooperate on any APIs needed for this...

swentel’s picture

Title: Create a views filter field to render facets in exposed form when using ajax » Create a views filter field to render facets in exposed form
Issue summary: View changes

updated title and summary a bit - this also works nicely when not using ajax. I've got a filter working, hopefully I can post a patch tomorrow.

swentel’s picture

Issue summary: View changes
swentel’s picture

Status: Active » Needs review
FileSize
5.32 KB

First patch which adds the filter. Exposed form now renders facets and works fine - even when the exposed form is rendered without the view. Theming a facet mimics block at this point - this made sure we didn't have to change any css at all since we used blocks before, but maybe this isn't needed at all.

There are two things to finish:

1. facets and AJAX.

This is not in the patch yet. I have it working partially via ajax_render_alter() (and a current hack in views but that can be solved by overriding behaviors) but I'm not sure yet if this is the right approach - need to think about it a little more, especially since we use views_ajax_get and views_ajax_history. I'm thinking to actually alter the controller (like ajax_views_get does) which makes it a bit easier to fix the ajax.

2. Summary (AJAX)

I don't handle the summary yet either. When I realised this while working on the AJAX part, I momentarily thought that the area thing was probably a better idea, but then you can't put the facets in the exposed form, so you'd have to expose blocks again too. It's crazy in which kind of brainstorm loops you get while working on this :)

Summary should probably become an area plugin so you get almost free AJAX, but still brainstorming on that.

So this becomes complexer than I thought. I think, IMO, it might be better to move this to a separate module, not even within this module. I'm totally fine with maintaining it. It will cover 4 things:

  • facets as filter in views
  • ajax support for those filters
  • summary area views plugin
  • ajax summary support

Not sure about the namespace: facets_views_plugins, facets_views_extra (currently my personal preference as it might contain much more in the future), anything other?

So, everyone fine this becomes a separate module? I can move much faster then without bothering maintainers, I know how annoying that sometimes can be :)

geek-merlin’s picture

> Exposed form now renders facets and works fine - even when the exposed form is rendered without the view.

Wow, concerning the source, this is in fact impressingly simple. Not played with it though.

> [develop as facets_views_extra]

+1. (Maybe merged later.)

DamienMcKenna’s picture

Why not just "facets_views"? :)

This would be an amazing feature when it's finished, and IMHO it'd be worth including in the main Facets module.

I've tested it out and it works with AJAX, though I am using Better Exposed Filters.

One suggestion - the filter really should either hardcode the "Expose this filter" option, or include a message in the dialog that indicates that the "Expose" option must be enabled, otherwise the facets aren't displayed.

DamienMcKenna’s picture

DamienMcKenna’s picture

swentel’s picture

facets_views

Right! Naming things can really be easy :)

the filter really should either hardcode the "Expose this filter" option ....

Indeed, I think I'm going to hide the checkbox anyway (and submit it as exposed of course)

and IMHO it'd be worth including in the main Facets module.

I'm fine with either road ahead, I'm basically waiting for an answer from Borisson :)

borisson_’s picture

I'm fine with either road ahead, I'm basically waiting for an answer from Borisson :)

I don't think I'll get to this (or any other issue for that matter) before drupalcon.

swentel’s picture

Ok, I might be there as well, still not 100% sure, we can talk to see what the best plan is then if I'm there :)

kgeeraerts’s picture

Exactly what I need, except I need to disable the source check as noted in the comment ( @todo Find better way of filtering for facet source.)
I use facets from a different view for a custom search index so no facets show up with the check in place.
Except for that, great work!

DamienMcKenna’s picture

The facet works as intended, but it doesn't work via AJAX.

borisson_’s picture

After reading this issue - I agree this would be a good addition to the main facets module, I personally don't think this should be an additional module either (as in, it doesn't have to be a submodule).

I see that you've directly loaded search api's index in facets_views_data_alter. That won't work if someone is using core search as a source.

The class docblock needs to be updated.

+/**
+ * Provides filtering by language.
+ *
+ * @ingroup views_filter_handlers
+ *
+ * @ViewsFilter("facets_filter")
+ */
+class FacetsFilter extends FilterPluginBase  {

I don't know of an easier way to do this either.

+    // @todo Find better way of filtering for facet source.
+    $source = 'search_api:views_' . $this->view->getDisplay()->getPluginId() . '__' . $this->view->id() . '__' . $this->view->current_display;

Otherwise I'm super happy with how minimal this patch is. It doesn't seem to introduce any additional complexity. @swentel++

sahaj’s picture

Just noticed that the patch does not apply anymore via composer with the last dev version of facets.

swentel’s picture

Working on some fixes during drupalcon, a new patch is due for this week.

swentel’s picture

FileSize
11.7 KB

New patch. It's now a dedicated submodule. AJAX works fine, replacement of the response needs a double check and I also want to check when views_ajax_get is enabled.

borisson_’s picture

Issue tags: +Amsterdam2019

We just discussed this at drupalcon AMS. As I said there - I'm sorry but I think we have to make this harder.

I would very much love to remove all the old ajax code, because with this implementation we can be sure that the only bugs that this produces are views bugs, and luckily we don't have to solve those ourselves but that burden goes to others.

So I suggested that we could write an upgrade path to enable the facets that are defined on a view to the filters, so that all of that "magically" keeps working for our users. That is a bug ask, I realize that, but I think that doing it like that will reduce the surface for possible bugs and it will be better for us in the long run.

Thank you for all the help on this already @swentel

swentel’s picture

FileSize
12.64 KB

New version moving everything back to the main module. Views Ajax Get now works as well. I've marked the TODO's which do not block the actual functionality, everything works fine. The javascript to register the facet links could use a review from someone who's better in Drupal JS than me.

I've closed #2957950: Add views area plugin - in case we still want an area plugin, that can still happen, but seems a bit redundant imo.

Next up: summary plugin and ajax detection of those. After that, ripping out all the old code :)

edit - Just noticed: the replacement of the block with ajax needs an update, it's not entirely right when there are multiple facets, fixing now :)

swentel’s picture

FileSize
12.64 KB

Better selector. Found a problem with ajax and multiple facets, checking that now (it works perfect with one)

swentel’s picture

Actually multiple facets work fine - it was the 'Hide facet when facet source is not rendered' setting which got in the way for AJAX. I might add a check for that in the manager because this one can be very confusing imo.

swentel’s picture

FileSize
29.31 KB

First batch of removing code, that was fun :)

borisson_’s picture

Oh, that looks great! You've been able to remove more code than is added with the new (better) approach, this is the best possible situation.

I asked @StryKaizer to to a look at this patch to see if it already works, he has a real-world project where he can test this.

swentel’s picture

@borisson_ I'm surprised no tests are failing, there are no tests for the current ajax code? What exactly does ajaxbehaviortest do then? (unless I missed code of course)

borisson_’s picture

Huh, it might not check that is actually an ajax request but it could possibly be that it still works because it now still does page requests. Good to know that our tests are insufficient.

swentel’s picture

Right, makes sense I guess, even though I see assertWaitOnAjaxRequest calls, but I don't know the exact internals there.

swentel’s picture

@borisson: does facets ignore the 'page' parameter, or am I missing something in my setup. Even with a standard facets block and no ajax, if you go to page 2, and inspect the facet link, you do not see page=1 for instance - I probably never really looked at that, so if it's by design, that's fine :)

There is one outstanding bug with ajax: if you would go to a url with a facet in it, you can not disable the selected facet again, it looks like internally in the rendering somewhere it still listens to f[0] in the $request. Checking whether that that's an JS thing or something in the code (pager ajax works fine in views - so will have to compare the js/php in views for this one)

StryKaizer’s picture

Not sure why, but it does not seem to work here.

Some remarks:
- facets rendered as checkbox are still links
- ajax does not seem to work overhere, the links are actually

What I did:

enable ajax in search api view, and add a filter of type "facet"

Do I need some extra steps to use this?

swentel’s picture

facets rendered as checkbox are still links

That's the problem, I can reproduce, it only works on links now. Checking.
The dropdown probably won't work yet either.

StryKaizer’s picture

okay, links do trigger ajax indeed.
However, they disappear once clicked, see video

One extra thing we probably need to check is how this patch behaves on existing sites which use the "better exposed filters" module.

StryKaizer’s picture

Issue tags: +Needs change record
swentel’s picture

@StryKaizer - that's probably the 'Hide facet when facet source is not rendered' setting. I'm going to add something in the FacetManager for that because that's going to be something that will be forgotten a lot.

swentel’s picture

FileSize
33.3 KB

new patch. Exposes an area plugin for the facets too. Added that check in the FacetManager to ignore the views.ajax route (still need to inject though, but it works fine now)

swentel’s picture

Issue summary: View changes
borisson_’s picture

Right, makes sense I guess, even though I see assertWaitOnAjaxRequest calls, but I don't know the exact internals there.

I checked with @lendude, this assertWaitOnAjaxRequest thing actually doesn't check if anything happened with ajax and just checks if there are any current ajax requests.

@borisson: does facets ignore the 'page' parameter, or am I missing something in my setup. Even with a standard facets block and no ajax, if you go to page 2, and inspect the facet link, you do not see page=1 for instance - I probably never really looked at that, so if it's by design, that's fine :)

    // When adding/removing a filter the number of pages may have changed,
    // possibly resulting in an invalid page parameter.
    if ($get_params->has('page')) {
      $get_params->remove('page');
    }

This code is in the query string url processor, so yeah - this is by design.

There is one outstanding bug with ajax: if you would go to a url with a facet in it, you can not disable the selected facet again, it looks like internally in the rendering somewhere it still listens to f[0] in the $request. Checking whether that that's an JS thing or something in the code (pager ajax works fine in views - so will have to compare the js/php in views for this one)

I have no idea how to resolve without also debugging, no idea what the source of the problem is here.

borisson_’s picture

Adding credit to people from the other issue - thanks for reminding me @swentel

swentel’s picture

FileSize
34.05 KB

Last one for today (I think). Fixes the bug I mentioned where there was already a 'f' or 'page' param in the url, done server side.

swentel’s picture

Title: Create a views filter field to render facets in exposed form » Create a views plugins field to render facets and summaries in filters and areas
Issue summary: View changes

updated title and summary

swentel’s picture

Title: Create a views plugins field to render facets and summaries in filters and areas » Create views plugins field to render facets and summaries in filters and areas
swentel’s picture

Issue summary: View changes
swentel’s picture

Issue summary: View changes
swentel’s picture

Issue summary: View changes
swentel’s picture

Issue summary: View changes
swentel’s picture

FileSize
43.09 KB

Oh well, while we're busy .. :) This adds the summary filter and area plugins. Works great with ajax too.

swentel’s picture

FileSize
43.86 KB

More cleanups. I finally understand the trigger system after reading #3031581: Provide JavaScript API for facet widgets, so this will probably very easy to fix it for all widgets.

swentel’s picture

Title: Create views plugins field to render facets and summaries in filters and areas » Create views plugins to render facets and summaries in filters and areas
swentel’s picture

FileSize
46.07 KB

Last patch for real now: all widgets now work with ajax. This is getting very close.

swentel’s picture

FileSize
45.43 KB

Really really last one for the day. This fixes the check to include the js library if the ajax is enabled or not.

swentel’s picture

FileSize
55.82 KB

Ok, this is ready for another review and heavy testing. More cleanups in the code (injection, docs etc).

Outstanding besides tests and upgrade path:

1. checkboxes are duplicated with views ajax get (the behavior runs twice, which is weird)
2. retain other exposed fields (e.g. a search text field)

borisson_’s picture

I discussed the upgrade path with strykaizer again yesterday and he figured that might not be needed. But I can't remember his reasons for that.

+++ b/modules/facets_summary/src/Plugin/facets_summary/processor/HideWhenNotRenderedProcessor.php
@@ -19,14 +22,50 @@ use Drupal\facets_summary\Processor\ProcessorPluginBase;
-class HideWhenNotRenderedProcessor extends ProcessorPluginBase implements BuildProcessorInterface {
+class HideWhenNotRenderedProcessor extends ProcessorPluginBase implements BuildProcessorInterface, ContainerFactoryPluginInterface {

This change won't work on 8.6 I think - but I don't think this will get in before we drop support for 8.6 (when 8.8 is released).

I will look/test in more detail after work or on sunday afternoon. If @StryKaizer has more time - it would be good to try this already.

andypost’s picture

+1 to support both area and field plugins

Murz’s picture

@borisson_, many thanks for the patch, it works well! Can you please describe, how hard will be alter facet widgets for apply his changes via one "Apply" button from views exposed filters? At now, if I use Facet with checkboxes, they applies instantly, not like other Views filters, that wait when button is pressed.

DamienMcKenna’s picture

FileSize
57.87 KB
10.93 KB

Some fixes to the coding standards.

DamienMcKenna’s picture

FileSize
2.13 KB
58 KB

A few more small coding standards improvements.

There are a few method arguments that I'm not sure about how to document, and it might be worthwhile adding the docblock comment for skipping the coding standards tests on some lines e.g. the Views variables and methods that don't match camel case properly.

StryKaizer’s picture

I discussed the upgrade path with strykaizer again yesterday and he figured that might not be needed. But I can't remember his reasons for that.

The reason why we cant do an upgrade path is, because facets are seperate blocks, which can be placed in any region.

If we automaticly upgrade ajax enabled facets to live in the "contextual filters" block, we can not ensure their position is still in the same place.

So I guess we either support both ajax approaches for a while, or we just switch, and write a change record stating how users using ajax facets should manually upgrade their configuration to keep ajax working.

borisson_’s picture

If we automaticly upgrade ajax enabled facets to live in the "contextual filters" block, we can not ensure their position is still in the same place.

This is a good reason of not doing the upgrade path.

So I guess we either support both ajax approaches for a while, or we just switch, and write a change record stating how users using ajax facets should manually upgrade their configuration to keep ajax working.

I would very much prefer to remove to old implementation because that is the source for a bunch of errors that could just be forgotten about :)
So the change record should be enough.

swentel’s picture

If we automaticaly upgrade ajax enabled facets to live in the "contextual filters" block, we can not ensure their position is still in the same place.

Fair point. CSS selectors might probably be messing up things as well (e.g. because they wrapped things in a sidebar for instance), so there would be probably more disruption then really needed.

Supporting both seems reasonable indeed, but it's tricky stuff, I'd rather just remove it too and add that to the change record. Nothing will break, the facets just won't react with AJAX, which is ok to me.

That said, still need to look at the JS anyway for views ajax get. The JS API patch which was added in #3031581: Provide JavaScript API for facet widgets triggers attaching of behaviors again, which means (in case you would for instance add 2 facets), ALL Drupal behaviors are called 3 times. The new JS needs to account for that (but I'd like to figure out if we can't change that - might be separate patch of course, because the more facets, the more calls).

mirom’s picture

This patch should fix problem with facets on views with contextual filters.

During testing I found out problem with fulltext exposed filter, now I'm trying to figure out if it's generic issue or project specific.

mirom’s picture

Some minor changes to make it work for AJAX requests as well.

DamienMcKenna’s picture

scrap that, I had to change composer to use the dev version, then this applied successfully

DamienMcKenna’s picture

This doesn't seem to work with views that are output in blocks, it hits facet_source\SearchApiDisplay->extractArgumentsForViewDisplay() and then it hits this:

      $viewUrlParameters = $this->getViewsDisplay()->getDisplay()->getUrl()->getRouteParameters();

A block view doesn't have a URL.

DamienMcKenna’s picture

I don't know the APIs yet to be able to make a recommendation, but this line is wrong:

      $viewUrlParameters = $this->getViewsDisplay()->getDisplay()->getUrl()->getRouteParameters();

It makes the assumption that the current display is a page display and parses the arguments from it. Because of this assumption it doesn't handle other display types that can accept arguments / conditional filters, like blocks.

DamienMcKenna’s picture

Here's the error you get when you load a facet that comes from a block:

InvalidArgumentException: You cannot create a URL to a display without routes. in Drupal\views\ViewExecutable->getUrl() (line 1939 of core/modules/views/src/ViewExecutable.php).

Drupal\views\Plugin\views\display\DisplayPluginBase->getUrl() (Line: 167)
DamienMcKenna’s picture

This verifies that the display plugin has a path before calling getUrl(). There might be a better way of doing this? It also adds a @todo item that other plugin types need to be handled too.

DamienMcKenna’s picture

I just realized that it also doesn't work in situations where the display uses default arguments, e.g. "Content ID from URL".

mirom’s picture

Do you mean it's not working for blocks with "Content ID from URL"? I'm using it on page with "Content ID from URL" and it's working just fine. Can we always use $_REQUEST? It's filled in some ViewController, so maybe it's there for all displays?

mirom’s picture

I was thinking about problem with contextual filters and it seems to me that we must be doing something wrong if we need to do exact same things as views are already doing.

DamienMcKenna’s picture

I don't think we should remove "use strict" from the JS. Also, it's spelled "AJAX".

DamienMcKenna’s picture

Apologies for the small change, but this should fix two more coding standards violations.

DamienMcKenna’s picture

@mirom: On your view which has arguments, are there any arguments which do *not* use a default? Have you confirmed that it gives you the expected results?

My view has:

  • Block display.
  • Single argument: a node ID with the "when the filter is not available" option set to "provide default value" "Content ID from URL"; validation is set to use the "Content" validator and with the specific content type that's expected, and a single argument.

The view works, it just runs into the problem described above where block displays do not have a URL.

DamienMcKenna’s picture

I should also mention that while AJAX is enabled on the view, it's failing on the initial request.

DamienMcKenna’s picture

DamienMcKenna’s picture

I'm looking at the arguments in the request in extractArgumentsForViewDisplay():

      // @todo Support other plugin types.
      else {
        $argumentValues = $this->request->attributes->all();
      }

This results in the following error:

Warning: array_flip(): Can only flip STRING and INTEGER values! in Drupal\Core\Entity\EntityStorageBase->loadMultiple() (line 266 of core/lib/Drupal/Core/Entity/EntityStorageBase.php).

Will dig at it some more tomorrow.

DamienMcKenna’s picture

This doesn't work either:

      // @todo Support other plugin types.
      else {
        $arguments = $this->request->attributes->all();
        if (isset($arguments['node'])) {
          $argumentValues[] = (int) $arguments['node']->id();
        }
      }

Clarification: it doesn't result in any errors, it results in $argumentValues being an array containing the ID of the node passed as an argument on the page, but the argument still isn't passed in correctly, so the facet shows all items rather than those only relevant for the current selection.

DamienMcKenna’s picture

Interdiff for those who'd like to play along at home.

mirom’s picture

I think you need to keep node as a key of that new array. Currently under pressure on project, I'll try to come back and help more after that.

DamienMcKenna’s picture

The array gets passed to this function in Drupal\views\ViewsExecutable:

  public function setArguments(array $args) {
    // The array keys of the arguments will be incorrect if set by
    // views_embed_view() or \Drupal\views\ViewExecutable:preview().
    $this->args = array_values($args);
  }

I changed the code to this, but it didn't make any difference:

      // @todo Support other plugin types.
      else {
        $arguments = $this->request->attributes->all();
        if (isset($arguments['node'])) {
          $argumentValues['node'] = (int) $arguments['node']->id()];
        }
      }
DamienMcKenna’s picture

Might anyone be able to provide some insights on where I should look next? I have some time available to work on it, but I'm a little lost. Thanks.

Murz’s picture

With applied patch (from #76 and earlier), facet widgets successfully handle other Views exposed filter values (adds them to url), but when I submit Views exposed form - it clears out all Facet's selected items (AJAX is disabled). Is this known issue for this patch, or something is broken?

I fix this problem by quick, but not so good workaround in hook_form_views_exposed_form_alter():

    if($facetValues = \Drupal::request()->query->get('f')) {
      foreach($facetValues as $key => $facetValue) {
        $form['f[' . $key . ']'] = [
          '#type' => 'hidden',
          '#value' => $facetValue,
        ];
      }
    }

mirom’s picture

@Murz yeah, it's known issue, but it's afaik not related to this patch, it's not working for me with HEAD of facets and search api.

ayalon’s picture

Hi!
I tested the latest patch and found several JavaScript syntax error that do not allow me to use the AJAX functionality.

Here is a fixed version.

vasi1186’s picture

I had an issue on pages which have multiple ajax views, some of them are search api views, some not. Attached a very small change in the patch to fix that.

seanB’s picture

Just gave this patch a try. We currently have a site where the exposed filters are in the content region, and all facets are in the first sidebar. It seems I can no longer have AJAX facets in the sidebar with this patch applied. Is that correct?

StryKaizer’s picture

@seanB yes, that is correct. Ajax facets are moved to the exposed filters area, which does not allow individual placement...
Not sure how to proceed on this, we have no usecase where exposed filters are in other places than facets, but it looks like you do... Damn :)

seanB’s picture

Yeah sorry! As an example, check here: https://www.eur.nl/en/esl/search?s=drupal
The search bar is above the results, and the facets are in the sidebar. It doesn't really feel like an edge case to me, so I'm kind of hoping there is a way to not break our existing functionality.

I'm kind of thinking it would be cool to have a views area exposed as a block (just like the exposed filters). That would at least provide a lot of flexibility. Not sure how hard that would be though.

StryKaizer’s picture

That does look like a valid case indeed.
You could fix this by making the search and "include general" a block, since both are not ajaxified, but I do agree that this issue introduces some issues, while trying to solve others :)

If I'm not mistaken, @swentel started working on this issue because it allows doing 1 request (instead of multiple requests now).

We should discuss asap how to move forward with this issue, as this will break a lot of sites anyway, if this gets committed (Exposed filters are most of the time not in the same place as facets, by default).

I *think* that offering blocks per exposed filter beats the purpose of this patch, and re-introduces the multiple requests, but I might be wrong

DamienMcKenna’s picture

IMHO this would deserve a new branch as the change is rather significant.

geek-merlin’s picture

#93: See #22 for why this is important to make this module maintainable. Short: The only sane way to support ajax is to let views do it and do not interfere. And i guess this outweights by far the cost of blockifying areas or exposed-filters (probably in a separate module)(I won't push the ball rolling, but if someone does, i will chime in and help).

danharper’s picture

I've just been testing this patch and it only seems to work on from what I can see is where machine name is page_1.

First I tried to use it with an entity browser display type then I tried to add a second page type but neither worked. The facets display but they don't filter the results.

Cheers Dan

DamienMcKenna’s picture

Maybe because of this?

diff --git a/tests/src/FunctionalJavascript/AjaxBehaviorTest.php b/tests/src/FunctionalJavascript/AjaxBehaviorTest.php
index 0e34525..315dda2 100644
--- a/tests/src/FunctionalJavascript/AjaxBehaviorTest.php
+++ b/tests/src/FunctionalJavascript/AjaxBehaviorTest.php
@@ -17,7 +17,7 @@ class AjaxBehaviorTest extends JsBase {
   public function setUp() {
     parent::setUp();
 
-    // Force ajax.
+    // Force AJAX.
     $view = View::load('search_api_test_view');
     $display = $view->getDisplay('page_1');
     $display['display_options']['use_ajax'] = TRUE;
-- 
2.20.1

That's existing code in the module.

anruether’s picture

Some quick comments on the patch from testing it on a quite complex site

  • Facets only work if I set caching to none (instead of search api tag based)
  • If I enable the views reset button it will not show if I select a facet, but if another not-facet filter is filled it will show up (e.g. text search field)
danharper’s picture

@DamienMcKenna I did see that but thought that it wouldn't impact as it's just a test isn't it?

DamienMcKenna’s picture

@danharper: ugh, yes, you are correct. Maybe it has to do more with the type of display plugin? e.g. it has been noted above that it doesn't (didn't? I haven't tested recent patches) work with block displays.

danharper’s picture

@DamienMcKenna I did think that too, I tried creating a new page display so basically it's view id page_2 bit when I look at the field for facets it doesn't show any facets in the list for me to turn on or off.

Changing the machine name of the first page from page_1 to page_3 stopped it working.

geek-merlin’s picture

@danharper #96:
> I've just been testing this patch and it only seems to work on from what I can see is where machine name is page_1. ... The facets display but they don't filter the results.

Valuable that you battle test this! What a strange result. SOme thoughts which may or may not help...:

One bet might be a missing cache context. Does clear cache change something? Does adding the filter first on page_3 change something?

And: What are the filter parameters, do they change?

+++ b/modules/facets_summary/src/Plugin/views/filter/FacetsSummaryFilter.php
@@ -0,0 +1,143 @@
+    $options['expose']['contains']['identifier'] = ['default' => 'facet_summary_' . $random->name()];

Maybe it's an issue with that random value (which looks wierd anyway and might benefit from a code comment).

oxyc’s picture

Work in progress patch for BEF support. In it's current state it resets facets when a BEF filter changes, unless it's a sort field, in which case it keeps them.

Status: Needs review » Needs work
oxyc’s picture

Found another issue when using this together with TVI (and their https://www.drupal.org/project/tvi/issues/2993234 patch to actually fix their side).

If a parameter wasn't available it was resolved as NULL and caused various errors down the flow. I made a change that if none of the view parameters were resolved, dont pass any arguments.

I'm not sure if this is actually the correct logic. If someone is in doubt, maybe it's better to just tackle this as a separate issue once this feature has landed. So I'm mostly posting this patch to highlight a possible issue but it needs to be considered by someone more knowledgable.

vuil’s picture

Status: Needs work » Needs review

Status: Needs review » Needs work
liquidcms’s picture

Mostly i am trying to do a faceted filter apply with a submit button rather than through ajax. Haven't had any luck but seemed like if this was tying into exposed filters; then it might do the trick.

But, my use case has 3 view as blocks added as blocktabs (like quick tabs). Adding a facet in the view with this and i get fatal error: Error: Call to a member function getRegion() on null in theme suggestion alter. I suspect what was reported above that this doesn't work inside a block.

It does work inside the views preview.

gsquirrel’s picture

I have found this patch very useful and is working pretty well. I think a recent change in facets dev version is causing issues though because my checkbox facets were being disabled. There are many other issues and patches that deal with similar ajax issues but I think they are working with the same code and files as this patch so don't work well together, at least the ones I tried.

Am still experimenting with combinations of the various patches to see if there is one that will get it working again.

Does anyone else using this patch have checkbox facets, are they working still? I don't think it is actually to do with this patch but I would like to be able to find a fix where i can still use this patch.

ransomweaver’s picture

I agree that this has problems with DEV. With the view set to ajax it doesn't do anything (for checkbox facets). There's no ajax load after checking a box.

Checkbox facets are working well for me in Facets 1.5 and patch 89.

ransomweaver’s picture

Can anyone tell how to get the facets query parameters rewritten into the url? I have a previous site that does this and I'm pretty sure that the url rewrite wasn't something I impemented, so maybe the JS reworking of this patch has removed it?

ETA: to answer my own question, its having views_infinite_scroll that causes the ajax query params to be rewritten to the url during ajax load.

dan2k3k4 made their first commit to this issue’s fork.

jmee’s picture

Thanks to everyone working on this!

I'm using the most recent patch on a site and the only problem I've run into is integration with Better Exposed Filters and the 'Secondary options' section. I've seen the same behaviour whether or not the facets block is the only secondary option. The site is using the Olivero theme.

The <div class="facets-views-plugin"> element isn't nested within the secondary options element, instead it is placed just above the <details class="bef--secondary [...]"> element (it should be nested inside the <div class="details-wrapper"> element that follows)

Not missions critical but 'nice to have', and I hadn't seen this mentioned anywhere in this thread yet.

bgilhome’s picture

The latest patches didn't apply to the latest dev - I've rerolled #104 against the latest dev commit (5ef2c7c). Some of the hunks from the views ajax js seem to already have been committed so this file might need to be checked over.

vaccinemedia’s picture

@jmee I'm in the process of building a site which has to mix and match facets and exposed filters and display the results on a map and in a table underneath. There's a full text search and distance exposed filters and I'll be adding in some facets too - probably 4 so it would be cool to be able to pop some of them into the "secondary options" to make the initial form smaller. Did you find a work around for this?

jmee’s picture

@vaccinemedia I just used some jquery to fix the markup, not the best solution but it's quick

  $(document).ready(function(){
      $( '.facets-views-plugin' ).appendTo( $( '.details-wrapper' ) );
  });

just make sure that jquery is specified as a dependency!

vaccinemedia’s picture

I've applied the latest patch against the latest stable facets module and getting a WSOD when viewing my page view. It has 2 displays - the main page display as a table and an attachment as a map. When looking at the logs I'm seeing:

TypeError: Argument 1 passed to Drupal\Core\Render\Element::children() must be of the type array, null given, called in /var/www/drupalvm/sites/flashy.local/httpdocs/core/modules/views/src/Plugin/views/filter/FilterPluginBase.php on line 949 in Drupal\Core\Render\Element::children() (line 71 of /var/www/drupalvm/sites/flashy.local/httpdocs/core/lib/Drupal/Core/Render/Element.php)

I'm on Drupal 9 and if I remove the facets from the view and display them as blocks on the page instead the page displays without any errors.

mhavelant’s picture

I have the same issue as #117.

Drupal\facets\Plugin\facets\facet_source\SearchApiDisplay->fillFacetsWithResults has $view = Views::getView($display_definition['view_id']) and $view->execute() and that execute() is the one that fails.

FilterPluginBase::buildExposedForm() uses count(Element::children($form[$value])), but at this point the facets exposed filter has NULL as the value, and it fails.

As a temporary fix, I added $form[$value] = $form[$value] ?? []; there, which solves the error. Sadly, I couldn't find a place in facets where I could add something to achieve a similar result.

geek-merlin’s picture

#118: Great debug work!

+++ b/modules/facets_summary/src/Plugin/views/filter/FacetsSummaryFilter.php
@@ -0,0 +1,143 @@
+    if ($is_processing) {
+      $form['value'] = NULL;
+      return;
+    }
+

Try "$form['value'] = [];" here.

uniquename’s picture

#119 seems to fix that error, but I had to edit

facets/src/Plugin/views/filter/FacetsFilter.php line 110

not facets/modules/facets_summary/src/Plugin/views/filter/FacetsSummaryFilter.php

Siegrist’s picture

FileSize
66.93 KB

I created a patch with #119 s feedback in it.

Siegrist’s picture

FileSize
66.93 KB

Actually also including #120 as well. Seems to work generally. I notice the block and the filter have titles? I guess I can just remove the one on the facet... Seems weird tho.

Siegrist’s picture

Can we also get the reset button harmonize with the facets? The button only appears when views filters are applied and not when a facet is filtering.

Also similarly it would be nice if the facet did not reset when a views filter was applied.

Siegrist’s picture

I added this hook. But its very unstable. I get 414 URI too large errors. Any ideas on how to solve it?

function facets_form_views_exposed_form_alter(&$form, FormStateInterface $form_state, $form_id)
{

  if (isset($form_state->getUserInput()['f'])) {
    foreach ($form_state->getUserInput()['f'] as $key => $value) {
      $form['f[' . $key . ']'] = [
        '#type' => 'hidden',
        '#value' => $value,
      ];
    }
  }
}
Siegrist’s picture

It seems like facets somewhere pass the current url as a get param for future requests along. This compounds the size of the request with each apply of exposed filters. In my case after 5 times re applying the filters I get a 414 request too large. Does anyone know what code is responsible for this?

Siegrist’s picture

This JS seems to omit the unnecessary clutter quite well. Can someone review? I will soon provide a patch file as well.

let form = document.querySelector('.views-exposed-form');
      if(form) {
        form.addEventListener('submit', () => {
          document.querySelectorAll('[data-drupal-facet-id]')
            .forEach(facet => facet.removeAttribute('name'));
        });
      }

Siegrist’s picture

I added the changes from the files and my suggestions into the MR. I think its easier to proceed there. :)

mkalkbrenner’s picture

Version: 8.x-1.x-dev » 2.0.x-dev
Leksat’s picture

What's the reason for facets_views_ajax settings being removed in the last patch?

hswong3i made their first commit to this issue’s fork.

hswong3i’s picture

oheller’s picture

@hswong3i I don't understand what you're doing with the above changes. https://git.drupalcode.org/project/facets/-/merge_requests/43 doesn't look like it belongs in this issue.

hswong3i’s picture

> @hswong3i I don't understand what you're doing with the above changes. https://git.drupalcode.org/project/facets/-/merge_requests/43 doesn't look like it belongs in this issue.

Sorry I means recreate https://git.drupalcode.org/project/facets/-/merge_requests/34 (for 8.x-1.x-dev which now not able to apply to 2.0.x-dev) as https://git.drupalcode.org/project/facets/-/merge_requests/42 for 2.0.x-dev.

joshmiller’s picture

First off, positive feedback: THIS WORKS. OMG, this is what facets should always do.

Slightly less good news: For some reason, I've narrowed down out of memory errors that we are getting to the facets that I have enabled in a solr-based view. Without the facets, renders, and caches, the same view is just fine. With the facets, I get strange, and often inconsistent, 500 errors, like the following:

Allowed memory size of 536870912 bytes exhausted (tried to allocate 20480 bytes) web/core/lib/Drupal/Core/Cache/DatabaseBackend.php:167

Allowed memory size of 536870912 bytes exhausted (tried to allocate 32768 bytes) web/core/lib/Drupal/Core/Database/Driver/mysql/Connection.php:190

Etc.

Since these errors are 500, none of the logs can give me a backtrace, and my local doesn't experience the same instability. So I can't be sure it's related to this, but I have successfully mitigated the error by removing facets from a view that appears on most pages.

joshmiller’s picture

Update: I've been reading through some of the issues in the queue for facets and found #2939710: Add support for "Search API (tags based)" caching in Views which states:

Currently, when a view is configured to 'Caching: None' the search results page is cached by the Internal page cache for anonymous users and the page is not invalidated when the data of a result changes.

After changing the views caching that has facets added to its filters from `none` to `Search API: Tags` I am no longer seeing 500 errors. Might be worth documenting that, at least in my case, having no caching *might* have led to weird 500 errors. Anecdotally, as I don't have any backtraces to prove exactly what went wrong.

Grimreaper’s picture

Status: Needs review » Needs work

I have done some review in the MR.

attisan’s picture

what I've found so far (merge request 42):
* renaming the views page machine name breaks the view (preview)
* facets are not (have been with MR 34) shown on the views preview - works on the actual views page though

sonfd’s picture

The latest patches seem to remove AJAX functionality When using the latest patches and facets as a filter - `facets_views_ajax` is not set in drupalSettings so the facets-views-ajax.js file can't operate.

gsquirrel’s picture

I am trying to update a site using this patch to drupal 9 and finding that facets 2.0.x-dev with the latest patch from here sort of works but ajax is broken.

The patch didn't cleanly apply - these chunks were problematic:
patching file src/FacetManager/DefaultFacetManager.php
Hunk #5 FAILED at 339.
Hunk #6 FAILED at 354.

patching file src/Plugin/Block/FacetBlock.php
Hunk #4 FAILED at 147.

Comment in #140 suggests maybe something important to do with ajax got lost along the way.

Does anyone have the patch working properly in drupal 9 / facets v2 ?

gsquirrel’s picture

Looking at the failed hunks I don't think they are that problematic (anything important got changed properly i think, in some cases changes were already made in latest facets release).
So that was a red herring i guess.

3li’s picture

Was using patch in #122, but after updating to 2.x it seems no patches apply smoothly.

geek-merlin’s picture

Priority: Normal » Major

Daring to raise prio, cause this is a key step in "fixing" ajax facets according to #3075378-8: [META] Overview of Facets + Ajax issues

3li’s picture

Re-roll of #122 that should now apply to version 2.0.x
However it should be noted that this patch along with #122 does not allow ajax to be used, I tried to resolve this issue but did not have that much luck.

hswong3i’s picture

https://www.drupal.org/project/facets/issues/3073444#comment-14505630 and https://www.drupal.org/project/facets/issues/2939710#comment-14480153 is now in conflict for one single line so I merge them locally in here for composer patcher...

Farnoosh’s picture

Receiving Undefined Index. Add Index class to the facets_summary.module

hswong3i’s picture

hswong3i’s picture

FileSize
138.34 KB
hswong3i’s picture

FileSize
43.85 KB
hswong3i’s picture

Farnoosh’s picture

Update the patch #151 against 2.0.x with the following:
1- Imported ContainerFactoryPluginInterface and RouteMatchInterface and defined \Symfony\Component\DependencyInjection\ContainerInterface in create() function `HideWhenNotRenderedProcessor.php`
2- Import Drupal\search_api\Entity\Index in `facets.module`

Note: This patch works against 2.0.x

Farnoosh’s picture

FileSize
100.5 KB

Re-roll my patch against 2.0.x

attisan’s picture

which patch should we use / test / review? I would tend towards the MR42 but don't know what (if any) the differences are to #153.

mkalkbrenner’s picture

Version: 2.0.x-dev » 3.0.x-dev
Status: Needs work » Needs review

I think that most of the users who provided feedback for facets 3.0 agreed that this is the right way to go. So I want to get this patch into 3.0.x-dev quickly.

But I wonder if we should remove the support for custom Search API displays and search results that are not based on Views first.
What Do you think?

HitchShock made their first commit to this issue’s fork.

HitchShock’s picture

Status: Needs review » Reviewed & tested by the community

I need to say, that the patch works great for me. I also added an option to allow/deny to show the block title because it is not always needed.
The first +RTBC from me. But it should be reviewed again. Probably we missed something.

mkalkbrenner’s picture

Status: Reviewed & tested by the community » Needs review

Can anyone else involved here test the latest version of the MR?

If there's a second one who sets RTBC I'll merge it into 3.0.x.

attisan’s picture

As views can be called programmatically it should be possible to do so for facets (I would expect that to work when there is an option to add facet-filters directly to views (see #3301075: Provide a method in QueryString for programmatically called facets for detailed explanation).

attisan’s picture

Status: Needs review » Reviewed & tested by the community

+1 RTBC from me.

mkalkbrenner’s picture

Status: Reviewed & tested by the community » Needs work

@attisan I think I understand your motivation and I agree with your issue. But it should not be mixed in here.

I won't commit the new feature into 2.0.x nut into 3.0.x. But your bug fix is suitable for both branches and not essential for the feature here.
Please revert your commits to the MR. They currently block this issue.

attisan’s picture

Status: Needs work » Reviewed & tested by the community

@mkalkbrenner done

  • mkalkbrenner committed 545af03 on 3.0.x
    Issue #3073444 by hswong3i, swentel, Siegrist, attisan, DamienMcKenna,...
mkalkbrenner’s picture

Status: Reviewed & tested by the community » Fixed

Thanks to everyone involved here. I committed the feature to the 3.0.x branch.

Any further help on 3.0.x is welcome. And it would be great if someone could write a change record for this issue.

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.

hswong3i’s picture

Quick re-roll for 2.0.x-dev

hswong3i’s picture

roman.haluska’s picture

small correction for 2.0.x. After filtering via ajax facets were removed

roman.haluska’s picture

FileSize
49.44 KB

fixed previous version

tgoeg’s picture

Just re-read the whole issue.
Came here for some of the (missing?) functionality also mentioned in the comments here. It seems they have not been addressed in the course of development (but I might be wrong).
Precisely,
#59 (https://www.drupal.org/project/facets/issues/3073444#comment-13337346) and
#108 (https://www.drupal.org/project/facets/issues/3073444#comment-13875604)
- Is it possible to apply Facet filters and search box terms in one go, without having the request sent off when clicking a facet checkbox? Can @murz and/or @liquidcms probably give feedback on this?
#92 (https://www.drupal.org/project/facets/issues/3073444#comment-13486224):
- Can facets still live in separate blocks after the changes performed here? Can @seanB probably give feedback on this?

If all (or some) of the above is not fixed yet, I think we should open new issues for the specific problems.
Thanks for your hard work!