Is there a way to limit the amount of filters within 1 filter block to 1? (I'm using the OR operator)

For example, I have a facet on colors (taxonomy term). Each node can have multiple colors. If I pick 'Blue' in the filter block, I shouldn't be able to filter by 'Yellow' simultaneously. It's either Blue or Yellow.

Comments

cpliakas’s picture

Version: 7.x-1.0-rc1 » 7.x-1.x-dev
Category: support » feature

Currently there isn't an easy way to do this. Looking at the ways to extend the module it is possible, but would probably take a hundred lines of code to do so. I am not going to spell out how to do this other than saying that you would have to write a custom URL Processor plugin. Yuck. Changing to a feature request since this is the second time I have heard this, and let's see if we can get an elegant solution into the rc2 / 1.0 release.

cpliakas’s picture

Title: Limit amount of filters to 1 » Add a per-facet setting that allows only one item to be active at a time

Changing title.

cpliakas’s picture

Category: feature » task

Changing to a task.

strykaizer’s picture

Attached you'll find a patch for the "1393928-single-active-item" branch.
This patch will give an extra option on facet settings, allowing you to enable limitting facets and enter the specific number to limit on.

cpliakas’s picture

Status: Active » Needs review

Thanks for the contribution, StryKaizer! marking issue as "needs review", and I will take a harder look at it tonight.

Thanks for your work on this,
Chris

cpliakas’s picture

Status: Needs review » Needs work

Hi StryKaizer.

Patch looks like a good start. I did have a couple of questions about the patch...

  • It looks like this is a JavaScript only solution that is tied to the checkbox widget. Is this correct?
  • Why does the patch add two new theme functions for the active / inactive facet item?

When I was looking at this the first time, I was thinking of making the settings global as opposed to a widget-based setting. So the settings would be added in to the facetapi_facet_display_form() function somewhere under the "Global Settings" comment. Then we would have to add the defaults to the FacetapiAdapter::facetSettingsGlobal() method.

Then in order to enforce the "one item per facet" limit on the server side, we could pull the global setting and add some logic to the FacetapiUrlProcessor::getQueryString() method that strips all other active items belonging to that facet. I think the magic code required to enforce the one item per facet limit would need to be added between lines 44 and 45 and would be something like the snippet below:

foreach ($qstring[$this->filterKey] as $pos => $filter) {
  if (0 === strpos($filter, $field_alias)) {
    unset($qstring[$this->filterKey][$pos]);
  }
}

Let me know if this makes sense or if you think another approach should be taken.
~Chris

sun-fire’s picture

The patch #4 is working for me. It's really great feature!!!

In my project I need to display only one active element per facet and do not show inactive elements. How to implement this?

I think, it would be a useful functionality to have a checkbox in UI such as "Show only active element" when "Active item limit count" equals 1.

restyler’s picture

And for me, method suggested by cpliakas works better.
The only issue - how can I pull the global setting from FacetapiUrlProcessor::getQueryString()?
$this->adapter-> ...?

danielnolde’s picture

Limiting the number of simultaneously active facet items should be
a) configurable per facet (and realm), and..
b) handled on the server side, not the client side requiring js

Until FacetAPI doesn't support it by default, there's another way to do this: Using a filter on the facet items build, by either implementing a custom FacetAPI Filter class, or, using the facetapi_bonus.module, by simply implementing hook_facet_items_alter(), e.g with following code for limiting the number of simultaneously active facet items allowed:

  $facet_max_number = 1; // number of simultaneously active facet items allowed

  // Prepare data on how many facet items are active
  $facet_active_count = 0;
  foreach($build as $key => $item) {
    if ($build[$key]['#active']) {
      $facet_active_count++;
    }
  }

  // Deactivate links when maximum number of allowed facet items are active.
  if ($facet_active_count >= $facet_max_number) {
    foreach($build as $key => $item) {
      if (!$build[$key]['#active']) {
        $build[$key]['#path'] = '';
      }
    }
  }

Important: You'll also need to override theme_facetapi_link_inactive to render items with empty #path as simple text instead of links.

cpliakas’s picture

Status: Needs work » Needs review
StatusFileSize
new11.17 KB
new29.95 KB

So I took a crack at this, and it is much more complex that I anticipated for two reasons: The first is that this setting really has to be tied to the URL processor, so we needed a way for processors to add settings to the system. The second is that the settings retrieval in the adapter has a bug that doesn't add the defaults, so adding this new setting caused undefined index errors. There really should be a separate issue for the settings fix, but I am rolling it into this patch for testing and will separate out into a separate issue later.

I think I have it working, but we have to figure out where this might break. For example, date facets do work with this setting but it causes some really funky results. Specifically, whatever date we select becomes the top level of the drilldown. See the screenshot below:

limit-active-items-1393928-10-1-1.jpg

We could limit this setting to term queries only, however I am not sure if that is an arbitrary limitation. Would love to hear thoughts on that.

Thanks to everyone who is participating in this issue,
Chris

cpliakas’s picture

Task related to the settings posted at #1451110: Cache facet settings at the adapter level.

cpliakas’s picture

StatusFileSize
new5.09 KB

Patch rerolled after committing #1451110: Cache facet settings at the adapter level. Concerns in #10 still apply.

cpliakas’s picture

I am interpreting the lack of reviews by the community as a lack of interest in this feature, so there won't be any momentum here until others get involved.

cpliakas’s picture

Category: task » feature

Changing to a feature request.

uditmahajan’s picture

is #12 fine to use?
I am looking for this functionality exactly for a website.

cpliakas’s picture

uditmahajan,

You tell me :-). That patch is working for me, but it needs testing from the community to push this through. Your feedback would be a great contribution to this project.

Chris

uditmahajan’s picture

It is working...

Have finally implemented it on my live website. To checkout: http://www.getdandy.com.

Facets or Brands and Publisher (In Gizmos) are both One item only.

Thank you so much.
If I encounter any problem, will let you know.

restyler’s picture

Looks good!
can we commit it to dev?

cpliakas’s picture

Before committing to dev, I do want to address the concerns in #10. I might just say, this isn't available yet for date facets to push this through.

Thanks for the feedback,
Chris

modstore’s picture

Something related to this that I would like to do, in my case, I have values like so:
Less than $10/month (5)
Less than $20/month (8)
...etc.

So if I select the second option, all of the first options nodes are still valid, so both options are still shown in the facet. I need to make is so when one value is selected, all other options in that facet are hidden, until the selected value is de-selected.

If someone could point me in the right direction with a hook, or maybe this would be a nice feature as well (hide all other options checkbox).

modstore’s picture

I just used hook_block_view_alter to achieve what I wanted here, so all good. If anyone else needs the same functionality I can post the code.

Cheers.

cpliakas’s picture

@modstore,

Thanks for sharing. You could also do this via the facet's alter callback, which allows you direct access to the values returned by the backend before they are passed to the widget system. hook_block_view_alter() will definitely work, but I imagine it could cause problems if the structure of the render arrays are a bit different based on the widget being used.

Thanks for sharing,
Chris

modstore’s picture

Great, thanks for the info, I will look at doing it with the facet alter callbacks. Cheers.

SergeyR’s picture

as i see this feature is suitable for facet value synonims
so... you give possibility to user choose the most familiar for him variant and then hide anothers as soon as he found the one at least
right ??
ps strange example at the beginning ((

SergeyR’s picture

ooops
i realized that feature to hide synonyms is performed by "Don't show items that won't narrow down the results"
included in Facet Bonus

jsacksick’s picture

Status: Needs review » Reviewed & tested by the community

I just tried it, and it worked perfectly... I can only select one facet at a time which is just fine in combination with a radio widget.

cpliakas’s picture

jsacksick,

Thanks for the additional testing! Feedback is much appreciated.

Chris

cpliakas’s picture

StatusFileSize
new5.02 KB

Re-rolled against head.

cpliakas’s picture

Status: Reviewed & tested by the community » Needs review

Marking as needs review again for the testing bot to test this.

Status: Needs review » Needs work

The last submitted patch, limit-active-items-1393928-28.patch, failed testing.

mwesthof’s picture

Hi cpliakas, thanks for all the great work so far!
Tested the patch, but it fails for me:

Am I using the correct branch?

git clone --recursive --branch 7.x-1.x http://git.drupal.org/project/facetapi.git
Cloning into facetapi...
remote: Counting objects: 2738, done.
remote: Compressing objects: 100% (2113/2113), done.
remote: Total 2738 (delta 1808), reused 508 (delta 395)
Receiving objects: 100% (2738/2738), 614.76 KiB | 257 KiB/s, done.
Resolving deltas: 100% (1808/1808), done.

cd facetapi/

git apply -v limit-active-items-1393928-28.patch 
Checking patch facetapi.admin.inc...
Checking patch plugins/facetapi/adapter.inc...
Hunk #1 succeeded at 843 (offset 199 lines).
Checking patch plugins/facetapi/url_processor.inc...
Hunk #1 succeeded at 181 (offset 37 lines).
Checking patch plugins/facetapi/url_processor_standard.inc...
error: while searching for:
class FacetapiUrlProcessorStandard extends FacetapiUrlProcessor {

  /**
   * Implements FacetapiUrlProcessor::fetchParams().
   *
   * Pulls facet params from the $_GET variable.

error: patch failed: plugins/facetapi/url_processor_standard.inc:11
error: plugins/facetapi/url_processor_standard.inc: patch does not apply
cpliakas’s picture

mwesthof,

Thanks for the kind words. Unfortunately this patch has fallen behind the codebase, so it needs to be reworked against the latest code in order to be applied. I will probably get to it eventually, like in the next month or two, but I would love to get some contributions to push this forward more quickly.

Thanks!
Chris

mwesthof’s picture

StatusFileSize
new5.02 KB

Hi Chris,
I reworked the patch against the latest code.

A thought:
When selecting one facet, other applicable facets are still shown.
So for example: a node with two terms. Select one facet item term, the second term is also applicable and will still show and is clickable.
Only one will be active because of the patch.

I'm wondering if this is intuitive behavior or maybe only the active facet should be shown and the rest hidden.
Also.. I guess hiding non-active sibling facets, when one facet is active could be done by a filter. Any thoughts on this?

Other then that the code seems to work fine for me.

mwesthof’s picture

Status: Needs work » Needs review

Marking as "needs review" for the testing bot to test this.

cpliakas’s picture

Thanks for re-rolling the patch! Great work.

Regarding your thoughts, I agree that this is not intuitive. I am thinking that maybe it is a good idea to not allow this setting either for date facets or hierarchical facets since I am not sure how to logically handle these issues in a way that makes sense. Those seem to be the two use cases so far that cause issues. What do you think about this?

mwesthof’s picture

Hi Chris,

we had a use-case where we wanted the filter the users by year (of birth). We didn't want to the months and days to show after having clicked the year. Limiting to only one facet and hiding the rest of inactive facets would have been a solution.
Also, I guess it wouldn't break the date facet, because in the query the date range would just span less wide. Thus limiting to a specific month.. (for example).
You case were "whatever is selected becomes the top of the hierarchy", doesn't really seem to leave a usable facet. Is there a way to still display the active facet items? Or would that conflict with the URL Processor?

For hierarchical facets you probably would still want to see the inactive / deeper facet items. Not allowing multiple active facets, might give unexpected behavior in multiple parent taxonomy configuration if the tree is expanded by default and two branches hold the same child element, but with different parents, causing a different filter to be applied per child (not sure if the case could actually occur in the current release of facetapi and solr). Other then that, I don't think it will break the facet when only allowing one facet item to be active at a time.
Mind you: I haven't tested any hierarchical facets to see how they behave with the patch.

Considering the above: the intuitively hiding of inactive facets when only allowing one active facet item at a time, should probably not be part if this development, but perhaps go in facet filter. Since it wouldn't logically apply to hierarchical facets.

Another consideration: over-thinking this 'limiting' functionality for dates and hierarchical facets raises a lot of questions and there seem to be a lot of gotcha's. Perhaps it's not a bad idea to add support for those cases when there's a demand for it and some more clear use-cases which should really be solve this way.

marcoka’s picture

hm well this patch breaks here if i try to access config page of a facet

[27-Oct-2012 00:06:48] PHP Fatal error:  Call to undefined method FacetapiUrlProcessorStandard::settingsForm() in /mnt/www/WORKSPACE_DRUPAL/EIGENE_PROJEKTE/...

cpliakas’s picture

Status: Needs review » Needs work

mwesthof,

Thanks for the detailed response.

Another consideration: over-thinking this 'limiting' functionality for dates and hierarchical facets raises a lot of questions and there seem to be a lot of gotcha's. Perhaps it's not a bad idea to add support for those cases when there's a demand for it and some more clear use-cases which should really be solve this way.

That's what I am thinking. Let's do that and provide a code snippet that people can implement to enable this setting for dates and hierarchical facetes so they can use at their own risk and hopefully iron out the kinks.

e-anima,

Thanks for reporting. Marking patch as "needs work" and will try to replicate.

Chris

kirie’s picture

Thanks to all for the awesome work being done - both on the module in general, and this feature request!

I've applied the patch in #33 to both 7.x-1.2 and latest dev, it applied successfully to both, with some offesets.

I have done some preliminary testing, and so far the patch works as expected. I have, however, not been able to replicate the error reported by e-anima in #37. e-anima, could you provide any info on how to replicate the error?

milesw’s picture

StatusFileSize
new17.28 KB

The patch in #33 has been working well for me on 7.x-1.2. Used with the "OR" operator, it helped me easily create an alphabetical index facet. Thanks!

screenshot

cpliakas’s picture

milesw,

Cool UI!

Thanks for sharing,
Chris

jaydub’s picture

StatusFileSize
new5.02 KB

I just rerolled on current dev as the patch in #33 has some offsets. Patch applies and works as advertised.

jaydub’s picture

Status: Needs work » Needs review

marking as needs review to get bot to test.

Romisha’s picture

#42 did not work for me.

#33 worked fine for me. Great work!! Thanks!!

jaydub’s picture

Just encountered issue with this patch when also using Facet API Pretty Paths module for the facet links. Patch does not work when pretty paths are in place which isn't all that surprising. Will look into whether can be resolved.

update: Wrote a quick and dirty patch and posted in issue: #1935782: Support pretty paths for Facet API per-facet setting to only allow one active item

With this in place I can use pretty paths and also constrain to single active item via patch in this issue.

luksak’s picture

Status: Needs review » Active

I am not able to get this functionality to work. I am using search_api_solr as server and search_api_views to display the results. On the same page i have the facet block. But the URLs still look like this:

/products?f[0]=field_title_first_letter%3AG&f[1]=field_title_first_letter%3AP

And after clicking it both facets are active. Did i configure something wrong?

luksak’s picture

I had a module enabled that made this patch non functional: #1797616: Marry facets and Views exposed filters

Until now the patch works perfectly.

jaydub’s picture

Status: Active » Needs review
StatusFileSize
new5.02 KB

Patch in #33 still applies to newly released 1.3 release with some fuzz, rerolled against tagged 1.3 release.

Also in #46 you shouldn't change status from patch needs review/work to active as the issue still has a patch so active is not correct. If you have an issue, set as needs work...If it's not marked as having a patch the module maintainer may overlook.

luksak’s picture

You are totally right. Sorry.

attiks’s picture

Status: Needs review » Reviewed & tested by the community

This works like a charm

epifab’s picture

Hi all. I applied the patch 48 and it worked perfectly.

However, I got a doubt.
Let's suppose I have a facet with the following options:
Students (19)
Workers (11)

As I select 'Students' I got:
Students
Workers (3)

I got this because there are 3 students who are workers as well.
My understanding is that the items #count attribute passed to the widget is initialized without considering the fact that selecting the "Workers" option, the "Students" one would be removed.

I'm wondering whether I missed something.

fago’s picture

Confirmed patch works well, and code looks good. I agree, that's ready to fly.

Anonymous’s picture

I can confirm that it works like a charm! This should be transferred to the facetapi_pretty_paths module. I'll give it a go whenever I can find the time.

fago’s picture

Related use-ful widget: Use radio buttons! #2034777: Radio button widget plugin

yurgon’s picture

Hi, any news?
In last dev in pretty path don't work this patch((

revagomes’s picture

The patch worked like a charm!

Thanks!

teknocat’s picture

StatusFileSize
new5.02 KB

I tried to apply this patch to v 1.3 but there was a hunk failure. I just manually applied the bit that didn't work and have re-rolled the patch again.

mike.davis’s picture

I have tried patch #57 and it works great, just what I needed.

Thanks

rp7’s picture

#57

Seems to work. Thanks!

andyg5000’s picture

Confirming #57 on 7.x-1.3 works as designed. ++

mengi’s picture

Issue summary: View changes

#57 works for me (7.x-1.3). Only one value is allowed to selected.

Is the expected behavior to show other values for an multi-value facet?

For example if a node has values of 'blue/red' and another has a value of just 'red', when you pick red for the facet, it will still show the blue value. I would expect blue not to be displayed, just red, and then being able to click it to reset the faceted search.

ianthomas_uk’s picture

RE #51, set the operator to 'OR' and the counts will be correct.

Which makes me think, wouldn't this be better implemented as a third operator, perhaps 'SINGLE'? Neither OR nor AND really makes sense with this option. Is there ever a case when you would want it to show the AND counts? I don't think there is, as they won't reflect the count that you get when you click through.

ianthomas_uk’s picture

This setting isn't respected by the facetapi_pretty_paths module. Rather than raise an issue on that module for a feature that may not even be committed in its current form I thought I'd upload a patch here. Note that this patch applies to facetapi_pretty_paths, not to facetapi.

If #57 (or similar) gets committed, please open an issue for facetapi_pretty_paths with this patch.

jaydub’s picture

@ianthomas_uk try looking at this patch for pretty paths per your comment in #63: #1935782: Support pretty paths for Facet API per-facet setting to only allow one active item

hanoii’s picture

#57 works very good to me too, I also needed a way to treat parent items of a hierarchical facets as individual, meaning that I didn't want to select them unless they were specifically selected, and the same when unselected. Maybe is something other might need or want to try, referencing here just in case: #2244933: Allow parent terms in a hierarchy to be enabled / disabled independent of their children.

I hope this gets accepted.

khiminrm’s picture

#57 and #63 work fine for me

  • cpliakas committed 8f053f5 on 7.x-1.x authored by teknocat
    Issue #1393928 by teknocat, StryKaizer, mwesthof, jaydub: Add a per-...

  • cpliakas committed d0a888b on authored by teknocat
    Issue #1393928 by teknocat, StryKaizer, mwesthof, jaydub: Add a per-...
cpliakas’s picture

Status: Reviewed & tested by the community » Fixed

Status: Fixed » Closed (fixed)

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

kitikonti’s picture

How does this feature work? I want to see always every term, and when i click another one the first one should be removed. But actually both are used. I thought that this feature would prevent this behaviour?