It would be nice to have an option in the facet display to "remember the last setting" similar as in the views exposed filters settings. This can be particularly useful when filtering an index on country or location. That's a filter setting a user will not quickly change.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

cpliakas’s picture

Project: Facet API » Facet API Extra
Version: 7.x-1.0-beta8 » 7.x-1.x-dev
Component: Usability » Code

This is a cool feature request, but I don't see it getting into the core module. Moving over to Facet API Extra for consideration.

ygerasimov’s picture

This is really nice feature. Views does saving selection of exposed filter to $_SESSION['views'][$view->name][$display_id] and when we come to the view page it checks if none of exposed filters selected, it loads variables from session (view::get_exposed_input() function).

In terms of Facet API this sounds like changes in the core of Facet API as we need to add another option of the settings for the facets generally. In that case we will also check if page is opened but no facets are active we load last saved values from session.

Chris, what do you think about this approach?

cpliakas’s picture

My only concern here is that the facets change depending on what is searched for an when it is searched. I am open to exploring this, but I think before doing so we need to iron out the use cases and expected behavior before coding anything. I think flushing out the "what ifs" is a critical first step here.

ygerasimov’s picture

Project: Facet API Extra » Facet API Bonus

Moving issue to Facet API Bonus module.

jtbayly’s picture

I just want a basic "search within results" option. I think that's the most basic use-case, and it seems like it would have broad appeal.

I've got facets that filter by date and taxonomy term, but then let's say somebody wants to do a search within the results that are displayed. Keeping the currently selected options would be the same thing, right?

-Joseph

pradbone’s picture

Could really do with this, is it going to be included in this module?

Paul.

cpliakas’s picture

Re: #1380716-5: Remember last settings of facet block, I think the "search within results" is an incredibly useful feature that is missing from Drupal search solutions in general. However, I am not sure that is the same thing as what is being proposed. The "search within results" is something that should be constructed outside of Facet API, and it wouldn't have to know about Facet API in order for the filters to be retained since it could simply pass along the query string parameters and current menu path on the new search.

I could be wrong, but I believe the use case is that a user enters a search query and selects some filters. They then go away, maybe for an hour, maybe for a week, and the next time they visit the search page their filters are remembered and pre-selected.

pradbone’s picture

Either would suit me. Effectively you are searching within the search criteria if the facets are 'remembered'.

jtbayly’s picture

This issue #1381524: Search within results / remember filters and facets in the Search API module is a request for the "search within results" functionality that I'm after. Sounds like some of you might be interested in it, too.

-Joseph

cpliakas’s picture

jtbayly,

Definitely interested. Thanks for pointing it out!

Chris

pradbone’s picture

I'm still really wanting this for a site I'm building.

I would look at doing the code myself - but it would be my first piece of Drupal code - probably not the easiest thing to start on!

Paul.

cpliakas’s picture

pradbone,

You on IRC? I would be happy to set aside 30 minutes and provide some mentorship if you are interested in contributing. There is no time like the present for getting your first credited commit to Drupal.

Chris

pradbone’s picture

Hi,

I've got an irc client installed. Not used it for years though! Give me a server/channel and we can have a chat?

Paul.

cpliakas’s picture

Hi Paul. I usually hang out in the Drupal channels at http://drupal.org/irc/, and I can most often be found in the #drupal-apachesolr channel which might be the best place to sync up.

pradbone’s picture

Hi,

Will you be around tonight at about 7pm GMT?

paul

pradbone’s picture

Hi,

Antone else want to help with this? I'm happy to have a go with some guidance.

Cheers,

Paul.

andrewbelcher’s picture

If anyone is interested, I've attached a URL Processor that allows lets you remember your last selection. Things of note are:

Namespaces

I've attempted some namespacing so that it only remembers relevant info and you can create groups of URLs that work together. For my implementation, I needed it to work together at 2 urls, so I went down the round of patterns and groups, but if you only ever need it to keep on a single url, you could ditch the pattern stuff, especially as it doesn't have a UI.

Above the namespaces, it also also groups things by the searcher, as I couldn't see it being useful across multiple searchers... Not sure if that's necessarily the case though.

Removing the last facet

Normally when the last facet gets removed (in FacetapiUrlProcessorStandard), its simple as there will just be no facets build. With the session storage however, it would result in nothing happening. Therefore the getQueryString() method will set the query string to 'clear' if there are no facets to prompt a clear.

Programmatic clearing

I also needed to clear programmatically, so there is a clearSession() static method that can be used anywhere to do that. My use case was making it so that when you reset the filters on the view, it also resets the facets. So a little form alter on the view_exposed_form adds a submit handler that triggers the clear.

/**
 * Submit handler to clear facets on views form submit.
 */
function mymodule_views_exposed_form_submit($form, &$form_state) {
  if ($form_state['triggering_element']['#id'] == 'edit-reset') {
    FacetapiUrlProcessorSession::clearSession('search_api@party_index');
  }
}

Breadcrumbs

I'm not sure breadcrumbs make sense when things are stored in the session and I didn't want them in my use case, so at the moment I just override the setBreadcrumb() and return nothing.

Todo

At the moment my patterns are hard coded in the class. I think probably using a variable and creating an admin UI to manage it is the way to go. Perhaps when I get some time I'll put it all together with a UI and submit it as a patch.

Changing the URL Processorr on a searcher

I couldn't find anywhere in the config to do this, so I used a hook to do it:

/**
 * Implements hook_facetapi_searcher_info().
 */
function mymodule_facetapi_searcher_info_alter(array &$searcher_info) {
  foreach ($searcher_info as &$info) {
    if ($info['adapter'] == 'search_api' && $info['instance'] == 'party_index') {
      $info['url processor'] = 'session';
    }
  }
}

To register the searcher you also have to use:

/**
 * Implements hook_facetapi_url_processors().
 */
function mymodule_party_facetapi_url_processors() {
  return array(
    'session' => array(
      'handler' => array(
        'label' => t('Session'),
        'class' => 'FacetapiUrlProcessorSession',
      ),
    ),
  );
}
valderama’s picture

Thanks for the Code in #17! It works fine so far - only the search-string in the exposed filter seems to be not remembered.

andrewbelcher’s picture

@valderama - The exposed filters in views are handled complete separately. There is a tick box in the settings for the exposed filter to remember it in the session, so if you use the two in combination, you'll have the whole lot remembered.

pradbone’s picture

Hi,

Can someone tell me how to use this code? Where does it go? Do I install it like a module??

Paul.

andrewbelcher’s picture

Yes, it needs to go as a custom module. You will have a .info file like:

mymodule.info

name = "My Module"
description = "Provide a session based Facet API URL Handler."
core = 7.x
version = 1.0
dependencies[] = facetapi

files[] = includes/facetapi/url_processor_session.inc

A .module file like:

mymodule.module

/**
* Implements hook_facetapi_searcher_info().
*/
function mymodule_facetapi_searcher_info_alter(array &$searcher_info) {
  foreach ($searcher_info as &$info) {
    if ($info['adapter'] == 'search_api' && $info['instance'] == 'party_index') {
      $info['url processor'] = 'session';
    }
  }
}

/**
* Implements hook_facetapi_url_processors().
*/
function mymodule_party_facetapi_url_processors() {
  return array(
    'session' => array(
      'handler' => array(
        'label' => t('Session'),
        'class' => 'FacetapiUrlProcessorSession',
      ),
    ),
  );
}

And the attached url_processor_session.inc at includes/facetapi/url_processor_session.inc.

It's important to note that in hook_facetapi_searcher_info() you need to find the correct adapter and instance, which in my case was search_api and party_index.

pradbone’s picture

Hi,

$info['url processor'] = 'session'; is being set, but it's not working? any pointers please? Ive put some debug messages in and the message in remember_classifieds_facetapi_url_processors isnt being output.

<?php
/**
* Implements hook_facetapi_searcher_info().
*/
function remember_classifieds_facetapi_searcher_info_alter(array &$searcher_info) {
  foreach ($searcher_info as &$info) {
dpm($info['adapter'], $name = NULL);
dpm($info['instance'], $name = NULL);
    if ($info['adapter'] == 'search_api' && $info['instance'] == 'classifieds_index') {
      $info['url processor'] = 'session';
dpm("IN!!", $name = NULL);
    }
  }
}

/**
* Implements hook_facetapi_url_processors().
*/
function remember_classifieds_facetapi_url_processors() {
dpm("facetapi_url_processors", $name = NULL);
  return array(
    'session' => array(
      'handler' => array(
        'label' => t('Session'),
        'class' => 'FacetapiUrlProcessorSession',
      ),
    ),
  );
}
?>

Paul.

luo8’s picture

hello andrewbelcher,
sound a good feature, but is not working for me as well,is there any update?
Thanks

andrewbelcher’s picture

Hello!

padbone: Are the hooks getting called at all? If not, are other hooks in the same module getting called? If it is, what do you get if you dpm($searcher_info);?

luo8: Do you know what is not working?

In case it's version that are causing the problem, I'm on the current stable release - 7.x-1.2.

luo8’s picture

Dear andrewbelcher,
thanks for response.
I was tried reinstall Facet api from version ".dev" to version "7.x-1.2", but with no success.
I have main problem where should be placed "My_module" folder with "url_processor_session.inc" file and how should be enabled.
Should be placed to root module folder or to Facet api, Search api module as submodule or where?
You mentioned party_index, should I have installed Party module?
Pls. could you advise me.
Thanks.

andrewbelcher’s picture

I would suggest the following:

sites/all/modules/contrib/mymodule.info
sites/all/modules/contrib/mymodule.module
sites/all/modules/contrib/includes/facetapi/url_processor_session.inc

You should then see 'My Module' in the list of modules at admin/modules and you can enable it from there.

luo8’s picture

Dear andrewbelcher,
I'm sorry, it's not working for me.
My modules with version:facetapi-7.x-1.2,search_facetapi-7.x-1.x-dev,ctools-7.x-1.2.
I was placed mymodule.info and mymodule.module files to sites/all/modules/contrib folder and url_processor_session.inc to sites/all/modules/contrib/includes/facetapi folder,then I was enabled it.
I was assigned "Faceted Navigation for Search" in core search.
After searching some string the particular facets were showed,then I was selecting some taxonomy term from facets,but when I was trying search again the facets were unselected and url was changed to http://localhost/drupal10/search/content/"new search string".
What I doing bad?

Thanks.

andrewbelcher’s picture

Have you updated the bit of code with the name of your adaptor and index:

mymodule_facetapi_searcher_info_alter()

    if ($info['adapter'] == 'search_api' && $info['instance'] == 'classifieds_index') {

If you're using search_api the adaptor will be search_api. I assume if you're using something else it'll be the module name. In the case of search API, the instance needs to be the machine name of the index you want. Alternatively you could remove that part of the if statement to apply it to all indexes.

There are also some hard-coded bits in the url processor include:

      // Define our patterns.
      // @TODO move this into an admin UI.
      $patterns = array(
        'party_dashboard' => "admin/party\nadmin/party/*",
      );

These patterns are there to namespace the facets so you could potentially have multiple ones across the site. The patterns are passed through drupal_match_path() so check that out for how to define it, but if you want a single namespace for the whole site, set it to *.

luo8’s picture

Dear andrewbelcher,
thanks a lot for your support.
I was installed search_api module with search_api_page and search_api_db module,then I was created server and "party_index" index and "party_index" page.
I didn't change below code.....but again nothing happened.
Do I need install party module?Do you have any idea what I should change?
Thanks

      <?php
      // Define our patterns.
      // @TODO move this into an admin UI.
      $patterns = array(
        'party_dashboard' => "admin/party\nadmin/party/*",
      );
?>
andrewbelcher’s picture

Party is a base for CRM style things and is what I developed the code to be used with, but it'll work with any index as long as you name it.

The patterns you want to update to reflect your usage. If you want the sessions to be remembered globally, just set it to something like:

$patterns = array(
  'site' => '*',
);
luo8’s picture

Hello andrewbelcher,
I made update acc. to your proposal, but with no success.
As well, I tried to create view page based on search_api "party index", but after re-searching facets couldn't be remember.
I was tried to install Party module, but I’m not sure about connection with searching(search index). Do you think, that I have to use party module…? If yes, could you simple describe what should be done?

Thank you a lto.

andrewbelcher’s picture

Party module is not relevant, it's just what my index was based off.

Can you zip up your module and attach it and I'll have a look.

luo8’s picture

Hello andrewbelcher,
pls. see appendix.
I think that should be ok...

Thanks.

luo8’s picture

FileSize
2.64 KB

Hello andrewbelcher,
pls. see appendix.
I think that files should be correct...

Thanks.

pradbone’s picture

Hi,

Sorry for the delay,

Both hooks are firing. I got the following info from dpm($searcher_info);

search_api@classifieds_index (Array, 12 elements)
label (String, 33 characters ) Search service: Classifieds index
adapter (String, 10 characters ) search_api
instance (String, 17 characters ) classifieds_index
types (Array, 1 element)
path (String, 0 characters )
supports facet missing (Boolean) TRUE
supports facet mincount (Boolean) TRUE
include default facets (Boolean) FALSE
module (String, 19 characters ) search_api_facetapi
name (String, 28 characters ) search_api@classifieds_index
url processor (String, 8 characters ) standard
type (String, 4 characters ) node

andrewbelcher’s picture

luo8 - Sorry about the slow response, I didn't see that you'd posted that up! It all looks ok to me. Can you find our what $searcher_info is at the end of mymodule_facetapi_searcher_info_alter(). What version of facetapi are you using?

pradbone - Was that dpm() at the beginning or end of mymodule_facetapi_searcher_info_alter(), or somewhere else entirely?

luo8’s picture

Dear andrewbelcher,
thank for response,anyway I was solve it for 1.Search api module need to installed module facetapi_pretty_paths (http://drupal.org/project/facetapi_pretty_paths),check http://drupal.org/node/1826576 .
For 2.Apachesolr module exist some patches,which working throught views module as well..

Thanks

pradbone’s picture

Hi,

I had to set the namespace to '*' in the url processor include. Working now, thanks!

Paul.

xeeshangulzar’s picture

Hi

I am using following combination of modules.
Views 7.x-3.5
Openlayers 7.x-2.0-beta3
OpenLayers Views 7.x-2.0-beta3
Database search 7.x-1.0-beta4
Search API 7.x-1.5
Search facets 7.x-1.5
Search ranges 7.x-1.4
Facet API 7.x-1.3
Facet API Pretty Paths 7.x-1.0 and some other supporting modules.

I am using using openlayers to display data on map. Than user can search data on map using exposed fulltext search filter (from view) and than narrow down it using facets.I used code(from comment#17) to remember facets. But it is not working fine for me.User comes at home page and search a key word using search exposed filter and when it selects any facet to narrow down it search, it clear the old search(search by keyword) and display data only for selected facet.Actually it overrides search instead to narrow down. Can you help me that how can i resolve this issue.

Thank You,
Xee

andrewbelcher’s picture

ze3sh@an - Have you set the view to remember the search filter in the session? If not, that is the expected behaviour.

Lendude’s picture

Issue summary: View changes
Status: Active » Needs review
FileSize
6.39 KB

Turned the great write up by andrewbelcher in #17 into a patch for Facet API Bonus. It adds this functionality as a separate module, and when you enable it, it will work for all search indexes.

It's not dependent on the parent module so you can use this without using any of the other features in Facet API Bonus.

Yes it would be better to be able to set this on a per-index-basis but this is a start :-)

Lendude’s picture

FileSize
6.19 KB

Couple of misnamed hooks in #41, this should be better.

pinueve’s picture

Issue summary: View changes

Hi @Lendude, patch #42 works like a charm, thanks a lot, but my breadcrumbs are gone. Any sugestions please?

Lendude’s picture

In #17 @ andrewbelcher said

I'm not sure breadcrumbs make sense when things are stored in the session and I didn't want them in my use case, so at the moment I just override the setBreadcrumb() and return nothing.

I just turned his code into a patch and really never gave the breadcrumb much thought.

@pinueve If you delete the setBreadcrumb() method in facetapi_bonus/modules/facetapi_bonus_session/includes/facetapi/url_processor_session.inc, I assume you will get a breadcrumb back. I haven't tested this, so no idea if this give you the right breadcrumb. But right now setBreadcrumb() doesn't do anything, so 'no breadcrumbs' is the expected behaviour.

seanB’s picture

I just updated the patch from nr 42. In my case the facet api pretty paths module came after the new module, so the 'url processor' got reset again. I added a hook_module_implements_alter() to make sure the hook_facetapi_searcher_info() from the session module runs last.

Patch is attached.

seanB’s picture

The last patch breaks the pretty paths... We probably need a way to fix this!

seanB’s picture

Never mind, it wasn't a problem with the pretty paths, it was a problem in fetchParams(). We need to merge the session array with the array of the parent fetchParams() function to allow extra query parameters (like keyword or whatever).

New patch attached.

Neograph734’s picture

Patch applied nicely and seems to work pretty good so far. Thanks!

seanB’s picture

So is it RTBC? Maybe someone else can also confirm it works?

Neograph734’s picture

Better to have at least one more before setting RTBC.

Neograph734’s picture

Status: Needs review » Reviewed & tested by the community

I had hoped for more reviews by now. But let's mark this RTBC. It has been working very nice.

NWOM’s picture

I tried #47 but couldn't figure out how to get it to work. Is there a configuration that I'm missing somewhere? I tried skimming the thread and I read something about having to change the URL processor first. Thanks in advance for the help and everyone's work on this.

Neograph734’s picture

Status: Reviewed & tested by the community » Needs work

It appears this is only works for the Link widget, not for all widgets. @NWOM can you confirm you are using something different?

I just tried the Links with checkboxes widget and it didn't work either.

NWOM’s picture

@Neograph734 Oh thank you, I hadn't realized that. I am using the Facetapi Multiselect widget in combination with Chosen. It would be great if it was somehow widget independent.

Neograph734’s picture

I accidentally figured it out myself a few minutes ago, but I was hoping for the same :)

NWOM’s picture

Ah I see. Is the saved filter setting persistent after logout for the user or is it only session based? I created my own approach to saving filters for the logged in user as a workaround for now, but would be interesting to know in order to get rid of some of the bloat.

Neograph734’s picture

@NWOM, this method is session based and works pretty nice for links. Would you mind sharing your method with me? I am looking for some solution in the short term.

NWOM’s picture

@Neograph: Ah so if it's session based, it wouldn't exactly work for me anyways, but would definitely be a good feature for other use-cases for sure.

The workaround I have in place is probably not a great workaround for most, since it adds a bunch of modules that may not be used by many. So it's probably best to not include the workaround within this issue queue. If you would like, you could send me your Skype details via my Contact Form, or login to the #drupal-support @ freenode IRC channel, and I can go over the entire workaround with you.

Neograph734’s picture

Status: Needs work » Reviewed & tested by the community

It appears this works after all. Somehow the module file have been removed from my server, but the sessions were still getting saved until I changed the widget...

Anyway, apologies for the spam. This is still RTBC.

Neograph734’s picture

Issue summary: View changes

Restoring the summary that was removed earlier.

berlintower’s picture

To use it with Solr, too:

/**
 * Implements hook_facetapi_searcher_info().
 */
function facetapi_bonus_session_facetapi_searcher_info_alter(array &$searcher_info) {

  foreach ($searcher_info as &$info) {
    if ($info['adapter'] == 'search_api' || $info['adapter'] == 'apachesolr') {
        $info['url processor'] = 'session';
    }
  }
}

  • joseph.olstad committed 2766ea2 on 7.x-1.x authored by luo8
    Issue #1380716 by seanB, Lendude, andrewbelcher, luo8, pradbone,...
joseph.olstad’s picture

Status: Reviewed & tested by the community » Fixed

Thanks

Status: Fixed » Closed (fixed)

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