(function($) {
var history;
Drupal.search_api_ajax = {};
if (Drupal.settings.search_api_ajax) {
var blocks = Drupal.settings.search_api_ajax.blocks;
var content = Drupal.settings.search_api_ajax.content;
var regions = Drupal.settings.search_api_ajax.regions;
var spinner = Drupal.settings.search_api_ajax.spinner;
var target = Drupal.settings.search_api_ajax.scrolltarget;
var fade = Drupal.settings.search_api_ajax.fade;
var opacity = Drupal.settings.search_api_ajax.opacity;
var speed = Drupal.settings.search_api_ajax.scrollspeed;
// notice the "search_api_ajax_path" instead of
// "search_api_ajax.path" for magic reasons
var ajaxPath = Drupal.settings.search_api_ajax_path;
var qPath = Drupal.settings.search_api_ajax_qpath;
var isView = Drupal.settings.search_api_ajax.view;
// initialize listeners
Drupal.search_api_ajax.initialize = function() {
if (content) {
Drupal.search_api_ajax.ajax(content);
}
if (blocks) {
for (var block in blocks) {
Drupal.search_api_ajax.ajax(blocks[block]);
}
}
};
// extract url for ajax history
Drupal.search_api_ajax.url_to_state = function(url) {
var state = '';
if (isView) {
var query = Drupal.search_api_ajax.get_url_state(url)["query"];
}
state = url.replace(new RegExp('^.*' + Drupal.settings.basePath + ajaxPath + '/' + '?'), '');
if (query) {
state = query + state.replace('?query=' + query, '');
}
else {
state = state.replace('?query=', '');
state = state.replace('?', '&');
}
return state;
};
Drupal.search_api_ajax.get_url_state = function(url) {
var vars = [], hash;
var hashes = url.slice(url.indexOf('?') + 1).split('&');
for (var i = 0; i < hashes.length; i++) {
hash = hashes[i].split('=');
vars.push(hash[0]);
vars[hash[0]] = hash[1];
}
return vars;
}
// prepare and perform ajax search request
Drupal.search_api_ajax.request_callback = function(state) {
if (content) {
if (fade) {
$(content + ':first').fadeTo('fast', opacity);
}
if (spinner) {
$('#content').append('
![](' + Drupal.settings.basePath + spinner + ')
')
}
}
// Scroll back to top, when top is out of view. Inspired by views module.
if (target) {
var offset = $(target).offset();
var scrollTarget = target;
while ($(scrollTarget).scrollTop() == 0 && $(scrollTarget).parent()) {
scrollTarget = $(scrollTarget).parent()
}
if (offset.top - 10 < $(scrollTarget).scrollTop()) {
$(scrollTarget).animate({
scrollTop: (offset.top - 10)
}, speed);
}
}
// post ajax, read json
var keysPath = '/' + state;
if (isView) {
keysPath = '?query=' + state;
}
$.post(Drupal.settings.basePath + 'search_api_ajax/' + ajaxPath + keysPath, {
js: 1
}, Drupal.search_api_ajax.response_callback, 'json');
};
// update search page with ajax, based on the json we read
Drupal.search_api_ajax.response_callback = function(data) {
if (content) {
if (fade) {
$(content + ':first').fadeTo('fast', 1);
}
if (spinner) {
$('#search-api-ajax-spinner').remove();
}
}
for (var setting in data.settings) {
Drupal.settings[setting] = data.settings[setting];
}
var list = [];
// we have to add the new blocks, that have come into existence
// @see search_api_ajax.pages.inc where we add this blocks variable
if (data.blocks) {
for (var new_block in data.blocks) {
blocks[new_block] = data.blocks[new_block];
}
}
// schedule items for removal to reduce page jumpiness.
if (blocks) {
for (var block in blocks) {
list.push($(blocks[block]));
}
for (var i = 0, l = list.length; i < l; i++) {
list[i].remove();
}
}
for (var region in data.regions) {
if (region == 'search_api_ajax') {
if (content) {
$(content + ':first').html(data.regions[region]);
}
}
else {
for (var block in data.regions[region]) {
if (regions[region] && blocks[block]) {
$(regions[region]).append(data.regions[region][block]);
}
}
}
}
// re-attach Drupal behaviors for whole document
Drupal.attachBehaviors('body');
};
Drupal.search_api_ajax.navigate = function(url) {
if (url !== undefined) {
YUI().use('history', function(Y) {
history.add({
q: Drupal.search_api_ajax.url_to_state(url)
});
});
}
return false;
};
Drupal.search_api_ajax.ajax = function(selector) {
// observe regular facet and sorts links ^ starts with * contains
// check two paths: ^basePath/ajaxPath OR ^search_api_ajax/basePath/ajaxPath
// @see http://api.jquery.com/category/selectors/attribute-selectors/
// Create an array of selectors for readability.
var selectors = [selector + ' a[href^="' + Drupal.settings.basePath + ajaxPath + '"]', selector + ' a[href^="' + Drupal.settings.basePath + 'search_api_ajax/' + ajaxPath + '"]'];
$(selectors.join(', ')).livequery('click', function() {
return Drupal.search_api_ajax.navigate($(this).attr('href'));
});
// Add support for facetapi checkboxes widget.
// Unbind facetapi click event.
$(selector + ' .facetapi-checkbox').unbind('click');
$(selector + ' .facetapi-checkbox').livequery('click', function() {
return Drupal.search_api_ajax.navigate($(this).next('a').attr('href'));
})
// observe search keys forms (or views input forms, must be custom set)
$(selector + ' form[action^="' + Drupal.settings.basePath + ajaxPath + '"], ' + selector + ' form[action^="' + Drupal.settings.basePath + 'search_api_ajax/' + ajaxPath + '"]').livequery('submit', function() {
return Drupal.search_api_ajax.navigate($(this).find('input[name*="keys"]').val());
});
// observe facet range sliders
$(selector + ' .search-api-ranges-widget form[action^="' + Drupal.settings.basePath + ajaxPath + '"], ' + selector + ' .search-api-ranges-widget form[action^="' + Drupal.settings.basePath + 'search_api_ajax/' + ajaxPath + '"]').livequery('submit', function() {
var separator = '?';
if ($(this).find('input[name="range-ajax-target"]').val().indexOf("?") !== -1) {
separator = '&';
}
// add a filter in the form of &f[n]=field_name:[A B]
// instead of actually knowing what "n" is, we just f[]
// @todo Facet API can have different 'f', how to know which?
var addFilter = 'f[]=' + $(this).find('input[name="range-field"]').val() + ':' + '[' + $(this).find('input[name="range-from"]').val() + ' TO ' + $(this).find('input[name="range-to"]').val() + ']';
return Drupal.search_api_ajax.navigate($(this).find('input[name="range-ajax-target"]').val() + separator + addFilter);
});
};
}
// we initiate YUI3's History extension
YUI().use('history', function(Y) {
// initialize
history = new Y.HistoryHash();
if (history.get('q')) {
Drupal.search_api_ajax.request_callback(history.get('q'));
}
// listen to changes
// @todo when going from /page#q= to /page it should also trigger
Y.on('history:change', function(e) {
var changed = e.changed;
if (changed.q) {
Drupal.search_api_ajax.request_callback(history.get('q'));
}
});
});
Drupal.behaviors.search_api_ajax = {
attach: function(context, settings) {
// initialize livequery() event only if there is an active search
// only needed for search api pages, not for views paths
if (Drupal.search_api_ajax.url_to_state(window.location.href) != '' || isView === 1) {
Drupal.search_api_ajax.initialize();
}
}
};
})(jQuery);