2015-08-17 17:00:26 -07:00
/ * *
* @ file
* Handles AJAX fetching of views , including filter submission and response .
* /
( function ( $ , Drupal , drupalSettings ) {
"use strict" ;
/ * *
* Attaches the AJAX behavior to Views exposed filter forms and key View
* links .
*
* @ type { Drupal ~ behavior }
* /
Drupal . behaviors . ViewsAjaxView = { } ;
Drupal . behaviors . ViewsAjaxView . attach = function ( ) {
if ( drupalSettings && drupalSettings . views && drupalSettings . views . ajaxViews ) {
var ajaxViews = drupalSettings . views . ajaxViews ;
for ( var i in ajaxViews ) {
if ( ajaxViews . hasOwnProperty ( i ) ) {
Drupal . views . instances [ i ] = new Drupal . views . ajaxView ( ajaxViews [ i ] ) ;
}
}
}
} ;
/ * *
* @ namespace
* /
Drupal . views = { } ;
/ * *
* @ type { object . < string , Drupal . views . ajaxView > }
* /
Drupal . views . instances = { } ;
/ * *
* Javascript object for a certain view .
*
* @ constructor
*
* @ param { object } settings
* @ param { string } settings . view _dom _id
* /
Drupal . views . ajaxView = function ( settings ) {
var selector = '.js-view-dom-id-' + settings . view _dom _id ;
this . $view = $ ( selector ) ;
// Retrieve the path to use for views' ajax.
var ajax _path = drupalSettings . views . ajax _path ;
// If there are multiple views this might've ended up showing up multiple
// times.
if ( ajax _path . constructor . toString ( ) . indexOf ( "Array" ) !== - 1 ) {
ajax _path = ajax _path [ 0 ] ;
}
// Check if there are any GET parameters to send to views.
var queryString = window . location . search || '' ;
if ( queryString !== '' ) {
// Remove the question mark and Drupal path component if any.
queryString = queryString . slice ( 1 ) . replace ( /q=[^&]+&?|&?render=[^&]+/ , '' ) ;
if ( queryString !== '' ) {
// If there is a '?' in ajax_path, clean url are on and & should be
// used to add parameters.
queryString = ( ( /\?/ . test ( ajax _path ) ) ? '&' : '?' ) + queryString ;
}
}
this . element _settings = {
url : ajax _path + queryString ,
submit : settings ,
setClick : true ,
event : 'click' ,
selector : selector ,
progress : { type : 'fullscreen' }
} ;
this . settings = settings ;
// Add the ajax to exposed forms.
this . $exposed _form = $ ( 'form#views-exposed-form-' + settings . view _name . replace ( /_/g , '-' ) + '-' + settings . view _display _id . replace ( /_/g , '-' ) ) ;
this . $exposed _form . once ( 'exposed-form' ) . each ( jQuery . proxy ( this . attachExposedFormAjax , this ) ) ;
// Add the ajax to pagers.
this . $view
// Don't attach to nested views. Doing so would attach multiple behaviors
// to a given element.
. filter ( jQuery . proxy ( this . filterNestedViews , this ) )
. once ( 'ajax-pager' ) . each ( jQuery . proxy ( this . attachPagerAjax , this ) ) ;
// Add a trigger to update this view specifically. In order to trigger a
// refresh use the following code.
//
// @code
// jQuery('.view-name').trigger('RefreshView');
// @endcode
var self _settings = $ . extend ( { } , this . element _settings , {
event : 'RefreshView' ,
base : this . selector ,
element : this . $view
} ) ;
this . refreshViewAjax = Drupal . ajax ( self _settings ) ;
} ;
/ * *
* @ method
* /
Drupal . views . ajaxView . prototype . attachExposedFormAjax = function ( ) {
2015-08-27 12:03:05 -07:00
var that = this ;
this . exposedFormAjax = [ ] ;
$ ( 'input[type=submit], input[type=image]' , this . $exposed _form ) . each ( function ( index ) {
var self _settings = $ . extend ( { } , that . element _settings , {
base : $ ( this ) . attr ( 'id' ) ,
element : this
} ) ;
that . exposedFormAjax [ index ] = Drupal . ajax ( self _settings ) ;
2015-08-17 17:00:26 -07:00
} ) ;
} ;
/ * *
* @ return { bool }
* If there is at least one parent with a view class return false .
*
* @ todo remove . size ( ) replace with . length .
* /
Drupal . views . ajaxView . prototype . filterNestedViews = function ( ) {
// If there is at least one parent with a view class, this view
// is nested (e.g., an attachment). Bail.
return ! this . $view . parents ( '.view' ) . size ( ) ;
} ;
/ * *
* Attach the ajax behavior to each link .
* /
Drupal . views . ajaxView . prototype . attachPagerAjax = function ( ) {
this . $view . find ( 'ul.js-pager__items > li > a, th.views-field a, .attachment .views-summary a' )
. each ( jQuery . proxy ( this . attachPagerLinkAjax , this ) ) ;
} ;
/ * *
* Attach the ajax behavior to a singe link .
*
* @ param { string } id
* @ param { HTMLElement } link
* /
Drupal . views . ajaxView . prototype . attachPagerLinkAjax = function ( id , link ) {
var $link = $ ( link ) ;
var viewData = { } ;
var href = $link . attr ( 'href' ) ;
// Construct an object using the settings defaults and then overriding
// with data specific to the link.
$ . extend (
viewData ,
this . settings ,
Drupal . Views . parseQueryString ( href ) ,
// Extract argument data from the URL.
Drupal . Views . parseViewArgs ( href , this . settings . view _base _path )
) ;
var self _settings = $ . extend ( { } , this . element _settings , {
submit : viewData ,
base : false ,
element : $link
} ) ;
this . pagerAjax = Drupal . ajax ( self _settings ) ;
} ;
/ * *
*
* @ param { Drupal . Ajax } [ ajax ]
* @ param { object } response
* @ param { string } response . selector
* /
Drupal . AjaxCommands . prototype . viewsScrollTop = function ( ajax , response ) {
// Scroll to the top of the view. This will allow users
// to browse newly loaded content after e.g. clicking a pager
// link.
var offset = $ ( response . selector ) . offset ( ) ;
// We can't guarantee that the scrollable object should be
// the body, as the view could be embedded in something
// more complex such as a modal popup. Recurse up the DOM
// and scroll the first element that has a non-zero top.
var scrollTarget = response . selector ;
while ( $ ( scrollTarget ) . scrollTop ( ) === 0 && $ ( scrollTarget ) . parent ( ) ) {
scrollTarget = $ ( scrollTarget ) . parent ( ) ;
}
// Only scroll upward.
if ( offset . top - 10 < $ ( scrollTarget ) . scrollTop ( ) ) {
$ ( scrollTarget ) . animate ( { scrollTop : ( offset . top - 10 ) } , 500 ) ;
}
} ;
} ) ( jQuery , Drupal , drupalSettings ) ;