You can build very powerful search tools in Drupal. We recently used the Search API, Facet API and Views modules to build a nifty faceted search that also does full text searches, all backed by a SOLR server.
The search page itself was built as a view, based on a Search API index with an exposed full text filter. The facets were configured to appear on the view page using the blocks system (yes, we probably should have used Panels, but we didn’t).
Setting up the search index, the facets and the view was tricky, fiddly work. But once the configuration was done the facets and the full text search just worked. And so long as the user did a full text search first, and then added some facet selections, the full text search and the facets worked together. BUT, if the user made facet selections first, and then tried to refine the search with a full text search term, no dice — the search page would forget the facet selections, and the user would have to start over. We had a frustrated client.
The cause of this problem turns out to be a fundamental incompatibility between the way that the Facet API passes facet selections around (by adding query parameters to the page URL) and the way that Views collects exposed filter values. Exposed filters are rendered as inputs in a form that uses GET to submit its values. Per the HTML spec, any input values in a form that uses GET are supposed to be appended as query parameters to the URL in the form’s action attribute and to replace any existing query parameters. In short, as soon as someone uses an exposed filter any existing query parameters added by Facet API are simply lost.
It would be great if the Facet API and Views maintainers could get together to agree on a fix to this problem (and to agree which module should make the fix), but there’s no sign of that happening.
Here’s code to solve the problem in the meanwhile, inspired by comments on this issue: https://www.drupal.org/node/1381524
/** * Implements hook_form_FORM_ID_alter(). */ function MYMODULE_form_views_exposed_form_alter(&$form, &$form_state, $form_id) { // Add facets as hidden inputs to preserve selection. if ( isset($_GET['f']) /* && ADD ANY OTHER VIEW-IDENTIFYING CODE DESIRED */ ) { // Get the parameters from the current page request. $params = drupal_get_query_parameters(); // Add the facet values as hidden elements to the form. // The browser will turn them back into query parameters. foreach ( $params['f'] as $delta => $value ) { $form['f[' . $delta . ']'] = array( '#type' => 'hidden', '#value' => check_plain($value), ); } } }
Add this code to a custom module.