Is it possible to integrate hash history BBQ integration like is implemented in isotope.metafizzy?

Comments

kreynen’s picture

Status: Active » Closed (works as designed)

Since JQuery BBQ is included in core for overlay, I don't see why this wouldn't work. Have you tried loading /misc/jquery.ba-bbq.js on the page of the view you want to use? Shouldn't require any changes this module's code to work.

asioren’s picture

Yes, I've loaded jquery.ba-bbq.js on the page of the view but didn't manage to implement the hash.
I also changed the code for the filter menu to look like:
<li><a class="filterbutton" href="#filter=*" class="selected">show all</a></li>
instead of:
<li><a class="filterbutton" data-option-value="*" href="#filter">show all</a></li>
and also included this little script I found to implement the hash on click:

    $('#isotope-options a').click(function() {
        // get href attr, remove leading #
        var href = $(this).attr('href').replace(/^#/, ''),
        // convert href into object
        // i.e. 'filter=.inner-transition' -> { filter: '.inner-transition' }
        option = $.deparam(href);
        // set hash, triggers hashchange on window
        $.bbq.pushState(option);
        return false;
    }); 

    $(window).bind('hashchange', function(event) {
        // get options object from hash
        var hashOptions = $.deparam.fragment();
        // apply options from hash
         $container.isotope(hashOptions);
    })
    // trigger hashchange to capture any hash data on init
    .trigger('hashchange');

But it seemed like something in the model code was interfering. I could manage to get the hash to work without the isotope or the reverse but not both of them together.

any help about the code needed to implement this with isotope views will be greatly appreciated.

I believe this addition to this great model will make it much much stronger and useful :)

cees.vanegmond’s picture

asioren,
First make shure bbq is loaded (for non overlay users), add in hte .js
$.getScript("/misc/jquery.ba-bbq.js")

Next you should change:
$('#isotope-options a').click(function() {
in
$('.isotope-options li a').click(function() {

audriusb’s picture

javascript gives error on
$container.isotope(hashOptions);
line because this $container is a private variable. go to sites/all/modules/views_isotope/views_isotope.js and remove 'var' in line 4. Now you can access this object site wide.

caspervoogt’s picture

you also need to remove var from 'var $optionSets' in views_isotope/views_isotope.js
Correction: no you don't need to remove this. I was using different JS code. Will post working code in a moment.

caspervoogt’s picture

I got this working so that the selector class is also reassigned when you call a hash URL. Here's what I did:

  • #4; remove var in line 4
  • created views-isotope-filter-block.tpl.php in my theme's /templates directory
  • added JS using drupal_add_js within this template, since it is only needed when this template is rendered.

Code for views-isotope-filter-block.tpl.php:

<?php
/**
 * @file views-isotope-filter-block.tpl.php
 * Default simple view template to display a list of rows.
 *
 * @ingroup views_templates
 */
drupal_add_js('
  jQuery(document).ready(function () {
    jQuery(window).bind( "hashchange", function( event ){
      // get options object from hash
      var hashChanged, defaultOptions, isOptionLinkClicked, changeSelectedLink;
      var hashOptions = window.location.hash ? jQuery.deparam.fragment( window.location.hash, true ) : {},
      // do not animate first call
      aniEngine = hashChanged ? "best-available" : "none",
      // apply defaults where no option was specified
      options = jQuery.extend( {}, defaultOptions, hashOptions, { animationEngine: aniEngine } );
      // apply options from hash
      $container.isotope( options );
      // save options
      isotopeOptions = hashOptions;
      if ( !isOptionLinkClicked ) {
        // iterate over options
        var hrefObj, hrefValue, $selectedLink;
        for ( var key in options ) {
          hrefObj = {};
          hrefObj[ key ] = options[ key ];
          hrefValue = jQuery.param( hrefObj );
          jQuery("ul.isotope-filters li a").each(function(){
            if (jQuery(this).attr("href") ==  "#" + hrefValue){
              jQuery("ul.isotope-filters li a.selected").removeClass("selected");
              jQuery(this).addClass("selected");
            }
          });
        }
      }
      isOptionLinkClicked = false;
      hashChanged = true;
  })
  .trigger("hashchange");
});
', 'inline');
?>
<div class="isotope-options">
  <ul class="isotope-filters option-set clearfix" data-option-key="filter">
        <li><a href="#filter=*" data-option-value="*" class="selected"><?php print t('All'); ?></a></li>
  <?php
    $count = 0;
    foreach ($rows as $id => $row):
  ?>
    <li><a class="filterbutton" data-option-value="<?php print $isotope_filter_classes[$count]; ?>" href="#filter=<?php print $isotope_filter_classes[$count];?>"><?php print trim($row); ?></a></li>
  <?php
      $count++;
    endforeach;
  ?>
  </ul>
</div>

I would like to not have the dots in the hash URLs so that http://www.mysite.com/isotopeview#filter=.somefilter would become http://www.mysite.com/isotopeview#filter=somefilter. That would require a change to views_isotope/views_isotope.theme.inc. The relevant code is:

if (strstr($value, ',')) {
          // Check for commas and treat as an array for list of taxonomy terms.
          $classes = explode(',', $value);
          foreach ($classes as $class) {
            if (isset($vars['isotope_filter_classes'][$index]))
              $vars['isotope_filter_classes'][$index] .= ' ' . strtolower(drupal_clean_css_identifier(trim($class)));
            else
              $vars['isotope_filter_classes'][$index] = strtolower(drupal_clean_css_identifier(trim($class)));
          }
        } else {

I did not attempt this change because I'm unsure what else I might affect in the process. Would be great to not have to have dots in the hash URLs though.

caspervoogt’s picture

I made a patch for #4... the comment box won't let me attach files.. there's no option to attach anything..

So here it is:

diff --git a/views_isotope.js b/views_isotope.js
index cd79a93..6aef38a 100755
--- a/views_isotope.js
+++ b/views_isotope.js
@@ -1,6 +1,6 @@
 (function($) {
   $(document).ready(function() {
-    var $container = $('#isotope-container');
+    $container = $('#isotope-container');

     $container.isotope({
        itemSelector: '.isotope-element'

If the above TPL and patch work for others, I can update this issue with the patch file as an attachment. Weird that I can't attach files to comments. I swear that used to be possible.

johnnymowmow’s picture

Issue summary: View changes

Thank you all. I was able to get this working with the recommended changes.
However, I placed the isotope-filter-block in the navigation region and am using bootstrap ul class "nav nav-bar" - so I had to modify a small amount to use <li class="active"> vs <a class="selected">. I'm posting this here to help out any future readers also using bootstrap.

I used:
#2 - Add custom "All" filter to views-isotope-filter-block.tpl.php *note this <li> is "active" by default.

<li class="active"><a class="filterbutton" data-option-value="*" href="#filter=*">All</a></li>

#4 - removed "var" as instructed.

#6 -
(#6 JQuery) *slightly modified to remove "active" from <li> and add to <li> vs. <a>

<?php
/**
 * @file views-isotope-filter-block.tpl.php
 * Default simple view template to display a list of rows.
 *
 * @ingroup views_templates
 */
drupal_add_js('
  jQuery(document).ready(function () {
    jQuery(window).bind( "hashchange", function( event ){
      // get options object from hash
      var hashChanged, defaultOptions, isOptionLinkClicked, changeSelectedLink;
      var hashOptions = window.location.hash ? jQuery.deparam.fragment( window.location.hash, true ) : {},
      // do not animate first call
      aniEngine = hashChanged ? "best-available" : "none",
      // apply defaults where no option was specified
      options = jQuery.extend( {}, defaultOptions, hashOptions, { animationEngine: aniEngine } );
      // apply options from hash
      $container.isotope( options );
      // save options
      isotopeOptions = hashOptions;
      if ( !isOptionLinkClicked ) {
        // iterate over options
        var hrefObj, hrefValue, $selectedLink;
        for ( var key in options ) {
          hrefObj = {};
          hrefObj[ key ] = options[ key ];
          hrefValue = jQuery.param( hrefObj );
          jQuery("ul.isotope-filters li a").each(function(){
            if (jQuery(this).attr("href") ==  "#" + hrefValue){
              jQuery("ul.isotope-filters li.active").removeClass("active");
              jQuery(this).parent().addClass("active");
            }
          });
        }
      }
      isOptionLinkClicked = false;
      hashChanged = true;
  })
  .trigger("hashchange");
});
', 'inline');


?>

(#6 HTML) *note ul class has added "nav" and "navbar-nav" for bootstrap. This block was assigned to the "Navigation" region when configuring the block. Also, my loop and code for getting the value for the filter was pulled from the original code of isotope view module.

<div class="isotope-options">
  <ul class="isotope-filters option-set clearfix nav navbar-nav" data-option-key="filter">
        <li><a href="#filter=*" data-option-value="*" class="selected"><?php print t('All'); ?></a></li>
  	   <?php foreach ( $rows as $id => $row ): ?>
	   <?php
	      // remove characters that cause problems with classes
	      // this is also do to the isotope elements
	      $dataoption = trim(strip_tags(strtolower($row)));
	      $dataoption = str_replace(' ', '-', $dataoption);
	      $dataoption = str_replace('/', '-', $dataoption);
	      $dataoption = str_replace('&amp;', '', $dataoption);
	    ?>
	   <li><a class="filterbutton" data-option-value=".<?php print $dataoption; ?>" href="#filter=.<?php print $dataoption; ?>"><?php print trim($row); ?></a></li>
	   <?php endforeach; ?>

  </ul>
</div>

Now on to figure out how to incorporate infinitescroll...

johnnymowmow’s picture

One more thing, hash bbq script is loaded for Admin - not anonymous. So make sure you add the script for the page as #3 suggests.

Chris Gillis’s picture

Version: 7.x-1.0-beta2 » 7.x-2.x-dev
Assigned: Unassigned » Chris Gillis
Category: Support request » Feature request
Status: Closed (works as designed) » Active

I'm planning to add this to the 2.x branch. See also #2170149: External Link to filtered isotope view - how to?

Chris Gillis’s picture

Title: Hash history BBQ integration » Hash history

I've just committed code that allows filters and sorts to be represented in the URL fragment. If anyone is available to test it on the latest dev version, that would be great. You'll see a new option in the config for it.

I have decided not to use BBQ for the following reasons:

  • It is not compatible with newer versions of jQuery
  • It has been 5 years since it was last updated. It seems like a dead project.
Chris Gillis’s picture

Assigned: Chris Gillis » Unassigned
Status: Active » Needs review
Chris Gillis’s picture

Status: Needs review » Fixed

Status: Fixed » Closed (fixed)

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