diff --git a/ajax_facets.module b/ajax_facets.module index bf64c24..09a45d8 100755 --- a/ajax_facets.module +++ b/ajax_facets.module @@ -94,11 +94,13 @@ function ajax_facets_add_ajax_js($facet) { } } $apply_path = url($search_path); + $base_path = $url_processor->getBasePath(); } else { // Note that we add in query only filter params and exclude pages and etc... $query = (isset($_GET[$filter_key])) ? array($filter_key => $_GET[$filter_key]) : array(); $apply_path = url($search_path, array('query' => $query)); + $base_path = $search_path; } if (!empty($views)) { @@ -123,6 +125,7 @@ function ajax_facets_add_ajax_js($facet) { $setting['facetapi'] = array( 'defaultQuery' => $default_query, 'searchPath' => $search_path, + 'basePath' => $base_path, 'index_id' => $facet_info['map options']['index id'], 'view_name' => $view_name, 'display_name' => $display_name, diff --git a/js/ajax_facets.js b/js/ajax_facets.js index 6d9ffb2..9cd1330 100755 --- a/js/ajax_facets.js +++ b/js/ajax_facets.js @@ -8,14 +8,17 @@ Drupal.ajax_facets.queryState = null; // State of each facet. Drupal.ajax_facets.facetQueryState = null; + // Whether or not this is the first page load. To be reset in + // Drupal.ajax_facets.initHistoryState + Drupal.ajax_facets.firstLoad = true; // You can use it for freeze facet form elements while ajax is processing. Drupal.ajax_facets.beforeAjaxCallbacks = {}; - Drupal.ajax_facets.beforeAjax = function(context, settings, element) { + Drupal.ajax_facets.beforeAjax = function(elementId, facetName) { $.each(Drupal.ajax_facets.beforeAjaxCallbacks, function () { if ($.isFunction(this)) { - this(context, settings, element); + this(elementId, facetName); } }); }; @@ -83,6 +86,7 @@ } $('body').once(function() {$(this).append('
');}); + } }; @@ -132,7 +136,9 @@ Drupal.ajax_facets.processSelectbox = function(event) { var $this = $(this); - var facetOptions = event.data[0]; + Drupal.ajax_facets.initHistoryState($this.attr('id'), $this.data('facet')); + // Not in use anymore...? + // var facetOptions = event.data[0]; if (Drupal.settings.facetapi.prettyPaths) { var name = '/' + $this.attr('name'); } @@ -158,7 +164,7 @@ } } - Drupal.ajax_facets.sendAjaxQuery($this, facetOptions); + Drupal.ajax_facets.sendAjaxQuery($this.attr('id'), $this.data('facet'), true); }; /** @@ -166,7 +172,9 @@ */ Drupal.ajax_facets.processCheckboxes = function(event) { var $this = $(this); - var facetOptions = event.data[0]; + Drupal.ajax_facets.initHistoryState($this.attr('id'), $this.data('facet')); + // Not in use anymore...? + // var facetOptions = event.data[0]; var facetCheckboxName = $this.attr('name'); if (Drupal.ajax_facets.queryState['f'] != undefined) { var queryNew = new Array(); @@ -193,37 +201,68 @@ } } - Drupal.ajax_facets.sendAjaxQuery($this, facetOptions); + Drupal.ajax_facets.sendAjaxQuery($this.attr('id'), $this.data('facet'), true); }; /* Send ajax. */ - Drupal.ajax_facets.sendAjaxQuery = function($this, facetOptions) { - var current_id = $this.attr('id'); - var current_facet_name = $this.data('facet'); - Drupal.ajax_facets.beforeAjax(); - var data = Drupal.ajax_facets.queryState; + Drupal.ajax_facets.sendAjaxQuery = function(current_id, current_facet_name, set_state) { + + // Run our beforeAjax callbacks + Drupal.ajax_facets.beforeAjax(current_id, current_facet_name); + + // Setup some variables that will be used in the success callback + // Hooray for closures. + // var current_id = $this.attr('id'); + // var current_facet_name = $this.data('facet'); + // The base url for the ajax request. var url = encodeURI(Drupal.settings.basePath + Drupal.settings.pathPrefix + 'ajax/ajax_facets/refresh'); + + // Our request data + var data = Drupal.ajax_facets.queryState; + + // The url to use to update the location bar using pushState + var stateUrl = encodeURI(Drupal.settings.basePath + Drupal.settings.pathPrefix + Drupal.settings.facetapi.basePath); + + // The state information for popstate + var state = { + current_id: current_id, + current_facet_name: current_facet_name, + facets: Drupal.ajax_facets.queryState['f'] + }; + // Custom handling of facets for pretty paths. Technically we're still // sending the get variable 'f' but it will be ignored by the pretty path // url processor if (Drupal.settings.facetapi.prettyPaths && data.f != undefined) { url += data.f.join(''); + stateUrl += data.f.join(''); + } + // If it's not pretty paths, we need to add the query string to our state path + if (!Drupal.settings.facetapi.prettyPaths) { + stateUrl += '?' + $.param({f: $.extend({}, data.f)}); } + // Render the exposed filter data to send along with the ajax request var exposedFormId = '#views-exposed-form-' + Drupal.ajax_facets.queryState['view_name'] + '-' + Drupal.ajax_facets.queryState['display_name']; exposedFormId = exposedFormId.replace(/\_/g, '-'); $.each($(exposedFormId).serializeArray(), function(index, value) { data[value.name] = value.value; }); + + // Make the AJAX Request $.ajax({ type: 'GET', url: url, dataType: 'json', - // We copy all params to force search query with proper arguments. data: data, success: function (response) { + // Update the url only if the request is successful + if (typeof history.pushState != "undefined" && set_state) { + history.pushState(state, null, stateUrl); + } + if (response.activeItems != undefined) { Drupal.ajax_facets.facetQueryState = response.activeItems; } @@ -327,7 +366,6 @@ Drupal.ajax_facets.showTooltip = function($, response, current_id) { var pos = $('#' + current_id).offset(); - console.log(pos); jQuery('#ajax-facets-tooltip').css('top', pos.top - 15); jQuery('#ajax-facets-tooltip').css('left', pos.left - jQuery('#ajax-facets-tooltip').width() - 40); jQuery('#ajax-facets-tooltip').show(); @@ -336,4 +374,35 @@ jQuery('#ajax-facets-tooltip').hide(250); }, 1000); } + + /** + * Initialize the history state. We only want to do this on the initial page + * load but we can't call it until after a facet has been clicked because we + * need to communicate which one is being "deactivated" for our ajax success + * handler + */ + Drupal.ajax_facets.initHistoryState = function (current_id, current_facet_name) { + // Set the initial state only initial page load + if (typeof history.replaceState != "undefined" && Drupal.ajax_facets.firstLoad) { + history.replaceState({ + current_id: current_id, + current_facet_name: current_facet_name, + facets: Drupal.ajax_facets.queryState['f'] + }, null, null); + Drupal.ajax_facets.firstLoad = false; + } + } + + /** + * HTML5 popstate callback. Re-runs the ajax query based on stored state info + */ + window.onpopstate = function (event) { + if (event.state != null) { + Drupal.ajax_facets.queryState['f'] = event.state.facets; + Drupal.ajax_facets.sendAjaxQuery(event.state.current_id, event.state.current_facet_name, false); + } + }; + + })(jQuery); +