123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224 |
- (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('<div id="search-api-ajax-spinner"><img class="spinner" src="' + Drupal.settings.basePath + spinner + '" /></div>')
- }
- }
- // 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);
|