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