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