https://www.jooz.nu/wp-content/plugins/wp-views/embedded/res/js/wpv-pagination-embedded_ver-2.5.2.js
1var WPViews = WPViews || {}; 2 3var wpv_stop_rollover = {}; 4window.wpvPaginationAjaxLoaded = {}; 5window.wpvPaginationAnimationFinished = {}; 6window.wpvPaginationQueue = {}; 7 8// ------------------------------------ 9// Clone 10// ------------------------------------ 11 12// Textarea and select clone() bug workaround | Spencer Tipping 13// Licensed under the terms of the MIT source code license 14// Motivation. 15// jQuery's clone() method works in most cases, but it fails to copy the value of textareas and select elements. This patch replaces jQuery's clone() method with a wrapper that fills in the 16// values after the fact. 17// An interesting error case submitted by Piotr Przybyl: If two <select> options had the same value, the clone() method would select the wrong one in the cloned box. The fix, suggested by Piotr 18// and implemented here, is to use the selectedIndex property on the <select> box itself rather than relying on jQuery's value-based val(). 19;( function() { 20 jQuery.fn.wpv_clone = function() { 21 var result = jQuery.fn.clone.apply( this, arguments ), 22 my_textareas = this.find( 'textarea' ).add( this.filter( 'textarea' ) ), 23 result_textareas = result.find( 'textarea' ).add( result.filter( 'textarea' ) ), 24 my_selects = this.find( 'select' ).add( this.filter( 'select' ) ), 25 result_selects = result.find( 'select' ).add( result.filter( 'select' ) ); 26 for ( var i = 0, l = my_textareas.length; i < l; ++i ) { 27 jQuery( result_textareas[i] ).val( jQuery( my_textareas[i] ).val() ); 28 } 29 for ( var i = 0, l = my_selects.length; i < l; ++i ) { 30 for ( var j = 0, m = my_selects[i].options.length; j < m; ++j ) { 31 if ( my_selects[i].options[j].selected === true ) { 32 result_selects[i].options[j].selected = true; 33 } else { 34 result_selects[i].options[j].selected = false; 35 } 36 } 37 } 38 return result; 39 }; 40})(); 41 42WPViews.ViewFrontendUtils = function( $ ) { 43 44 // ------------------------------------ 45 // Constants and variables 46 // ------------------------------------ 47 48 var self = this; 49 50 self.datepicker_style_id = 'js-toolset-datepicker-style'; 51 self.is_datepicker_style_loaded = false; 52 53 // ------------------------------------ 54 // Methods 55 // ------------------------------------ 56 57 self.just_return = function() { 58 return; 59 }; 60 61 /** 62 * extract_url_query_parameters 63 * 64 * Extracts parameters from a query string, managing arrays, and returns an array of pairs key => value 65 * 66 * @param string query_string 67 * 68 * @return array 69 * 70 * @note ##URLARRAYVALHACK## is a hacky constant 71 * 72 * @uses decodeURIComponent 73 * 74 * @since 1.9 75 */ 76 77 self.extract_url_query_parameters = function( query_string ) { 78 var query_string_pairs = {}; 79 if ( query_string == "" ) { 80 return query_string_pairs; 81 } 82 var query_string_split = query_string.split( '&' ), 83 query_string_split_length = query_string_split.length; 84 for ( var i = 0; i < query_string_split_length; ++i ) { 85 var qs_part = query_string_split[i].split( '=' ); 86 if ( qs_part.length != 2 ) { 87 continue; 88 }; 89 var thiz_key = qs_part[0], 90 thiz_val = decodeURIComponent( qs_part[1].replace( /\+/g, " " ) ); 91 // Adjust thiz_key to work with POSTed arrays 92 thiz_key = thiz_key.replace( /(\[)\d?(\])/, "" ); 93 thiz_key = thiz_key.replace( "[]", "" );// Just in case 94 thiz_key = thiz_key.replace( /(%5B)\d?(%5D)/, "" ); 95 thiz_key = thiz_key.replace( "%5B%5D", "" );// Just in case 96 thiz_key = thiz_key.replace( /(%255B)\d?(%255D)/, "" ); 97 thiz_key = thiz_key.replace( "%255B%255D", "" );// Just in case 98 if ( query_string_pairs.hasOwnProperty( thiz_key ) ) { 99 if ( query_string_pairs[thiz_key] != thiz_val ) { 100 // @hack alert!! We can not avoid using this :-( 101 query_string_pairs[thiz_key] += '##URLARRAYVALHACK##' + thiz_val; 102 } else { 103 query_string_pairs[thiz_key] = thiz_val; 104 } 105 } else { 106 query_string_pairs[thiz_key] = thiz_val; 107 } 108 } 109 return query_string_pairs; 110 }; 111 112 /** 113 * get_extra_url_query_parameters 114 * 115 * Gets the current URL query parameters, but only those that do not belong to the current form already. 116 * 117 * @note Arrays are returned on a single key with values on a single str
117ing, separated by the ##URLARRAYVALHACK## placeholder. We might review that later 118 * @note Since 2.2, force include URL parameters that belong to form controls when the form does not use dependency nor AJAX results. 119 * As the form should be posted with page reload in this case, and we are not performing a dependency call, URL parameters win over optios in the form 120 * and have been not recorded yet in the AJAX method manager. 121 * 122 * @return array 123 * 124 * @uses self.extract_url_query_parameters 125 * 126 * @since 2.1 127 */ 128 129 self.get_extra_url_query_parameters_by_form = function( form ) { 130 var query_string = self.extract_url_query_parameters( window.location.search.substr( 1 ) ), 131 data = {}, 132 force_from_form = ! ( form.hasClass( 'js-wpv-dps-enabled' ) 133 || form.hasClass( 'js-wpv-ajax-results-enabled' ) 134 || form.hasClass( 'js-wpv-ajax-results-submit-enabled' ) 135 ); 136 for ( var prop in query_string ) { 137 if ( 138 query_string.hasOwnProperty( prop ) 139 && ! data.hasOwnProperty( prop ) 140 && ( 141 force_from_form 142 || form.find( '[name="' + prop + '"], [name="' + prop + '\\[\\]"]' ).length === 0 143 ) 144 ) { 145 data[ prop ] = query_string[ prop ]; 146 } 147 } 148 return data; 149 }; 150 151 /** 152 * set_extra_url_query_parameters 153 * 154 * Forces the current URL query parameters in a form, but only those that do not belong to the form already. 155 * 156 * @uses self.extract_url_query_parameters 157 * 158 * @since 2.1 159 */ 160 161 self.set_extra_url_query_parameters_by_form = function( form ) { 162 var extra = self.get_extra_url_query_parameters_by_form( form ); 163 $.each( extra, function( key, value ) { 164 if ( form.find( '[name="' + key + '"], [name="' + key + '\\[\\]"]' ).length === 0 ) { 165 // @hack alert!! WE can not avoid this :-( 166 var pieces = value.split( '##URLARRAYVALHACK##' ), 167 pieces_length = pieces.length; 168 if ( pieces_length < 2 ) { 169 $( '<input>' ).attr({ 170 type: 'hidden', 171 name: key, 172 value: value 173 }) 174 .appendTo( form ); 175 } else { 176 for ( var iter = 0; iter < pieces_length; iter++ ) { 177 $( '<input>' ).attr({ 178 type: 'hidden', 179 name: key + "[]", 180 value: pieces[iter] 181 }) 182 .appendTo( form ); 183 } 184 } 185 } 186 }); 187 }; 188 189 /** 190 * Dynamically load the Toolset datepicker style, only when needed. 191 * 192 * @note we should do the same with mediaelement and wp-mediaelement 193 * @note the handle for this used to be wptoolset-field-datepicker 194 * 195 * @since 2.3.0 196 */ 197 198 self.maybe_load_datepicker_style = function() { 199 200 if ( ! self.is_datepicker_style_loaded ) { 201 202 if ( document.getElementById( self.datepicker_style_id ) ) { 203 204 self.is_datepicker_style_loaded = true; 205 206 } else { 207 208 var head = document.getElementsByTagName( 'head' )[0], 209 link = document.createElement( 'link' ); 210 211 link.id = self.datepicker_style_id; 212 link.rel = 'stylesheet'; 213 link.type = 'text/css'; 214 link.href = wpv_pagination_local.datepicker_style_url; 215 link.media = 'all'; 216 head.appendChild( link ); 217 218 self.is_datepicker_style_loaded = true; 219 220 } 221 222 } 223 224 }; 225 226 /** 227 * Destroy all initialized datepickers in the page, before doing changes and initializing them again. 228 * 229 * @since 2.3.0 230 */ 231 232 self.destroy_frontend_datepicker = function() { 233 234 $( ".js-wpv-frontend-datepicker.js-wpv-frontend-datepicker-inited" ) 235 .removeClass( 'js-wpv-frontend-datepicker-inited' ) 236 .datepicker( "destroy" ); 237 238 }; 239 240 /** 241 * render_frontend_datepicker 242 * 243 * Adds a datepicker to a selector but only if it has not been added before. 244 * 245 * Fired on document.ready, after AJAX pagination and after AJAX parametric search events. 246 * 247 * @since 1.9 248 */ 249 250 self.render_frontend_datepicker = function() { 251 $( '.js-wpv-frontend-datepicker:not(.js-wpv-frontend-datepicker-inited)' ).each( function() { 252 self.maybe_load_datepicker_style(); 253 var thiz = $( this ); 254 thiz 255 .addClass( 'js-wpv-frontend-datepicker-inited' ) 256 .datepicker({ 257 onSelect: function( dateText, inst ) { 258 var url_param = thiz.data( 'param' ), 259 data = 'date=' + dateText, 260 form = thiz.closest( 'form' ); 261 data += '&date-format=' + $( '.js-wpv-date-param-' + url_param + '-format' ).val(); 262 data += '&action=wpv_format_date'; 263 $.post( wpv_pagination_local.front_ajaxurl, data, function( response ) { 264 response = $.parseJSON( response ); 265 form.find('.js-wpv-date-param-' + url_param ).html( response['display'] ); 266 form.find('.js-wpv-date-front-end-clear-' + url_param ).show(); 267 form.find('.js-wpv-date-param-' + url_param + '-value' ).val( response['timestamp'] ).trigger( 'change' ); 268 }); 269 }, 270 dateFormat: 'ddmmyy', 271 minDate: wpv_pagination_local.datepicker_min_date, 272 maxDate: wpv_pagination_local.datepicker_max_date, 273 showOn: "button", 274 buttonImage: wpv_pagination_local.calendar_image, 275 buttonText: wpv_pagination_local.calendar_text, 276 buttonImageOnly: true, 277 changeMonth: true, 278 changeYear: true 279 }); 280 }); 281 }; 282 283 /** 284 * clone_form 285 * 286 * Clones a form using the fixed clone() method that covers select and textarea elements 287 * 288 * @param object fil 289 * @param array targets 290 * 291 * @since 1.9 292 */ 293 294 self.clone_form = function( fil, targets ) { 295 var cloned = fil.wpv_clone(); 296 targets.each( function() { 297 $( this ).replaceWith( cloned ); 298 }); 299 }; 300 301 /** 302 * render_frontend_media_shortcodes 303 * 304 * Render the WordPress media players for items inside a container. 305 *
306 * @param object container 307 * 308 * @since 1.9 309 */ 310 311 self.render_frontend_media_shortcodes = function( container ) { 312 container.find( '.wp-audio-shortcode, .wp-video-shortcode' ).each( function() { 313 var thiz = $( this ); 314 thiz.mediaelementplayer(); 315 }); 316 container.find( '.wp-playlist' ).each( function() { 317 var thiz = $( this ); 318 return new WPPlaylistView({ el: this }); 319 }); 320 }; 321 322 /** 323 * get_form_element_type 324 * 325 * Get a form element type, be it text, radio, checkbox, textarea or select 326 * 327 * @param selector A jQuery selector object 328 * 329 * @return string 'text'|'radio'|'checkbox'|'textarea'|'select'|empty if selector is empty 330 * 331 * @since 2.2 332 */ 333 334 self.get_form_element_type = function( selector ) { 335 if ( selector.length > 0 ) { 336 return selector[0].tagName == "INPUT" ? selector[0].type.toLowerCase() : selector[0].tagName.toLowerCase(); 337 } else { 338 return ''; 339 } 340 } 341 342 self.get_hidden_item_width = function( item ) { 343 var item_clone = item 344 .clone() 345 .css({ 346 'display': 'block', 347 'visibility': 'visible', 348 'position': 'absolute', 349 'z-index': '-99999', 350 'left': '99999999px', 351 'top': '0px', 352 'white-space': 'nowrap' 353 }) 354 .appendTo( 'body' ), 355 width = item_clone.outerWidth(); 356 item_clone.remove(); 357 return width; 358 }; 359 360 // ------------------------------------ 361 // Get updated results 362 // ------------------------------------ 363 364 /** 365 * get_updated_query_results 366 * 367 * Shared method for paginating Views and WordPress Archives, and also for parametric search on both. 368 * Returns a promise so you can operate on the response at will. 369 * 370 * Note that it applis the current form regardless it being submitted or not. 371 * @todo we might want to avoid adding that data when the form contains unsubmitted changes. 372 * 373 * @param view_number The object hash 374 * @param page The page that we want to get 375 * @param form The form to track changes against 376 * @param expect 'form'|'full'|'both' Whether to return the full View, just the form, or both 377 * 378 * @since 2.1 379 */ 380 381 self.get_updated_query_results = function( view_number, page, form, expect ) { 382 var data = {}, 383 sort = {}, 384 environment = {}, 385 search = {}, 386 extra = {}. 387 attributes = {}, 388 lang = ( typeof icl_lang == 'undefined' ) ? false : icl_lang, 389 parametric_data = form.data( 'parametric' ); 390 391 sort = WPViews.view_sorting.get_sort_data( view_number, form ); 392 393 if ( parametric_data['environment'].current_post_id > 0 ) { 394 environment['wpv_aux_current_post_id'] = parametric_data['environment'].current_post_id; 395 } 396 if ( parametric_data['environment'].parent_post_id > 0 ) { 397 environment['wpv_aux_parent_post_id'] = parametric_data['environment'].parent_post_id; 398 } 399 if ( parametric_data['environment'].parent_term_id > 0 ) { 400 environment['wpv_aux_parent_term_id'] = parametric_data['environment'].parent_term_id; 401 } 402 if ( parametric_data['environment'].parent_user_id > 0 ) { 403 environment['wpv_aux_parent_user_id'] = parametric_data['environment'].parent_user_id; 404 } 405 406 environment['archive'] = parametric_data['environment'].archive; 407 408 if ( form.find( '.js-wpv-post-relationship-update' ).length ) { 409 search['dps_pr'] = form.find( '.js-wpv-post-relationship-update' ).serializeArray(); 410 } 411 if ( 412 form.hasClass( 'js-wpv-dps-enabled' ) 413 || form.hasClass( 'js-wpv-ajax-results-enabled' ) 414 || form.hasClass( 'js-wpv-ajax-results-submit-enabled' ) 415 ) { 416 search['dps_general'] = form.find( '.js-wpv-filter-trigger, .js-wpv-filter-trigger-delayed' ).serializeArray(); 417 } 418 419 attributes = parametric_data['attributes']; 420 421 extra = self.get_extra_url_query_parameters_by_form( form ); 422 423 data = { 424 'view_number': view_number, 425 page: page, 426 sort: sort, 427 attributes: attributes, 428 environment: environment, 429 search: search, 430 extra: extra, 431 expect: expect 432 }; 433 434 if ( lang ) { 435 data['lang'] = lang; 436 } 437 438 switch ( parametric_data.query ) { 439 case 'archive': 440 data['action'] = 'wpv_get_archive_query_results'; 441 data['loop'] = parametric_data.loop; 442 break; 443 default: 444 data['action'] = 'wpv_get_view_query_results'; 445 data['id'] = parametric_data.id; 446 if ( form.attr( 'data-targetid' ) ) { 447 data['target_id'] = form.data( 'targetid' ); 448 } else if ( $( '.js-wpv-form-only.js-wpv-filter-form-' + view_number ).length > 0 ) { 449 data['target_id'] = $( '.js-wpv-form-only.js-wpv-filter-form-' + view_number ).data( 'targetid' ); 450 } 451 data['wpv_view_widget_id'] = parametric_data['widget_id']; 452 break; 453 } 454 return $.ajax({ 455 type: "POST", 456 dataType: "json", 457 url: wpv_pagination_local.front_ajaxurl, 458 data: data 459 }); 460 }; 461 462 /** 463 * Add, update or remove query string argument. 464 * 465 * @param key {string} Argument name 466 * @param value {string} Argument value. Not supplying a value will remove the parameter, supplying one will 467 * add/update the argument. 468 * @param url {string} The URL. If no URL is supplied, it will be grabbed from window.location 469 * @return string The updated URL. 470 * @link http://stackoverflow.com/a/11654596/3191395 471 * 472 * @since 2.3 473 */ 474 self.updateUrlQuery = function(key, value, url) { 475 if(!url) { 476 url = window.location.href; 477 } 478 var re = new RegExp("([?&])" + key + "=.*?(&|#|$)(.*)", "gi"); 479 var hash; 480 if (re.test(url)) { 481 if (typeof value !== 'undefined' && value !== null) { 482 return url.replace(re, '$1' + key + "=" + value + '$2$3'); 483 } else { 484 hash = url.split('#'); 485 url = hash[0].replace(re, '$1$3').replace(/(&|\?)$/, ''); 486 if(typeof hash[1] !== 'undefined' && hash[1] !== null) { 487 url += '#' + hash[1]; 488 } 489 return url; 490 } 491 } else { 492 if (typeof value !== 'undefined' && value !== null) { 493 var separator = url.indexOf('?') !== -1 ? '&' : '?'; 494 hash = url.split('#'); 495 url = hash[0] + separator + key + '=' + value; 496 if (typeof hash[1] !== 'undefined' && hash[1] !== null) { 497 url += '#' + hash[1]; 498 } 499 return url; 500 } else { 501 return url; 502 } 503 } 504 }; 505 506 // ------------------------------------ 507 // Events 508 // ------------------------------------ 509 510 /** 511 * Window resize event 512 * 513 * Make Views layouts responsive 514 * 515 * @since 1.9
516 * @since 1.11 added debounce 517 */ 518 519 $( window ).on( 'resize', _.debounce( 520 function() { 521 $( '.js-wpv-layout-responsive' ).each( function() { 522 $( this ).css( 'width', '' ); 523 }) 524 .promise() 525 .done( function() { 526 $( document ).trigger( 'js_event_wpv_layout_responsive_resize_completed' ); 527 }); 528 }, 529 wpv_pagination_local.resize_debounce_tolerance 530 )); 531 532 // ------------------------------------ 533 // Init 534 // ------------------------------------ 535 536 self.init = function() { 537 self.render_frontend_datepicker(); 538 }; 539 540 self.init(); 541 542}; 543 544WPViews.ViewSorting = function( $ ) { 545 546 var self = this; 547 548 /** 549 * Get the sort data for a given View. 550 * 551 * @note If the current orderby option does not have an orderby_as option and does not match the stored option, 552 * we remove (we empty) that value so it gets sorted as a native, string value. 553 * 554 * @since 2.3.0 555 */ 556 self.get_sort_data = function( view_number, form ) { 557 var sort = {}, 558 parametric_data = form.data( 'parametric' ); 559 560 sort['wpv_sort_orderby'] = parametric_data['sort']['orderby']; 561 sort['wpv_sort_order'] = parametric_data['sort']['order']; 562 sort['wpv_sort_orderby_as'] = parametric_data['sort']['orderby_as']; 563 sort['wpv_sort_orderby_second'] = parametric_data['sort']['orderby_second']; 564 sort['wpv_sort_order_second'] = parametric_data['sort']['order_second']; 565 566 if ( form.find( '.js-wpv-sort-control-orderby' ).length > 0 ) { 567 var orderby_type = WPViews.view_frontend_utils.get_form_element_type( form.find( '.js-wpv-sort-control-orderby' ) ); 568 switch ( orderby_type ) { 569 case 'select': 570 sort['wpv_sort_orderby'] = form.find( '.js-wpv-sort-control-orderby' ).val(); 571 if ( form.find( '.js-wpv-sort-control-orderby option:selected' ).data( 'orderbyas' ) ) { 572 sort['wpv_sort_orderby_as'] = form.find( '.js-wpv-sort-control-orderby option:selected' ).data( 'orderbyas' ); 573 } else if ( sort['wpv_sort_orderby'] != parametric_data['sort']['orderby'] ) { 574 sort['wpv_sort_orderby_as'] = ''; 575 } 576 break; 577 case 'radio': 578 sort['wpv_sort_orderby'] = form.find( '.js-wpv-sort-control-orderby:checked' ).val(); 579 if ( form.find( '.js-wpv-sort-control-orderby:checked' ).data( 'orderbyas' ) ) { 580 sort['wpv_sort_orderby_as'] = form.find( '.js-wpv-sort-control-orderby:checked' ).data( 'orderbyas' ); 581 } else if ( sort['wpv_sort_orderby'] != parametric_data['sort']['orderby'] ) { 582 sort['wpv_sort_orderby_as'] = ''; 583 } 584 break; 585 case 'text': 586 case 'hidden': 587 sort['wpv_sort_orderby'] = form.find( '.js-wpv-sort-control-orderby' ).val(); 588 if ( form.find( '.js-wpv-sort-control-orderby' ).data( 'orderbyas' ) ) { 589 sort['wpv_sort_orderby_as'] = form.find( '.js-wpv-sort-control-orderby' ).data( 'orderbyas' ); 590 } else if ( sort['wpv_sort_orderby'] != parametric_data['sort']['orderby'] ) { 591 sort['wpv_sort_orderby_as'] = ''; 592 } 593 break; 594 } 595 } 596 597 if ( form.find( '.js-wpv-sort-control-order' ).length > 0 ) { 598 var order_type = WPViews.view_frontend_utils.get_form_element_type( form.find( '.js-wpv-sort-control-order' ) ); 599 switch ( order_type ) { 600 case 'select': 601 sort['wpv_sort_order'] = form.find( '.js-wpv-sort-control-order' ).val(); 602 break; 603 case 'radio': 604 sort['wpv_sort_order'] = form.find( '.js-wpv-sort-control-order:checked' ).val(); 605 break; 606 case 'text': 607 case 'hidden': 608 sort['wpv_sort_order'] = form.find( '.js-wpv-sort-control-order' ).val(); 609 break; 610 } 611 } 612 613 if ( 614 '' === sort['wpv_sort_order'] 615 && form.find( '.js-wpv-sort-control-orderby' ).length > 0 616 ) { 617 var order_type = WPViews.view_frontend_utils.get_form_element_type( form.find( '.js-wpv-sort-control-orderby' ) ); 618 switch ( order_type ) { 619 case 'select': 620 sort['wpv_sort_order'] = form.find( '.js-wpv-sort-control-orderby option:selected' ).data( 'forceorder' ); 621 break; 622 case 'radio': 623 sort['wpv_sort_order'] = form.find( '.js-wpv-sort-control-orderby:checked' ).data( 'forceorder' ); 624 break; 625 case 'text': 626 case 'hidden': 627 sort['wpv_sort_order'] = form.find( '.js-wpv-sort-control-orderby' ).data( 'forceorder' ); 628 break; 629 } 630 } 631 632 return sort; 633 } 634 635 /** 636 * Sync the sorting controls used inside and outside of the View form. 637 * 638 * @since 2.3.0 639 * @since 2.3.1 Split into set_sort_data_inside_form and set_sort_data_outside_form. 640 */ 641 self.set_sort_data = function( form, sort ) { 642 self.set_sort_data_inside_form( form, sort ) 643 .set_sort_data_outside_form( form, sort ); 644 return self; 645 }; 646 647 /** 648 * Sync the sorting controls used inside and outside of the View form for the case of paginating while the View is 649 * already sorted. 650 * 651 * @since 2.5.2 652 */ 653 self.set_sort_data_for_pagination = function ( form ) { 654 var sort = {}, 655 parametric_data = form.data( 'parametric' );; 656 657 if ( form.find( '.js-wpv-sort-control-orderby' ).length > 0 ) { 658 var orderby_type = WPViews.view_frontend_utils.get_form_element_type( form.find( '.js-wpv-sort-control-orderby' ) ); 659 switch ( orderby_type ) { 660 case 'select': 661 sort['orderby'] = form.find( '.js-wpv-sort-control-orderby' ).val(); 662 if ( form.find( '.js-wpv-sort-control-orderby option:selected' ).data( 'orderbyas' ) ) { 663 sort['orderby_as'] = form.find( '.js-wpv-sort-control-orderby option:selected' ).data( 'orderbyas' ); 664 } else if ( sort['orderby'] != parametric_data['sort']['orderby'] ) { 665 sort['orderby_as'] = ''; 666 } 667 668 if ( form.find( '.js-wpv-sort-control-orderby option:selected' ).data( 'forceorder' ) ) { 669 sort['order'] = form.find( '.js-wpv-sort-control-orderby option:selected' ).data( 'forceorder' ); 670 } 671 break; 672 case 'radio': 673 sort['orderby'] = form.find( '.js-wpv-sort-control-orderby:checked' ).val(); 674 if ( form.find( '.js-wpv-sort-control-orderby:checked' ).data( 'orderbyas' ) ) { 675 sort['orderby_as'] = form.find( '.js-wpv-sort-control-orderby:checked' ).data( 'orderbyas' ); 676 } else if ( sort['orderby'] != parametric_data['sort']['orderby'] ) { 677 sort['orderby_as'] = ''; 678 } 679 680 if ( form.find( '.js-wpv-sort-control-orderby:checked' ).data( 'forceorder' ) ) { 681 sort['order'] = form.find( '.js-wpv-sort-control-orderby:checked' ).data( 'forceorder' ); 682 } 683 break; 684 case 'text': 685 case 'hidden': 686 sort['orderby'] = form.find( '.js-wpv-sort-control-orderby' ).val(); 687 if ( form.find( '.js-wpv-sort-control-orderby' ).data( 'orderbyas' ) ) { 688 sort['orderby_as'] = form.find( '.js-wpv-sort-control-orderby' ).data( 'orderbyas' ); 689 } else if ( sort['orderby'] != parametric_data['sort']['orderby'] ) { 690 sort['orderby_as'] = ''; 691 } 692 693 if ( form.find( '.js-wpv-sort-control-orderby' ).data( 'forceorder' ) ) { 694 sort['order'] = form.find( '.js-wpv-sort-control-orderby' ).data( 'forceorder' ); 695 } 696 break; 697 } 698 } 699 self.set_sort_data( form, sort ); 700 }; 701 702 /** 703 * Set the sort data for orderby controls as select dropdowns. 704 * 705 * @since 2.3.1 706 */ 707 self.set_sort_data_orderby_select = function( orderby_control, sort ) { 708 if ( orderby_control.find( 'option[value="' + sort['orderby'] + '"]' ).length == 0 ) { 709 orderby_control.append( $('<option>', { 710 value: sort['orderby'], 711 text: sort['orderby'] 712 })); 713 } 714 orderby_control.val( sort['orderby'] ); 715 if ( _.has( sort, 'orderby_as' ) ) { 716 orderby_control.find( 'option:selected' ) 717 .data( 'orderbyas', sort['orderby_as'] ) 718 .attr( 'data-orderbyas', sort['orderby_as'] ); 719 } 720 return self; 721 }; 722 723 /** 724 * Set the sort data for orderby controls as text or hidden input
724s. 725 * 726 * @since 2.3.1 727 */ 728 self.set_sort_data_orderby_text = function( orderby_control, sort ) { 729 orderby_control.val( sort['orderby'] ); 730 if ( _.has( sort, 'orderby_as' ) ) { 731 orderby_control 732 .data( 'orderbyas', sort['orderby_as'] ) 733 .attr( 'data-orderbyas', sort['orderby_as'] ); 734 } 735 return self; 736 }; 737 738 /** 739 * Set the sort data for orderby controls as radio inputs. 740 * 741 * @note Create a radio input if it does not exist one for the right orderby value. 742 * 743 * @since 2.3.1 744 */ 745 self.set_sort_data_orderby_radio = function( orderby_control, sort, form ) { 746 if ( orderby_control.filter( '[value="' + sort['orderby'] + '"]' ).length == 0 ) { 747 form.append( $('<input>', { 748 type: 'radio', 749 "class": 'js-wpv-sort-control-orderby', 750 name: 'wpv_sort_orderby', 751 value: sort['orderby'] 752 })); 753 } 754 form.find( '.js-wpv-sort-control-orderby[value="' + sort['orderby'] + '"]' ).prop( 'checked', true ); 755 if ( _.has( sort, 'orderby_as' ) ) { 756 form.find( '.js-wpv-sort-control-orderby:checked' ) 757 .data( 'orderbyas', sort['orderby_as'] ) 758 .attr( 'data-orderbyas', sort['orderby_as'] ); 759 } 760 return self; 761 }; 762 763 /** 764 * Set the sort data for orderby controls as radio inputs. 765 * 766 * @note Uncheck all radio inputs if it does not exist one for the right orderby value. 767 * 768 * @since 2.3.1 769 */ 770 self.maybe_set_sort_data_orderby_radio = function( orderby_control, sort ) { 771 if ( orderby_control.filter( '[value="' + sort['orderby'] + '"]' ).length == 0 ) { 772 orderby_control.prop( 'checked', false ); 773 } else { 774 orderby_control.filter( '[value="' + sort['orderby'] + '"]' ).prop( 'checked', true ); 775 if ( _.has( sort, 'orderby_as' ) ) { 776 orderby_control.filter( ':checked' ) 777 .data( 'orderbyas', sort['orderby_as'] ) 778 .attr( 'data-orderbyas', sort['orderby_as'] ); 779 } 780 } 781 return self; 782 }; 783 784 /** 785 * Set the sort data for orderby controls as lists. 786 * 787 * @since 2.3.1 788 */ 789 self.set_sort_data_orderby_list = function( orderby_control, sort ) { 790 var orderby_control_to_set = orderby_control.find( '.js-wpv-sort-list-orderby[data-orderby="' + sort['orderby'] + '"]' ); 791 if ( orderby_control_to_set.length == 0 ) { 792 793 } else { 794 if ( ! orderby_control_to_set.closest( '.js-wpv-sort-list-item' ).hasClass( 'wpv-sort-list-current' ) ) { 795 orderby_control 796 .find( 'span.wpv-sort-list-current' ) 797 .removeClass( 'wpv-sort-list-current' ); 798 orderby_control 799 .find( '.js-wpv-sort-list-item' ) 800 .css( {'display':'none'} ); 801 orderby_control_to_set 802 .closest( '.js-wpv-sort-list-item' ) 803 .addClass( 'wpv-sort-list-current' ) 804 .css( {'display': 'block'} ); 805 orderby_control 806 .find( '.js-wpv-sort-list' ) 807 .prepend( orderby_control_to_set.closest( '.js-wpv-sort-list-item' ) ); 808 } 809 } 810 return self; 811 }; 812 813 /** 814 * Set the sort data for order controls as select dropdowns. 815 * 816 * @since 2.3.1 817 */ 818 self.set_sort_data_order_select = function( order_control, sort ) { 819 if ( order_control.find( 'option[value="' + sort['order'] + '"]' ).length == 0 ) { 820 order_control.append( $('<option>', { 821 value: sort['order'], 822 text: sort['order'] 823 })); 824 } 825 order_control.val( sort['order'] ); 826 if ( 827 _.has( sort, 'orderby' ) 828 && typeof order_control.data('labels') !== 'undefined' 829 ) { 830 // We are setting the order in a command that also sets the orderby, so we need to modify the order labels 831 var order_labels = order_control.data( 'labels' ), 832 order_labels_to_push = {}, 833 orderby_to_check = sort.orderby.toLowerCase(); 834 if ( _.has( order_labels, orderby_to_check ) ) { 835 order_labels_to_push = order_labels[ orderby_to_check ]; 836 } else if ( _.has( order_labels, 'default' ) ) { 837 order_labels_to_push = order_labels[ 'default' ]; 838 } 839 840 if ( _.has( order_labels_to_push, 'asc' ) ) { 841 order_control.find( 'option[value="asc"]' ).html( order_labels_to_push.asc ); 842 } 843 if ( _.has( order_labels_to_push, 'desc' ) ) { 844 order_control.find( 'option[value="desc"]' ).html( order_labels_to_push.desc ); 845 } 846 } 847 return self; 848 }; 849 850 /** 851 * Set the sort data for order controls as text or hidden input
851s. 852 * 853 * @since 2.3.1 854 */ 855 self.set_sort_data_order_text = function( order_control, sort ) { 856 order_control.val( sort['order'] ); 857 return self; 858 }; 859 860 /** 861 * Set the sort data for order controls as radio inputs. 862 * 863 * @note Create a radio input if it does not exist one for the right order value. 864 * 865 * @since 2.3.1 866 */ 867 self.set_sort_data_order_radio = function( order_control, sort, form ) { 868 if ( order_control.filter( '[value="' + sort['order'] + '"]' ).length == 0 ) { 869 form.append( $('<input>', { 870 type: 'radio', 871 "class": 'js-wpv-sort-control-order', 872 name: 'wpv_sort_order', 873 value: sort['order'] 874 })); 875 } 876 form.find( '.js-wpv-sort-control-order[value="' + sort['order'] + '"]' ).prop( 'checked', true ); 877 878 if ( 879 _.has( sort, 'orderby' ) 880 && typeof order_control.data('labels') !== 'undefined' 881 ) { 882 // We are setting the order in a command that also sets the orderby, so we need to modify the order labels 883 var order_labels = order_control.data( 'labels' ), 884 order_labels_to_push = {}, 885 orderby_to_check = sort.orderby.toLowerCase(), 886 label_to_update = null, 887 input_to_keep = null; 888 if ( _.has( order_labels, orderby_to_check ) ) { 889 order_labels_to_push = order_labels[ orderby_to_check ]; 890 } else if ( _.has( order_labels, 'default' ) ) { 891 order_labels_to_push = order_labels[ 'default' ]; 892 } 893 894 if ( _.has( order_labels_to_push, 'asc' ) ) { 895 label_to_update = order_control.filter( '[value="asc"]' ).closest( 'label' ); 896 input_to_keep = order_control.filter( '[value="asc"]' ).detach(); 897 898 label_to_update 899 .html( order_labels_to_push.asc ) 900 .prepend( input_to_keep ); 901 } 902 if ( _.has( order_labels_to_push, 'desc' ) ) { 903 label_to_update = order_control.filter( '[value="desc"]' ).closest( 'label' ); 904 input_to_keep = order_control.filter( '[value="desc"]' ).detach(); 905 906 label_to_update 907 .html( order_labels_to_push.desc ) 908 .prepend( input_to_keep ); 909 } 910 } 911 return self; 912 }; 913 914 /** 915 * Set the sort data for order controls as radio inputs. 916 * 917 * @note Uncheck all radio inputs if it does not exist one for the right order value. 918 * 919 * @since 2.3.1 920 */ 921 self.maybe_set_sort_data_order_radio = function( order_control, sort ) { 922 if ( order_control.filter( '[value="' + sort['order'] + '"]' ).length == 0 ) { 923 order_control.prop( 'checked', true ); 924 } else { 925 order_control.filter( '[value="' + sort['order'] + '"]' ).prop( 'checked', true ); 926 } 927 return self; 928 }; 929 930 /** 931 * Set the sort data for order controls as lists. 932 * 933 * @since 2.3.1 934 */ 935 self.set_sort_data_order_list = function( order_control, sort ) { 936 var order_control_to_set = order_control.find( '.js-wpv-sort-list-order[data-order="' + sort['order'] + '"]' ); 937 if ( order_control_to_set.length == 0 ) { 938 939 } else { 940 if ( ! order_control_to_set.closest( '.js-wpv-sort-list-item' ).hasClass( 'wpv-sort-list-current' ) ) { 941 order_control 942 .find( 'span.wpv-sort-list-current' ) 943 .removeClass( 'wpv-sort-list-current' ); 944 order_control 945 .find( '.js-wpv-sort-list-item' ) 946 .css( {'display':'none'} ); 947 order_control_to_set 948 .closest( '.js-wpv-sort-list-item' ) 949 .addClass( 'wpv-sort-list-current' ) 950 .css( {'display': 'block'} ); 951 order_control 952 .find( '.js-wpv-sort-list' ) 953 .prepend( order_control_to_set.closest( '.js-wpv-sort-list-item' ) ); 954 } 955 } 956 if ( 957 _.has( sort, 'orderby' ) 958 && typeof order_control.data('labels') !== 'undefined' 959 ) { 960 // We are setting the order in a command that also sets the orderby, so we need to modify the order labels 961 var order_labels = order_control.data( 'labels' ), 962 order_labels_to_push = {}, 963 orderby_to_check = sort.orderby.toLowerCase(), 964 width_update_needed = false; 965 if ( _.has( order_labels, orderby_to_check ) ) { 966 order_labels_to_push = order_labels[ orderby_to_check ]; 967 } else if ( _.has( order_labels, 'default' ) ) { 968 order_labels_to_push = order_labels[ 'default' ]; 969 } 970 971 if ( _.has( order_labels_to_push, 'asc' ) ) { 972 order_control.find( '.js-wpv-sort-list-order[data-order="asc"] span' ).html( order_labels_to_push.asc ); 973 width_update_needed = true; 974 } 975 if ( _.has( order_labels_to_push, 'desc' ) ) { 976 order_control.find( '.js-wpv-sort-list-order[data-order="desc"] span' ).html( order_labels_to_push.desc ); 977 width_update_needed = true; 978 } 979 if ( width_update_needed ) { 980 self.adjust_sort_list_width( order_control ); 981 } 982 } 983 return self; 984 }; 985 986 /** 987 * Sync the sorting controls used inside of the View form. 988 * 989 * @since 2.3.1 990 * 991 * @note Setting "orderby_as" demands that "orderby" is also set. 992 */ 993 self.set_sort_data_inside_form = function( form, sort ) { 994 if ( _.has( sort, 'orderby' ) ) { 995 if ( form.find( '.js-wpv-sort-control-orderby' ).length > 0 ) { 996 var orderby_control = form.find( '.js-wpv-sort-control-orderby' ), 997 orderby_type = WPViews.view_frontend_utils.get_form_element_type( orderby_control ); 998 switch ( orderby_type ) { 999 case 'select': 1000 self.set_sort_data_orderby_select( orderby_control, sort ); 1001 break; 1002 case 'text': 1003 case 'hidden': 1004 self.set_sort_data_orderby_text( orderby_control, sort ); 1005 break; 1006 case 'radio': 1007 self.set_sort_data_orderby_radio( orderby_control, sort, form ); 1008 break; 1009 } 1010 } else { 1011 var orderby_attributes = { 1012 type: 'hidden', 1013 "class": 'js-wpv-sort-control-orderby', 1014 name: 'wpv_sort_orderby', 1015 value: sort['orderby'] 1016 }; 1017 if ( _.has( sort, 'orderby_as' ) ) { 1018 orderby_attributes['data-orderbyas'] = sort['orderby_as']; 1019 } 1020 if ( _.has( sort, 'forceorder' ) ) { 1021 orderby_attributes['data-forceorder'] = sort['forceorder']; 1022 } 1023 $( '<input>' ) 1024 .attr( orderby_attributes ) 1025 .appendTo( form ); 1026 } 1027 // We set this as a hidden input for forms that submit with page refresh. 1028 if ( _.has( sort, 'orderby_as' ) ) { 1029 if ( form.find( '.js-wpv-sort-control-orderby-as' ).length > 0 ) { 1030 form.find( '.js-wpv-sort-control-orderby-as' ).remove(); 1031 } 1032 $( '<input>' ) 1033 .attr({ 1034 type: 'hidden', 1035 "class": 'js-wpv-sort-control-orderby-as', 1036 name: 'wpv_sort_orderby_as', 1037 value: sort['orderby_as'] 1038 }) 1039 .appendTo( form ); 1040 } 1041 if ( form.find( '.js-wpv-sort-list-orderby-dropdown' ).length > 0 ) { 1042 var orderby_list_control = form.find( '.js-wpv-sort-list-orderby-dropdown' ); 1043 self.set_sort_data_orderby_list( orderby_list_control, sort ); 1044 } 1045 } 1046 if ( _.has( sort, 'order' ) ) { 1047 if ( form.find( '.js-wpv-sort-control-order' ).length > 0 ) { 1048 var order_control = form.find( '.js-wpv-sort-control-order' ), 1049 order_type = WPViews.view_frontend_utils.get_form_element_type( order_control ); 1050 switch ( order_type ) { 1051 case 'select': 1052 self.set_sort_data_order_select( order_control, sort ); 1053 break; 1054 case 'text': 1055 case 'hidden': 1056 self.set_sort_data_order_text( order_control, sort ); 1057 break; 1058 case 'radio': 1059 self.set_sort_data_order_radio( order_control, sort, form ); 1060 break; 1061 } 1062 } else { 1063 $( '<input>' ) 1064 .attr({ 1065 type: 'hidden', 1066 "class": 'js-wpv-sort-control-order', 1067 name: 'wpv_sort_order', 1068 value: sort['order'] 1069 }) 1070 .appendTo( form ); 1071 } 1072 if ( form.find( '.js-wpv-sort-list-order-dropdown' ).length > 0 ) { 1073 var order_list_control = form.find( '.js-wpv-sort-list-order-dropdown' ); 1074 self.set_sort_data_order_list( order_list_control, sort ); 1075 } 1076 } 1077 return self; 1078 } 1079 1080 /** 1081 * Sync the sorting controls used outside of the View form. 1082 * 1083 * @since 2.3.1 1084 * 1085 * @note Setting "orderby_as" demands that "orderby" is also set. 1086 */ 1087 self.set_sort_data_outside_form = function( form, sort ) { 1088 1089 var view_number = form.data( 'viewnumber' ); 1090 1091 if ( _.has( sort, 'orderby' ) ) { 1092 var extra_orderby = $( '.js-wpv-sort-control-orderby[data-viewnumber="' + view_number + '"]:not(.js-wpv-filter-form .js-wpv-sort-control-orderby)' ),
1093 extra_orderby_list = $( '.js-wpv-sort-list-orderby-dropdown[data-viewnumber="' + view_number + '"]:not(.js-wpv-filter-form .js-wpv-sort-list-orderby-dropdown)' ); 1094 if ( extra_orderby.length > 0 ) { 1095 var orderby_type = WPViews.view_frontend_utils.get_form_element_type( extra_orderby ); 1096 switch ( orderby_type ) { 1097 case 'select': 1098 self.set_sort_data_orderby_select( extra_orderby, sort ); 1099 break; 1100 case 'text': 1101 case 'hidden': 1102 self.set_sort_data_orderby_text( extra_orderby, sort ); 1103 break; 1104 case 'radio': 1105 self.maybe_set_sort_data_orderby_radio( extra_orderby, sort ); 1106 break; 1107 } 1108 } 1109 if ( extra_orderby_list.length > 0 ) { 1110 self.set_sort_data_orderby_list( extra_orderby_list, sort ); 1111 } 1112 } 1113 1114 if ( _.has( sort, 'order' ) ) { 1115 var extra_order = $( '.js-wpv-sort-control-order[data-viewnumber="' + view_number + '"]:not(.js-wpv-filter-form .js-wpv-sort-control-order)' ), 1116 extra_order_list = $( '.js-wpv-sort-list-order-dropdown[data-viewnumber="' + view_number + '"]:not(.js-wpv-filter-form .js-wpv-sort-list-order-dropdown)' ); 1117 if ( extra_order.length > 0 ) { 1118 var order_type = WPViews.view_frontend_utils.get_form_element_type( extra_order ); 1119 switch ( order_type ) { 1120 case 'select': 1121 self.set_sort_data_order_select( extra_order, sort ); 1122 break; 1123 case 'text': 1124 case 'hidden': 1125 self.set_sort_data_order_text( extra_order, sort ); 1126 break; 1127 case 'radio': 1128 self.maybe_set_sort_data_order_radio( extra_order, sort ); 1129 break; 1130 } 1131 } 1132 if ( extra_order_list.length > 0 ) { 1133 self.set_sort_data_order_list( extra_order_list, sort ); 1134 } 1135 } 1136 1137 return self; 1138 1139 }; 1140 1141 // ------------------------------------ 1142 // Sorting links - not implemented yet 1143 // ------------------------------------ 1144 1145 $( document ).on( 'click', '.js-wpv-sort-trigger', function( e ) { 1146 e.preventDefault(); 1147 var thiz = $( this ), 1148 view_number = thiz.data( 'viewnumber' ), 1149 form = $( '.js-wpv-filter-form-' + view_number ), 1150 sort = { 1151 'orderby': ( typeof thiz.data( 'orderby' ) != 'undefined' ) ? thiz.data( 'orderby' ) : '', 1152 'order': ( typeof thiz.data( 'order' ) != 'undefined' ) ? thiz.data( 'order' ) : '', 1153 'orderby_as': ( typeof thiz.data( 'orderbyas' ) != 'undefined' ) ? thiz.data( 'orderbyas' ) : '', 1154 }, 1155 form_each; 1156 form.each( function() { 1157 form_each = $( this ); 1158 self.set_sort_data( form_each, sort ); 1159 WPViews.view_frontend_utils.set_extra_url_query_parameters_by_form( form_each ); 1160 }); 1161 if ( 1162 thiz.hasClass( 'js-wpv-column-header-click' ) 1163 || ( 1164 ! form.hasClass( 'js-wpv-ajax-results-enabled' ) 1165 && ! form.hasClass( 'js-wpv-ajax-results-submit-enabled' ) 1166 ) 1167 ) { 1168 // Backwards compatibility: table sorting does reload the page for sorting 1169 // Also, submit the form for a page reload when the form is not set to load results using AJAX 1170 form.submit(); 1171 } else { 1172 // Elsewhere, trigger a parametric search change, and make sure AJAX is used where due 1173 var data_for_events = { 1174 view_unique_id: view_number, 1175 form: form, 1176 force_results_update: form.hasClass( 'js-wpv-ajax-results-submit-enabled' ) 1177 }; 1178 1179 data_for_events = WPViews.view_parametric_search.extend_wpv_parametric_search_triggered_data( data_for_events ); 1180 1181 $( document ).trigger( 'js_event_wpv_parametric_search_triggered', [ data_for_events ] ); 1182 } 1183 }); 1184 1185 // ------------------------------------ 1186 // Sorting controls 1187 // ------------------------------------ 1188 1189 $( document ).on( 'change', 'select.js-wpv-sort-control-orderby', function() { 1190 1191 var thiz = $( this ), 1192 thiz_selected = thiz.find( ':selected' ), 1193 sort = {}, 1194 view_number = thiz.data( 'viewnumber' ), 1195 form = $( '.js-wpv-filter-form-' + view_number ), 1196 data_for_events = { 1197 view_unique_id: view_number, 1198 form: form 1199 }; 1200 1201 sort[ 'orderby' ] = thiz.val(); 1202 if ( thiz_selected.data( 'orderbyas' ) !== undefined ) { 1203 sort[ 'orderby_as' ] = thiz_selected.data( 'orderbyas' ); 1204 } 1205 if ( 1206 thiz_selected.data( 'forceorder' ) !== undefined 1207 && thiz_selected.data( 'forceorder' ) !== '' 1208 ) { 1209 sort[ 'order' ] = thiz_selected.data( 'forceorder' ); 1210 } 1211 1212 self.set_sort_data( form, sort ); 1213 1214 wpv_stop_rollover[ view_number ] = true; 1215 1216 data_for_events = WPViews.view_parametric_search.extend_wpv_parametric_search_triggered_data( data_for_events ); 1217 1218 $( document ).trigger( 'js_event_wpv_parametric_search_triggered', [ data_for_events ] ); 1219 1220 }); 1221 1222 $( document ).on( 'change', 'input.js-wpv-sort-control-orderby', function() { 1223 1224 var thiz = $( this ), 1225 sort = {}, 1226 view_number = thiz.data( 'viewnumber' ), 1227 sort_control = $( '.js-wpv-sort-control-orderby[data-viewnumber="' + view_number + '"]:checked' ), 1228 form = $( '.js-wpv-filter-form-' + view_number ), 1229 data_for_events = { 1230 view_unique_id: view_number, 1231 form: form 1232 }; 1233
1234 sort[ 'orderby' ] = sort_control.val(); 1235 if ( sort_control.data( 'orderbyas' ) !== undefined ) { 1236 sort[ 'orderby_as' ] = sort_control.data( 'orderbyas' ); 1237 } 1238 if ( 1239 sort_control.data( 'forceorder' ) !== undefined 1240 && sort_control.data( 'forceorder' ) !== '' 1241 ) { 1242 sort[ 'order' ] = sort_control.data( 'forceorder' ); 1243 } 1244 1245 self.set_sort_data( form, sort ); 1246 1247 wpv_stop_rollover[ view_number ] = true; 1248 1249 data_for_events = WPViews.view_parametric_search.extend_wpv_parametric_search_triggered_data( data_for_events ); 1250 1251 $( document ).trigger( 'js_event_wpv_parametric_search_triggered', [ data_for_events ] ); 1252 1253 }); 1254 1255 $( document ).on( 'click', '.js-wpv-sort-list-orderby', function( e ) { 1256 e.preventDefault(); 1257 var orderby_link = $( this ), 1258 orderby = orderby_link.data( 'orderby' ), 1259 orderby_as = orderby_link.data( 'orderbyas' ), 1260 orderby_order = orderby_link.data( 'forceorder' ), 1261 orderby_list = orderby_link.closest( '.wpv-sort-list' ), 1262 orderby_list_item = orderby_link.closest( 'span.js-wpv-sort-list-item' ), 1263 view_number = orderby_link.data( 'viewnumber' ), 1264 form = $( '.js-wpv-filter-form-' + view_number ), 1265 sort = { 1266 'orderby': orderby, 1267 'orderby_as': orderby_as 1268 }, 1269 data_for_events = { 1270 view_unique_id: view_number, 1271 form: form 1272 }; 1273 1274 1275 if ( orderby_list_item.hasClass( 'wpv-sort-list-current' ) ) { 1276 return; 1277 } 1278 1279 orderby_list 1280 .find( 'span.wpv-sort-list-current' ) 1281 .removeClass( 'wpv-sort-list-current' ); 1282 orderby_list 1283 .find( '.js-wpv-sort-list-item' ) 1284 .css( {'display':'none'} ); 1285 orderby_list_item 1286 .addClass( 'wpv-sort-list-current' ) 1287 .css( {'display': 'block'} ); 1288 orderby_list.prepend( orderby_list_item ); 1289 1290 if ( orderby_order !== '' ) { 1291 sort[ 'order' ] = orderby_order; 1292 } 1293 1294 self.set_sort_data( form, sort ); 1295 1296 wpv_stop_rollover[ view_number ] = true; 1297 1298 data_for_events = WPViews.view_parametric_search.extend_wpv_parametric_search_triggered_data( data_for_events ); 1299 1300 $( document ).trigger( 'js_event_wpv_parametric_search_triggered', [ data_for_events ] ); 1301 1302 }); 1303 1304 $( document ).on( 'change', 'select.js-wpv-sort-control-order', function() { 1305 1306 var thiz = $( this ), 1307 sort = {}, 1308 view_number = thiz.data( 'viewnumber' ), 1309 form = $( '.js-wpv-filter-form-' + view_number ), 1310 data_for_events = { 1311 view_unique_id: view_number, 1312 form: form 1313 }; 1314 1315 sort[ 'order' ] = thiz.val(); 1316 1317 self.set_sort_data( form, sort ); 1318 1319 wpv_stop_rollover[ view_number ] = true; 1320 1321 data_for_events = WPViews.view_parametric_search.extend_wpv_parametric_search_triggered_data( data_for_events ); 1322 1323 $( document ).trigger( 'js_event_wpv_parametric_search_triggered', [ data_for_events ] ); 1324 1325 }); 1326 1327 $( document ).on( 'change', 'input.js-wpv-sort-control-order', function() { 1328 1329 var thiz = $( this ), 1330 sort = {}, 1331 view_number = thiz.data( 'viewnumber' ), 1332 sort_control = $( '.js-wpv-sort-control-order[data-viewnumber="' + view_number + '"]:checked' ), 1333 form = $( '.js-wpv-filter-form-' + view_number ), 1334 data_for_events = { 1335 view_unique_id: view_number, 1336 form: form 1337 }; 1338 1339 sort[ 'order' ] = sort_control.val(); 1340 1341 self.set_sort_data( form, sort ); 1342 1343 wpv_stop_rollover[ view_number ] = true; 1344 1345 data_for_events = WPViews.view_parametric_search.extend_wpv_parametric_search_triggered_data( data_for_events ); 1346 1347 $( document ).trigger( 'js_event_wpv_parametric_search_triggered', [ data_for_events ] ); 1348 1349 }); 1350 1351 $( document ).on( 'click', '.js-wpv-sort-list-order', function( e ) { 1352 e.preventDefault(); 1353 var order_link = $( this ), 1354 order = order_link.data( 'order' ), 1355 order_list = order_link.closest( '.wpv-sort-list' ), 1356 order_list_item = order_link.closest( 'span.js-wpv-sort-list-item' ), 1357 view_number = order_link.data( 'viewnumber' ), 1358 form = $( '.js-wpv-filter-form-' + view_number ), 1359 sort = { 1360 'order': order 1361 }, 1362 data_for_events = { 1363 view_unique_id: view_number, 1364 form: form 1365 }; 1366 1367 1368 if ( order_list_item.hasClass( 'wpv-sort-list-current' ) ) { 1369 return; 1370 } 1371 1372 order_list 1373 .find( 'span.wpv-sort-list-current' ) 1374 .removeClass( 'wpv-sort-list-current' ); 1375 order_list 1376 .find( '.js-wpv-sort-list-item' ) 1377 .css( {'display':'none'} ); 1378 order_list_item 1379 .addClass( 'wpv-sort-list-current' ) 1380 .css( {'display': 'block'} ); 1381 order_list.prepend( order_list_item ); 1382 1383 self.set_sort_data( form, sort ); 1384 1385 wpv_stop_rollover[ view_number ] = true; 1386 1387 data_for_events = WPViews.view_parametric_search.extend_wpv_parametric_search_triggered_data( data_for_events ); 1388 1389 $( document ).trigger( 'js_event_wpv_parametric_search_triggered', [ data_for_events ] ); 1390 1391 }); 1392 1393 $( document ).on( 'mouseenter', '.js-wpv-sort-list-dropdown', function() { 1394 var orderby_list = $( this ); 1395 orderby_list 1396 .find( '.js-wpv-sort-list-item' ) 1397 .css( {'display': 'block'} ); 1398 }); 1399 1400 $( document ).on( 'mouseleave', '.js-wpv-sort-list-dropdown', function() { 1401 var orderby_list = $( this ); 1402 orderby_list 1403 .find( '.js-wpv-sort-list-item:not(.wpv-sort-list-current)' ) 1404 .css( {'display': 'none'} ); 1405 }); 1406 1407 // @todo calculate inital width and height of the container and also maybe re-calculate height on selection 1408 1409 self.init_sort_list_width = function( selector ) { 1410 /* 1411 selector 1412 .find( '.js-wpv-sort-list-dropdown' ) 1413 .each( function() { 1414 var sort_list = $( this ), 1415 sort_list_width = 0, 1416 sort_list_items = sort_list.find( '.js-wpv-sort-list-item' ), 1417 sort_list_anchors = sort_list.find( '.wpv-sort-list-anchor' ); 1418 sort_list_anchors.each( function() { 1419 var item_width = WPViews.view_frontend_utils.get_hidden_item_width( $( this ) ); 1420 if ( item_width > sort_list_width ) { 1421 sort_list_width = item_width; 1422 } 1423 }); 1424 sort_list.css( { 'width': sort_list_width + 'em' } ); 1425 sort_list_items.css( { 'width': sort_list_width + 'em' } ); 1426 }); 1427 */ 1428 }; 1429 1430 /** 1431 * Adjust the sort list width to span at least its length in "em" units. 1432 * 1433 * @note When the length is less than 10 units, add an extra one for the toggle icon. 1434 * 1435 * @since 2.3.1 1436 */ 1437 self.adjust_sort_list_width = function( selector ) { 1438 var sort_list = selector, 1439 sort_list_width = 0, 1440 sort_list_items = sort_list.find( '.js-wpv-sort-list-item' ), 1441 sort_list_anchors = sort_list.find( '.wpv-sort-list-anchor span' ); 1442 1443 sort_list_anchors.each( function() { 1444 var item_width = $( this ).text().length; 1445 if ( item_width > sort_list_width ) { 1446 sort_list_width = item_width; 1447 } 1448 }); 1449 sort_list_width = ( sort_list_width < 10 ) ? sort_list_width + 1 : sort_list_width; 1450 sort_list.css( { 'width': sort_list_width + 'em' } ); 1451 sort_list_items.css( { 'width': sort_list_width + 'em' } ); 1452 }; 1453 1454 /** 1455 * Initialize sorting data for special cass: 1456 * - When the sorting controls are of type 'list'. 1457 * - When the sorting controls are of type 'dropdown' or 'radio', but are located outside of their related form. 1458 * In those cases, there are no real sorting control elements inside the form, so we need to manually add them. 1459 * 1460 * @param selector The DOM object where this should be run, helps to narrow down on AJAX related operations. 1461 * 1462 * @since 2.3.0 1463 *
1464 * @todo Check whether we need to initialize the order coming from "forceorder" attributes in orderby controlos. 1465 */ 1466 self.maybe_init_sort_data = function( selector ) { 1467 1468 // Init sort data for sort list controls, as they do not add proper form input elements 1469 selector.find( '.js-wpv-sort-list-dropdown' ).each( function() { 1470 var sorting_list = $( this ), 1471 sorting_list_type = sorting_list.hasClass( 'wpv-sort-list-orderby-dropdown' ) ? 'orderby' : 'order'; 1472 1473 switch ( sorting_list_type ) { 1474 case 'orderby': 1475 var sorting_current = sorting_list.find( '.wpv-sort-list-current .js-wpv-sort-list-orderby' ), 1476 sorting_viewnumber = sorting_current.data( 'viewnumber' ), 1477 sorting_form = $( '.js-wpv-filter-form-' + sorting_viewnumber ), 1478 sorting_data = { 1479 orderby: sorting_current.data( 'orderby' ), 1480 orderby_as: sorting_current.data( 'orderbyas' ), 1481 forceorder: sorting_current.data( 'forceorder' ) 1482 }; 1483 1484 self.set_sort_data( sorting_form, sorting_data ); 1485 break; 1486 case 'order': 1487 var sorting_current = sorting_list.find( '.wpv-sort-list-current .js-wpv-sort-list-order' ), 1488 sorting_viewnumber = sorting_current.data( 'viewnumber' ), 1489 sorting_form = $( '.js-wpv-filter-form-' + sorting_viewnumber ), 1490 sorting_data = { 1491 order: sorting_current.data( 'order' ), 1492 }; 1493 1494 self.set_sort_data( sorting_form, sorting_data ); 1495 break; 1496 } 1497 }); 1498 1499 // Init sort data for dropdowns or radios that are rendered outside their proper form 1500 selector.find( 'select.js-wpv-sort-control-orderby' ).each( function() { 1501 var sorting_control = $( this ); 1502 if ( sorting_control.closest( '.js-wpv-filter-form' ).length == 0 ) { 1503 var sorting_viewnumber = sorting_control.data( 'viewnumber' ), 1504 sorting_form = $( '.js-wpv-filter-form-' + sorting_viewnumber ), 1505 sorting_data = { 1506 orderby: sorting_control.val() 1507 }; 1508 1509 if ( sorting_control.find( ':selected' ).data( 'orderbyas' ) !== undefined ) { 1510 sorting_data[ 'orderby_as' ] = sorting_control.find( ':selected' ).data( 'orderbyas' ); 1511 } 1512 1513 self.set_sort_data( sorting_form, sorting_data ); 1514 } 1515 }); 1516 selector.find( 'select.js-wpv-sort-control-order' ).each( function() { 1517 var sorting_control = $( this ); 1518 if ( sorting_control.closest( '.js-wpv-filter-form' ).length == 0 ) { 1519 var sorting_viewnumber = sorting_control.data( 'viewnumber' ), 1520 sorting_form = $( '.js-wpv-filter-form-' + sorting_viewnumber ), 1521 sorting_data = { 1522 order: sorting_control.val() 1523 }; 1524 1525 self.set_sort_data( sorting_form, sorting_data ); 1526 } 1527 }); 1528 selector.find( 'input.js-wpv-sort-control-orderby:checked' ).each( function() { 1529 var sorting_control = $( this ); 1530 if ( sorting_control.closest( '.js-wpv-filter-form' ).length == 0 ) { 1531 var sorting_viewnumber = sorting_control.data( 'viewnumber' ), 1532 sorting_form = $( '.js-wpv-filter-form-' + sorting_viewnumber ), 1533 sorting_data = { 1534 orderby: sorting_control.val() 1535 }; 1536 1537 if ( sorting_control.data( 'orderbyas' ) !== undefined ) { 1538 sorting_data[ 'orderby_as' ] = sorting_control.data( 'orderbyas' ); 1539 } 1540 1541 self.set_sort_data( sorting_form, sorting_data ); 1542 } 1543 }); 1544 selector.find( 'input.js-wpv-sort-control-order:checked' ).each( function() { 1545 var sorting_control = $( this ); 1546 if ( sorting_control.closest( '.js-wpv-filter-form' ).length == 0 ) { 1547 var sorting_viewnumber = sorting_control.data( 'viewnumber' ), 1548 sorting_form = $( '.js-wpv-filter-form-' + sorting_viewnumber ), 1549 sorting_data = { 1550 order: sorting_control.val() 1551 }; 1552 1553 self.set_sort_data( sorting_form, sorting_data ); 1554 } 1555 }); 1556 1557 }; 1558 1559 $( document ).on( 'js_event_wpv_pagination_completed', function( event, data ) { 1560 //self.init_sort_list_width( data.layout ); 1561 self.maybe_init_sort_data( data.layout ); 1562 if ( data.filter ) { 1563 self.maybe_init_sort_data( data.filter ); 1564 } 1565 }); 1566 1567 $( document ).on( 'js_event_wpv_parametric_search_form_updated', function( event, data ) { 1568 //self.init_sort_list_width( data.view_changed_form ); 1569 self.maybe_init_sort_data( data.view_changed_form ); 1570 }); 1571 1572 $( document ).on( 'js_event_wpv_parametric_search_results_updated', function( event, data ) { 1573 //self.init_sort_list_width( data.layout ); 1574 self.maybe_init_sort_data( data.layout ); 1575 }); 1576 1577 // ------------------------------------ 1578 // Init 1579 // ------------------------------------ 1580 1581 self.init = function() { 1582 //self.init_sort_list_width( $( 'body' ) ); 1583 self.maybe_init_sort_data( $( 'body' ) ); 1584 }; 1585 1586 self.init(); 1587 1588}; 1589 1590WPViews.ViewPagination = function( $ ) { 1591 1592 // ------------------------------------ 1593 // Constants and variables 1594 // ------------------------------------ 1595 1596 var self = this; 1597 1598 self.rollover_running = []; 1599 self.rollover_stopped = []; 1600 self.rollover_paused = []; 1601 1602 self.init_rollover_timing_fired = false;
1603 1604 self.pagination_queue = {}; 1605 1606 self.pagination_effects = {}; 1607 self.pagination_effects_conditions = {}; 1608 self.pagination_effects_spinner = {}; 1609 self.paged_views = {}; 1610 self.paged_views_initial_page = {}; 1611 1612 self.last_paginated_view = []; 1613 self.paginated_history_reach = 0; 1614 self.add_paginated_history = true; 1615 self.pagination_effect_state_push = [ 'fade', 'slidev', 'slideh' ]; 1616 self.pagination_effect_state_replace = []; 1617 self.pagination_effect_state_keep = [ 'infinite' ]; 1618 1619 self.init_scrolling_event_fired = false; 1620 1621 self.slide_data_defaults = { 1622 view_number: '', 1623 page: 0, 1624 max_pages: 0, 1625 speed: 500, 1626 next: true, 1627 effect: 'fade', 1628 response: null, 1629 wpvPaginatorFilter: null, 1630 wpvPaginatorLayout: null, 1631 responseFilter: null, 1632 responseView: null, 1633 callback_next_func: WPViews.view_frontend_utils.just_return 1634 }; 1635 1636 self.pagination_doing_ajax = []; 1637 1638 // ------------------------------------ 1639 // Methods 1640 // ------------------------------------ 1641 1642 /** 1643 * add_view_parameters 1644 * 1645 * Add several information to the data used to get pagination pages. 1646 * For example, add column sorting data, parametric search data and parent View data. 1647 * 1648 * @since 1.9 1649 * @since 2.1 Deprecated 1650 */ 1651 1652 self.add_view_parameters = function( data, page, view_number ) { 1653 var this_form = $( 'form.js-wpv-filter-form-' + view_number ), 1654 this_prelements = this_form.find( '.js-wpv-post-relationship-update' ), 1655 this_form_environment = this_form.data( 'environment' ); 1656 1657 data['action'] = 'wpv_get_page'; 1658 data['page'] = page; 1659 data['view_number'] = view_number; 1660 data['wpv_sort_orderby'] = ( typeof this_form.data( 'orderby' ) != 'undefined' ) ? this_form.data( 'orderby' ) : ''; 1661 data['wpv_sort_order'] = ( typeof this_form.data( 'order' ) != 'undefined' ) ? this_form.data( 'order' ) : ''; 1662 data['wpv_sort_orderby_as'] = ( typeof this_form.data( 'orderbyas' ) != 'undefined' ) ? this_form.data( 'orderbyas' ) : ''; 1663 data['wpv_sort_orderby_second'] = ( typeof this_form.data( 'orderbysecond' ) != 'undefined' ) ? this_form.data( 'orderbysecond' ) : ''; 1664 data['wpv_sort_order_second'] = ( typeof this_form.data( 'ordersecond' ) != 'undefined' ) ? this_form.data( 'ordersecond' ) : ''; 1665 data['wpv_view_widget_id'] = this_form.data( 'viewwidgetid' ); 1666 data['view_hash'] = this_form.data( 'viewhash' ); 1667 data['dps_pr'] = {}; 1668 data['dps_general'] = {}; 1669 1670 if ( this_form_environment.current_post_id > 0 ) { 1671 data['wpv_aux_current_post_id'] = this_form_environment.current_post_id; 1672 } 1673 if ( this_form_environment.parent_post_id > 0 ) { 1674 data['wpv_aux_parent_post_id'] = this_form_environment.parent_post_id; 1675 } 1676 if ( this_form_environment.parent_term_id > 0 ) { 1677 data['wpv_aux_parent_term_id'] = this_form_environment.parent_term_id; 1678 } 1679 if ( this_form_environment.parent_user_id > 0 ) { 1680 data['wpv_aux_parent_user_id'] = this_form_environment.parent_user_id; 1681 } 1682 1683 if ( this_prelements.length ) { 1684 data['dps_pr'] = this_prelements.serializeArray(); 1685 } 1686 if ( this_form.hasClass( 'js-wpv-dps-enabled' ) || this_form.hasClass( 'js-wpv-ajax-results-enabled' ) ) { 1687 data['dps_general'] = this_form.find( '.js-wpv-filter-trigger, .js-wpv-filter-trigger-delayed' ).serializeArray(); 1688 } 1689 1690 return data; 1691 }; 1692 1693 /** 1694 * pagination_preload_pages 1695 * 1696 * Preload pages to a reach. 1697 * 1698 * @param object preload_data 1699 * 1700 * @since 1.9 1701 */ 1702 1703 self.pagination_preload_pages = function( preload_data ) { 1704 var page = parseInt( preload_data.page, 10 ), 1705 max_pages = parseInt( preload_data.max_pages, 10 ), 1706 max_reach = parseInt( preload_data.max_reach, 10 ); 1707 1708 if ( max_reach > max_pages ) { 1709 max_reach = max_pages; 1710 } 1711 1712 if ( preload_data.preload_pages == 'enabled' ) { 1713 var reach = 1; 1714 while ( reach < max_reach ) { 1715 self.pagination_preload_next_page( preload_data.view_number, page, max_pages, reach ); 1716 self.pagination_preload_previous_page( preload_data.view_number, page, max_pages, reach ); 1717 reach++; 1718 } 1719 } 1720 if ( preload_data.cache_pages == 'enabled' ) { 1721 self.pagination_cache_current_page( preload_data.view_number, page ); 1722 } 1723 }; 1724 1725 /** 1726 * pagination_cache_current_page 1727 *
1728 * Cache current page. 1729 * 1730 * @param string view_number 1731 * @param int page 1732 * 1733 * @since 1.9 1734 */ 1735 1736 self.pagination_cache_current_page = function( view_number, page ) { 1737 window.wpvCachedPages[ view_number ] = window.wpvCachedPages[ view_number ] || []; 1738 var current_page_permalink, 1739 content; 1740 icl_lang = ( typeof icl_lang == 'undefined' ) ? false : icl_lang; 1741 if ( ! window.wpvCachedPages[view_number].hasOwnProperty( page ) ) { 1742 WPViews.view_frontend_utils.get_updated_query_results( view_number, page, $( 'form.js-wpv-filter-form-' + view_number ), 'full' ) 1743 .done( function( response ) { 1744 if ( response.success ) { 1745 window.wpvCachedPages[view_number][page] = response.data.full; 1746 content = $( response.data.full ).find( 'img' ); 1747 content.each( function() { 1748 window.wpvCachedImages.push( this.src ); 1749 }); 1750 } 1751 }); 1752 } 1753 }; 1754 1755 /** 1756 * pagination_preload_next_page 1757 * 1758 * Load the next page, or the next one counting "reach" pages. 1759 * 1760 * @param string view_number 1761 * @param int page 1762 * @param int max_pages 1763 * @param int reach 1764 * 1765 * @since 1.9 1766 */ 1767 1768 self.pagination_preload_next_page = function( view_number, page, max_pages, reach ) { 1769 window.wpvCachedPages[ view_number ] = window.wpvCachedPages[ view_number ] || []; 1770 var next_page = page + reach, 1771 content, 1772 current_page_permalink; 1773 icl_lang = ( typeof icl_lang == 'undefined' ) ? false : icl_lang; 1774 if ( ! window.wpvCachedPages[view_number].hasOwnProperty( next_page ) ) { 1775 if ( ( next_page - 1 ) < max_pages ) { 1776 WPViews.view_frontend_utils.get_updated_query_results( view_number, next_page, $( 'form.js-wpv-filter-form-' + view_number ), 'full' ) 1777 .done( function( response ) { 1778 if ( response.success ) { 1779 window.wpvCachedPages[view_number][next_page] = response.data.full; 1780 content = $( response.data.full ).find( 'img' ); 1781 content.each( function() { 1782 window.wpvCachedImages.push( this.src ); 1783 }); 1784 } 1785 }); 1786 } 1787 } 1788 }; 1789 1790 /** 1791 * pagination_preload_previous_page 1792 * 1793 * Load the previous page, or the previous one counting "reach" pages. 1794 * 1795 * @param string view_number 1796 * @param int page 1797 * @param int max_pages 1798 * @param int reach 1799 * 1800 * @since 1.9 1801 */ 1802 1803 self.pagination_preload_previous_page = function(view_number, page, max_pages, reach) { 1804 window.wpvCachedPages[ view_number ] = window.wpvCachedPages[ view_number ] || []; 1805 var previous_page = page - reach, 1806 current_page_permalink, 1807 content; 1808 icl_lang = ( typeof icl_lang == 'undefined' ) ? false : icl_lang; 1809 if ( ! window.wpvCachedPages[view_number].hasOwnProperty( previous_page ) ) { 1810 // LOAD PREVIOUS 1811 if ( ( previous_page + 1 ) > 1 ) { 1812 WPViews.view_frontend_utils.get_updated_query_results( view_number, previous_page, $( 'form.js-wpv-filter-form-' + view_number ), 'full' ) 1813 .done( function( response ) { 1814 if ( response.success ) { 1815 window.wpvCachedPages[view_number][previous_page] = response.data.full; 1816 content = $( response.data.full ).find( 'img' ); 1817 content.each( function() { 1818 window.wpvCachedImages.push( this.src ); 1819 }); 1820 } 1821 }); 1822 } else if ( (previous_page + 1 ) === 1 ) { // LOAD LAST PAGE IF ON FIRST PAGE 1823 WPViews.view_frontend_utils.get_updated_query_results( view_number, max_pages, $( 'form.js-wpv-filter-form-' + view_number ), 'full' ) 1824 .done( function( response ) { 1825 if ( response.success ) { 1826 window.wpvCachedPages[view_number][max_pages] = response.data.full; 1827 window.wpvCachedPages[view_number][0] = response.data.full; 1828 content = $( response.data.full ).find( 'img' ); 1829 content.each( function() { 1830 window.wpvCachedImages.push( this.src ); 1831 }); 1832 } 1833 }); 1834 } 1835 } 1836 }; 1837 1838 /** 1839 * trigger_pagination 1840 * 1841 * Manage the View pagination after a control has been inited 1842 * 1843 * @param string view_number 1844 * @param int page 1845 * 1846 * @since 1.9 1847 */ 1848 1849 self.trigger_pagination = function( view_number, page ) { 1850 if ( ! window.wpvPaginationAnimationFinished.hasOwnProperty( view_number ) ) { 1851 window.wpvPaginationAnimationFinished[ view_number ] = false;
1852 } else if ( window.wpvPaginationAnimationFinished[ view_number ] !== true ) { 1853 if ( ! window.wpvPaginationQueue.hasOwnProperty( view_number ) ) { 1854 window.wpvPaginationQueue[view_number] = []; 1855 } 1856 window.wpvPaginationQueue[ view_number ].push( arguments ); 1857 return; 1858 } 1859 1860 window.wpvPaginationAnimationFinished[ view_number ] = false; 1861 1862 var data = {}, 1863 wpvPaginatorLayout = $( '#wpv-view-layout-' + view_number ), 1864 wpvPaginatorFilter = $( 'form[name="wpv-filter-' + view_number + '"]' ), 1865 speed = 500, 1866 next = true, 1867 paged_view_data = self.get_paged_view( view_number ), 1868 max_reach = parseInt( paged_view_data.preload_reach ) + 1, 1869 callback_next_func = WPViews.view_frontend_utils.just_return, 1870 data_for_get_page, 1871 img; 1872 1873 // Not using AJAX pagination 1874 // For WPAs we just need to adjust the form target and we are done :-) 1875 if ( 1876 paged_view_data.type == 'disabled' 1877 || paged_view_data.type == 'paged' 1878 ) { 1879 1880 switch ( paged_view_data.query ) { 1881 case 'archive': 1882 current_page_permalink = paged_view_data[ 'base_permalink' ].replace( 'WPV_PAGE_NUM', page ); 1883 window.location.replace( current_page_permalink ); 1884 break; 1885 default: 1886 WPViews.view_frontend_utils.set_extra_url_query_parameters_by_form( wpvPaginatorFilter ); 1887 // Adjust the wpv_paged hidden input to the page that we want to show 1888 if ( $( 'input[name="wpv_paged"]' ).length > 0 ) { 1889 $( 'input[name="wpv_paged"]' ).attr( 'value', page ); 1890 } else { 1891 $( '<input>') 1892 .attr({ 1893 type: 'hidden', 1894 name: 'wpv_paged', 1895 value: page 1896 }) 1897 .appendTo( wpvPaginatorFilter ); 1898 } 1899 wpvPaginatorFilter[0].submit(); 1900 break; 1901 } 1902 return; 1903 } 1904 1905 // Using AJAX pagination 1906 1907 if ( paged_view_data.effect in self.pagination_effects_conditions ) { 1908 if ( ! self.pagination_effects_conditions[ paged_view_data.effect ]( paged_view_data, page ) ) { 1909 window.wpvPaginationAnimationFinished[ view_number ] = true; 1910 return; 1911 } 1912 } 1913 1914 window.wpvPaginationAjaxLoaded[view_number] = false; 1915 window.wpvCachedPages[ view_number ] = window.wpvCachedPages[view_number] || []; 1916 1917 if ( this.historyP.hasOwnProperty( view_number ) ) { 1918 next = ( this.historyP[ view_number ] < page ) ? true : false; 1919 } 1920 1921 if ( paged_view_data.callback_next !== '' ) { 1922 callback_next_func = window[ paged_view_data.callback_next ]; 1923 if ( typeof callback_next_func !== "function" ) { 1924 callback_next_func = WPViews.view_frontend_utils.just_return; 1925 } 1926 } 1927 1928 data_for_get_page = { 1929 view_number: view_number, 1930 page: page, 1931 max_pages: parseInt( paged_view_data.max_pages, 10 ), 1932 speed: parseFloat( paged_view_data.duration ), 1933 next: next, 1934 effect: paged_view_data.effect, 1935 wpvPaginatorFilter: wpvPaginatorFilter, 1936 wpvPaginatorLayout: wpvPaginatorLayout, 1937 responseView: null, 1938 callback_next_func: callback_next_func 1939 }; 1940 1941 if ( 1942 window.wpvCachedPages[ view_number ].hasOwnProperty( page ) 1943 ) { 1944 data_for_get_page.response = window.wpvCachedPages[ view_number ][ page ]; 1945 self.prepare_slide( data_for_get_page ); 1946 } else { 1947 // Set loading class 1948 if ( paged_view_data.spinner !== 'disabled' ) { 1949 if ( paged_view_data.effect in self.pagination_effects_spinner ) { 1950 self.pagination_effects_spinner[ paged_view_data.effect ]( view_number, wpvPaginatorLayout ); 1951 } else { 1952 self.pagination_effects_spinner[ 'fade' ]( view_number, wpvPaginatorLayout ); 1953 } 1954 } 1955 WPViews.view_frontend_utils.get_updated_query_results( view_number, page, $( 'form.js-wpv-filter-form-' + view_number ), 'full' ) 1956 .done( function( response ) { 1957 if ( response.success ) { 1958 data_for_get_page.response = response.data.full; 1959 self.prepare_slide( data_for_get_page ); 1960 } 1961 }); 1962 } 1963 self.pagination_preload_pages({ 1964 view_number: view_number, 1965 cache_pages: paged_view_data.cache_pages, 1966 preload_pages: paged_view_data.preload_pages, 1967 page: page, 1968 max_reach: max_reach, 1969 max_pages: paged_view_data.max_pages 1970 }); 1971 this.historyP[ view_number ] = page; 1972 return; 1973 }; 1974 1975 /** 1976 * prepare_slide 1977 * 1978 * Wrap the old layout into a div.wpv_slide_remove and change its ID to ~-response 1979 * Preload images on the new page if needed 1980 * Fire self.pagination_slide 1981 * 1982 * @param object data 1983 * 1984 * @since 1.9 1985 */ 1986 1987 self.prepare_slide = function( data ) { 1988 var slide_data = $.extend( {}, self.slide_data_defaults, data ), 1989 width = slide_data.wpvPaginatorLayout.width(), 1990 outer_width = slide_data.wpvPaginatorLayout.outerWidth(), 1991 height = slide_data.wpvPaginatorLayout.height(), 1992 outer_height = slide_data.wpvPaginatorLayout.outerHeight(), 1993 responseObj = $( '<div></div>' ).append( slide_data.response ), 1994 preloadedImages, 1995 images; 1996 1997 slide_data.responseView = responseObj.find( '.js-wpv-view-layout-' + slide_data.view_number ); 1998 slide_data.responseFilterSelector = responseObj.find( 'form.js-wpv-filter-form-' + slide_data.view_number ); 1999 slide_data.responseFilter = responseObj.find( 'form.js-wpv-filter-form-' + slide_data.view_number ).html(); 2000 slide_data.pagination_page_permalink = slide_data.responseView.data( 'permalink' ); 2001 2002 // Wrap old layout in a div.wpv_slide_remove nd change its ID to ~-response 2003 slide_data.wpvPaginatorLayout 2004 .attr( 'id', 'wpv-view-layout-' + slide_data.view_number + '-response' ) 2005 .wrap( '<div class="wpv_slide_remove" style="width:' + outer_width + 'px;height:' + outer_height + 'px;overflow:hidden;" />' ) 2006 .css( 'width', width ); 2007 // Add an ID attribute to the upcoming new layout, and hide it 2008 slide_data.responseView 2009 .attr( 'id', 'wpv-view-layout-' + slide_data.view_number ) 2010 .css( { 2011 'visibility': 'hidden', 2012 'width': width 2013 } ); 2014
2015 // Preload images if needed 2016 if ( slide_data.wpvPaginatorLayout.hasClass( 'js-wpv-layout-preload-images' ) ) { 2017 preloadedImages = []; 2018 images = slide_data.responseView.find( 'img' ); 2019 if ( images.length < 1 ) { 2020 self.pagination_slide( slide_data ); 2021 } else { 2022 images.one( 'load', function() { 2023 preloadedImages.push( $( this ).attr( 'src' ) ); 2024 if ( preloadedImages.length === images.length ) { 2025 self.pagination_slide( slide_data ); 2026 } 2027 }).each( function() { 2028 $( this ).load(); 2029 }); 2030 } 2031 // Fix inner nested Views with AJAX pagination: the inner View, when preloading images, was rendered with visibility:hidden by default 2032 slide_data.responseView 2033 .find( '.js-wpv-layout-preload-images' ) 2034 .css( 'visibility', 'visible' ); 2035 } else { 2036 self.pagination_slide( slide_data ); 2037 } 2038 }; 2039 2040 /** 2041 * pagination_slide 2042 * 2043 * Routes to the right pagination effect callback 2044 * 2045 * @param object data 2046 * 2047 * @since 1.9 2048 */ 2049 2050 self.pagination_slide = function( data ) { 2051 var slide_data = $.extend( {}, self.slide_data_defaults, data ); 2052 2053 switch ( slide_data.effect ) { 2054 case 'slideleft': 2055 slide_data.next = true; 2056 slide_data.effect = 'slideh'; 2057 break; 2058 case 'slideright': 2059 case 'sliderightforward': 2060 slide_data.next = false; 2061 slide_data.effect = 'slideh'; 2062 break; 2063 case 'slidedown': 2064 case 'slidedownforward': 2065 slide_data.next = false; 2066 slide_data.effect = 'slidev'; 2067 break; 2068 case 'slideup': 2069 slide_data.next = true; 2070 slide_data.effect = 'slidev'; 2071 break; 2072 } 2073 2074 if ( ! slide_data.effect in self.pagination_effects ) { 2075 slide_data.effect = 'fade'; 2076 } 2077 2078 self.pagination_effects[ slide_data.effect ]( slide_data ); 2079 }; 2080 2081 /** 2082 * pagination_queue_trigger 2083 * 2084 * Manage multiple and fast pagination requests. 2085 * 2086 * @param int view_number 2087 * @param boolean next 2088 * @param object wpvPaginatorFilter 2089 * 2090 * @todo why do we pass next and wpvPaginatorFilter here? 2091 * 2092 * @since 1.9 2093 */ 2094 2095 self.pagination_queue_trigger = function( view_number, next, wpvPaginatorFilter ) { 2096 var args, 2097 page, 2098 max_pages; 2099 if ( window.wpvPaginationQueue.hasOwnProperty( view_number ) && window.wpvPaginationQueue[view_number].length > 0 ) { 2100 // when double clicking,we have set window.wpvPaginationQueue[view_number][1] and maybe we could tweak it to change the page number. Maybe checkin historyP 2101 window.wpvPaginationQueue[view_number].sort(); 2102 args = window.wpvPaginationQueue[view_number][0]; 2103 window.wpvPaginationQueue[view_number].splice(0, 1); 2104 page = args[1]; 2105 max_pages = args[4]; 2106 if ( page > max_pages ) { 2107 page = 1; 2108 } else if ( page < 1 ) { 2109 page = max_pages; 2110 } 2111 self.trigger_pagination( view_number, page ); 2112 } 2113 }; 2114 2115 // ------------------------------------ 2116 // Events for Views pagination 2117 // ------------------------------------ 2118 2119 /** 2120 * Manage pagination triggered from prev/next or first/last links 2121 * 2122 * @since 1.9
2123 * @since 2.4.1 Added support for first/last pagination links 2124 */ 2125 2126 $( document ).on( 'click', '.js-wpv-pagination-next-link, .js-wpv-pagination-previous-link, .js-wpv-pagination-first-link, .js-wpv-pagination-last-link', function( e ) { 2127 e.preventDefault(); 2128 var thiz = $( this ), 2129 view_number = thiz.data( 'viewnumber' ), 2130 page = thiz.data( 'page' ), 2131 form = $( '.js-wpv-filter-form-' + view_number ); 2132 2133 WPViews.view_sorting.set_sort_data_for_pagination( form ); 2134 2135 wpv_stop_rollover[ view_number ] = true; 2136 self.trigger_pagination( view_number, page ); 2137 }); 2138 2139 /** 2140 * Manage pagination triggered by a change in the page selector dropdown 2141 * 2142 * @since 1.9 2143 */ 2144 2145 $( document ).on( 'change', '.js-wpv-page-selector', function( e ) { 2146 e.preventDefault(); 2147 var thiz = $( this ), 2148 view_number = thiz.data( 'viewnumber' ), 2149 page = thiz.val(); 2150 wpv_stop_rollover[ view_number ] = true 2151 self.trigger_pagination( view_number, page ); 2152 }); 2153 2154 /** 2155 * Manage pagination triggered by a click on a pagination link. 2156 * 2157 * @since 1.9 2158 * 2159 * @note Safari on iOS might need to also listen to the touchstart event. Investigate this! 2160 */ 2161 2162 $( document ).on( 'click', '.js-wpv-pagination-link', function( e ) { 2163 e.preventDefault(); 2164 var thiz = $( this ), 2165 data_collected = {}; 2166 data_collected.view_number = thiz.data( 'viewnumber'); 2167 data_collected.page = thiz.data( 'page' ); 2168 var i; 2169 // TODO this can be improved: we should not need a loop here at all 2170 // @todo review this, data_collected.max_pages is UNDEFINED 2171 for ( i = 1; i <= data_collected.max_pages; i++ ) { 2172 if ( i === data_collected.page ) { 2173 $( '.js-wpv-page-link-' + data_collected.view_number + '-' + i ).addClass( 'wpv_page_current' ); 2174 } else { 2175 $( '.js-wpv-page-link-' + data_collected.view_number + '-' + i ).removeClass( 'wpv_page_current' ); 2176 } 2177 2178 } 2179 wpv_stop_rollover[ data_collected.view_number ] = true 2180 self.trigger_pagination( data_collected.view_number, data_collected.page ); 2181 }); 2182 2183 /* 2184 $( document ).on( 'click', '.js-wpv-pagination-pause-rollover', function( e ) { 2185 e.preventDefault(); 2186 var view_num = $( this ).data( 'viewnumber' ); 2187 wpv_stop_rollover[view_num] = true; 2188 }); 2189 2190 $( document ).on( 'click', '.js-wpv-pagination-resume-rollover', function( e ) { 2191 e.preventDefault(); 2192 var view_num = $( this ).data( 'viewnumber' ); 2193 delete wpv_stop_rollover[view_num]; 2194 }); 2195 */ 2196 2197 // ------------------------------------ 2198 // Events for WordPress Archives pagination 2199 // ------------------------------------ 2200 2201 /** 2202 * Manage pagination triggered from prev/next and first/last links, and numeric links, including their own prev/next ones 2203 * 2204 * @since 2.1
2205 * @since 2.4.1 Added support for first/last links. 2206 */ 2207 2208 $( document ).on( 'click', '.js-wpv-archive-pagination-link, .js-wpv-archive-pagination-next-link, .js-wpv-archive-pagination-prev-link, .js-wpv-archive-pagination-links-next-link, .js-wpv-archive-pagination-links-prev-link, .js-wpv-archive-pagination-links-first-link, .js-wpv-archive-pagination-links-last-link', function( e ) { 2209 e.preventDefault(); 2210 var thiz = $( this ), 2211 view_number = thiz.data( 'viewnumber' ), 2212 page = thiz.data( 'page' ); 2213 wpv_stop_rollover[ view_number ] = true; 2214 self.trigger_pagination( view_number, page ); 2215 }); 2216 2217 // ------------------------------------ 2218 // Custom events 2219 // ------------------------------------ 2220 2221 /** 2222 * js_event_wpv_pagination_completed 2223 * 2224 * Event fired after a pagination transition has been completed 2225 * 2226 * @param data 2227 * - view_unique_id 2228 * - effect 2229 * - speed 2230 * - layout 2231 * 2232 * @since 1.9 2233 */ 2234 2235 $( document ).on( 'js_event_wpv_pagination_completed', function( event, data ) { 2236 WPViews.view_frontend_utils.render_frontend_media_shortcodes( data.layout ); 2237 WPViews.view_frontend_utils.render_frontend_datepicker(); 2238 // Init pagination for any inner View that might be included inside the new page 2239 self.init_paged_views( data.layout ); 2240 self.init_preload_images( data.layout ); 2241 self.init_preload_pages( data.layout ); 2242 self.init_pagination_button_state(); 2243 }); 2244 2245 $( document ).on( 'js_event_wpv_parametric_search_results_updated', function( event, data ) { 2246 // Init the pagination settings for this View results being updated 2247 self.init_paged_view( data.view_unique_id ); 2248 // Init pagination for any inner View that might be included inside the new page 2249 self.init_paged_views( data.layout ); 2250 self.init_preload_images( data.layout ); 2251 self.init_preload_pages( data.layout ); 2252 }); 2253 2254 // ------------------------------------ 2255 // Init 2256 // ------------------------------------ 2257 2258 /** 2259 * init_effects 2260 * 2261 * Define the default pagination effects, can be extended by third parties. 2262 * Each callback gets the following parameters: 2263 * @param object slide_data 2264 * 2265 * @since 1.11 2266 */ 2267 2268 self.init_effects = function() { 2269 self.pagination_effects = { 2270 infinite: function( slide_data ) { 2271 2272 if ( slide_data.page != ( self.get_paged_view( slide_data.view_number ).page + 1 ) ) { 2273 // This should never happen! See self.pagination_effects_conditions 2274 $( '.js-wpv_slide_loading_img_' + slide_data.view_number ).fadeOut( function() { 2275 $( this ).remove(); 2276 }); 2277 slide_data.wpvPaginatorLayout 2278 .animate( { opacity: 1 }, 300 ) 2279 .unwrap()// If it got here, it has a -response suffix in the ID and is wrapped in an auxiliar div 2280 .attr( 'id', 'wpv-view-layout-' + slide_data.view_number ); 2281 window.wpvPaginationAjaxLoaded[slide_data.view_number] = true; 2282 window.wpvPaginationAnimationFinished[slide_data.view_number] = true; 2283 2284 } else { 2285 2286 // content.match(/<!-- HOOK OPEN -->(W?)\<!-- HOOK CLOSE -->/); 2287 var data_for_events = {}, 2288 data_for_history = {}; 2289 2290 data_for_events.view_unique_id = slide_data.view_number; 2291 data_for_events.effect = 'infinite'; 2292 data_for_events.speed = slide_data.speed; 2293 2294 data_for_history.view_number = slide_data.view_number; 2295 data_for_history.page = slide_data.page; 2296 data_for_history.effect = 'infinite'; 2297 data_for_history.pagination_page_permalink = slide_data.pagination_page_permalink; 2298 2299 if ( 2300 slide_data.wpvPaginatorLayout.find( '.js-wpv-loop' ).length > 0 2301 && slide_data.responseView.find( '.js-wpv-loop' ).length > 0 2302 ) { 2303 slide_data.responseView 2304 .find( '.js-wpv-loop' ) 2305 .children() 2306 .addClass( 'wpv-loop-item-blink' ) 2307 .css( { 'opacity': '0.3' } ); 2308 slide_data.responseView 2309 .find( '.js-wpv-loop' ) 2310 .prepend( 2311 slide_data.wpvPaginatorLayout 2312 .find( '.js-wpv-loop' ) 2313 .html() 2314 ); 2315 slide_data.wpvPaginatorLayout.html( slide_data.responseView.html() ); 2316 slide_data.wpvPaginatorLayout 2317 .find( '.wpv-loop-item-blink' ) 2318 .removeClass( 'wpv-loop-item-blink' ) 2319 .animate( { opacity: 1 }, slide_data.speed ); 2320 2321 } else { 2322 var oldHTML = slide_data.wpvPaginatorLayout.html(), 2323 oldArray = oldHTML.split( '<!-- WPV_Infinite_Scroll -->', 3 ), 2324 oldReplace = ( oldArray.length > 2 ) ? oldArray[1] : ''; 2325 slide_data.wpvPaginatorLayout.html( 2326 slide_data.responseView.html().replace( 2327 '<!-- WPV_Infinite_Scroll_Insert -->', 2328 oldReplace 2329 ) 2330 ); 2331 } 2332 data_for_events.layout = slide_data.wpvPaginatorLayout; 2333 $( '.js-wpv_slide_loading_img_' + slide_data.view_number ).fadeOut( function() { 2334 $( this ).remove(); 2335 }); 2336 slide_data.wpvPaginatorLayout 2337 .unwrap() 2338 .attr( 'id', 'wpv-view-layout-' + slide_data.view_number ) 2339 .animate( { opacity: 1 }, 300, function() { 2340 slide_data.wpvPaginatorFilter.html( slide_data.responseFilter ); 2341 2342 self.get_paged_view( slide_data.view_number ).page = slide_data.page; 2343 2344 window.wpvPaginationAjaxLoaded[slide_data.view_number] = true; 2345 window.wpvPaginationAnimationFinished[slide_data.view_number] = true; 2346 slide_data.callback_next_func(); 2347 self.manage_browser_history( data_for_history ); 2348 $( document ).trigger( 'js_event_wpv_pagination_completed', [ data_for_events ] ); 2349 self.pagination_queue_trigger( slide_data.view_number, slide_data.next, slide_data.wpvPaginatorFilter ); 2350 }); 2351 } 2352 }, 2353 slideh: function( slide_data ) { 2354 var height = slide_data.wpvPaginatorLayout.height(), 2355 old_height = slide_data.wpvPaginatorLayout.outerHeight(), 2356 new_height, 2357 data_for_events = {}, 2358 data_for_history = {}; 2359 2360 data_for_events.view_unique_id = slide_data.view_number; 2361 data_for_events.effect = 'slideh'; 2362 data_for_events.speed = slide_data.speed; 2363 data_for_events.layout = slide_data.responseView; 2364 data_for_events.filter = slide_data.responseFilterSelector; 2365 2366 data_for_history.view_number = slide_data.view_number; 2367 data_for_history.page = slide_data.page; 2368 data_for_history.effect = 'slideh'; 2369 data_for_history.pagination_page_permalink = slide_data.pagination_page_permalink; 2370 2371 if ( slide_data.next === true ) { 2372 slide_data.wpvPaginatorLayout.css( 'float', 'left' ); 2373 slide_data.responseView.css( {"float": "left", "visibility": "visible"} ); 2374 slide_data.wpvPaginatorLayout 2375 .after( slide_data.responseView ) 2376 .parent() 2377 .children() 2378 .wrapAll( '<div style="width:5000px;" />' ); 2379 $( '.js-wpv_slide_loading_img_' + slide_data.view_number ).fadeOut(function() { 2380 $( this ).remove(); 2381 }); 2382 new_height = slide_data.responseView.outerHeight(); 2383 if ( old_height === new_height ) { 2384 slide_data.wpvPaginatorLayout 2385 .parent() 2386 .animate( {marginLeft: '-' + slide_data.wpvPaginatorLayout.outerWidth()+'px'}, slide_data.speed+500, function() { 2387 slide_data.responseView.css( {'position': 'static', 'float': 'none'} ); 2388 slide_data.wpvPaginatorLayout.unwrap().unwrap().remove(); 2389 2390 slide_data.wpvPaginatorFilter.html( slide_data.responseFilter ); 2391 2392 window.wpvPaginationAjaxLoaded[slide_data.view_number] = true; 2393 window.wpvPaginationAnimationFinished[slide_data.view_number] = true; 2394 slide_data.callback_next_func(); 2395 self.manage_browser_history( data_for_history ); 2396 $( document ).trigger( 'js_event_wpv_pagination_completed', [ data_for_events ] ); 2397 self.pagination_queue_trigger( slide_data.view_number, slide_data.next, slide_data.wpvPaginatorFilter ); 2398 }); 2399 } else if ( old_height > new_height ) { 2400 slide_data.wpvPaginatorLayout 2401 .parent() 2402 .animate( {marginLeft: '-' + slide_data.wpvPaginatorLayout.outerWidth()+'px'}, slide_data.speed+500, function() { 2403 slide_data.wpvPaginatorLayout 2404 .parent().parent() 2405 .animate( {height: slide_data.responseView.outerHeight()+'px'}, slide_data.speed/2, function() { 2406 slide_data.responseView.css( {'position': 'static', 'float': 'none'} ); 2407 slide_data.wpvPaginatorLayout.unwrap().unwrap().remove(); 2408 2409 slide_data.wpvPaginatorFilter.html( slide_data.responseFilter ); 2410 2411 window.wpvPaginationAjaxLoaded[slide_data.view_number] = true; 2412 window.wpvPaginationAnimationFinished[slide_data.view_number] = true; 2413 slide_data.callback_next_func(); 2414 self.manage_browser_history( data_for_history ); 2415 $( document ).trigger( 'js_event_wpv_pagination_completed', [ data_for_events ] ); 2416 self.pagination_queue_trigger( slide_data.view_number, slide_data.next, slide_data.wpvPaginatorFilter ); 2417 }); 2418 }); 2419 } else { 2420 slide_data.wpvPaginatorLayout 2421 .parent().parent() 2422 .animate( {height: slide_data.responseView.outerHeight()+'px'}, slide_data.speed/2, function() { 2423 slide_data.wpvPaginatorLayout 2424 .parent() 2425 .animate( {marginLeft: '-' + slide_data.wpvPaginatorLayout.outerWidth()+'px'}, slide_data.speed+500, function() { 2426 slide_data.responseView.css( {'position': 'static', 'float': 'none'} ); 2427 slide_data.wpvPaginatorLayout.unwrap().unwrap().remove(); 2428 2429 slide_data.wpvPaginatorFilter.html( slide_data.responseFilter ); 2430 2431 window.wpvPaginationAjaxLoaded[slide_data.view_number] = true; 2432 window.wpvPaginationAnimationFinished[slide_data.view_number] = true; 2433 slide_data.callback_next_func(); 2434 self.manage_browser_history( data_for_history ); 2435 $( document ).trigger( 'js_event_wpv_pagination_completed', [ data_for_events ] ); 2436 self.pagination_queue_trigger( slide_data.view_number, slide_data.next, slide_data.wpvPaginatorFilter ); 2437 }); 2438 }); 2439 } 2440 } else { 2441 slide_data.wpvPaginatorLayout.css( 'float', 'right' ); 2442 slide_data.responseView.css( {'float': 'right', 'visibility': 'visible'} ); 2443 slide_data.wpvPaginatorLayout 2444 .after( slide_data.responseView ) 2445 .parent() 2446 .children() 2447 .wrapAll( '<div style="height:' + height + ';width:' + ( slide_data.responseView.outerWidth() + slide_data.wpvPaginatorLayout.outerWidth() ) + 'px; margin-left:-' + ( slide_data.wpvPaginatorLayout.outerWidth() ) + 'px;" />' ); 2448 $( '.js-wpv_slide_loading_img_' + slide_data.view_number ).fadeOut( function() { 2449 $( this ).remove(); 2450 }); 2451 new_height = slide_data.responseView.outerHeight(); 2452 if ( old_height === new_height ) { 2453 slide_data.wpvPaginatorLayout 2454 .parent() 2455 .animate( {marginLeft: '0px'}, slide_data.speed+500, function() { 2456 slide_data.responseView.css( {'position': 'static', 'margin': '0px', 'float': 'none'} ); 2457 slide_data.wpvPaginatorLayout.unwrap().unwrap().remove(); 2458 2459 slide_data.wpvPaginatorFilter.html( slide_data.responseFilter ); 2460 2461 window.wpvPaginationAjaxLoaded[slide_data.view_number] = true; 2462 window.wpvPaginationAnimationFinished[slide_data.view_number] = true; 2463 slide_data.callback_next_func(); 2464 self.manage_browser_history( data_for_history ); 2465 $( document ).trigger( 'js_event_wpv_pagination_completed', [ data_for_events ] ); 2466 self.pagination_queue_trigger( slide_data.view_number, slide_data.next, slide_data.wpvPaginatorFilter ); 2467 }); 2468 } else if ( old_height > new_height ) { 2469 slide_data.wpvPaginatorLayout 2470 .parent() 2471 .animate( {marginLeft: '0px'}, slide_data.speed+500, function() { 2472 slide_data.wpvPaginatorLayout 2473 .parent().parent() 2474 .animate( {height: slide_data.responseView.outerHeight()+'px'}, slide_data.speed/2, function() { 2475 slide_data.responseView.css( {'position': 'static', 'margin': '0px', 'float': 'none'} ); 2476 slide_data.wpvPaginatorLayout.unwrap().unwrap().remove(); 2477 2478 slide_data.wpvPaginatorFilter.html( slide_data.responseFilter ); 2479 2480 window.wpvPaginationAjaxLoaded[slide_data.view_number] = true; 2481 window.wpvPaginationAnimationFinished[slide_data.view_number] = true; 2482 slide_data.callback_next_func(); 2483 self.manage_browser_history( data_for_history ); 2484 $( document ).trigger( 'js_event_wpv_pagination_completed', [ data_for_events ] ); 2485 self.pagination_queue_trigger( slide_data.view_number, slide_data.next, slide_data.wpvPaginatorFilter ); 2486 }); 2487 }); 2488 } else { 2489 slide_data.wpvPaginatorLayout 2490 .parent().parent() 2491 .animate( {height: slide_data.responseView.outerHeight()+'px'}, slide_data.speed/2, function() { 2492 slide_data.wpvPaginatorLayout 2493 .parent() 2494 .animate( {marginLeft: '0px'}, slide_data.speed+500, function() { 2495 slide_data.responseView.css( {'position': 'static', 'margin': '0px', 'float': 'none'} ); 2496 slide_data.wpvPaginatorLayout.unwrap().unwrap().remove(); 2497 2498 slide_data.wpvPaginatorFilter.html( slide_data.responseFilter ); 2499 2500 window.wpvPaginationAjaxLoaded[slide_data.view_number] = true; 2501 window.wpvPaginationAnimationFinished[slide_data.view_number] = true; 2502 slide_data.callback_next_func(); 2503 self.manage_browser_history( data_for_history ); 2504 $( document ).trigger( 'js_event_wpv_pagination_completed', [ data_for_events ] ); 2505 self.pagination_queue_trigger( slide_data.view_number, slide_data.next, slide_data.wpvPaginatorFilter ); 2506 }); 2507 }); 2508 } 2509 } 2510 }, 2511 slidev: function( slide_data ) { 2512 var old_height = slide_data.wpvPaginatorLayout.outerHeight(), 2513 new_height, 2514 data_for_events = {}, 2515 data_for_history = {}; 2516 2517 data_for_events.view_unique_id = slide_data.view_number; 2518 data_for_events.effect = 'slidev'; 2519 data_for_events.speed = slide_data.speed; 2520 data_for_events.layout = slide_data.responseView; 2521 data_for_events.filter = slide_data.responseFilterSelector; 2522 2523 data_for_history.view_number = slide_data.view_number; 2524 data_for_history.page = slide_data.page; 2525 data_for_history.effect = 'slidev'; 2526 data_for_history.pagination_page_permalink = slide_data.pagination_page_permalink; 2527 2528 if ( slide_data.next === true ) { 2529 slide_data.responseView.css( 'visibility', 'visible' ); 2530 slide_data.wpvPaginatorLayout 2531 .after( slide_data.responseView ) 2532 .parent() 2533 .children() 2534 .wrapAll( '<div />' ); 2535 $( '.js-wpv_slide_loading_img_' + slide_data.view_number ).fadeOut( function(){ 2536 $( this ).remove(); 2537 }); 2538 new_height = slide_data.responseView.outerHeight(); 2539 if ( old_height === new_height ) { 2540 slide_data.wpvPaginatorLayout 2541 .parent() 2542 .animate( {marginTop: '-' + slide_data.responseView.outerHeight()+'px'}, slide_data.speed+500, function() { 2543 slide_data.responseView.css( {'position': 'static', 'margin': '0px'} ); 2544 slide_data.wpvPaginatorLayout.unwrap().unwrap().remove(); 2545 2546 slide_data.wpvPaginatorFilter.html( slide_data.responseFilter ); 2547 2548 window.wpvPaginationAjaxLoaded[slide_data.view_number] = true; 2549 window.wpvPaginationAnimationFinished[slide_data.view_number] = true; 2550 slide_data.callback_next_func(); 2551 self.manage_browser_history( data_for_history ); 2552 $( document ).trigger( 'js_event_wpv_pagination_completed', [ data_for_events ] ); 2553 self.pagination_queue_trigger( slide_data.view_number, slide_data.next, slide_data.wpvPaginatorFilter ); 2554 }); 2555 } else if ( old_height > new_height ) { 2556 slide_data.wpvPaginatorLayout 2557 .parent() 2558 .animate( {marginTop: '-'+old_height+'px'}, slide_data.speed+500, function() { 2559 slide_data.wpvPaginatorLayout 2560 .parent().parent() 2561 .animate( {height: slide_data.responseView.outerHeight()+'px'}, slide_data.speed/2, function() { 2562 slide_data.responseView.css( {'position': 'static', 'margin': '0px'} ); 2563
2563 slide_data.wpvPaginatorLayout.unwrap().unwrap().remove(); 2564 2565 slide_data.wpvPaginatorFilter.html( slide_data.responseFilter ); 2566 2567 window.wpvPaginationAjaxLoaded[slide_data.view_number] = true; 2568 window.wpvPaginationAnimationFinished[slide_data.view_number] = true; 2569 slide_data.callback_next_func(); 2570 self.manage_browser_history( data_for_history ); 2571 $( document ).trigger( 'js_event_wpv_pagination_completed', [ data_for_events ] ); 2572 self.pagination_queue_trigger( slide_data.view_number, slide_data.next, slide_data.wpvPaginatorFilter ); 2573 }); 2574 }); 2575 } else { 2576 slide_data.wpvPaginatorLayout 2577 .parent().parent() 2578 .animate( {height: slide_data.responseView.outerHeight()+'px'}, slide_data.speed/2, function() { 2579 slide_data.wpvPaginatorLayout 2580 .parent() 2581 .animate( {marginTop: '-'+old_height+'px'}, slide_data.speed+500, function() { 2582 slide_data.responseView.css( {'position': 'static', 'margin': '0px'} ); 2583 slide_data.wpvPaginatorLayout.unwrap().unwrap().remove(); 2584 2585 slide_data.wpvPaginatorFilter.html( slide_data.responseFilter ); 2586 2587 window.wpvPaginationAjaxLoaded[slide_data.view_number] = true; 2588 window.wpvPaginationAnimationFinished[slide_data.view_number] = true; 2589 slide_data.callback_next_func(); 2590 self.manage_browser_history( data_for_history ); 2591 $( document ).trigger( 'js_event_wpv_pagination_completed', [ data_for_events ] ); 2592 self.pagination_queue_trigger( slide_data.view_number, slide_data.next, slide_data.wpvPaginatorFilter ); 2593 }); 2594 }); 2595 } 2596 } else { 2597 slide_data.responseView.css( 'visibility', 'visible' ); 2598 slide_data.wpvPaginatorLayout 2599 .before( slide_data.responseView ) 2600 .parent() 2601 .children() 2602 .wrapAll( '<div />' ); 2603 $( '.js-wpv_slide_loading_img_' + slide_data.view_number ).fadeOut( function() { 2604 $( this ).remove(); 2605 }); 2606 new_height = slide_data.responseView.outerHeight(); 2607 slide_data.wpvPaginatorLayout.parent().css( {'position': 'relative', 'margin-top': '-' + slide_data.responseView.outerHeight() + 'px'} ); 2608 if ( old_height === new_height ) { 2609 slide_data.wpvPaginatorLayout 2610 .parent() 2611 .animate( {marginTop: '0px'}, slide_data.speed+500, function() { 2612 slide_data.responseView.css( {'position': 'static', 'margin': '0px'} ); 2613 slide_data.wpvPaginatorLayout.unwrap().unwrap().remove(); 2614 2615 slide_data.wpvPaginatorFilter.html( slide_data.responseFilter ); 2616 2617 window.wpvPaginationAjaxLoaded[slide_data.view_number] = true; 2618 window.wpvPaginationAnimationFinished[slide_data.view_number] = true; 2619 slide_data.callback_next_func(); 2620 self.manage_browser_history( data_for_history ); 2621 $( document ).trigger( 'js_event_wpv_pagination_completed', [ data_for_events ] ); 2622 self.pagination_queue_trigger( slide_data.view_number, slide_data.next, slide_data.wpvPaginatorFilter ); 2623 }); 2624 } else if ( old_height > new_height ) { 2625 slide_data.wpvPaginatorLayout 2626 .parent() 2627 .animate( {marginTop: '0px'}, slide_data.speed+500, function() { 2628 slide_data.wpvPaginatorLayout 2629 .parent().parent() 2630 .animate( {height: slide_data.responseView.outerHeight()+'px'}, slide_data.speed/2, function() { 2631 slide_data.responseView.css( {'position': 'static', 'margin': '0px'} ); 2632 slide_data.wpvPaginatorLayout.unwrap().unwrap().remove(); 2633 2634 slide_data.wpvPaginatorFilter.html( slide_data.responseFilter ); 2635 2636 window.wpvPaginationAjaxLoaded[slide_data.view_number] = true; 2637 window.wpvPaginationAnimationFinished[slide_data.view_number] = true; 2638 slide_data.callback_next_func(); 2639 self.manage_browser_history( data_for_history ); 2640 $( document ).trigger( 'js_event_wpv_pagination_completed', [ data_for_events ] ); 2641 self.pagination_queue_trigger( slide_data.view_number, slide_data.next, slide_data.wpvPaginatorFilter ); 2642 }); 2643 }); 2644 } else { 2645 slide_data.wpvPaginatorLayout 2646 .parent().parent() 2647 .animate( {height: slide_data.responseView.outerHeight()+'px'}, slide_data.speed/2, function() { 2648 slide_data.wpvPaginatorLayout 2649 .parent() 2650 .animate( {marginTop: '0px'}, slide_data.speed+500, function() { 2651 slide_data.responseView.css( {'position': 'static', 'margin': '0px'} ); 2652 slide_data.wpvPaginatorLayout.unwrap().unwrap().remove(); 2653 2654 slide_data.wpvPaginatorFilter.html( slide_data.responseFilter ); 2655 2656 window.wpvPaginationAjaxLoaded[slide_data.view_number] = true; 2657 window.wpvPaginationAnimationFinished[slide_data.view_number] = true; 2658 slide_data.callback_next_func(); 2659 self.manage_browser_history( data_for_history ); 2660 $( document ).trigger( 'js_event_wpv_pagination_completed', [ data_for_events ] ); 2661 self.pagination_queue_trigger( slide_data.view_number, slide_data.next, slide_data.wpvPaginatorFilter ); 2662 }); 2663 }); 2664 } 2665 } 2666 }, 2667 fade: function( slide_data ) { 2668 var old_height = slide_data.wpvPaginatorLayout.outerHeight(), 2669 new_height, 2670 data_for_events = {}, 2671 data_for_history = {}; 2672 2673 data_for_events.view_unique_id = slide_data.view_number; 2674 data_for_events.effect = 'fade'; 2675 data_for_events.speed = slide_data.speed; 2676 data_for_events.layout = slide_data.responseView; 2677 data_for_events.filter = slide_data.responseFilterSelector; 2678 2679 data_for_history.view_number = slide_data.view_number; 2680 data_for_history.page = slide_data.page; 2681 data_for_history.effect = 'fade'; 2682 data_for_history.pagination_page_permalink = slide_data.pagination_page_permalink; 2683 2684 $( '.js-wpv_slide_loading_img_' + slide_data.view_number ).fadeOut( function() { 2685 $( this ).remove(); 2686 }); 2687 2688 slide_data.wpvPaginatorLayout 2689 .css( {'position': 'absolute', 'z-index': '5'} ) 2690 .after( slide_data.responseView ) 2691 .next() 2692 .css( 'position', 'static' ); 2693 // We need to set a zero timeout here since the above modifications introduce a race condition that produces a wrong new_height 2694 setTimeout( function() { 2695 new_height = slide_data.responseView.outerHeight(); 2696 if ( old_height === new_height ) { 2697 slide_data.wpvPaginatorLayout.fadeOut( slide_data.speed, function() { 2698 slide_data.wpvPaginatorLayout.unwrap().remove(); 2699 2700 slide_data.wpvPaginatorFilter.html( slide_data.responseFilter ); 2701 }); 2702 // In the case when the old height is equal to the new height, we need to perform the fade-out of the old container and the 2703 // fade in of the new container in parallel, at the same time. Even though, UX-wise, this is not 100% correct, this choice 2704 // was made because of some clients complaints. This is due to backwards compatibility 2705 slide_data.responseView 2706 .hide() 2707 .css( 'visibility', 'visible' ) 2708 .fadeIn( slide_data.speed, function() { 2709 window.wpvPaginationAjaxLoaded[slide_data.view_number] = true; 2710 window.wpvPaginationAnimationFinished[slide_data.view_number] = true; 2711 slide_data.callback_next_func(); 2712 self.manage_browser_history( data_for_history ); 2713 $( document ).trigger( 'js_event_wpv_pagination_completed', [ data_for_events ] ); 2714 WPViews.view_pagination.pagination_queue_trigger( slide_data.view_number, slide_data.next, slide_data.wpvPaginatorFilter ); 2715 }); 2716 } else { 2717 slide_data.wpvPaginatorLayout.fadeOut( slide_data.speed, function() { 2718 slide_data.wpvPaginatorLayout 2719 .parent() 2720 .animate( {height: new_height+'px'}, slide_data.speed, function() { 2721 slide_data.wpvPaginatorLayout.unwrap().remove(); 2722 2723 slide_data.wpvPaginatorFilter.html( slide_data.responseFilter ); 2724 2725 slide_data.responseView 2726 .hide() 2727 .css( 'visibility', 'visible' ) 2728 .fadeIn( slide_data.speed, function() { 2729 window.wpvPaginationAjaxLoaded[slide_data.view_number] = true; 2730 window.wpvPaginationAnimationFinished[slide_data.view_number] = true; 2731 slide_data.callback_next_func(); 2732 self.manage_browser_history( data_for_history ); 2733 $( document ).trigger( 'js_event_wpv_pagination_completed', [ data_for_events ] ); 2734 WPViews.view_pagination.pagination_queue_trigger( slide_data.view_number, slide_data.next, slide_data.wpvPaginatorFilter ); 2735 }); 2736 }); 2737 }); 2738 } 2739 }, 0 ); 2740 } 2741 }; 2742 2743 }; 2744 2745 /** 2746 * manage_browser_history 2747 * 2748 * Makes the history in the browser work with AJAX pagination, except infinite scrolling and sliders 2749 * 2750 * @param object data 2751 * 2752 * @since 1.11 2753 */ 2754 2755 self.manage_browser_history = function( data ) { 2756 if ( 2757 self.get_paged_view( data.view_number ).type != 'rollover' 2758 ) { 2759 if ( self.get_paged_view( data.view_number ).manage_history == 'enabled' ) { 2760 if ( self.add_paginated_history == true ) { 2761 if ( ! _.contains( self.pagination_effect_state_keep, data.effect ) ) { 2762 if ( _.contains( self.pagination_effect_state_replace, data.effect ) ) { 2763 history.replaceState( null, '', data.pagination_page_permalink ); 2764 } else { 2765 self.last_paginated_view.push( data.view_number ); 2766 state_obj = { 2767 view_number: data.view_number, 2768 page: data.page 2769 }; 2770 history.pushState( state_obj, '', data.pagination_page_permalink ); 2771 // http://scrollsample.appspot.com/items 2772 // http://html5.gingerhost.com/ 2773 self.paginated_history_reach = self.paginated_history_reach + 1; 2774 } 2775 } 2776 } else { 2777 self.add_paginated_history = true; 2778 } 2779 } 2780 } 2781 }; 2782 2783 /** 2784 * window.onpopstate 2785 * 2786 * Manages the browser back button click based on daya added by Views pagination 2787 * 2788 * @since 1.11 2789 */ 2790 2791 window.onpopstate = function( event ) { 2792 if ( event.state == null ) { 2793 var last_paginated_view_number = self.last_paginated_view.pop(); 2794 if ( last_paginated_view_number != undefined ) { 2795 self.add_paginated_history = false;
2796 self.paged_views_initial_page[ last_paginated_view_number ] = self.paged_views_initial_page[ last_paginated_view_number ] || 1; 2797 self.trigger_pagination( last_paginated_view_number, self.paged_views_initial_page[ last_paginated_view_number ] ); 2798 } 2799 } else { 2800 if ( 2801 _.has( event.state, 'view_number' ) 2802 && _.has( event.state, 'page' ) 2803 ) { 2804 self.add_paginated_history = false; 2805 self.trigger_pagination( event.state.view_number, event.state.page ); 2806 } 2807 } 2808 }; 2809 2810 /** 2811 * When the parametric search with automatic results has been completed, reset the pagination history and add a state with the current URL 2812 * 2813 * @since 1.11 2814 */ 2815 2816 $( document ).on( 'js_event_wpv_parametric_search_results_updated', function( event, data ) { 2817 window.wpvCachedPages[ data.view_unique_id ] = []; 2818 self.last_paginated_view = []; 2819 if ( self.paginated_history_reach > 0 ) { 2820 window.history.go( -Math.abs( self.paginated_history_reach ) ); 2821 self.paginated_history_reach = 0; 2822 } 2823 // HACK! HACK! HACK! 2824 // Chrome and Safari execute history.replaceState before history.go so we end up with a mess 2825 // That is why we need to set a timeout here 2826 // See https://code.google.com/p/chromium/issues/detail?id=529810 2827 setTimeout( function() { 2828 history.replaceState( null, '', data.permalink ); 2829 }, 100 ); 2830 }); 2831 2832 /** 2833 * init_effects_conditions 2834 * 2835 * Lets you define a condition that an effect must meet to be applied, doing nothing otherwise. 2836 * Each callback gets the following parameters: 2837 * @param object view_pagination_data 2838 * @param int page 2839 * 2840 * @since 1.11 2841 */ 2842 2843 self.init_effects_conditions = function() { 2844 self.pagination_effects_conditions = { 2845 infinite: function( view_pagination_data, page ) { 2846 if ( page != ( view_pagination_data.page + 1 ) ) { 2847 return false; 2848 } 2849 return true; 2850 } 2851 }; 2852 }; 2853 2854 /** 2855 * init_effects_conditions 2856 * 2857 * Lets you define a condition that an effect must meet to be applied, doing nothing otherwise. 2858 * Each callback gets the following parameters: 2859 * @param string view_number 2860 * @param object wpvPaginatorLayout 2861 * 2862 * @since 1.11 2863 */ 2864 2865 self.init_effects_spinner = function() { 2866 self.pagination_effects_spinner['fade'] = 2867 self.pagination_effects_spinner['slideleft'] = 2868 self.pagination_effects_spinner['slideright'] = 2869 self.pagination_effects_spinner['sliderightforward'] = 2870 self.pagination_effects_spinner['slideh'] = 2871 self.pagination_effects_spinner['slideup'] = 2872 self.pagination_effects_spinner['slidedown'] = 2873 self.pagination_effects_spinner['slidedownforward'] = 2874 self.pagination_effects_spinner['slidev'] = function( view_number, wpvPaginatorLayout ) { 2875 var img = new Image(); 2876 img.src = self.get_paged_view( view_number ).spinner_image; 2877 img.onload = function() { 2878 var wpvPaginatorLayoutOffset = wpvPaginatorLayout.position(), 2879 wpvPaginatorSpinner = '<div style="' 2880 + 'width:' + img.width + 'px;' 2881 + 'height:' + img.height + 'px;' 2882 + 'border:none;' 2883 + 'background:transparent 50% 50% no-repeat url(' + self.get_paged_view( view_number ).spinner_image + ');' 2884 + 'position:absolute;' 2885 + 'z-index:99;' 2886 + 'top:' + ( Math.round( wpvPaginatorLayoutOffset.top ) + ( Math.round( wpvPaginatorLayout.height()/2 ) ) - ( Math.round( img.height/2 ) ) ) + 'px;' 2887 + 'left:' + ( Math.round( wpvPaginatorLayoutOffset.left ) + ( Math.round( wpvPaginatorLayout.width()/2 ) ) - ( Math.round( img.width/2 ) ) ) + 'px;' 2888 + '" ' 2889 + 'class="wpv_slide_loading_img js-wpv_slide_loading_img_' + view_number + '"' 2890 + '>' 2891 + '</div>'; 2892 wpvPaginatorLayout 2893 .before( wpvPaginatorSpinner ) 2894 .animate( { opacity: 0.5 }, 300 ); 2895 }; 2896 }; 2897 self.pagination_effects_spinner['infinite'] = function( view_number, wpvPaginatorLayout ) { 2898 var img = new Image(); 2899 img.src = self.get_paged_view( view_number ).spinner_image; 2900 img.onload = function() { 2901 var wpvPaginatorLayoutOffset = wpvPaginatorLayout.position(), 2902 wpvPaginatorSpinner = '<div style="' 2903 + 'width:' + img.width + 'px;' 2904 + 'height:' + img.height + 'px;' 2905 + 'border:none;' 2906 + 'background:transparent 50% 50% no-repeat url(' + self.get_paged_view( view_number ).spinner_image + ');' 2907 + 'position:absolute;' 2908 + 'z-index:99;' 2909 + 'top:' + ( Math.round( wpvPaginatorLayoutOffset.top ) + ( wpvPaginatorLayout.height() ) - ( Math.round( img.height/2 ) ) ) + 'px;' 2910 + 'left:' + ( Math.round( wpvPaginatorLayoutOffset.left ) + ( Math.round( wpvPaginatorLayout.width()/2 ) ) - ( Math.round( img.width/2 ) ) ) + 'px;' 2911 + '" ' 2912 + 'class="wpv_slide_loading_img js-wpv_slide_loading_img_' + view_number + '"' 2913 + '>' 2914 + '</div>'; 2915 wpvPaginatorLayout 2916 .before( wpvPaginatorSpinner ) 2917 .animate( { opacity: 0.5 }, 300 ); 2918 }; 2919 }; 2920 }; 2921 2922 /** 2923 * init_paged_views 2924 * 2925 * Gather the data for paginating each of the Views rendered in a page 2926 * 2927 * @since 1.11 2928 */ 2929 2930 self.init_paged_views = function( container ) { 2931 var init_scrolling_event = false, 2932 init_rollover_timing = false;
2933 this.historyP = this.historyP || []; 2934 window.wpvCachedPages = window.wpvCachedPages || []; 2935 window.wpvCachedImages = window.wpvCachedImages || []; 2936 $( '.js-wpv-view-layout', container ).each( function() { 2937 var thiz = $( this ), 2938 view_number = thiz.data( 'viewnumber' ); 2939 self.init_paged_view( view_number ); 2940 if ( 2941 self.paged_views[ view_number ].effect == 'infinite' 2942 && self.paged_views[ view_number ].page == 1 2943 ) { 2944 init_scrolling_event = true; 2945 } 2946 if ( 2947 self.paged_views[ view_number ].type == 'rollover' 2948 && ! wpv_stop_rollover.hasOwnProperty( view_number ) 2949 ) { 2950 init_rollover_timing = true; 2951 rollover_has_index = _.findIndex( self.rollover_running, function( item ) { 2952 return item.view_number == view_number; 2953 }); 2954 if ( rollover_has_index < 0 ) { 2955 // This rollover was not there, so trigger it 2956 var thiz_rollover_data = { 2957 view_number: view_number, 2958 page: 1, 2959 force_reset: false 2960 }; 2961 self.rollover_running.push( thiz_rollover_data ); 2962 if ( self.init_rollover_timing_fired ) { 2963 self.trigger_rollover( thiz_rollover_data ); 2964 } 2965 } else { 2966 self.rollover_running[ rollover_has_index ] = { 2967 view_number: view_number, 2968 page: 1, 2969 force_reset: true 2970 }; 2971 } 2972 } 2973 }); 2974 if ( 2975 ! self.init_scrolling_event_fired 2976 && init_scrolling_event 2977 ) { 2978 self.init_scrolling_event_callback(); 2979 } 2980 2981 if ( 2982 ! self.init_rollover_timing_fired 2983 && init_rollover_timing 2984 ) { 2985 self.init_rollover_timing_callback(); 2986 } 2987 return self; 2988 }; 2989 2990 /** 2991 * init_paged_view 2992 * 2993 * Gather pagination info for a specific View rendered in a page. 2994 * Note that this is also used to init the View pagination data after a parametric search change. 2995 * 2996 * @todo check the existence of $( '#wpv-view-layout-' + view_number ) and set defauls otherwise. 2997 * 2998 * @since 1.11 2999 */ 3000 3001 self.init_paged_view = function( view_number ) { 3002 this.historyP = this.historyP || []; 3003 self.paged_views[ view_number ] = $( '#wpv-view-layout-' + view_number ).data( 'pagination' ); 3004 self.paged_views_initial_page[ view_number ] = self.paged_views[ view_number ].page; 3005 this.historyP[ view_number ] = self.paged_views[ view_number ].page; 3006 window.wpvCachedPages[ view_number ] = []; 3007 if ( 3008 self.paged_views[ view_number ].type != 'disabled' 3009 && self.paged_views[ view_number ].type != 'paged' 3010 && self.paged_views[ view_number ].page > 1 3011 ) { 3012 // Infinite scrolling only can be triggered from the first page - individual URLs can not have that effect 3013 $( '#wpv-view-layout-' + view_number ).removeClass( 'js-wpv-layout-infinite-scrolling' ); 3014 } 3015 if ( $( '#wpv-view-layout-' + view_number ).parents( '.js-wpv-view-layout' ).length > 0 ) { 3016 // Disable history management in inner Views in nested structures 3017 self.paged_views[ view_number ].manage_history = 'disabled'; 3018 } 3019 }; 3020 3021 /** 3022 * Generate the View pagintion data, on demand. 3023 * 3024 * This method will ensure that we can generate the pagination data for a View JIT 3025 * when it is needed for a View which was dynamically added to the page, by a 3026 * third party provider. 3027 * 3028 * @param view_number string The View unique hash. 3029 * 3030 * @since 2.3.1 3031 */ 3032 3033 self.get_paged_view = function( view_number ) { 3034 if ( ! _.has( self.paged_views, view_number ) ) { 3035 self.init_paged_view( view_number ); 3036 } 3037 return self.paged_views[ view_number ]; 3038 } 3039 3040 /** 3041 * is_infinite_triggable 3042 * 3043 * Auxiliar method to check whether the scroll got to a point where a pagination event should be triggered 3044 * 3045 * @param object view_layout 3046 * 3047 * @since 1.11 3048 * @since 2.0 Add a tolerance setting 3049 * @since 2.0 Trigger the pagination when scrolling to the bottom of the page 3050 */ 3051 3052 self.is_infinite_triggable = function( view_layout ) { 3053 var flag_element = view_layout, 3054 view_number = view_layout.data( 'viewnumber' ); 3055 infinite_tolerance = self.get_paged_view( view_number ).infinite_tolerance; 3056 infinite_tolerance = ( isNaN( infinite_tolerance ) ) ? 0 : + infinite_tolerance; 3057 if ( view_layout.find( '.js-wpv-loop' ).length > 0 ) { 3058 flag_element = view_layout.find( '.js-wpv-loop' ); 3059 } 3060 return ( 3061 ( flag_element.offset().top + flag_element.outerHeight() ) <= ( $( window ).scrollTop() + $( window ).height() + infinite_tolerance ) 3062 || ( $( window ).scrollTop() + $(window).height() ) == $( document ).height() 3063 ); 3064 }; 3065 3066 /** 3067 * init_scrolling_event_callback 3068 * 3069 * Init the scrolling event callback, only when there is a View with infinite scrolling in a page 3070 * 3071 * @since 1.11 3072 */ 3073 3074 self.init_scrolling_event_callback = function() { 3075 $( window ).on( 'scroll', _.debounce( 3076 _.throttle( 3077 function() { 3078 $( '.js-wpv-layout-infinite-scrolling' ).each( function() { 3079 var thiz = $( this ), 3080 thiz_view_number = thiz.data( 'viewnumber' ), 3081 thiz_paged_view_data = self.get_paged_view( thiz_view_number ); 3082 if ( 3083 thiz_paged_view_data.page < thiz_paged_view_data.max_pages 3084 && self.is_infinite_triggable( thiz ) 3085 ) { 3086 self.trigger_pagination( thiz_view_number, thiz_paged_view_data.page + 1 ); 3087 } 3088 }); 3089 }, 3090 1000 3091 ),
3092 1000 3093 )); 3094 self.init_scrolling_event_fired = true; 3095 }; 3096 3097 /** 3098 * trigger_rollover 3099 * 3100 * Trigger the rollover on a given View, using timeout 3101 * 3102 * @since 2.2 3103 */ 3104 3105 self.trigger_rollover = function( view_data ) { 3106 var rollover_data = $.extend( {}, { view_number: '', page: 1, force_reset: false }, view_data ), 3107 view_number = rollover_data.view_number, 3108 paged_view_data = self.get_paged_view( view_number ); 3109 3110 if ( 3111 paged_view_data.max_pages > 1 3112 && $("#wpv-view-layout-" + view_number ).length > 0 3113 ) { 3114 setTimeout( function() { 3115 var rollover_index = _.findIndex( self.rollover_paused, function ( item ) { 3116 return item.view_number == view_number; 3117 } ); 3118 if ( self.rollover_paused[ rollover_index ] 3119 && self.rollover_paused[ rollover_index ].view_number 3120 && self.rollover_paused[ rollover_index ].view_number == view_number 3121 ) { 3122 setTimeout( function() { self.trigger_rollover( view_data ) }, 100 ); 3123 } else { 3124 if ( 3125 ! wpv_stop_rollover.hasOwnProperty( view_number ) && 3126 $( "#wpv-view-layout-" + view_number ).length > 0 3127 ) { 3128 // Get native current page and index on the rollovers array 3129 var view_page = rollover_data.page, 3130 rollover_index = _.findIndex( self.rollover_running, function ( item ) { 3131 return item.view_number == view_number; 3132 } ); 3133 // If reset is force, set the current page to 1 and stop the force 3134 if ( self.rollover_running[ rollover_index ].force_reset ) { 3135 self.rollover_running[ rollover_index ].force_reset = false; 3136 view_page = 1; 3137 } 3138 // Calculate the page to rollover to 3139 if ( 3140 paged_view_data.effect === 'slideright' 3141 || paged_view_data.effect === 'slidedown' 3142 ) { 3143 // Note that this was deprecated in 2.2, keep for backwards compatibility 3144 if ( view_page <= 1 ) { 3145 view_page = paged_view_data.max_pages; 3146 } else { 3147 view_page = view_page - 1; 3148 } 3149 } else { 3150 if ( view_page === paged_view_data.max_pages ) { 3151 view_page = 1; 3152 } else { 3153 view_page = view_page + 1; 3154 } 3155 } 3156 // Set the new current page 3157 self.rollover_running[ rollover_index ].page = view_page; 3158 WPViews.view_pagination.trigger_pagination( view_number, view_page ); 3159 } else { 3160 var rollover_index = _.findIndex( self.rollover_running, function ( item ) { 3161 return item.view_number == view_number; 3162 }); 3163 self.rollover_running.splice( rollover_index, 1 ); 3164 } 3165 } 3166 }, paged_view_data.speed * 1000 ); 3167 } else { 3168 var rollover_index = _.findIndex( self.rollover_running, function( item ) { 3169 return item.view_number == view_number; 3170 }); 3171 self.rollover_running.splice( rollover_index, 1 ); 3172 } 3173 }; 3174 3175 /** 3176 * init_rollover_timing_callback 3177 * 3178 * Init the rollover event callback, only when there is a View with rollover in a page 3179 * 3180 * @since 2.2 3181 * @since 2.3 Switched from iterating self.rollover_running to iterating a clone of it 3182 * in order to avoid modification of the iterated array. 3183 */ 3184 3185 self.init_rollover_timing_callback = function() { 3186 // We are cloning the self.rollover_running array and iterating the clone as we want to avoid modifying 3187 // the array that is been iterated. Remember that self.trigger_rollover removes views from the self.rollover_running 3188 // array, that don't need to be initiated as a rollover, for example when the view has only one page of results. 3189 var rollover_running = self.rollover_running.slice(0); 3190 _.each( rollover_running, function( view_data, index, list ) { 3191 self.trigger_rollover( view_data ); 3192 }); 3193 self.init_rollover_timing_fired = true; 3194 }; 3195 3196 $( document ).on( 'js_event_wpv_pagination_completed', function( event, data ) { 3197 if ( 3198 self.get_paged_view( data.view_unique_id ).type == 'rollover' 3199 && ! wpv_stop_rollover.hasOwnProperty( data.view_unique_id ) 3200 ) { 3201 var rollover_index = _.findIndex( self.rollover_running, function( item ) { 3202 return item.view_number == data.view_unique_id; 3203 }); 3204 self.trigger_rollover( self.rollover_running[ rollover_index ] ); 3205 } 3206 }); 3207 3208 $( document ).on( 'js_event_wpv_parametric_search_results_updated', function( event, data ) { 3209 if ( 3210 self.get_paged_view( data.view_unique_id ).type == 'rollover' 3211 && ! wpv_stop_rollover.hasOwnProperty( data.view_unique_id ) 3212 ) { 3213 var rollover_index = _.findIndex( self.rollover_running, function( item ) { 3214 return item.view_number == data.view_unique_id; 3215 }); 3216 self.trigger_rollover( self.rollover_running[ rollover_index ] ); 3217 } 3218 }); 3219 3220 $( document ).on( 'mouseenter', '.js-wpv-view-layout', function() { 3221 var view_number = $( this ).data( 'viewnumber' ); 3222 if ( self.get_paged_view( view_number ).pause_on_hover == 'enabled' ) { 3223 var thiz_rollover_data = { 3224 view_number: view_number, 3225 }; 3226 self.rollover_paused.push( thiz_rollover_data ); 3227 } 3228 3229 }); 3230 3231 $( document ).on( 'mouseleave', '.js-wpv-view-layout', function() { 3232 var view_number = $( this ).data( 'viewnumber' ); 3233 var rollover_index = _.findIndex( self.rollover_paused, function ( item ) { 3234 return item.view_number == view_number; 3235 }); 3236 self.rollover_paused.splice( rollover_index, 1 ); 3237 }); 3238 3239 /** 3240 * pagination_init_preload_images 3241 * 3242 * Init-preload images. 3243 * 3244 * @since 1.9 3245 */ 3246 3247 self.init_preload_images = function( container ) { 3248 $( '.js-wpv-layout-preload-images', container ).css( 'visibility', 'hidden' ); // TODO move it to the CSS file and test 3249 $( '.js-wpv-layout-preload-images', container ).each( function() { 3250 var preloadedImages = [], 3251 element = $( this ),
3252 images = element.find( 'img' ); 3253 if ( images.length < 1 ) { 3254 element.css( 'visibility', 'visible' ); 3255 } else { 3256 images.one( 'load', function() { 3257 preloadedImages.push( $( this ).attr( 'src' ) ); 3258 if ( preloadedImages.length === images.length ) { 3259 element.css( 'visibility', 'visible' ); 3260 } 3261 }).each( function() { 3262 if( this.complete ) { 3263 $( this ).load(); 3264 } 3265 }); 3266 setTimeout( function() { 3267 element.css( 'visibility', 'visible' ); 3268 }, 3000 ); 3269 } 3270 }); 3271 }; 3272 3273 self.init_preload_pages = function( container ) { 3274 $( '.js-wpv-layout-preload-pages', container ).each( function() { 3275 var thiz = $( this ), 3276 view_number = thiz.data( 'viewnumber' ), 3277 paged_view_data = self.get_paged_view( view_number ), 3278 max_pages = parseInt( paged_view_data.max_pages, 10 ), 3279 max_reach = parseInt( paged_view_data.preload_reach, 10 ) + 1; 3280 3281 self.pagination_preload_pages({ 3282 view_number: view_number, 3283 cache_pages: 'disabled', 3284 preload_pages: 'enabled', 3285 page: 1, 3286 max_reach: max_reach, 3287 max_pages: max_pages 3288 }); 3289 }); 3290 }; 3291 3292 /** 3293 * init_pagination_button_state 3294 * 3295 * Initiate the pagination's button state in the case of a Bootstrap pager (only "Previous" and "Next" links) 3296 * 3297 * @since 2.4.0 3298 */ 3299 self.init_pagination_button_state = function() { 3300 $( '.pagination li:not(.disabled,.active)' ).has('span').addClass('disabled'); 3301 $( '.pagination li.page-item:empty' ).remove(); 3302 }; 3303 3304 self.init = function() { 3305 self.init_effects(); 3306 self.init_effects_conditions(); 3307 self.init_effects_spinner(); 3308 // Init Views inside the html 3309 var init_html = $( 'html' ); 3310 self.init_paged_views( init_html ); 3311 self.init_preload_images( init_html ); 3312 self.init_preload_pages( init_html ); 3313 self.init_pagination_button_state(); 3314 } 3315 3316 self.init(); 3317 3318}; 3319 3320WPViews.ViewParametricSearch = function( $ ) { 3321 3322 // ------------------------------------ 3323 // Constants and variables 3324 // ------------------------------------ 3325 3326 var self = this; 3327 3328 // ------------------------------------ 3329 // Methods 3330 // ------------------------------------ 3331 3332 self.manage_update_results = function( data ) { 3333 if ( data.ajax_before !== '' ) { 3334 var ajax_before_func = window[data.ajax_before]; 3335 if ( typeof ajax_before_func === "function" ) { 3336 ajax_before_func( data.view_num ); 3337 } 3338 } 3339 var data_for_events = {}; 3340 data_for_events.view_unique_id = data.view_num; 3341 data_for_events.permalink = data.permalink; 3342 data.layout.fadeOut( 200, function() { 3343 data.layout.html( data.new_layout.html() ) 3344 .attr( 'data-pagination', data.new_layout.attr( 'data-pagination' ) ) 3345 .data( 'pagination', data.new_layout.data( 'pagination' ) ) 3346 .fadeIn( 'fast', function() { 3347 var ajax_after_func = window[data.ajax_after]; 3348 if ( typeof ajax_after_func === "function" ) { 3349 ajax_after_func( data.view_num ); 3350 } 3351 data_for_events.layout = data.layout; 3352 $( document ).trigger( 'js_event_wpv_parametric_search_results_updated', [ data_for_events ] ); 3353 }); 3354 }); 3355 }; 3356 3357 /** 3358 * manage_changed_form 3359 * 3360 * @param settings object 3361 * { 3362 * view_unique_id: string View unique ID 3363 * form: collection Filter jQuery object 3364 * force_form_update: boolean 3365 * update_form boolean Whether the form will be updated, either because forced or native 3366 * force_results_update: boolean 3367 * update_results boolean Whether the results wil be updated, either because forced or native 3368 * }; 3369 * 3370 * @todo Switch .js-wpv-filter-data-for-this-form into a form data attribute that we can init on document.ready and refresh when neeeded 3371 * 3372 * @since 1.9 3373 * @since 2.1 Merge a group of parameters into an object 3374 */ 3375 3376 self.manage_changed_form = function( settings ) { 3377 3378 var fil = settings.form, 3379 view_num = settings.view_unique_id, 3380 lay = $( '#wpv-view-layout-' + view_num ), 3381 full_data = fil.find( '.js-wpv-filter-data-for-this-form' ), 3382 ajax_pre_before = full_data.data( 'ajaxprebefore' ), 3383 view_type = 'full', 3384 additional_forms = $( '.js-wpv-filter-form-' + view_num ).not( fil ), 3385 additional_forms_only, 3386 additional_forms_full, 3387 ajax_get = 'both', 3388 new_content_form, 3389 new_content_form_filter, 3390 new_content_full, 3391 new_content_full_filter, 3392 new_content_full_layout, 3393 spinnerContainer = fil.find( '.js-wpv-dps-spinner' ).add( additional_forms.find( '.js-wpv-dps-spinner' ) ), 3394 spinnerItems = spinnerContainer.length 3395 data_for_events = {}, 3396 data_for_manage_updated_results = {}; 3397 3398 data_for_events.view_unique_id = view_num; 3399 3400 data_for_manage_updated_results.view_num = view_num; 3401 data_for_manage_updated_results.ajax_before = full_data.data( 'ajaxbefore' ); 3402 data_for_manage_updated_results.ajax_after = full_data.data( 'ajaxafter' ); 3403 3404 if ( fil.hasClass( 'js-wpv-form-only' ) ) { 3405 view_type = 'form'; 3406 } 3407 if ( settings.update_form ) { 3408 if ( additional_forms.length > 0 ) { 3409 additional_forms_only = additional_forms.not( '.js-wpv-form-full' ); 3410 additional_forms_full = additional_forms.not( '.js-wpv-form-only' ); 3411 if ( view_type == 'form' ) { 3412 if ( additional_forms_full.length > 0 || settings.update_results ) { 3413 ajax_get = 'both'; 3414 } else { 3415 ajax_get = 'form'; 3416 } 3417 if ( settings.update_results ) { 3418 if ( ajax_pre_before !== '' ) { 3419 var ajax_pre_before_func = window[ajax_pre_before]; 3420 if ( typeof ajax_pre_before_func === "function" ) { 3421 ajax_pre_before_func( view_num ); 3422 } 3423 } 3424 $( document ).trigger( 'js_event_wpv_parametric_search_started', [ data_for_events ] ); 3425 } 3426 if ( spinnerItems ) {// TODO maybe only when updating results 3427 $( spinnerContainer ).fadeIn( 'fast' ); 3428 } 3429 3430 wpv_stop_rollover[ view_num ] = true; 3431 3432 WPViews.view_frontend_utils.get_updated_query_results( view_num, 1, fil, ajax_get ) 3433 .done( function( response ) { 3434 if ( response.success ) { 3435 new_content_form = $( '<div></div>' ).append( response.data.form ); 3436 new_content_full = $( '<div></div>' ).append( response.data.full ); 3437 new_content_form_filter = new_content_form.find( '.js-wpv-filter-form-' + view_num ); 3438 new_content_full_filter = new_content_full.find( '.js-wpv-filter-form-' + view_num ); 3439 new_content_full_layout = new_content_full.find( '.js-wpv-view-layout-' + view_num ); 3440 3441 fil.html( new_content_form_filter.html() ); 3442 WPViews.view_frontend_utils.destroy_frontend_datepicker(); 3443 WPViews.view_frontend_utils.clone_form( fil, additional_forms_only ); 3444 additional_forms_full.each( function() { 3445 $( this ).html( new_content_full_filter.html() ); 3446 }); 3447 data_for_events.view_changed_form = fil; 3448 data_for_events.view_changed_form_additional_forms_only = additional_forms_only; 3449 data_for_events.view_changed_form_additional_forms_full = additional_forms_full; 3450 $( document ).trigger( 'js_event_wpv_parametric_search_form_updated', [ data_for_events ] ); 3451 if ( settings.update_results ) { 3452 data_for_manage_updated_results.layout = lay; 3453 data_for_manage_updated_results.new_layout = new_content_full_layout; 3454 data_for_manage_updated_results.permalink = response.data['parametric_permalink']; 3455 self.manage_update_results( data_for_manage_updated_results ); 3456 } 3457 spinnerContainer.hide(); 3458 } 3459 }); 3460 } else { 3461 if ( additional_forms_only.length > 0 ) { 3462 ajax_get = 'both'; 3463 } else { 3464 ajax_get = 'full'; 3465 } 3466 if ( settings.update_results ) { 3467 if ( ajax_pre_before !== '' ) { 3468 var ajax_pre_before_func = window[ajax_pre_before]; 3469 if ( typeof ajax_pre_before_func === "function" ) { 3470 ajax_pre_before_func( view_num ); 3471 } 3472 } 3473 $( document ).trigger( 'js_event_wpv_parametric_search_started', [ data_for_events ] ); 3474 } 3475 if ( spinnerItems ) {// TODO maybe only when updating results 3476 $( spinnerContainer ).fadeIn( 'fast' ); 3477 } 3478 3479 wpv_stop_rollover[ view_num ] = true; 3480 3481 WPViews.view_frontend_utils.get_updated_query_results( view_num, 1, fil, ajax_get ) 3482 .done( function( response ) { 3483 if ( response.success ) { 3484 new_content_form = $( '<div></div>' ).append( response.data.form ); 3485 new_content_full = $( '<div></div>' ).append( response.data.full ); 3486 new_content_form_filter = new_content_form.find( '.js-wpv-filter-form-' + view_num ); 3487 new_content_full_filter = new_content_full.find( '.js-wpv-filter-form-' + view_num ); 3488 new_content_full_layout = new_content_full.find( '.js-wpv-view-layout-' + view_num ); 3489 3490 fil.html( new_content_full_filter.html() ); 3491 WPViews.view_frontend_utils.destroy_frontend_datepicker(); 3492 WPViews.view_frontend_utils.clone_form( fil, additional_forms_full ); 3493 additional_forms_only.each( function() { 3494 $( this ).html( new_content_form_filter.html() ); 3495 }); 3496 data_for_events.view_changed_form = fil; 3497 data_for_events.view_changed_form_additional_forms_only = additional_forms_only; 3498 data_for_events.view_changed_form_additional_forms_full = additional_forms_full; 3499 $( document ).trigger( 'js_event_wpv_parametric_search_form_updated', [ data_for_events ] ); 3500 if ( settings.update_results ) { 3501 data_for_manage_updated_results.layout = lay; 3502 data_for_manage_updated_results.new_layout = new_content_full_layout; 3503 data_for_manage_updated_results.permalink = response.data['parametric_permalink']; 3504 self.manage_update_results( data_for_manage_updated_results ); 3505 } 3506 spinnerContainer.hide(); 3507 } 3508 }); 3509 } 3510 } else { 3511 if ( view_type == 'form' ) { 3512 if ( settings.update_results ) { 3513 ajax_get = 'both'; 3514 // NOTE this should never happen: 3515 // If change is done on an only-form and there is no extra form, there is no full form thus there is no layout 3516 // WARNING this can be executed on an only-form form from a View with automatic results 3517 // I might want to avoid this branch completely 3518 // NOTE-2 might be a good idea to keep-on-clear// As we might be displaying the layout in non-standard ways 3519 // So keeping the check for lay.length should suffice 3520 3521 } else { 3522 ajax_get = 'form'; 3523 } 3524 3525 if ( settings.update_results ) { 3526 if ( ajax_pre_before !== '' ) { 3527 var ajax_pre_before_func = window[ajax_pre_before]; 3528 if ( typeof ajax_pre_before_func === "function" ) { 3529 ajax_pre_before_func( view_num ); 3530 } 3531 } 3532 $( document ).trigger( 'js_event_wpv_parametric_search_started', [ data_for_events ] ); 3533 } 3534 if ( spinnerItems ) {// TODO maybe only when updating results 3535 $( spinnerContainer ).fadeIn( 'fast' ); 3536 } 3537 3538 wpv_stop_rollover[ view_num ] = true; 3539 3540 WPViews.view_frontend_utils.get_updated_query_results( view_num, 1, fil, ajax_get ) 3541 .done( function( response ) { 3542 if ( response.success ) { 3543 new_content_form = $( '<div></div>' ).append( response.data.form ); 3544 new_content_full = $( '<div></div>' ).append( response.data.full ); 3545 new_content_form_filter = new_content_form.find( '.js-wpv-filter-form-' + view_num ); 3546 //new_content_full_filter = new_content_full.find( '.js-wpv-filter-form' ).html(); 3547 new_content_full_layout = new_content_full.find( '.js-wpv-view-layout-' + view_num ); 3548 fil.html( new_content_form_filter.html() ); 3549 data_for_events.view_changed_form = fil; 3550 data_for_events.view_changed_form_additional_forms_only = additional_forms_only; 3551 data_for_events.view_changed_form_additional_forms_full = additional_forms_full; 3552 $( document ).trigger( 'js_event_wpv_parametric_search_form_updated', [ data_for_events ] ); 3553 if ( settings.update_results ) { 3554 data_for_manage_updated_results.layout = lay; 3555 data_for_manage_updated_results.new_layout = new_content_full_layout; 3556 data_for_manage_updated_results.permalink = response.data['parametric_permalink']; 3557 self.manage_update_results( data_for_manage_updated_results ); 3558 } 3559 spinnerContainer.hide(); 3560 } 3561 }); 3562 } else { 3563 if ( settings.update_results ) { 3564 if ( ajax_pre_before !== '' ) { 3565 var ajax_pre_before_func = window[ajax_pre_before]; 3566 if ( typeof ajax_pre_before_func === "function" ) { 3567 ajax_pre_before_func( view_num ); 3568 } 3569 } 3570 $( document ).trigger( 'js_event_wpv_parametric_search_started', [ data_for_events ] ); 3571 } 3572 if ( spinnerItems ) {// TODO maybe only when updating results 3573 $( spinnerContainer ).fadeIn( 'fast' ); 3574 } 3575 3576 wpv_stop_rollover[ view_num ] = true; 3577 3578 WPViews.view_frontend_utils.get_updated_query_results( view_num, 1, fil, 'full' ) 3579 .done( function( response ) { 3580 if ( response.success ) { 3581 //new_content_form = $( '<div></div>' ).append( ajax_result.form ); 3582 new_content_full = $( '<div></div>' ).append( response.data.full ); 3583 //new_content_form_filter = new_content_form.find( '.js-wpv-filter-form' ).html(); 3584 new_content_full_filter = new_content_full.find( '.js-wpv-filter-form-' + view_num ); 3585 new_content_full_layout = new_content_full.find( '.js-wpv-view-layout-' + view_num ); 3586 fil.html( new_content_full_filter.html() ); 3587 data_for_events.view_changed_form = fil; 3588 data_for_events.view_changed_form_additional_forms_only = additional_forms_only; 3589 data_for_events.view_changed_form_additional_forms_full = additional_forms_full; 3590 $( document ).trigger( 'js_event_wpv_parametric_search_form_updated', [ data_for_events ] ); 3591 if ( settings.update_results ) { 3592 data_for_manage_updated_results.layout = lay; 3593 data_for_manage_updated_results.new_layout = new_content_full_layout; 3594 data_for_manage_updated_results.permalink = response.data['parametric_permalink']; 3595 self.manage_update_results( data_for_manage_updated_results ); 3596 } 3597 spinnerContainer.hide(); 3598 } 3599 }); 3600 } 3601 } 3602 } else { 3603 if ( additional_forms.length > 0 ) { 3604 additional_forms_only = additional_forms.not( '.js-wpv-form-full' ); 3605 additional_forms_full = additional_forms.not( '.js-wpv-form-only' ); 3606 if ( view_type == 'form' ) { 3607 WPViews.view_frontend_utils.destroy_frontend_datepicker(); 3608 WPViews.view_frontend_utils.clone_form( fil, additional_forms_only ); 3609 if ( additional_forms_full.length > 0 || settings.update_results ) { 3610 if ( settings.update_results ) { 3611 if ( ajax_pre_before !== '' ) { 3612 var ajax_pre_before_func = window[ajax_pre_before]; 3613 if ( typeof ajax_pre_before_func === "function" ) { 3614 ajax_pre_before_func( view_num ); 3615 } 3616 } 3617 $( document ).trigger( 'js_event_wpv_parametric_search_started', [ data_for_events ] ); 3618 } 3619 if ( spinnerItems ) {// TODO maybe only when updating results 3620 $( spinnerContainer ).fadeIn( 'fast' ); 3621 } 3622 3623 wpv_stop_rollover[ view_num ] = true; 3624 3625 WPViews.view_frontend_utils.get_updated_query_results( view_num, 1, fil, 'full' ) 3626 .done( function( response ) { 3627 if ( response.success ) { 3628 //new_content_form = $( '<div></div>' ).append( response.data.form ); 3629 new_content_full = $( '<div></div>' ).append( response.data.full ); 3630 //new_content_form_filter = new_content_form.find( '.js-wpv-filter-form' ).html(); 3631 new_content_full_filter = new_content_full.find( '.js-wpv-filter-form-' + view_num ); 3632 new_content_full_layout = new_content_full.find( '.js-wpv-view-layout-' + view_num ); 3633 3634 additional_forms_full.each( function() { 3635 $( this ).html( new_content_full_filter.html() ); 3636 }); 3637 data_for_events.view_changed_form = fil; 3638 data_for_events.view_changed_form_additional_forms_only = additional_forms_only; 3639 data_for_events.view_changed_form_additional_forms_full = additional_forms_full; 3640 $( document ).trigger( 'js_event_wpv_parametric_search_form_updated', [ data_for_events ] ); 3641 if ( settings.update_results ) { 3642 data_for_manage_u
3642pdated_results.layout = lay; 3643 data_for_manage_updated_results.new_layout = new_content_full_layout; 3644 data_for_manage_updated_results.permalink = response.data['parametric_permalink']; 3645 self.manage_update_results( data_for_manage_updated_results ); 3646 } 3647 spinnerContainer.hide(); 3648 } 3649 }); 3650 } else { 3651 data_for_events.view_changed_form = fil; 3652 data_for_events.view_changed_form_additional_forms_only = additional_forms_only; 3653 data_for_events.view_changed_form_additional_forms_full = additional_forms_full; 3654 $( document ).trigger( 'js_event_wpv_parametric_search_form_updated', [ data_for_events ] ); 3655 } 3656 } else { 3657 WPViews.view_frontend_utils.destroy_frontend_datepicker(); 3658 WPViews.view_frontend_utils.clone_form( fil, additional_forms_full ); 3659 WPViews.view_frontend_utils.render_frontend_datepicker(); 3660 if ( additional_forms_only.length > 0 || settings.update_results ) { 3661 if ( additional_forms_only.length > 0 ) { 3662 ajax_get = 'both'; 3663 } else { 3664 ajax_get = 'full'; 3665 } 3666 3667 if ( settings.update_results ) { 3668 if ( ajax_pre_before !== '' ) { 3669 var ajax_pre_before_func = window[ajax_pre_before]; 3670 if ( typeof ajax_pre_before_func === "function" ) { 3671 ajax_pre_before_func( view_num ); 3672 } 3673 } 3674 $( document ).trigger( 'js_event_wpv_parametric_search_started', [ data_for_events ] ); 3675 } 3676 if ( spinnerItems ) {// TODO maybe only when updating results 3677 $( spinnerContainer ).fadeIn( 'fast' ); 3678 } 3679 3680 wpv_stop_rollover[ view_num ] = true; 3681 3682 WPViews.view_frontend_utils.get_updated_query_results( view_num, 1, fil, ajax_get ) 3683 .done( function( response ) { 3684 if ( response.success ) { 3685 new_content_form = $( '<div></div>' ).append( response.data.form ); 3686 new_content_full = $( '<div></div>' ).append( response.data.full ); 3687 new_content_form_filter = new_content_form.find( '.js-wpv-filter-form-' + view_num ); 3688 //new_content_full_filter = new_content_full.find( '.js-wpv-filter-form' ).html(); 3689 new_content_full_layout = new_content_full.find( '.js-wpv-view-layout-' + view_num ); 3690 additional_forms_only.each( function() { 3691 $( this ).html( new_content_form_filter.html() ); 3692 }); 3693 data_for_events.view_changed_form = fil; 3694 data_for_events.view_changed_form_additional_forms_only = additional_forms_only; 3695 data_for_events.view_changed_form_additional_forms_full = additional_forms_full; 3696 $( document ).trigger( 'js_event_wpv_parametric_search_form_updated', [ data_for_events ] ); 3697 if ( settings.update_results ) { 3698 data_for_manage_updated_results.layout = lay; 3699 data_for_manage_updated_results.new_layout = new_content_full_layout; 3700 data_for_manage_updated_results.permalink = response.data['parametric_permalink']; 3701 self.manage_update_results( data_for_manage_updated_results ); 3702 } 3703 spinnerContainer.hide(); 3704 } 3705 }); 3706 } 3707 } 3708 } else { 3709 if ( settings.update_results ) { 3710 if ( ajax_pre_before !== '' ) { 3711 var ajax_pre_before_func = window[ajax_pre_before]; 3712 if ( typeof ajax_pre_before_func === "function" ) { 3713 ajax_pre_before_func( view_num ); 3714 } 3715 } 3716 $( document ).trigger( 'js_event_wpv_parametric_search_started', [ data_for_events ] ); 3717 if ( spinnerItems ) {// TODO maybe only when updating results 3718 $( spinnerContainer ).fadeIn( 'fast' ); 3719 } 3720 3721 wpv_stop_rollover[ view_num ] = true; 3722 3723 WPViews.view_frontend_utils.get_updated_query_results( view_num, 1, fil, 'full' ) 3724 .done( function( response ) { 3725 if ( response.success ) { 3726 //new_content_form = $( '<div></div>' ).append( response.data.form ); 3727 new_content_full = $( '<div></div>' ).append( response.data.full ); 3728 //new_content_form_filter = new_content_form.find( '.js-wpv-filter-form' ).html(); 3729 //new_content_full_filter = new_content_full.find( '.js-wpv-filter-form' ).html(); 3730 new_content_full_layout = new_content_full.find( '.js-wpv-view-layout-' + view_num ); 3731 data_for_manage_updated_results.layout = lay; 3732 data_for_manage_updated_results.new_layout = new_content_full_layout; 3733 data_for_manage_updated_results.permalink = response.data['parametric_permalink']; 3734 self.manage_update_results( data_for_manage_updated_results ); 3735 spinnerContainer.hide(); 3736 } 3737 }); 3738 } 3739 } 3740 } 3741 }; 3742 3743 /** 3744 * Normalize the data passed to the js_event_wpv_parametric_search_triggered event. 3745 * 3746 * @para data Object 3747 * { 3748 * view_unique_id: string View unique ID 3749 * form: collection Filter jQuery object 3750 * force_form_update: boolean Optional 3751 * force_results_update: boolean Optional 3752 * }; 3753 * 3754 * @return settings Object 3755 * { 3756 * view_unique_id: string View unique ID 3757 * form: collection Filter jQuery object 3758 * force_form_update: boolean 3759 * update_form boolean Whether the form will be updated, either because forced or native 3760 * force_results_update: boolean 3761 * update_results boolean Whether the results wil be updated, either because forced or native 3762 * }; 3763 * 3764 * @since 2.1 3765 */ 3766 3767 self.extend_wpv_parametric_search_triggered_data = function( data ) { 3768 var defaults = { 3769 force_form_update: false, 3770 force_results_update: false 3771 }, 3772 settings = $.extend( {}, defaults, data ), 3773 view_loop = $( '#wpv-view-layout-' + settings.view_unique_id ); 3774 3775 if ( 3776 settings.force_form_update == false 3777 && ( 3778 // The form contains pagination settings and the results are set to be updated 3779 ( 3780 settings.force_results_update == true 3781 || settings.form.hasClass( 'js-wpv-ajax-results-enabled' ) 3782 ) 3783 && _.has( WPViews.view_pagination.paged_views, settings.view_unique_id ) 3784 && _.has( WPViews.view_pagination.paged_views[ settings.view_unique_id ], 'has_controls_in_form' ) 3785 && WPViews.view_pagination.paged_views[ settings.view_unique_id ].has_controls_in_form == 'enabled' 3786 ) 3787 ) { 3788 settings.force_form_update = true; 3789 } 3790 3791 settings.update_form = ( settings.force_form_update || settings.form.hasClass( 'js-wpv-dps-enabled' ) ); 3792 settings.update_results = ( view_loop.length > 0 && ( settings.force_results_update || settings.form.hasClass( 'js-wpv-ajax-results-enabled' ) ) ); 3793
3794 return settings; 3795 }; 3796 3797 // ------------------------------------ 3798 // Events 3799 // ------------------------------------ 3800 3801 // Show datepicker on date string click 3802 $( document ).on( 'click', '.js-wpv-date-display', function() { 3803 var url_param = $( this ).data( 'param' ); 3804 $( '.js-wpv-date-front-end-' + url_param ).datepicker( 'show' ); 3805 }); 3806 3807 // Remove current selected date 3808 $( document ).on( 'click', '.js-wpv-date-front-end-clear', function(e) { 3809 e.preventDefault(); 3810 var thiz = $( this ), 3811 url_param = thiz.data( 'param' ), 3812 form = thiz.closest( 'form' ); 3813 form.find( '.js-wpv-date-param-' + url_param ).html( '' ); 3814 form.find( '.js-wpv-date-front-end-' + url_param ).val( '' ); 3815 thiz.hide(); 3816 form.find('.js-wpv-date-param-' + url_param + '-value' ) 3817 .val( '' ) 3818 .trigger( 'change' ); 3819 }); 3820 3821 $( document ).on( 'change', '.js-wpv-post-relationship-update', function() { 3822 var thiz = $( this ), 3823 fil = thiz.closest( 'form' ), 3824 view_number = fil.data( 'viewnumber' ), 3825 additional_forms = $( '.js-wpv-filter-form-' + view_number ).not( fil ), 3826 currentposttype = thiz.data( 'currentposttype' ), 3827 watchers = fil.find( '.js-wpv-' + currentposttype + '-watch' ).add( additional_forms.find( '.js-wpv-' + currentposttype + '-watch' ) ), 3828 watcherslength = watchers.length, 3829 i; 3830 if ( watcherslength ) { 3831 for( i = 0; i < watcherslength; i++ ) { 3832 $( watchers[i] ) 3833 .attr( 'disabled', true ) 3834 .removeAttr( 'checked' ) 3835 .removeAttr( 'selected' ) 3836 .not( ':button, :submit, :reset, :hidden, :radio, :checkbox' ) 3837 .val( '0' ); 3838 } 3839 } 3840 3841 var data_for_events = { 3842 view_unique_id: view_number, 3843 form: fil, 3844 force_form_update: true 3845 }; 3846 3847 data_for_events = self.extend_wpv_parametric_search_triggered_data( data_for_events ); 3848 3849 $( document ).trigger( 'js_event_wpv_parametric_search_triggered', [ data_for_events ] ); 3850 }); 3851 3852 $( document ).on( 'change', '.js-wpv-filter-trigger', function() { 3853 var thiz = $( this ), 3854 fil = thiz.closest( 'form' ), 3855 view_number = fil.data( 'viewnumber' ); 3856 3857 var data_for_events = { 3858 view_unique_id: view_number, 3859 form: fil 3860 }; 3861 3862 data_for_events = self.extend_wpv_parametric_search_triggered_data( data_for_events ); 3863 3864 $( document ).trigger( 'js_event_wpv_parametric_search_triggered', [ data_for_events ] ); 3865 }); 3866 3867 $( document ).on( 'click', '.js-wpv-ajax-results-enabled .js-wpv-submit-trigger, .js-wpv-ajax-results-submit-enabled .js-wpv-submit-trigger', function( e ) { 3868 e.preventDefault(); 3869 var thiz = $( this ), 3870 fil = thiz.closest( 'form' ), 3871 view_number = fil.data( 'viewnumber' ); 3872 3873 var data_for_events = { 3874 view_unique_id: view_number, 3875 form: fil, 3876 force_form_update: false, 3877 force_results_update: true 3878 }; 3879 3880 data_for_events = self.extend_wpv_parametric_search_triggered_data( data_for_events ); 3881 3882 $( document ).trigger( 'js_event_wpv_parametric_search_triggered', [ data_for_events ] ); 3883 }); 3884 3885 $( document).on( 'keypress', '.js-wpv-ajax-results-enabled .js-wpv-filter-trigger-delayed, .js-wpv-ajax-results-submit-enabled .js-wpv-filter-trigger-delayed', function( e ) { 3886 // Enter pressed? 3887 if ( e.which == 13 ) { 3888 e.preventDefault(); 3889 var thiz = $( this ), 3890 fil = thiz.closest( 'form' ), 3891 view_number = fil.data( 'viewnumber' ); 3892 3893 var data_for_events = { 3894 view_unique_id: view_number, 3895 form: fil, 3896 force_results_update: true 3897 }; 3898 3899 data_for_events = self.extend_wpv_parametric_search_triggered_data( data_for_events ); 3900 3901 $( document ).trigger( 'js_event_wpv_parametric_search_triggered', [ data_for_events ] ); 3902 } 3903 }); 3904 3905 $( document ).on( 'click', '.js-wpv-reset-trigger', function( e ) { 3906 e.preventDefault(); 3907 var thiz = $( this ), 3908 fil = thiz.closest( 'form' ), 3909 view_number = fil.data( 'viewnumber' ), 3910 additional_forms = $( '.js-wpv-filter-form-' + view_number ).not( fil ), 3911 watchers, 3912 watcherslength, 3913 i, 3914 target = fil.attr( 'action' ), 3915 form_only_force_update = false, 3916 form_only_results_force_update = false; 3917 3918 if ( fil.hasClass( 'js-wpv-form-only' ) ) { 3919 watchers = fil.find( 'input, select' ).add( additional_forms.find( 'input, select' ) ); 3920 watcherslength = watchers.length; 3921 form_only_force_update = ( fil.hasClass( 'js-wpv-dps-enabled' ) || ( fil.find( '.js-wpv-post-relationship-update' ).length > 0 ) ); 3922 if ( 3923 fil.hasClass( 'js-wpv-ajax-results-enabled' ) 3924 || fil.hasClass( 'js-wpv-ajax-results-submit-enabled' ) 3925 ) { 3926 form_only_results_force_update = true; 3927 } 3928 3929 if ( watcherslength ) { 3930 for ( i = 0; i < watcherslength; i++ ) { 3931 if ( ! $( watchers[i] ).hasClass( 'js-wpv-keep-on-clear' ) ) {
3932 $( watchers[i] ) 3933 .attr( 'disabled', form_only_force_update ) 3934 .removeAttr( 'checked' ) 3935 .removeAttr( 'selected' ) 3936 .not( ':button, :submit, :reset, :hidden, :radio, :checkbox' ) 3937 .val( '' ); 3938 } 3939 } 3940 } 3941 3942 var data_for_events = { 3943 view_unique_id: view_number, 3944 form: fil, 3945 force_form_update: form_only_force_update, 3946 force_results_update: form_only_results_force_update 3947 }; 3948 3949 data_for_events = self.extend_wpv_parametric_search_triggered_data( data_for_events ); 3950 3951 if( ! form_only_results_force_update && $( '#wpv-view-layout-' + fil.data( 'viewnumber' ) ).length > 0 ) { 3952 window.location.href = target; 3953 } 3954 else { 3955 $( document ).trigger( 'js_event_wpv_parametric_search_triggered', [ data_for_events ] ); 3956 } 3957 3958 } else if ( fil.hasClass( 'js-wpv-ajax-results-enabled' ) || fil.hasClass( 'js-wpv-ajax-results-submit-enabled' ) ) { 3959 watchers = fil.find( 'input, select' ).add( additional_forms.find( 'input, select' ) ); 3960 watcherslength = watchers.length; 3961 if ( watcherslength ) { 3962 for ( i = 0; i < watcherslength; i++ ) { 3963 if ( ! $( watchers[i] ).hasClass( 'js-wpv-keep-on-clear' ) ) { 3964 $( watchers[i] ) 3965 .attr( 'disabled', true ) 3966 .removeAttr( 'checked' ) 3967 .removeAttr( 'selected' ) 3968 .not( ':button, :submit, :reset, :hidden, :radio, :checkbox' ) 3969 .val( '' ); 3970 } 3971 } 3972 } 3973 3974 var data_for_events = { 3975 view_unique_id: view_number, 3976 form: fil, 3977 force_form_update: true, 3978 force_results_update: true 3979 }; 3980 3981 data_for_events = self.extend_wpv_parametric_search_triggered_data( data_for_events ); 3982 3983 $( document ).trigger( 'js_event_wpv_parametric_search_triggered', [ data_for_events ] ); 3984 } else { 3985 window.location.href = WPViews.view_frontend_utils.updateUrlQuery( 'wpv_view_count', null, target ); 3986 } 3987 }); 3988 3989 $( document ).on( 'js_event_wpv_parametric_search_triggered', function( event, settings ) { 3990 self.manage_changed_form( settings ); 3991 }); 3992 3993 // Also, stop the rollover if we do any modification on the parametric search form 3994 3995 $( document ).on( 'change', '.js-wpv-filter-trigger, .js-wpv-filter-trigger-delayed', function() { 3996 var thiz = $( this ), 3997 fil = thiz.closest( 'form' ), 3998 view_num = fil.data( 'viewnumber' ); 3999 wpv_stop_rollover[view_num] = true; 4000 }); 4001 4002 // ------------------------------------ 4003 // Custom events 4004 // ------------------------------------ 4005 4006 /** 4007 * js_event_wpv_parametric_search_started 4008 * 4009 * Event fired before updating the parametric search forms and results. 4010 * 4011 * @param data 4012 * - view_unique_id 4013 * 4014 * @since 1.9 4015 */ 4016 4017 $( document ).on( 'js_event_wpv_parametric_search_started', function( event, data ) { 4018 4019 }); 4020 4021 4022 /** 4023 * js_event_wpv_parametric_search_form_updated 4024 * 4025 * Event fired after updating the parametric search forms. 4026 * 4027 * @param data 4028 * - view_unique_id 4029 * - view_changed_form 4030 * - view_changed_form_additional_forms_only 4031 * - view_changed_form_additional_forms_full 4032 * 4033 * @since 1.9 4034 */ 4035 4036 $( document ).on( 'js_event_wpv_parametric_search_form_updated', function( event, data ) { 4037 WPViews.view_frontend_utils.render_frontend_datepicker(); 4038 }); 4039 4040 /** 4041 * js_event_wpv_parametric_search_results_updated 4042 * 4043 * Event fired after updating the parametric search results. 4044 * 4045 * @param data 4046 * - view_unique_id 4047 * - layout 4048 * 4049 * @since 1.9 4050 */ 4051 4052 $( document ).on( 'js_event_wpv_parametric_search_results_updated', function( event, data ) { 4053 WPViews.view_frontend_utils.render_frontend_media_shortcodes( data.layout ); 4054 }); 4055 4056 // ------------------------------------ 4057 // Init 4058 // ------------------------------------ 4059 4060 self.init = function() { 4061 4062 } 4063 4064 self.init(); 4065 4066}; 4067 4068jQuery( document ).ready( function( $ ) { 4069 WPViews.view_frontend_utils = new WPViews.ViewFrontendUtils( $ ); 4070 WPViews.view_sorting = new WPViews.ViewSorting( $ ); 4071 WPViews.view_pagination = new WPViews.ViewPagination( $ ); 4072 WPViews.view_parametric_search = new WPViews.ViewParametricSearch( $ ); 4073});
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.