I am using this great module with facet api, so by default, each of the facet select blocks are collapsed.

When a block is expanded and a facet link is clicked, the page is reloaded with the filter applied and the block is returned to it's collapsed state. It would be great if there was some way to keep the block(s) that where expanded at their expanded state on the page reload.

Is this something that would be possible?

Comments

adammalone’s picture

I've just come up against this issue myself. The way I'm looking into is to take the query parameters facetapi uses using arg() and then analysing that to determine which blocks should be open on page load.

I'll update further when/if I progress down this track!

adammalone’s picture

Ok, so a quick piece of who knows how badly written code has produced the following.

1. Create a module for yourself with hook_init

/**
 * Implements hook_init
 * Adds further support for collapsiblock and facets
 */
function mymodule_init() {
  $arg = arg();
  if ($arg[0] == 'search' && $arg[1] == 'site') {
    $query = drupal_get_query_parameters();
    // Get query params and look for f (facets)
    if (!empty($query['f'])) {
      // create an empty array to fill with whichever facets
      // you wish to remain open on page reload
      $filters = array();
      // facetsapi appears to use 'f' as the query param so
      // look for parameters based on that
      foreach ($query['f'] as $facet) {
        // You will have to do a dpm($facet) to discover what
        // the machine names of your filters are (or look in the URL)
        if (strstr($facet, 'dm_field_datepublished')) {
          $filters['date'] = TRUE;
        }
        if (strstr($facet, 'im_field_taxonomy')) {
          $filters['topic'] = TRUE;
        }
      }
    // Pass the array of filters that it is currently filtered by to JS
    drupal_add_js(array('mymodule' => $filters), 'setting');
    }
  }
}

2. In a JS file that is loaded either on every page load (place scripts[] = mymodule.js in mymodule.info) OR in a js file that is loaded only on the search page (drupal_add_js()) place the following

Drupal.behaviors.mymodule = {
  attach: function(context) {
    var $ = jQuery;
    if (Drupal.settings.mymodule) {
      // for the values like topic refer to the elements of the filters array
      if (Drupal.settings.mymodule.topic) {
        // Open up element inspector to find the block names for the facet filters.
        $('.block-facetapi-pgooj5wv2majg6gthmjlu41gwwx4 h2').removeClass('collapsiblockCollapsed');
        $('.block-facetapi-pgooj5wv2majg6gthmjlu41gwwx4 .content').show();
      }
      if (Drupal.settings.mymodule.date) {
        $('.block-facetapi-jkwop13cenqfojfmtw0vtrbb1dkrstmdbyto h2').removeClass('collapsiblockCollapsed');
        $('.block-facetapi-jkwop13cenqfojfmtw0vtrbb1dkrstmdbyto .content').show();
      }
    }
  }
}

I'm sure it could be written with better code but this works for us!

modstore’s picture

Thanks typhonius, that gave me a good starting point. I used your code and made some changes to fit my implementation. Code here also if anyone else needs it. I changed it so $facet_ids variable should be the only place that needs changing.

function mymodule_init() {
  // so we can match the fields with their colapsiblock ids
  $facet_ids = array(
    'field_make' => 'block-facetapi-u6sfebk4xs0at358doofxgvw8tv1cvtp',
    'field_model' => 'block-facetapi-o2xsbtbuamlc59wjbosnjqyucl5bb3cq',
    'author:field_country_code' => 'block-facetapi-amv5wus0oelzxnvm0lpglfkhvpw0h2g0',
    'field_body_type' => 'block-facetapi-pos1ky1u08l38a3l7fr64m0cscjfzjrl',
    'field_aspiration' => 'block-facetapi-berlldrd621rahzrd31rotb0a1en0iz0',
    'field_transmission' => 'block-facetapi-jfiuqpq6ybx1xxutlbuatdcqlhicfjs7',
    'field_engine' => 'block-facetapi-rz109ehxuyxlgpyejiovfrrnhtjaomsb',
  );
  // the path we want this to load on
  if (arg(0) == 'cars') {
    $query = drupal_get_query_parameters();

    // Get query params and look for f (facets)
    if (!empty($query['f'])) {
      // create an empty array to fill with whichever facets should open on page reload
      $filters = array();
      // facetsapi uses 'f' as the query param so look for parameters based on that
      foreach ($query['f'] as $facet) {
        $parts = explode(':', $facet);
        $facet_name = urldecode($parts[0]);
        $filters[] = $facet_ids[$facet_name];
      }

      drupal_add_js(drupal_get_path('module', 'mymodule').'/js/mymodule.js');
      drupal_add_js(array('myModule' => $filters), 'setting');
    }
  }
}

and the js file

(function ($) {

Drupal.behaviors.myModule = {
  attach: function(context) {
    if (Drupal.settings.myModule) {
      // iterate over the block ids and expand them
      for(var i=0; i<Drupal.settings.myModule.length; i++) {
        $('#' + Drupal.settings.myModule[i] + ' h2').removeClass('collapsiblockCollapsed');
        $('#' + Drupal.settings.myModule[i] + ' .content').show();
      }
    }
  }
}

})(jQuery);
cavla’s picture

Hi guys,

I have tried both of your codes and it seems that i am out of luck.
I have tried many things/debugging to see what was wrong and i think it might come from the type of query we are looking for.

The following: if (!empty($query['f'])) always returns nothing as if i had no type of query: facet.

Any idea why?

PS: the module and the js are working fine if i don't have the check for the queries and the check for the query types...

modstore’s picture

What do you get if you do a dpm on the $query variable?

If you can't sort it out, post your code and I will see if I can notice anything obvious.

adammalone’s picture

Which options do you have if you output the results of drupal_get_query_parameters() ?

In both 7.x-1.x and 7.x-2.x facetapi the key is 'f' so this is quite curious.

cavla’s picture

Thanks for your replies.

Believe it or not but a dpm on the query returns nothing: blank message area with dpm and NULL with var_dump.

Same thing if I output the results of drupal_get_query_parameters() : it returns "array"

I am new to PHP coding tho but i did put the following in a custom module under my faceted block:

<?php
	 dpm($query);
         var_dump($query);

         $test= drupal_get_query_parameters();
         echo $test
?>

You can actually have a look: beta.restaurantsofbangkok.com/restaurants

Regarding the code of my module, it's pretty much the same as typhonius's:

<?php

function mymodule_init() {

  if (arg(0) == 'restaurants') {
    $query = drupal_get_query_parameters();
    // Get query params and look for f (facets)
    if (!empty($query['f'])) {
      // create an empty array to fill with whichever facets
      // you wish to remain open on page reload
      $filters = array();
      // facetsapi appears to use 'f' as the query param so
      // look for parameters based on that
      foreach ($query['f'] as $facet) {
        // You will have to do a dpm($facet) to discover what
        // the machine names of your filters are (or look in the URL)
        if (strstr($facet, 'field_price_range')) {
          $filters['price'] = TRUE;
        }
      }
    // Pass the array of filters that it is currently filtered by to JS
    drupal_add_js(array('mymodule' => $filters), 'setting');
    }
  }
}
?>

and the js file:

Drupal.behaviors.mymodule = {
  attach: function(context) {
    var $ = jQuery;
    if (Drupal.settings.mymodule) {
      // for the values like topic refer to the elements of the filters array
      if (Drupal.settings.mymodule.price) {
        // Open up element inspector to find the block names for the facet filters.
        $('.block-facetapi-lg365gyoujppihzrzo7rk6zcp2gulv1t h2').removeClass('collapsiblockCollapsed');
        $('.block-facetapi-lg365gyoujppihzrzo7rk6zcp2gulv1t .content').show();
      }
    }
  }
}
cavla’s picture

Hi again,

I go it: i am using Pretty Facets Paths and this module "sanitize" the query for the url cleaning.
That is why it wasn't working. I got your codes to work now. Thanks

However, i'm still interested in using Pretty Facets Paths and i will work around it.

Any ideas how to get the queries before Pretty Facets Paths does?

adammalone’s picture

You'll have to set your module weight lower so it gets executed before other modules.

See here for more information.

darvanen’s picture

Issue summary: View changes
Status: Active » Closed (outdated)

Cleaning up the issue queue, please reopen if you would like this to be looked at.