1(function($) { 2 3 var total_updated = false; 4 5 // Debounce timer for pewc_update_total_js: the function is called from multiple 6 // synchronous sources on a single click (form change, pewc_force_update_total_js, 7 // conditions chain). Debouncing collapses these into one call at the end of the 8 // event loop, removing the main-thread jank visible as click-to-selection lag. 9 var pewc_update_total_timer = null; 10 function pewc_update_total_js_debounced() { 11 clearTimeout( pewc_update_total_timer ); 12 pewc_update_total_timer = setTimeout( pewc_update_total_js, 0 ); 13 } 14 15 $( document ).ready( function() { 16 17 // $( 'body').find( '.dz-default.dz-message span' ).text( pewc_vars.drop_files_message ); 18 // Init each select-box separately 19 $( '.pewc-select-box' ).each( function( index, element ) { 20 $( element ).ddslick({ 21 onSelected: function( selectedData ) { 22 var original = selectedData.original[0]; 23 var index = selectedData.selectedIndex; 24 var value = selectedData.selectedData.value; 25 var box_id = $( original ).attr( 'id' ); 26 // Update field price 27 var hidden_option_id = box_id.replace( '_select_box', '' ) + '_' + index + '_hidden'; 28 var price = $( '#' + hidden_option_id ).attr( 'data-option-cost' ); 29 var wrapper = $( '#' + box_id ).closest( '.pewc-item' ) 30 .attr( 'data-selected-option-price', price ) 31 .attr( 'data-value', value ) 32 .attr( 'data-field-value', value ); 33 var hidden_select = $( '#' + box_id + '_' + index ).closest( '.pewc-item' ).find( '.pewc-select-box-hidden' ).attr( 'data-selected-option-price', price ).val( value ); 34 //pewc_update_total_js(); // before 3.21.4 35 36 var select_box_wrapper = $( 'body' ).find( '.pewc-item-select-box .dd-container' ); 37 $( 'body' ).find( '.dd-option label, .dd-selected label' ).each( function() { 38 $( this ).next( 'small' ).addBack().wrapAll( '<div class="dd-option-wrap"/>' ); 39 }); 40 // box_id = box_id.replace( '_select_box', '' ); 41 box_id = $( '#' + box_id ).closest( '.pewc-item' ).attr( 'data-id' ); 42 // Update the field attributes 43 $( 'body' ).find( '#' + box_id ).val( value ).trigger( 'change' ); 44 45 var selected_option_price = $( '#' + box_id ).find( 'option:selected' ).attr( 'data-option-cost' ); 46 $( wrapper ).attr( 'data-selected-option-price', selected_option_price ); 47 48 $( 'body' ).find( '#' + box_id ).trigger( 'pewc_update_select_box' ); 49 $( wrapper ).find( '.dd-selected-description' ).text( pewc_wc_price( selected_option_price, true ) ); 50 51 // pewc_update_total_js() removed: trigger(change) above already fires pewc_update_total_js_debounced via .pewc-form-field change handler // since 3.21.4, moved here so that WCFAD can also update the price of the selected option 52 53 } 54 }); 55 }); 56 57 // Init each color-picker separately 58 $( '.pewc-color-picker-field' ).each( function ( index, element ) { 59 $(element).wpColorPicker({ 60 defaultColor: $(element).data('color') ? $(element).data('color') : false, 61 change: function( event, ui ) { 62 // a callback to fire whenever the color changes to a valid color 63 $( 'body' ).trigger( 'pewc_trigger_calculations' ); 64 $(element).trigger( 'pewc_trigger_color_picker_change' ); 65 $(element).closest( '.pewc-item' ).attr( 'data-field-value', ui.color.toString() ); // 3.21.4 66 }, 67 clear: function() { 68 // a callback to fire when the input is emptied or an invalid color 69 $( 'body' ).trigger( 'pewc_trigger_calculations' ); 70 $(element).closest( '.pewc-item' ).attr( 'data-field-value', '' ); // 3.21.4 71 }, 72 hide: !$(element).data('show'), // hide the color picker controls on load 73 palettes: !!$(element).data('palettes'), // show a group of common colors beneath the square 74 width: $(element).data('box-width') ? $(element).data('box-width') : 255, 75 mode: 'hsv', 76 type: 'full', 77 slider: 'horizontal' 78 }); 79 }); 80 81 $( 'body' ).find( '.dd-option label, .dd-selected label' ).each( function() { 82 $( this ).next( 'small' ).addBack().wrapAll( '<div class="dd-option-wrap"/>' ); 83 }); 84 85 // 3.24.5, for input type range, so that the slider will display the default value on page load 86 $( 'input.pewc-range-slider' ).each( function(){ 87 if ( $(this).attr( 'value' ) > 0 ) { 88 $(this).trigger( 'change' ); 89 } 90 }); 91 92 // 3.26.7, force update totals when using the quantity selector +/- buttons 93 $( 'form.wp-block-add-to-cart-with-options .wc-block-components-quantity-selector' ).on( 'click', function( e ){ 94 $( 'body' ).trigger( 'pewc_force_update_total_js' ); 95 }); 96 97 // 3.27.3, update max on child product independent quantities on page load 98 $( '.products-quantities-independent .pewc-child-select-field' ).each( function(){ 99 var number_field = $( this ).closest( '.child-product-wrapper' ).find( '.pewc-child-quantity-field' ); 100 pewc_update_independent_quantity_input_max( $( this ), number_field ); 101 }); 102 }); 103 104 $('.require-depends li:first input').on('change',function() { 105 // Display asterisk on dependent required fields 106 if( $(this).val() != '' ) { 107 $(this).closest('.pewc-group').addClass('show-required'); 108 } else { 109 $(this).closest('.pewc-group').removeClass('show-required'); 110 } 111 }); 112 $('.pewc-file-upload').on('change',function(){ 113 readURL( this, $(this).attr('id') ); 114 }); 115 $('.pewc-remove-image').on('click',function(e){ 116 e.preventDefault(); 117 id = $(this).attr('data-id'); 118 $('#'+id).val(""); 119 $('#'+id+'-placeholder').css('display','none'); 120 $('#'+id+'-placeholder img').attr('src', '#'); 121 $('#'+id+'-wrapper').removeClass('image-loaded'); 122 }); 123 function readURL(input,id) { 124 if( input.files && input.files[0] ) { 125 var i = input.files.length; 126 var reader = new FileReader(); 127 reader.onload = function (e) { 128 $('#'+id+'-wrapper').addClass('image-loaded'); 129 $('#'+id+'-placeholder').fadeIn(); 130 $('#'+id+'-placeholder img').attr('src', e.target.result); 131 }
132 reader.readAsDataURL(input.files[0]); 133 } 134 } 135 $('body').on('change input keyup','.pewc-has-maxchars input, .pewc-has-maxchars textarea',function(){ 136 var maxchars = parseInt( $(this).attr('data-maxchars') ); 137 var str = $(this).val(); 138 var str_ex_spaces = $(this).val(); 139 // Don't cost spaces 140 // str_ex_spaces = str_ex_spaces.replace(/\s/g, ""); 141 if( pewc_vars.remove_spaces != 'no' ) { 142 str_ex_spaces = str.replace(/\s/g, ""); 143 var num_spaces = str.split( " " ).length - 1; 144 maxchars += parseInt( num_spaces ); 145 } else { 146 str_ex_spaces = str; 147 148 } 149 var str_len = str_ex_spaces.length; 150 if(str_len>maxchars){ 151 var new_str = str_ex_spaces.substring(0, maxchars); 152 $(this).val(new_str); 153 } 154 }); 155 $('body').on( 'change input', '.pewc-form-field', function() { 156 $form = $(this).closest( 'form' ); 157 add_on_images.update_add_on_image( $( this ), $form ); 158 // Debounced: this fires alongside the form.cart handler and pewc_force_update_total_js. 159 pewc_update_total_js_debounced(); 160 if ( 'yes' == pewc_vars.enable_character_counter ) { 161 pewc_update_text_field_counter( $(this) ); 162 } 163 }); 164 $('body').on( 'change input', '.pewc-range-slider', function() { 165 $( this ).closest( '.pewc-item-field-wrapper' ).find( '.pewc-range-value' ).text( $( this ).val() ); 166 $( this ).closest( '.pewc-item' ).attr( 'data-field-value', $( this ).val() ); // 3.24.5 167 }); 168 169 // this updates all text field counters, called on first load 170 function pewc_update_text_field_counters() { 171 $( '.pewc-form-field' ).each( function(){ 172 if ( $(this).closest( '.pewc-item' ).hasClass('pewc-item-text') || $(this).closest( '.pewc-item' ).hasClass('pewc-item-textarea') || $(this).closest( '.pewc-item' ).hasClass('pewc-item-advanced-preview') ) { 173 pewc_update_text_field_counter( $(this) ); 174 } 175 }); 176 } 177 178 function pewc_update_text_field_counter( field ) { 179 var wrapper = field.closest( '.pewc-item' ); 180 181 if ( ! wrapper.hasClass('pewc-item-text') && ! wrapper.hasClass('pewc-item-textarea') && ! wrapper.hasClass('pewc-item-advanced-preview') ) { 182 return; // do nothing if not text fields 183 } 184 185 var val_length = field.val().length; 186 var field_id = field.attr( 'id' ).replace( '_clone', '' ); // 3.26.11, remove _clone so that the counter inside the lightbox works 187 //var current_count = $( '.pewc-text-counter-container.'+field.attr('id')+' .pewc-current-count' ); 188 var current_count = field.closest( '.pewc-item' ).find( '.pewc-text-counter-container.' + field_id + ' .pewc-current-count' ); // 3.22.0, so that cloned text fields' counter works correctly 189 current_count.html( val_length ); 190 191 current_count.removeClass( 'error' ); 192 if ( parseInt( field.attr('data-minchars') ) > 0 && val_length < parseInt( field.attr('data-minchars') ) ) { 193 current_count.addClass( 'error' ); 194 } else if ( parseInt( field.attr('data-maxchars') ) > 0 && val_length > parseInt( field.attr('data-maxchars') ) ) { 195 current_count.addClass( 'error' ); 196 } 197 } 198 199 $('body').on('click','.pewc-remove-image',function(){ 200 $form = $(this).closest('form'); 201 // pewc_update_total( $form ); 202 pewc_update_total_js(); 203 }); 204 // Bind to the show_variation event 205 // Update pewc-product-price field with variation price 206 // 3.20.1, changed .bind to .on, .bind is deprecated as of jQuery 3.0 207 $( document ).on( 'hide_variation', function( event, variation, purchasable ) { 208 $('#pewc-product-price').val( 0 ); 209 $('#pewc-product-price-original').val( 0 ); // 3.21.7 210 pewc_update_total_js(); 211 // hide all variation-dependent fields 212 $('.pewc-variation-dependent').each(function(){ 213 if ($(this).hasClass( 'active' )) { 214 $(this).removeClass( 'active' ); 215 // 3.20.1, run only if Optimised conditions is enabled 216 if ( pewc_vars.conditions_timer > 0 ) { 217 if( pewc_vars.reset_fields == 'yes' && ! $(this).hasClass( 'pewc-reset-me' ) ) { 218 $(this).addClass( 'pewc-reset-me' ); 219 } 220 if ( $( this ).hasClass( 'pewc-field-triggers-condition' ) ) { 221 // 3.20.1, trigger the function trigger_field_condition_check() in pewc_conditions 222 if ( $( this ).find( 'input' ).length > 0 ) { 223 $( this ).find( 'input' ).trigger( 'change' ); 224 } else if ( $( this ).find( 'select' ).length > 0 ) { 225 $( this ).find( 'select' ).trigger( 'change' ); 226 } 227 } 228 if ( $( this ).hasClass( 'pewc-calculation-trigger' ) ) { 229 // sometimes the recalculate function is triggered too late, when the field is already hidden, so we trigger it manually 230 calculations.recalculate(); 231 } 232 } 233 // 3.21.4 234 $( 'body' ).trigger( 'pewc_field_visibility_updated', [ $(this).attr('data-id'), 'hide' ] ); 235 } 236 }); 237 $( 'body' ).trigger( 'pewc_reset_fields' ); // 3.20.1 238 }); 239 $( document ).on( 'show_variation', function( event, variation, purchasable ) { 240 $( '#pewc_calc_set_price' ).attr( 'data-calc-set', 0 ); 241 pewc_update_total_js(); 242 var var_price = variation.display_price; 243 $( '#pewc_variation_price' ).val( var_price ); 244 $( '#pewc-product-price' ).val( var_price ); 245 $( '#pewc-product-price-original' ).val( var_price ); // 3.21.7 246 // Update percentage prices 247 $( 'body' ).trigger( 'pewc_do_percentages' ); 248 // Find any select options with percentage prices - these might not have a field price 249 $( this ).find( '.pewc-percentage.pewc-item-select select' ).each( function() { 250 pewc_update_select_percentage_field( $( this ), var_price ); 251 }); 252 $( this ).find( '.pewc-percentage.pewc-item-select-box' ).each( function() { 253 pewc_update_select_box_percentage_field( $( this ), var_price ); 254 }); 255 $( this ).find( '.pewc-percentage.pewc-item-image_swatch, .pewc-percentage.pewc-item-radio' ).each( function() { 256 pewc_update_radio_percentage_field( $( this ), var_price ); 257 }); 258 // Check for variation dependent fields 259 var variation_id = variation.variation_id; 260 $('.pewc-variation-dependent').each(function(){ 261 var ids = $(this).attr('data-variations'); 262 ids = ids.split( ',' ); 263 ids = ids.map( function( x ) { 264 return parseInt( x, 10 ); 265 }); 266 if( ids.indexOf( variation_id ) != -1 ) { 267 $(this).addClass( 'active' ); 268 // 3.20.1 269 if( pewc_vars.reset_fields == 'yes' && pewc_vars.conditions_timer > 0 ) { 270 $(this).removeClass( 'pewc-reset-me' ); 271 } 272 // 3.21.4 273 $( 'body' ).trigger( 'pewc_field_visibility_updated', [ $(this).attr('data-id'), 'show' ] ); 274 } else { 275 $(this).removeClass( 'active' ); 276 // 3.20.1 277 if( pewc_vars.reset_fields == 'yes' && ! $(this).hasClass( 'pewc-reset-me' ) && pewc_vars.conditions_timer > 0 ) { 278 $(this).addClass( 'pewc-reset-me' ); 279 } 280 } 281 // 3.20.1 282 if ( pewc_vars.conditions_timer > 0 ) { 283 if ( $( this ).hasClass( 'pewc-field-triggers-condition' ) ) { 284 // trigger trigger_field_condition_check() or trigger_condition_check() in pewc_conditions 285 if ( $( this ).find( 'input' ).length > 0 ) { 286 $( this ).find( 'input' ).trigger( 'change' ); 287 } else if ( $( this ).find( 'select' ).length > 0 ) { 288 $( this ).find( 'select' ).trigger( 'change' ); 289 } 290 } 291 if ( $( this ).hasClass( 'pewc-calculation-trigger' ) ) { 292 // sometimes the recalculate function is triggered too late, when the field is already hidden, so we trigger it manually 293 calculations.recalculate(); 294 } 295 } 296 }); 297 // Update product dimensions 298 $( '#pewc_product_length' ).val( variation.dimensions['length'] ); 299 $( '#pewc_product_width' ).val( variation.dimensions['width'] ); 300 $( '#pewc_product_height' ).val( variation.dimensions['height'] ); 301 $( '#pewc_product_weight' ).val( variation.weight );
302 // Trigger recalculation 303 $( 'body' ).trigger( 'pewc_trigger_calculations' ); 304 $( 'body' ).trigger( 'pewc_variations_updated' ); 305 $( 'body' ).trigger( 'pewc_reset_fields' ); // 3.20.1 306 pewc_update_total_js(); 307 }); 308 309 $( 'body' ).on( 'pewc_do_percentages', function() { 310 $('.pewc-percentage').each(function() { 311 var var_price = $( '#pewc-product-price' ).val(); 312 var new_price = ( var_price / 100 ) * parseFloat( $( this ).attr( 'data-percentage' ) ); 313 if( isNaN( new_price ) ) { 314 new_price = 0; 315 } 316 $(this).attr( 'data-price', new_price ); 317 var new_price_html = pewc_wc_price( new_price.toFixed(pewc_vars.decimals) ); 318 $(this).find('.pewc-field-price').html(new_price_html); 319 320 // 3.21.4, for checkbox fields 321 if ( $(this).hasClass( 'pewc-item-checkbox' ) ) { 322 var new_price_currency_only = pewc_wc_price( new_price.toFixed( pewc_vars.decimals ), true ); 323 $(this).find( '.pewc-checkbox-price' ).html( new_price_currency_only ); 324 return; 325 } 326 // Find any options in this field - checkbox group 327 $(this).find( '.pewc-option-has-percentage' ).each(function() { 328 var option_price = ( var_price / 100 ) * $(this).attr('data-option-percentage'); 329 $(this).attr('data-option-cost',option_price.toFixed(pewc_vars.decimals)); 330 option_price = pewc_wc_price( option_price.toFixed(pewc_vars.decimals) ); 331 $(this).closest('.pewc-checkbox-form-label').find('.pewc-option-cost-label').html(option_price); 332 }); 333 }); 334 }); 335 $( 'body.pewc-variable-product' ).on( 'update change', '.pewc-percentage.pewc-item-select select', function( e ) { 336 // Only do this on variable products 337 pewc_update_select_percentage_field( $( this ), $( '#pewc_variation_price' ).val() ); 338 }); 339 // @param select is the select element itself 340 function pewc_update_select_percentage_field( select, var_price ) { 341 pewc_update_select_option_percentage( select, var_price ); 342 // Trigger recalculation 343 $( 'body' ).trigger( 'pewc_trigger_calculations' ); 344 pewc_update_total_js(); 345 } 346 // @param selectbox is the wrapper element 347 // @param var_price the variation price 348 function pewc_update_select_box_percentage_field( selectbox, var_price ) { 349 var select = $( selectbox ).find( 'select' ); 350 // Update the hidden select field 351 pewc_update_select_option_percentage( select, var_price ); 352 // Now update the select box options 353 var box = $( selectbox ).find( '.dd-select' ); 354 var box_options = $( selectbox ).find( '.dd-options' ); 355 $( select ).find( 'option' ).each( function( i, v ) { 356 var new_price = ( var_price / 100 ) * $( this ).attr( 'data-option-percentage' ); 357 var new_text = $( this ).val() + pewc_vars.separator + pewc_wc_price( new_price.toFixed( pewc_vars.decimals ), true ); 358 var option = $( box_options ).find( 'li' ).eq( i ); 359 $( option ).find( '.dd-option-description' ).text( new_text ); 360 }); 361 // Update the selected option price 362 var selected_price = $( select ).children( 'option:selected' ).attr( 'data-option-cost' ); 363 selected_price = pewc_wc_price( selected_price, true ); 364 $( selectbox ).find( '.dd-selected .dd-selected-description' ).text( selected_price ); 365 366 // Trigger recalculation 367 $( 'body' ).trigger( 'pewc_trigger_calculations' ); 368 pewc_update_total_js(); 369 } 370 // Shared function for select and select box fields 371 function pewc_update_select_option_percentage( select, var_price ) { 372 var selected = $( select ).children( 'option:selected' ); 373 var option_price = ( var_price / 100 ) * $( selected ).attr( 'data-option-percentage' ); 374 var item = $( select ).closest( '.pewc-item' ).attr( 'data-selected-option-price', option_price ); 375 $( selected ).attr( 'data-option-cost', option_price.toFixed( pewc_vars.decimals ) ); 376 option_price = pewc_wc_price( option_price.toFixed( pewc_vars.decimals ) ); 377 var data_price = $( select ).closest( '.pewc-item' ).attr( 'data-price' ); 378 if( isNaN( data_price ) ) { 379 $( select ).closest( '.pewc-item' ).attr( 'data-price', 0 ); 380 } 381 // Update all options prices 382 $( select ).find( 'option' ).each( function( i, v ) { 383 var new_price = ( var_price / 100 ) * $( this ).attr( 'data-option-percentage' ); 384 $( this ).attr( 'data-option-cost', new_price.toFixed( pewc_vars.decimals ) ); 385 if ( $( select ).closest( '.pewc-item' ).hasClass( 'pewc-hide-option-price' ) || $( this ).hasClass( 'pewc-first-option' ) ) { 386 return; // no need to proceed if option price is hidden for this field 387 } 388 var new_text = $( this ).val() + pewc_vars.separator + pewc_wc_price( new_price.toFixed( pewc_vars.decimals ), true ); 389 $( this ).text( new_text ); 390 }); 391 } 392 // @param swatch is the swatch or radio group field wrapper 393 function pewc_update_radio_percentage_field( field, var_price ) { 394 // Iterate through each input element and update all options prices 395 $( field ).find( 'input' ).each( function( i, v ) { 396 var new_price = ( var_price / 100 ) * $( this ).attr( 'data-option-percentage' ); 397 $( this ).attr( 'data-option-cost', new_price.toFixed( pewc_vars.decimals ) ); 398 var new_text = $( this ).val() + pewc_vars.separator + pewc_wc_price( new_price.toFixed( pewc_vars.decimals ), true ); 399 $( this ).closest( 'label' ).next().text( new_text ); 400 if ( $( field ).hasClass( 'pewc-hide-option-price' ) ) { 401 return; // no need to proceed if option price is hidden for this field 402 } 403 // 3.21.4, added pewc-item-image-swatch-checkbox 404 if( ( $( field ).hasClass( 'pewc-item-radio' ) || $( field ).hasClass( 'pewc-item-image-swatch-checkbox' ) ) && $( field ).hasClass( 'pewc-item-image_swatch' ) ) { 405 // 3.21.4, added .pewc-radio-image-desc to avoid duplicates 406 $( this ).closest( 'label' ).find( '.pewc-radio-image-desc span' ).text( new_text ); 407 } else if( $( field ).hasClass( 'pewc-item-radio' ) ) { 408 $( this ).closest( 'li' ).find( 'label span.pewc-radio-option-text' ).text( new_text ); 409 } 410 });
411 // Trigger recalculation 412 $( 'body' ).trigger( 'pewc_trigger_calculations' ); 413 pewc_update_total_js(); 414 } 415 function pewc_update_total_js( $update=0 ) { 416 417 var flat_rate_total = 0; 418 var product_price = parseFloat( $('#pewc-product-price').val() ); 419 var orig_product_price = parseFloat( $('#pewc-product-price-original').val() ); // 3.21.7 420 var total_price = 0; // Options running total 421 var orig_total_price = 0; // 3.21.7, stores add-on prices before getting adjusted by DPDR 422 var added_price = 0; 423 var repeatable_prices = 0; // 3.26.7, keeps track of repeatable field prices, in case we don't want them multiplied against the quantity 424 var field_value = []; 425 var field_label = []; 426 427 $('form.cart .pewc-form-field').each(function() { 428 429 added_price = 0; 430 431 var field_wrapper = $(this).closest('.pewc-group'); 432 $( field_wrapper ).removeClass( 'pewc-active-field' ); 433 434 // Ignore hidden variation dependent fields 435 if( ! $( field_wrapper ).hasClass( 'pewc-variation-dependent' ) || ( $( field_wrapper ).hasClass( 'pewc-variation-dependent' ) && $( field_wrapper ).hasClass( 'active' ) ) ) { 436 437 var group_wrap = $( field_wrapper ).closest( '.pewc-group-wrap' ); 438 if ( group_wrap.hasClass( 'pewc-group-hidden' ) && ! group_wrap.hasClass( 'pewc-group-always-include' ) ) { 439 // 3.27.9, added condition to check for class .pewc-group-always-include. If it exists, include it in the totals, 440 // since when added to the cart, the hidden field's cost are included. This makes it consistent on both the product page and 441 // the cart page. 442 return; // this field is inside a hidden group, so ignore and return 443 } 444 445 // Check that the extra field is not flat rate 446 if( ! $(field_wrapper).hasClass('pewc-flatrate') ) { 447 448 if( $(field_wrapper).hasClass('pewc-group-checkbox') && ! $(field_wrapper).hasClass('pewc-hidden-field') ) { 449 450 if( $(field_wrapper).hasClass('pewc-per-unit-pricing') && $(this).prop('checked') ) { 451 // Bookings for WooCommerce 452 // Multiply option cost by number of booked units 453 // total_price += parseFloat( $('#num_units_int').val() ) * parseFloat( $(field_wrapper).attr('data-price') ); 454 added_price = parseFloat( $('#num_units_int').val() ) * parseFloat( $(field_wrapper).attr('data-price') ); 455 $( field_wrapper ).addClass( 'pewc-active-field' ); 456 } else if( $(this).prop('checked') ) { 457 // total_price += parseFloat( $(field_wrapper).attr('data-price') ); 458 added_price = parseFloat( $(field_wrapper).attr('data-price') ); 459 $( field_wrapper ).addClass( 'pewc-active-field' ); 460 } else { 461 $( field_wrapper ).removeClass( 'pewc-active-field' ); 462 } 463 464 } else if( $(field_wrapper).hasClass('pewc-group-select' ) && ! $(field_wrapper).hasClass('pewc-hidden-field') ) { 465 466 // 3.24.8, added check for pewc-first-field-empty 467 if ( ! $( field_wrapper ).hasClass( 'pewc-first-field-empty' ) || $(this).find(':selected').val() != '' ) { 468 $( field_wrapper ).addClass( 'pewc-active-field' ); 469 $( field_wrapper ).attr( 'data-field-value', $(this).find(':selected').val() ); 470 471 // 'value' means use the price as value only, on calculation fields 472 // 3.25.6, moved here so that Select fields that have field price, but first element is instruction only, won't get added until an option is selected 473 if ( $(field_wrapper).attr( 'data-option-price-visibility' ) != 'value' ) { 474 // Add cost of selected option 475 added_price = parseFloat( $(this).find(':selected').attr('data-option-cost') ); 476 // Add cost of select field 477 added_price += parseFloat( $(field_wrapper).attr('data-price') ); 478 // Bookings for WooCommerce: multiply by number of booked units 479 if ( $(field_wrapper).hasClass('pewc-per-unit-pricing') ) { 480 added_price = parseFloat( $('#num_units_int').val() ) * added_price; 481 } 482 } 483 } 484 485 } else if( $(field_wrapper).hasClass('pewc-group-select-box' ) && ! $(field_wrapper).hasClass('pewc-hidden-field') ) { 486 487 // 3.24.8, added check for pewc-first-field-empty 488 if ( ! $( field_wrapper ).hasClass( 'pewc-first-field-empty' ) || $(this).find(':selected').val() != '' ) { 489 $( field_wrapper ).addClass( 'pewc-active-field' ); 490 //$( field_wrapper ).attr( 'data-field-value', $(this).find('.pewc-select-box-hidden' ).val() ); // doesn't work as of 3.21.6 491 $( field_wrapper ).attr( 'data-field-value', $(this).find( ':selected' ).val() ); // 3.21.7 492 493 // 'value' means use the price as value only, on calculation fields 494 // 3.25.6, moved here, similar to Select field above 495 if ( $(field_wrapper).attr( 'data-option-price-visibility' ) != 'value' ) { 496 // Add cost of selected option 497 added_price = parseFloat( $( field_wrapper ).attr( 'data-selected-option-price') ); 498 // Add cost of select field 499 added_price += parseFloat( $( field_wrapper ).attr( 'data-
499price' ) ); 500 // Bookings for WooCommerce: multiply by number of booked units 501 if ( $(field_wrapper).hasClass('pewc-per-unit-pricing') ) { 502 added_price = parseFloat( $('#num_units_int').val() ) * added_price; 503 } 504 } 505 } 506 507 } else if( $(this).val() && ! $(field_wrapper).hasClass('pewc-hidden-field') ) { 508 509 if( $(field_wrapper).hasClass('pewc-per-character-pricing') && ( $(field_wrapper).hasClass('pewc-item-text') || $(field_wrapper).hasClass('pewc-item-textarea') || $(field_wrapper).hasClass( 'pewc-item-advanced-preview' ) ) ) { 510 var str_len = pewc_get_text_str_len( $(this).val(), field_wrapper ); 511 added_price = str_len * parseFloat( $(field_wrapper).attr('data-price') ); 512 } else if( $(field_wrapper).hasClass( 'pewc-multiply-pricing' ) ) { 513 var num_value = $(this).val(); 514 added_price = num_value * parseFloat( $(field_wrapper).attr('data-price') ); 515 } else if( $(field_wrapper).hasClass('pewc-group-name_price') ) { 516 added_price = parseFloat( $(this).val() ); 517 } else { 518 added_price = parseFloat( $(field_wrapper).attr('data-price') ); 519 } 520 521 // 3.27.11, moved here so that Price per booking unit can be used with Multiply Price 522 if( $(field_wrapper).hasClass( 'pewc-item-number' ) && $(field_wrapper).hasClass( 'pewc-per-unit-pricing' ) ) { 523 // Bookings for WooCommerce 524 // Multiply option cost by number of booked units 525 // total_price += parseFloat( $('#num_units_int').val() ) * parseFloat( $(field_wrapper).attr('data-price') ); 526 // added_price = parseFloat( $('#num_units_int').val() ) * parseFloat( $(field_wrapper).attr('data-price') ) * parseFloat( $( this ).val() ); 527 added_price = parseFloat( added_price ) * parseFloat( $('#num_units_int').val() ); // 3.27.11, use added_price so that this can be used with Multiply Price setting 528 } 529 530 if( $(this).val() ) { 531 $( field_wrapper ).addClass( 'pewc-active-field' ); 532 533 if ( $(this).hasClass( 'pewc-range-slider' ) && $(this).attr( 'value' ) == '' ) { 534 // 3.24.5, input of type range always has a value, so if this is the first load, and we don't have a user-selected value, don't set data-field-value 535 } else { 536 $( field_wrapper ).attr( 'data-field-value', $(this).val() ); 537 } 538 } 539 540 } else { 541 542 // blank text value falls here 543 $( field_wrapper ).attr( 'data-field-value', '' ); 544 545 } 546 547 // 3.26.7, by default, add-on field prices are multiplied against the quantity. There are cases we don't want to do this for repeatable fields 548 if ( $( field_wrapper ).hasClass( 'pewc-repeatable-field' ) && ! $( field_wrapper ).hasClass( 'pewc-multiply-repeatable' ) ) { 549 repeatable_prices += added_price; // we don't add this field's price to the total price so that repeatable prices are not multiplied with quantity 550 } else { 551 total_price += added_price; // default behavior, later on total_price is multiplied against quantity 552 } 553 554 if( ! isNaN( added_price ) ) { 555 $( field_wrapper ).attr( 'data-field-price', added_price ); 556 } 557 558 } else { 559 560 // Flat rate item 561 if( $(field_wrapper).hasClass('pewc-group-checkbox') && ! $(field_wrapper).hasClass('pewc-hidden-field') ) { 562 if( $(field_wrapper).hasClass('pewc-per-unit-pricing') && $(this).prop('checked') ) { 563 // Bookings for WooCommerce 564 // Multiply option cost by number of booked units 565 added_price = parseFloat( $('#num_units_int').val() ) * parseFloat( $(field_wrapper).attr('data-price') ); 566 $( field_wrapper ).addClass( 'pewc-active-field' ); 567 } else if( $(this).prop('checked') ) { 568 added_price = parseFloat( $(field_wrapper).attr('data-price') ); 569 $( field_wrapper ).addClass( 'pewc-active-field' ); 570 } 571 } else if( ( $(field_wrapper).hasClass('pewc-group-select') || $(field_wrapper).hasClass('pewc-group-select-box') ) && ! $(field_wrapper).hasClass('pewc-hidden-field') ) { 572 // Add cost of selected option 573 added_price = parseFloat( $(this).find(':selected').attr('data-option-cost') ); 574 // Add cost of select field 575 added_price += parseFloat( $(field_wrapper).attr('data-price') ); 576 // Bookings for WooCommerce: multiply by number of booked units 577 if ( $(field_wrapper).hasClass('pewc-per-unit-pricing') ) { 578 added_price = parseFloat( $('#num_units_int').val() ) * added_price; 579 } 580 $( field_wrapper ).addClass( 'pewc-active-field' ); 581 } else if( $(this).val() && ! $(field_wrapper).hasClass('pewc-hidden-field') ) { 582 if( $(field_wrapper).hasClass('pewc-per-character-pricing') ) { 583 var str_len = pewc_get_text_str_len( $(this).val(), field_wrapper ); 584 added_price = str_len * parseFloat( $(field_wrapper).attr('data-price') ); 585 $( field_wrapper ).addClass( 'pewc-active-field' ); 586 } else if( $(field_wrapper).hasClass('pewc-multiply-pricing') ) { 587 var num_value = $(this).val(); 588 added_price = num_value * parseFloat( $(field_wrapper).attr('data-price') ); 589 $( field_wrapper ).addClass( 'pewc-active-field' ); 590 } else if( $(field_wrapper).hasClass('pewc-group-name_price') ) { 591 added_price = parseFloat( $(this).val() ); 592 } else { 593 added_price = parseFloat( $(field_wrapper).attr('data-price') ); 594 $( field_wrapper ).addClass( 'pewc-active-field' ); 595 } 596 } 597 598 flat_rate_total += added_price; 599 $( field_wrapper ).attr( 'data-field-price', added_price ); 600 $( field_wrapper ).attr( 'data-field-value', $(this).val() ); // 3.24.1, for JS validation 601 602 } 603 604 } 605 606 if( $( field_wrapper ).val() ) { 607 set_summary_panel_data( $( field_wrapper ), $( field_wrapper ).val(), added_price ); 608 } 609 610 }); 611 612 $( 'form.cart .pewc-item-radio, form.cart .pewc-item-image_swatch, form.cart .pewc-item-calendar-list' ).each(function() { 613 614 var field_value = []; 615 616 if( ! $( this ).hasClass( 'pewc-variation-dependent' ) || ( $( this ).hasClass( 'pewc-variation-dependent' ) && $( this ).hasClass( 'active' ) ) ) { 617 618 //var radio_group_id = $(this).attr( 'data-id' ); // 3.26.5, commented out 619 var group_wrap = $( this ).closest( '.pewc-group-wrap' ); 620 621 if( ! $(this).hasClass('pewc-hidden-field') && ! group_wrap.hasClass( 'pewc-group-hidden' ) ) { 622 623 // 3.26.5, let's use a variable 624 var checked_radio = $( this ).find( 'input[type=radio]:checked' ); 625 626 // 3.26.5, moved this condition outside of the 3 if/else 627 if( checked_radio.attr( 'data-option-cost' ) ) { 628 if ( $(this).attr('data-option-price-visibility') == 'value' ) { 629 630 // this option is only used for calculations, so don't add the price to the total 631 var selected_option_price = checked_radio.attr( 'data-option-cost' ); 632 $( this ).attr( 'data-selected-option-price', selected_option_price ); 633 634 } else if( ! $(this).hasClass( 'pewc-flatrate' ) ) { 635
636 added_price = parseFloat( $(this).attr( 'data-price' ) ); 637 var selected_option_price = checked_radio.attr( 'data-option-cost' ); 638 $( this ).attr( 'data-selected-option-price', selected_option_price ); 639 added_price += parseFloat( selected_option_price ); 640 641 // 3.26.7, by default, add-on field prices are multiplied against the quantity. There are cases we don't want to do this for repeatable fields 642 if ( $( this ).hasClass( 'pewc-repeatable-field' ) && ! $( this ).hasClass( 'pewc-multiply-repeatable' ) ) { 643 repeatable_prices += added_price; // we don't add this field's price to the total price so that repeatable prices are not multiplied with quantity 644 } else { 645 total_price += added_price; 646 } 647 648 } else { 649 650 flat_rate_total += parseFloat( $(this).attr( 'data-price' ) ); 651 var selected_option_price = checked_radio.attr( 'data-option-cost' ); 652 $( this ).attr( 'data-selected-option-price', selected_option_price ); 653 flat_rate_total += parseFloat( selected_option_price ); 654 655 } 656 } else { 657 $( this ).attr( 'data-selected-option-price', 0 ); 658 } 659 660 if( checked_radio.val() ) { 661 set_summary_panel_data( $( this ), checked_radio.val(), added_price ); 662 } else { 663 set_summary_panel_data( $( this ), '', 0 ); 664 $( this ).removeClass( 'pewc-active-field' ); // 3.21.4, moved here because set_summary_panel_data adds the class pewc-active-field 665 } 666 667 } 668 669 } 670 671 }); 672 673 $('form.cart .pewc-item-select').each(function() { 674 var selected_option_price = $( this ).find( 'option:selected' ).attr( 'data-option-cost' ); 675 $( this ).attr( 'data-selected-option-price', selected_option_price ); 676 }); 677 678 $('form.cart .pewc-item-checkbox_group').each(function() { 679 680 var field_value = []; 681 var selected_counter = 0; 682 683 if( ! $( this ).hasClass( 'pewc-variation-dependent' ) || ( $( this ).hasClass( 'pewc-variation-dependent' ) && $( this ).hasClass( 'active' ) ) ) { 684 685 var checkbox_group_id = $(this).attr( 'data-id' ); 686 var checkbox_group_price = 0; 687 var group_wrap = $( this ).closest( '.pewc-group-wrap' ); 688 689 if( ! $(this).hasClass('pewc-hidden-field') && ! group_wrap.hasClass( 'pewc-group-hidden' ) ) { 690 var checkbox_value = []; 691 if( ! $(this).hasClass('pewc-flatrate') ) { 692 // Get the field price 693 if( $("input[name='" + checkbox_group_id + "[]']:checked" ).val() ) { 694 checkbox_group_price += parseFloat( $(this).attr('data-price') ); 695 } 696 $('.'+checkbox_group_id).find( $('input[type=checkbox]:checked') ).each( function() { 697 checkbox_group_price += parseFloat( $(this).attr('data-option-cost') ); 698 checkbox_value.push( $( this ).val() ); 699 selected_counter++; 700 }); 701 total_price += checkbox_group_price; 702 703 // Summary panel 704 if( $("input[name='" + checkbox_group_id + "[]']:checked" ).val() ) { 705 $( this ).attr( 'data-field-price', checkbox_group_price ); 706 $( this ).addClass( 'pewc-active-field' ); 707 $( this ).attr( 'data-field-value', checkbox_value.join( ', ' ) ); 708 } 709 else { 710 // remove from summary panel 711 $( this ).attr( 'data-field-price', 0 ); 712 $( this ).removeClass( 'pewc-active-field' ); 713 $( this ).attr( 'data-field-value', '' ); 714 } 715 716 } else { 717 718 // Flat rate 719 if( $("input[name='" + checkbox_group_id + "[]']:checked" ).val() ) { 720 flat_rate_total += parseFloat( $(this).attr('data-price') ); 721 } 722 $('.'+checkbox_group_id).find( $('input[type=checkbox]:checked') ).each( function() { 723 flat_rate_total += parseFloat( $(this).attr('data-option-cost') ); 724 checkbox_value.push( $( this ).val() ); 725 selected_counter++; 726 }); 727 728 if ( checkbox_value.length > 0 ) { 729 $( this ).attr( 'data-field-value', checkbox_value.join( ', ' ) ); 730 } else { 731 $( this ).attr( 'data-field-value', '' ); 732 } 733 } 734 } 735 736 } 737 738 pewc_update_checkbox_field_counter( $(this), selected_counter ); 739 740 }); 741 $('form.cart .pewc-item-image-swatch-checkbox').each(function() { 742 743 var field_value = []; 744 var selected_counter = 0; 745 746 if( ! $( this ).hasClass( 'pewc-variation-dependent' ) || ( $( this ).hasClass( 'pewc-variation-dependent' ) && $( this ).hasClass( 'active' ) ) ) { 747 748 var checkbox_group_id = $(this).attr( 'data-id' ); 749 var checkbox_group_price = 0; 750 var group_wrap = $( this ).closest( '.pewc-group-wrap' ); 751 752 if( ! $(this).hasClass('pewc-hidden-field') && ! group_wrap.hasClass( 'pewc-group-hidden' ) ) { 753 var field_value = []; 754 if( ! $(this).hasClass('pewc-flatrate') ) { 755 // Get the field price 756 if( $("input[name='" + checkbox_group_id + "[]']:checked" ).val() ) { 757 checkbox_group_price += parseFloat( $(this).attr('data-price') ); 758 } 759 $('.'+checkbox_group_id).find( $('input[type=checkbox]:checked') ).each( function() { 760 field_value.push( $( this ).val() ); 761 checkbox_group_price += parseFloat( $(this).attr('data-option-cost') ); 762 selected_counter++; 763 }); 764 total_price += checkbox_group_price; 765 } else { 766 // Flat rate 767 if( $("input[name='" + checkbox_group_id + "[]']:checked" ).val() ) { 768 flat_rate_total += parseFloat( $(this).attr('data-price') ); 769 } 770 $('.'+checkbox_group_id).find( $('input[type=checkbox]:checked') ).each( function(){ 771 field_value.push( $( this ).val() ); 772 flat_rate_total += parseFloat( $(this).attr('data-option-cost') ); 773 selected_counter++; 774 }); 775 } 776 } 777 778 if( field_value.length > 0 ) { 779 set_summary_panel_data( $( this ), field_value.join( ', ' ), checkbox_group_price ); 780 } else { 781 $( this ).removeClass( 'pewc-active-field' ); 782 set_summary_panel_data( $( this ), '', 0 ); 783 } 784 785 } 786 787 pewc_update_checkbox_field_counter( $(this), selected_counter ); 788 789 }); 790 791 // Check child products with select layout 792 var child_products_total = 0; 793 $('form.cart .pewc-child-select-field').each(function() { 794 795 var field_wrapper = $( this ).closest( '.pewc-item' ); 796 var field_value = []; 797 var is_hidden = $( this ).closest( '.pewc-item' ).hasClass( 'pewc-hidden-field' ); 798 var is_dependent = ( $( this ).closest( '.pewc-item' ).hasClass( 'pewc-variation-dependent' ) ) && ( ! $( this ).closest( '.pewc-item' ).hasClass( 'active' ) ); 799 if( ! is_hidden && ! is_dependent ) { 800 // If the select field has a value 801 if( $(this).val() && $(this).val() != '' ) { 802 field_value.push( $(this).find(':selected').attr( 'data-field-value' ) ); 803 var selected = $(this).find(':selected'); 804 var child_product_price = selected.data( 'option-cost' ); 805 // 3.21.4, compatibility with FD 806 if ( parseFloat( selected.attr('data-wcfad-price') ) > 0 ) { 807 child_product_price = parseFloat( selected.attr('data-wcfad-price') ); 808 } 809 var qty = 0; 810 if( child_product_price > 0 ) { 811 var wrapper = $(this).closest('.child-product-wrapper'); 812 var quantities = $(wrapper).data('products-quantities'); 813 // Get the quantity 814 if( quantities == 'linked' ) { 815 //qty = $('form.cart .quantity .qty').val(); 816 // 3.27.0 817 qty = pewc_get_quantity( qty, 'linked' ); 818 } else if( quantities == 'independent' ) { 819 // Find the child_quantity field 820 qty = $(wrapper).find('.pewc-child-quantity-field').val(); 821 if ( pewc_vars.multiply_independent == 'yes' /*&& $('form.cart .quantity .qty').val() !== undefined*/ ) { 822 // 3.27.0 823 var main_quantity = pewc_get_quantity(); 824 qty = qty * parseFloat( main_quantity ); 825 } 826 } else if( quantities == 'one-only' ) { 827 qty = pewc_get_quantity( 1, 'one-only' ); 828 } 829 } 830 831 child_products_total += parseFloat( child_product_price ) * parseFloat( qty ); 832 if( field_value.length > 0 ) { 833 $( this ).closest( '.pewc-item' ).attr( 'data-field-price', child_products_total ); 834 set_summary_panel_data( $( this ).closest( '.pewc-item' ), field_value.join( ', ' ), parseFloat( child_product_price ) * parseFloat( qty ) ); 835 } else { 836 $( this ).closest( '.pewc-item' ).removeClass( 'pewc-active-field' ); 837 } 838 839 } 840 } 841 }); 842 $('form.cart .pewc-radio-images-wrapper.child-product-wrapper').each(function() { 843 var field_value = []; 844 var is_hidden = $( this ).closest( '.pewc-item' ).hasClass( 'pewc-hidden-field' ); 845 var is_dependent = ( $( this ).closest( '.pewc-item' ).hasClass( 'pewc-variation-dependent' ) ) && ( ! $( this ).closest( '.pewc-item' ).hasClass( 'active' ) ); 846 if( ! is_hidden && ! is_dependent ) { 847 var quantities = $(this).data('products-quantities'); 848 var checked_radio = $(this).find('.pewc-radio-form-field:checked'); 849 var radio_val = checked_radio.val(); 850 if( radio_val && radio_val != undefined ) { 851 var child_product_price = checked_radio.data('option-cost'); 852 // 3.21.4, compatibility with FD 853 if ( parseFloat( checked_radio.attr('data-wcfad-price') ) > 0 ) { 854 child_product_price = parseFloat( checked_radio.attr('data-wcfad-price') ); 855 } 856 var qty = 0; 857 // sometimes child_product_price is zero if it's discounted 858 859 // Get the quantity 860 if( quantities == 'linked' ) { 861 //qty = $('form.cart .quantity .qty').val(); 862 // 3.27.0 863 qty = pewc_get_quantity( qty, 'linked' ); 864 } else if( quantities == 'independent' ) { 865 // Find the child_quantity field 866 qty = $(this).closest('.pewc-item-field-wrapper').find('.pewc-child-quantity-field').val(); 867 if ( pewc_vars.multiply_independent == 'yes' /*&& $('form.cart .quantity .qty').val() !== undefined*/ ) { 868 // 3.27.0 869 var main_quantity = pewc_get_quantity(); 870 qty = qty * parseFloat( main_quantity ); 871 } 872 } else if( quantities == 'one-only' ) { 873 qty = pewc_get_quantity( 1, 'one-only' ); 874 } 875 876 child_products_total += parseFloat( child_product_price ) * parseFloat( qty ); 877 878 if( child_products_total > 0 || qty > 0 ) { 879 $( this ).closest( '.pewc-item' ).attr( 'data-field-price', child_products_total ); 880 set_summary_panel_data( $( this ).closest( '.pewc-item' ), checked_radio.attr( 'data-field-label' ), parseFloat( child_product_price ) * parseFloat( qty ) ); 881 } 882 883 } else { 884 $( this ).closest( '.pewc-item' ).removeClass( 'pewc-active-field' ); 885 $( this ).closest( '.pewc-item' ) 886 .attr( 'data-field-price', 0 ) 887 .attr( 'data-field-value', '' ); // 3.21.4, reset price and value 888 } 889 890 } 891 }); 892 893 // 3.25.3, added form.cart .pewc-components-wrapper.child-product-wrapper 894 $( 'form.cart .pewc-checkboxes-images-wrapper.child-product-wrapper, form.cart .pewc-components-wrapper.child-product-wrapper' ).each(function() { 895 896 var this_child_total = 0; 897 var field_value = []; 898 var selected_counter = 0; 899 var is_hidden = $( this ).closest( '.pewc-item' ).hasClass( 'pewc-hidden-field' ); 900 var is_dependent = ( $( this ).closest( '.pewc-item' ).hasClass( 'pewc-variation-dependent' ) ) && ( ! $( this ).closest( '.pewc-item' ).hasClass( 'active' ) ); 901 902 if( ! is_hidden && ! is_dependent ) { 903 var quantities = $(this).data('products-quantities'); 904 // Run through each selected checkbox 905 906 $( this ).closest( '.pewc-item' ).removeClass( 'pewc-active-field' ); 907 908 $( this ).find('.pewc-checkbox-form-field:checkbox:checked').each(function() { 909 field_value.push( $( this ).attr( 'data-field-label' ) ); 910 var child_product_price = $(this).data('option-cost'); 911 // 3.21.4, compatibility with FD 912 if ( parseFloat( $(this).attr('data-wcfad-price') ) > 0 ) { 913 child_product_price = parseFloat( $(this).attr('data-wcfad-price') ); 914 } 915 var qty = 0; 916 917 // Get the quantity 918 if( quantities == 'linked' ) { 919 //qty = $('form.cart .quantity .qty').val(); 920 // 3.27.0 921 qty = pewc_get_quantity( qty, 'linked' ); 922 selected_counter++; 923 } else if( quantities == 'independent' ) { 924 qty = $(this).closest('.pewc-checkbox-wrapper').find('.pewc-child-quantity-field').val(); 925 selected_counter += parseInt( qty ); 926 if ( pewc_vars.multiply_independent == 'yes' /*&& $('form.cart .quantity .qty').val() !== undefined*/ ) { 927 // 3.27.0 928 var main_quantity = pewc_get_quantity(); 929 qty = qty * parseFloat( main_quantity ); 930 } 931 } else if( quantities == 'one-only' ) { 932 qty = pewc_get_quantity( 1, 'one-only' ); 933 selected_counter++; 934 } 935 936 if( child_product_price > 0 ) { 937 child_products_total += parseFloat( child_product_price ) * parseFloat( qty ); 938 this_child_total += parseFloat( child_product_price ) * parseFloat( qty ); 939 } 940 941 }); 942 943 if( field_value.length > 0 ) { 944 $( this ).closest( '.pewc-item' ).attr( 'data-field-price', child_products_total ); 945 set_summary_panel_data( $( this ).closest( '.pewc-item' ), field_value.join( ', ' ), this_child_total ); 946 } 947 948 } 949 950 pewc_update_checkbox_field_counter( $( this ).closest( '.pewc-item' ), selected_counter ); 951 952 }); 953 954 // reset products column first 955 $('form.cart .pewc-item-products-column').each(function(){ 956 $(this).removeClass('pewc-active-field'); 957 $(this).attr('data-field-price', 0); 958 $(this).attr('data-field-value', ''); 959 pewc_update_checkbox_field_counter( $(this), 0 ); 960 }); 961 $('form.cart .pewc-column-wrapper .pewc-variable-child-product-wrapper.checked').each(function() { 962 var field_value = []; 963 var field_wrapper = $( this ).closest( '.pewc-item' ); 964 var parent_field_value = field_wrapper.attr('data-field-value'); 965 if ( parent_field_value != 0 && parent_field_value != '') { 966 field_value = parent_field_value.split(', '); 967 } 968 var parent_field_price = parseFloat( field_wrapper.attr('data-field-price') ); 969 var selected_counter = parseInt ( field_wrapper.attr( 'data-field-selected-counter' ) ); 970 var is_hidden = field_wrapper.hasClass( 'pewc-hidden-field' ); 971 var is_dependent = ( field_wrapper.hasClass( 'pewc-variation-dependent' ) ) && ( ! field_wrapper.hasClass( 'active' ) ); 972 973 if( ! is_hidden && ! is_dependent ) { 974 var quantities = $(this).closest( '.pewc-column-wrapper' ).data('products-quantities'); 975 // Run through each selected checkbox for variable child products 976 977 field_wrapper.removeClass( 'pewc-active-field' ); 978 979 $(this).find('.pewc-variable-child-select').each(function() { 980 field_value.push( $( this ).find('option:selected').text() ); 981 var child_product_price = $(this).find(':selected').data('option-cost'); 982 // 3.21.4, compatibility with FD 983 if ( parseFloat( $(this).find(':selected').attr('data-wcfad-price') ) > 0 ) { 984 child_product_price = parseFloat( $(this).find(':selected').attr('data-wcfad-price') ); 985 } 986 var qty = 0; 987 988 // Get the quantity 989 if( quantities == 'linked' ) { 990 //qty = $('form.cart .quantity .qty').val(); 991 // 3.27.0 992 qty = pewc_get_quantity( qty, 'linked' ); 993 selected_counter++; 994 } else if( quantities == 'independent' ) { 995 qty = $(this).closest('.pewc-checkbox-image-wrapper').find('.pewc-child-quantity-field').val(); 996 selected_counter += parseInt( qty ); 997 if ( pewc_vars.multiply_independent == 'yes' /*&& $('form.cart .quantity .qty').val() !== undefined*/ ) { 998 // 3.27.0 999 var main_quantity = pewc_get_quantity(); 1000 qty = qty * parseFloat( main_quantity ); 1001 } 1002 } else if( quantities == 'one-only' ) { 1003 qty = pewc_get_quantity( 1, 'one-only' ); 1004 selected_counter++; 1005 } 1006 1007 if( child_product_price > 0 ) { 1008 child_products_total += parseFloat( child_product_price ) * parseFloat( qty ); 1009 parent_field_price += parseFloat( child_product_price ) * parseFloat( qty ); 1010 } 1011 1012 if( field_value.length > 0 ) { 1013 field_wrapper.attr( 'data-field-price', parent_field_price ); 1014 set_summary_panel_data( field_wrapper, field_value.join( ', ' ), parent_field_price ); 1015 } 1016 1017 }); 1018 1019 // aou-products-column-new, for column layout with attributes select 1020 if ( $( this ).find( '.pewc-column-attributes-select' ).length > 0 ) { 1021 var child_id = $( this ).data( 'option-id' ); 1022 var child_variant = $( this ).find( 'input[name="pewc_child_variants_' + child_id + '"]' ); 1023 field_value.push( child_variant.attr( 'data-variation-name' ) ); 1024 var child_product_price = child_variant.attr( 'data-option-cost' ); 1025 // no
1025t yet supported, maybe add later 1026 //if ( parseFloat( $(this).find(':selected').attr('data-wcfad-price') ) > 0 ) { 1027 // child_product_price = parseFloat( $(this).find(':selected').attr('data-wcfad-price') ); 1028 //} 1029 var qty = 0; 1030 1031 // Get the quantity 1032 if( quantities == 'linked' ) { 1033 qty = pewc_get_quantity( qty, 'linked' ); 1034 selected_counter++; 1035 } else if( quantities == 'independent' ) { 1036 qty = $(this).find( '.pewc-child-quantity-field' ).val(); 1037 selected_counter += parseInt( qty ); 1038 if ( pewc_vars.multiply_independent == 'yes' ) { 1039 var main_quantity = pewc_get_quantity(); 1040 qty = qty * parseFloat( main_quantity ); 1041 } 1042 } else if( quantities == 'one-only' ) { 1043 qty = pewc_get_quantity( 1, 'one-only' ); 1044 selected_counter++; 1045 } 1046 1047 if( child_product_price > 0 ) { 1048 child_products_total += parseFloat( child_product_price ) * parseFloat( qty ); 1049 parent_field_price += parseFloat( child_product_price ) * parseFloat( qty ); 1050 } 1051 1052 if( field_value.length > 0 ) { 1053 field_wrapper.attr( 'data-field-price', parent_field_price ); 1054 set_summary_panel_data( field_wrapper, field_value.join( ', ' ), parent_field_price ); 1055 } 1056 } 1057 1058 } 1059 1060 pewc_update_checkbox_field_counter( field_wrapper, selected_counter ); 1061 1062 }); 1063 $('form.cart .pewc-column-wrapper .pewc-simple-child-product-wrapper.checked').each(function() { 1064 var field_value = []; 1065 var field_wrapper = $( this ).closest( '.pewc-item' ); 1066 var parent_field_value = field_wrapper.attr('data-field-value'); 1067 if ( parent_field_value != 0 && parent_field_value != '') { 1068 field_value = parent_field_value.split(', '); 1069 } 1070 var parent_field_price = parseFloat( field_wrapper.attr('data-field-price') ); 1071 var selected_counter = parseInt ( field_wrapper.attr( 'data-field-selected-counter' ) ); 1072 var is_hidden = field_wrapper.hasClass( 'pewc-hidden-field' ); 1073 var is_dependent = ( field_wrapper.hasClass( 'pewc-variation-dependent' ) ) && ( ! field_wrapper.hasClass( 'active' ) ); 1074 1075 if( ! is_hidden && ! is_dependent ) { 1076 var quantities = $(this).closest( '.pewc-column-wrapper' ).data('products-quantities'); 1077 1078 field_wrapper.removeClass( 'pewc-active-field' ); 1079 1080 // Run through each selected checkbox 1081 $(this).find('.pewc-checkbox-form-field').each(function(){ 1082 field_value.push( $( this ).attr( 'data-field-label' ) ); 1083 var child_product_price = $(this).data('option-cost'); 1084 // 3.21.4, compatibility with FD 1085 if ( parseFloat( $(this).attr('data-wcfad-price') ) > 0 ) { 1086 child_product_price = parseFloat( $(this).attr('data-wcfad-price') ); 1087 } 1088 var qty = 0; 1089 1090 // Get the quantity 1091 if( quantities == 'linked' ) { 1092 //qty = $('form.cart .quantity .qty').val(); 1093 // 3.27.0 1094 qty = pewc_get_quantity( qty, 'linked' ); 1095 selected_counter++; 1096 } else if( quantities == 'independent' ) { 1097 qty = $(this).closest('.pewc-simple-child-product-wrapper').find('.pewc-child-quantity-field').val(); 1098 selected_counter += parseInt( qty ); 1099 if ( pewc_vars.multiply_independent == 'yes' /*&& $('form.cart .quantity .qty').val() !== undefined*/ ) { 1100 // 3.27.0 1101 var main_quantity = pewc_get_quantity(); 1102 qty = qty * parseFloat( main_quantity ); 1103 } 1104 } else if( quantities == 'one-only' ) { 1105 qty = pewc_get_quantity( 1, 'one-only' ); 1106 selected_counter++; 1107 } 1108 1109 if( child_product_price > 0 ) { 1110 child_products_total += parseFloat( child_product_price ) * parseFloat( qty ); 1111 parent_field_price += parseFloat( child_product_price ) * parseFloat( qty ); 1112 } 1113 1114 if( field_value.length > 0 ) { 1115 field_wrapper.attr( 'data-field-price', parent_field_price ); 1116 set_summary_panel_data( field_wrapper, field_value.join( ', ' ), parent_field_price ); 1117 } 1118 1119 }); 1120 1121 } 1122 1123 pewc_update_checkbox_field_counter( field_wrapper, selected_counter ); 1124 1125 }); 1126 1127 // reset products swatches first 1128 $('form.cart .pewc-item-products-swatches').each(function(){ 1129 $(this).removeClass('pewc-active-field'); 1130 $(this).attr('data-field-price', 0); 1131 $(this).attr('data-field-value', ''); 1132 }); 1133 $('form.cart .pewc-swatches-wrapper .pewc-child-variation-main').each(function() { 1134 var field_value = []; 1135 var parent_field_value = $( this ).closest( '.pewc-item' ).attr('data-field-value'); 1136 if ( parent_field_value != 0 && parent_field_value != '') { 1137 field_value = parent_field_value.split(', '); 1138 } 1139 var parent_field_price = parseFloat( $( this ).closest( '.pewc-item' ).attr('data-field-price') ); 1140 var is_hidden = $( this ).closest( '.pewc-item' ).hasClass( 'pewc-hidden-field' ); 1141 var is_dependent = ( $( this ).closest( '.pewc-item' ).hasClass( 'pewc-variation-dependent' ) ) && ( ! $( this ).closest( '.pewc-item' ).hasClass( 'active' ) ); 1142 if( ! is_hidden && ! is_dependent ) { 1143 1144 var quantities = $(this).closest( '.pewc-swatches-wrapper' ).data('products-quantities'); 1145 1146 // Run through each selected variation product 1147 $(this).find('.pewc-child-name input').each(function() { 1148 var child_product_price = parseFloat( $(this).attr( 'data-option-cost' ) ); 1149 // 3.21.4, compatibility with FD 1150 if ( parseFloat( $(this).attr('data-wcfad-price') ) > 0 ) { 1151 child_product_price = parseFloat( $(this).attr('data-wcfad-price') ); 1152 } 1153 var qty = 0; 1154 if( child_product_price > 0 && $(this).is( ':checked' ) ) { 1155 // Get the quantity 1156 // 3.21.4, added is :checked, only consider selected child product 1157 if( quantities == 'linked' ) { 1158 //qty = $('form.cart .quantity .qty').val(); 1159 // 3.27.0 1160 qty = pewc_get_quantity( qty, 'linked' ); 1161 } else if( quantities == 'independent' ) { 1162 qty = $(this).closest('.pewc-child-variation-main').find('.pewc-child-quantity-field').val(); 1163 if ( pewc_vars.multiply_independent == 'yes' /*&& $('form.cart .quantity .qty').val() !== undefined*/ ) { 1164 // 3.27.0 1165 var main_quantity = pewc_get_quantity(); 1166 qty = qty * parseFloat( main_quantity ); 1167 } 1168 } else if( quantities == 'one-only' ) { 1169 qty = pewc_get_quantity( 1, 'one-only' ); 1170 } 1171 } 1172 if ( qty < 1 ) { 1173 return; // quantity is zero, so ignore this field 1174 } 1175 field_value.push( $( this ).attr( 'data-field-label' ) ); 1176 child_products_total += parseFloat( child_product_price ) * parseFloat( qty ); 1177 parent_field_price += parseFloat( child_product_price ) * parseFloat( qty ); 1178 1179 if( field_value.length > 0 ) { 1180 $( this ).closest( '.pewc-item' ).attr( 'data-field-price', parent_field_price ); 1181 set_summary_panel_data( $( this ).closest( '.pewc-item' ), field_value.join( ', ' ), parent_field_price ); 1182 } 1183 }); 1184 1185 } 1186 1187 }); 1188 $('form.cart .grid-layout').each( function() { 1189 1190 var is_hidden = $( this ).closest( '.pewc-item' ).hasClass( 'pewc-hidden-field' ); 1191 var is_hidden_group = $( this ).closest( '.pewc-group-wrap' ).hasClass( 'pewc-group-hidden' ); 1192 var is_dependent = ( $( this ).closest( '.pewc-item' ).hasClass( 'pewc-variation-dependent' ) ) && ( ! $( this ).closest( '.pewc-item' ).hasClass( 'active' ) ); 1193 if( ! is_hidden && ! is_hidden_group && ! is_dependent ) { 1194 var child_product_price = parseFloat( $( this ).closest( '.pewc-item' ).attr( 'data-
1194price' ) ); 1195 child_products_total += parseFloat( child_product_price ); 1196 } 1197 1198 }); 1199 1200 if( product_price < 0 ) product_price = 0; 1201 1202 // Summary panel rows 1203 1204 // Summary panel for add-on groups 1205 $( '.pewc-summary-panel-group-row' ).addClass( 'pewc-summary-panel-field-row-inactive' ); 1206 1207 $( '.pewc-group-wrap' ).not( '.pewc-group-hidden' ).each( function() { 1208 var group_id = $( this ).attr( 'data-group-id' ); 1209 $( '.pewc-summary-panel-group-'+group_id ).removeClass( 'pewc-summary-panel-field-row-inactive' ); 1210 }); 1211 1212 // Summary panel for add-on fields 1213 $( '.pewc-summary-panel-field-row' ).addClass( 'pewc-summary-panel-field-row-inactive' ); 1214 1215 // 3.26.14, added .pewc-hidden-calculation to the not() selector so that hidden Calculation fields are not displayed on the Summary panel 1216 $( '.pewc-active-field' ).not( '.pewc-hidden-field, .pewc-hidden-calculation' ).each( function() { 1217 var field_id = $( this ).attr( 'data-field-id' ); 1218 var field_type = $( '.pewc-field-' + field_id ).attr( 'data-field-type' ); 1219 $( '#pewc-summary-row-' + field_id ).removeClass( 'pewc-summary-panel-field-row-inactive' ).addClass( 'pewc-field-' + field_type ); 1220 var field_price = parseFloat( $( this ).attr( 'data-field-price' ) ); 1221 if( field_price ) { 1222 field_price = field_price.toFixed( pewc_vars.decimals ); 1223 } 1224 1225 var field_label = $( this ).attr( 'data-field-label' ); 1226 var field_value; 1227 if( $( this ).attr( 'data-field-type') != 'checkbox' ) { 1228 field_value = $( this ).attr( 'data-field-value' ); 1229 } 1230 $( '#pewc-summary-row-' + field_id ).find( '.pewc-summary-panel-product-name' ).text( field_label ); 1231 $( '#pewc-summary-row-' + field_id ).find( '.pewc-summary-panel-product-value' ).text( field_value ); 1232 $( '#pewc-summary-row-' + field_id ).find( '.pewc-summary-panel-price' ).html( pewc_wc_price( field_price ) ); 1233 }); 1234 1235 var qty = 1; 1236 // 3.27.0, we use 'linked' so that add-ons are multiplied per day and per num_bookings (quantity)? 1237 qty = pewc_get_quantity( qty, 'linked' ); 1238 1239 // See if we need to apply a discount to the add-ons care of Dynamic Pricing and Discount Rules 1240 // Updated on 3.21.4 1241 orig_total_price = total_price; // 3.21.7, for DPDR 1242 if ( pewc_wcfad_apply_discount() ) { 1243 total_price = pewc_wcfad.adjust_price( total_price ); 1244 if ( repeatable_prices > 0 ) { 1245 repeatable_prices = pewc_wcfad.adjust_price( repeatable_prices ); // 3.26.7 1246 } 1247 } 1248 1249 // Summary panel subtotal (3.9.8) 1250 var subtotal = parseFloat( child_products_total ) + parseFloat( total_price ) + parseFloat( qty * product_price ); 1251 if( ! isNaN( subtotal ) ) { 1252 $( '#pewc-summary-panel-subtotal' ).html( pewc_wc_price( subtotal.toFixed(pewc_vars.decimals) ) ); 1253 } 1254 1255 var total_grid_variations = $( '#pewc-grid-total-variations' ).val(); 1256 1257 // 3.27.0, for Booking products, product_price already includes "qty" (num_units), no need to multiply again 1258 // 4.1.1, also skip for variable products using Better Variations grid mode 1259 if ( ! pewc_is_booking_product() && ! pewc_wcbvp_variation_grid() ) { 1260 var product_price = qty * product_price; 1261 } 1262 1263 var grand_total = product_price; 1264 var orig_grand_total = qty * orig_product_price; // 3.21.7, for DPDR 1265 base_price = product_price; 1266 product_price = product_price.toFixed(pewc_vars.decimals); 1267 product_price = pewc_wc_price( product_price ); 1268 product_price = add_price_suffix( product_price, base_price ); 1269 $('#pewc-per-product-total').html( product_price ); 1270 1271 total_price = qty * total_price; 1272 orig_total_price = qty * orig_total_price; // 3.21.7, for DPDR 1273 1274 // 3.26.7, we have a separate variable for repeatable field prices in case we dont want them multiplied with quantity 1275 if ( repeatable_prices > 0 ) { 1276 total_price += repeatable_prices; 1277 orig_total_price += repeatable_prices; 1278 } 1279 1280 // Multiply add-ons by number of variations in bulk grid 1281 // 2.7.1, added > 0 to the condition so that option total doesn't become 0 if no variations are selected 1282 if( total_grid_variations > 0 ) { 1283 total_price = total_grid_variations * total_price; 1284 } 1285 total_price += child_products_total; 1286 grand_total += total_price; 1287 orig_grand_total += orig_total_price; // 3.21.7, for DPDR 1288 1289 if( ! isNaN( total_price ) ) { 1290 var base_total_price = total_price; 1291 total_price = total_price.toFixed(pewc_vars.decimals); 1292 total_price = pewc_wc_price( total_price ); 1293 total_price = add_price_suffix( total_price, base_total_price ); 1294 $('#pewc-options-total').html( total_price ); 1295 } 1296 1297 if( flat_rate_total < 0 ) flat_rate_total = 0; 1298 base_flat_rate_total = flat_rate_total; 1299 grand_total += flat_rate_total; 1300 flat_rate_total = flat_rate_total.toFixed(pewc_vars.decimals); 1301 flat_rate_total = pewc_wc_price( flat_rate_total ); 1302 flat_rate_total = add_price_suffix( flat_rate_total, base_flat_rate_total ); 1303 $('#pewc-flat-rate-total').html( flat_rate_total ); 1304 1305 // Set the product price using a calculation field 1306 // 3.13.3 added 2nd condition to apply only calculated price if at least 1 calculation field is not hidden 1307 if( ( $( '#pewc_calc_set_price').attr( 'data-calc-set' ) == 1 || $('input[name="pewc_calc_set_price"]').length > 1 ) && $( '.pewc-product-extra-groups-wrap .pewc-item-calculation' ).not( '.pewc-hidden-field' ).length > 0 ) { 1308 if ( $('input[name="pewc_calc_set_price"]').length > 1 ) { 1309 // 3.17.2, compatibility with Product Table Ultimate 1310 // find the first non-hidden total 1311 var new_grand_total = 0; 1312 $('input[name="pewc_calc_set_price"]').each(function(){ 1313 if ( $(this).attr( 'data-calc-set' ) == 1 && $(this).closest( '.pewc-product-extra-groups-wrap' ).is( ':visible' ) ) { 1314 new_grand_total = parseFloat( $(this).closest( '.pewc-product-extra-groups-wrap' ).find('input[name="pewc_calc_set_price"][data-calc-set="1"]').val() ); 1315 } 1316 }); 1317 if ( new_grand_total > 0 ) { 1318 grand_total = new_grand_total; 1319 } 1320 } else { 1321 // single product page 1322 grand_total = parseFloat( $( '#pewc_calc_set_price').val() ); 1323 } 1324 1325 // 4.3.2. In DPDR if a product has a regular price, a strikethrough is added to it if the final calculated price is less than the regular price 1326 // we copy it here before the possible DPDR discount below 1327 orig_grand_total = grand_total; 1328 1329 if ( $('form.cart .quantity .qty').length > 0 ) { 1330 1331 // 3.12.0, apply dynamic pricing if it exists 1332 if ( pewc_wcfad_apply_discount() ) {
1333 grand_total = pewc_wcfad.adjust_price( grand_total ); 1334 } 1335 1336 // 3.11.6 multiply product price by quantity 1337 grand_total = grand_total * parseFloat( $('form.cart .quantity .qty').val() ); 1338 // 4.3.2, for DPDR 1339 orig_grand_total = orig_grand_total * parseFloat( $('form.cart .quantity .qty').val() ); 1340 1341 } 1342 } 1343 1344 if( ! isNaN( grand_total ) ) { 1345 if ( isNaN( orig_grand_total ) || orig_grand_total == grand_total ) { 1346 orig_grand_total = ''; // 3.21.7, let's clear this so that we know we don't need it 1347 } 1348 var base_price = grand_total; 1349 grand_total = grand_total.toFixed( pewc_vars.decimals ); 1350 grand_total = pewc_wc_price( grand_total ); 1351 if( pewc_vars.update_price == 'yes' ) { 1352 update_product_price( grand_total, base_price, orig_grand_total ); 1353 } 1354 grand_total = add_price_suffix( grand_total, base_price ); 1355 $('#pewc-grand-total').html( grand_total ); 1356 if ( $( '#pewc-grand-total_clone' ).length > 0 ) { 1357 // 3.26.11, also update the grand total inside the lightbox 1358 $( '#pewc-grand-total_clone' ).html( grand_total ); 1359 } 1360 } 1361 1362 // Re-run this because some browsers are too quick 1363 // This won't run if we're using the optimised condition option 1364 if( $update == 0 && pewc_vars.conditions_timer < 1 ) { 1365 var interval = setTimeout( function() { 1366 pewc_update_total_js( 1 ); 1367 if( ! total_updated ) { 1368 // Check any calculations before input fields are updated 1369 $( 'body' ).trigger( 'pewc_trigger_calculations' ); 1370 total_updated = true; 1371 } 1372 }, 1373 250 ); 1374 } 1375 1376 // 3.15.0, let other plugins hook into this 1377 $( 'body' ).trigger( 'pewc_after_update_total_js', [ base_total_price, base_price, grand_total ] ); 1378 } 1379 1380 /* 1381 * Counts selected checkboxes, swatches, or products 1382 */ 1383 function pewc_update_checkbox_field_counter( field_wrapper, counter ) { 1384 1385 var current_count = field_wrapper.attr( 'data-field-selected-counter' ); 1386 1387 // hopefully this prevents this process from being run multiple times 1388 if ( current_count != counter ) { 1389 field_wrapper.attr( 'data-field-selected-counter', counter ); 1390 // Optimised validation will hook into the trigger below 1391 $( 'body' ).trigger( 'pewc_field_selected_counter_updated', [ field_wrapper, counter ] ); 1392 } 1393 } 1394 1395 function add_price_suffix( price, base_price ) { 1396 if( pewc_vars.show_suffix == 'yes' ) { 1397 var price_suffix_setting = pewc_vars.price_suffix_setting; 1398 if( price_suffix_setting.indexOf( '{price_excluding_tax}' ) > -1 ) { 1399 var price_ex_tax = base_price * ( pewc_vars.percent_exc_tax / 100 ); 1400 suffix = price_suffix_setting.replace( '{price_excluding_tax}', pewc_wc_price( price_ex_tax.toFixed( pewc_vars.decimals ), false, false ) ); 1401 } else if( price_suffix_setting.indexOf( '{price_including_tax}' ) > -1 ) { 1402 var price_inc_tax = base_price * ( pewc_vars.percent_inc_tax / 100 ); 1403 suffix = price_suffix_setting.replace( '{price_including_tax}', pewc_wc_price( price_inc_tax.toFixed( pewc_vars.decimals ), false, false ) ); 1404 } else { 1405 suffix = pewc_vars.price_suffix; 1406 } 1407 price = price + ' <small class="woocommerce-price-suffix">' + suffix + '</small>'; 1408 } 1409 return price; 1410 } 1411 1412 function update_product_price( grand_total, base_price, orig_grand_total ) { 1413 var price_suffix_setting = pewc_vars.price_suffix_setting; 1414 // We can rebuild him 1415 // 3.27.5, Related Products could also have pewc-main-price, so we assume the first one to be the correct main one 1416 // This fixes an issue where if a Related Product has a hidden price, that it affects all prices on the product page 1417 // Let's also exclude main price from QuickView here instead of later in the function 1418 var main_price = $( '.pewc-main-price' ).not( '.pewc-quickview-product-wrapper .pewc-main-price' ); 1419 if ( main_price.length > 1 ) { 1420 // get only the first? 1421 main_price.each(function( index, element){ 1422 // add a special class to the first main price, we assume that's the real main price 1423 if ( index < 1 ) { 1424 $( this ).addClass( 'pewc-main-main-price' ); 1425 return false; 1426 }; 1427 }); 1428 main_price = $( '.pewc-main-price.pewc-main-main-price' ); 1429 } 1430 var suffix = main_price.find( '.woocommerce-price-suffix' ).html(); 1431 var label = main_price.find( '.wcfad-rule-label' ).html(); 1432 var before = main_price.find( '.pewc-label-before' ).html(); 1433 var after = main_price.find( '.pewc-label-after' ).html(); 1434 var hide = main_price.find( '.pewc-label-hidden' ); 1435 var new_total = ''; 1436 1437 if( hide.length > 0 ) { 1438 new_total = '<span class="pewc-label-hidden">' + hide.html() + '</span>'; 1439 } else { 1440 if( before ) { 1441 new_total += '<span class="pewc-label-before">' + before + ' </span>'; 1442 } 1443 1444 // 3.21.7 1445 if ( orig_grand_total != '' && pewc_vars.disable_wcfad_label != 'yes' ) { 1446 orig_grand_total.toFixed( pewc_vars.decimals ); 1447 orig_grand_total = pewc_wc_price( orig_grand_total ); 1448 new_total += ' <s>' + orig_grand_total + '</s> '; 1449 } 1450 1451 new_total += grand_total; 1452 1453 if( after ) { 1454 new_total += '<span class="pewc-label-after"> ' + after + '</span>'; 1455 } 1456 if( suffix ) { 1457 if( price_suffix_setting.indexOf( '{price_excluding_tax}' ) > -1 ) { 1458 var price_ex_tax = base_price * ( pewc_vars.percent_exc_tax / 100 ); 1459 suffix = price_suffix_setting.replace( '{price_excluding_tax}', pewc_wc_price( price_ex_tax.toFixed( pewc_vars.decimals ), false, false ) ); 1460 } else if( price_suffix_setting.indexOf( '{price_including_tax}' ) > -1 ) { 1461 var price_inc_tax = base_price * ( pewc_vars.percent_inc_tax / 100 ); 1462 suffix = price_suffix_setting.replace( '{price_including_tax}', pewc_wc_price( price_inc_tax.toFixed( pewc_vars.decimals ), false, false ) ); 1463 } 1464 if( label && suffix.indexOf( 'wcfad-rule-label' ) < 0 ) { 1465 suffix += '<br><span class="wcfad-rule-label">' + label + '</span>'; 1466 } 1467 new_total += ' <small class="woocommerce-price-suffix">' + suffix + '</small>'; 1468 } 1469 } 1470 1471 // 3.22.1, retain DPDR label even if Update pricing label is enabled 1472 //var main_price = $( '.pewc-main-price').not( '.pewc-quickview-product-wrapper .pewc-main-price' ); // 3.27.5, commented out, maybe no longer needed? 1473 if ( main_price.find( '.wcfad-rule-label' ).length > 0 && new_total.indexOf( 'wcfad-rule-label' ) == -1 ) { 1474 // this has a DPDR discount label, add it to the new_total 1475 var dpdr_label = main_price.find( '.wcfad-rule-label' ); 1476 new_total += '<br>' + dpdr_label[0].outerHTML; 1477 } 1478 main_price.html( new_total ); 1479 } 1480 1481 function set_summary_panel_data( field, value, added_price ) { 1482 $( field ).attr( 'data-field-value', value ); 1483 $( field ).attr( 'data-field-price', added_price ); 1484 $( field ).addClass( 'pewc-active-field' ); 1485 } 1486 1487 // old position of pewc_wc_price_without_currency and pewc_wc_price, moved outside of this container since 3.21.4 1488 1489 function format_separator( num ) { 1490 return num.toString().replace( /(\d)(?=(\d{3})+(?!\d))/g, '$1,' ); 1491 } 1492 // var interval = setInterval(function(){ 1493 // pewc_update_total_js(); 1494 // }, 1495 // 500); 1496 1497 // 3.24.7, add a trigger event so that other plugins like PTU can re-trigger the form.cart input changes
1498 $( 'body' ).on( 'pewc_attach_form_cart_input_change', function() { 1499 $( 'form.cart' ).on('keyup input change paste', 'input:not(.pewc-grid-quantity-field), select, textarea.pewc-has-field-price', function(){ 1500 // Debounced: batches rapid keyup/input events and redundant change events. 1501 pewc_update_total_js_debounced(); 1502 $( 'body' ).trigger( 'pewc_updated_total_js' ); 1503 }); 1504 }); 1505 $( 'body' ).trigger( 'pewc_attach_form_cart_input_change' ); 1506 1507 var interval = setTimeout( function() { 1508 pewc_update_total_js(); 1509 if ( 'yes' == pewc_vars.enable_character_counter ) { 1510 pewc_update_text_field_counters(); 1511 } 1512 }, 1513 250 ); 1514 $( 'body' ).on( 'pewc_add_button_clicked', function() { 1515 pewc_update_total_js(); 1516 }); 1517 $( 'body' ).on( 'pewc_force_update_total_js', function() { 1518 // Debounced: this event fires multiple times per user action from conditions.js. 1519 pewc_update_total_js_debounced(); 1520 }); 1521 1522 // Accordion and tabs 1523 // 4.3.3, created a function for the click so that repeatable groups can use it. Moved the function out of the container 1524 $( '.pewc-groups-accordion h3' ).on( 'click', function( e ){ 1525 pewc_accordion_click( $( this ) ); 1526 }); 1527 1528 if( pewc_vars.accordion_toggle == 'open' ) { 1529 $('.pewc-group-wrap').addClass('group-active'); 1530 } else if( pewc_vars.accordion_toggle == 'closed' ) { 1531 $('.pewc-group-wrap').removeClass('group-active'); 1532 } else { 1533 $('.first-group').addClass('group-active'); 1534 } 1535 1536 $('.pewc-tab').on('click',function(e) { 1537 // 3.13.7 1538 if ( $(this).hasClass( 'pewc-disabled-group') ) { 1539 return; 1540 } 1541 1542 e.preventDefault(); 1543 var tab_id = $(this).attr('data-group-id'); 1544 $('.pewc-tab').removeClass('active-tab tab-failed'); 1545 $( '.pewc-group-js-validation-notice' ).hide(); 1546 $(this).addClass('active-tab'); 1547 $('.pewc-group-wrap').removeClass('group-active'); 1548 $('.pewc-group-wrap-'+tab_id).addClass('group-active'); 1549 }); 1550 $('.pewc-next-step-button').on('click',function(e) { 1551 e.preventDefault(); 1552 // 3.13.7 1553 if ( $(this).hasClass( 'pewc-disabled-group') ) { 1554 return; 1555 } 1556 1557 var tab_id = $( this ).attr( 'data-group-id' ); 1558 var tab_index = $( this ).closest( '.pewc-group-wrap' ).attr( 'data-group-index' ); 1559 var direction = $( this ).attr( 'data-direction' ); 1560 $( '.pewc-tab' ).removeClass( 'active-tab tab-failed' ); 1561 $( '.pewc-group-js-validation-notice' ).hide(); 1562 // Check if the next group is visible 1563 if( $( '.pewc-group-wrap-' + tab_id ).hasClass( 'pewc-group-hidden' ) ) { 1564 // Count the total tabs 1565 var total_tabs = $( '.pewc-group-wrap' ).length; 1566 if( direction == 'next' ) { 1567 // Find the next group ID 1568 for( var i = parseInt( tab_index ) + 1; i < total_tabs; i++ ) { 1569 if( ! $( '.pewc-group-index-' + i ).hasClass( 'pewc-group-hidden' ) ) { 1570 tab_id = $( '.pewc-group-index-' + i ).attr( 'data-group-id' ); 1571 break; 1572 } 1573 } 1574 } else { 1575 // Find the previous group ID 1576 for( var i = parseInt( tab_index ) - 1; i >= 0; i-- ) { 1577 if( ! $( '.pewc-group-index-' + i ).hasClass( 'pewc-group-hidden' ) ) { 1578 tab_id = $( '.pewc-group-index-' + i ).attr( 'data-group-id' ); 1579 break; 1580 } 1581 } 1582 } 1583 } 1584 $( '#pewc-tab-' + tab_id ).addClass( 'active-tab' ); 1585 $( '.pewc-group-wrap' ).removeClass( 'group-active' ); 1586 $( '.pewc-group-wrap-' + tab_id ).addClass( 'group-active' ); 1587 1588 // Scroll to top 1589 if ( pewc_vars.steps_group_disable_scroll_to_top != 'yes' ) { 1590 if( $( '.pewc-steps-wrapper' ).length > 0 ) { 1591 $([document.documentElement, document.body]).animate({ 1592 scrollTop: $( '.pewc-steps-wrapper' ).offset().top 1593 }, 150); 1594 } 1595 } 1596 }); 1597 1598 function pewc_get_text_str_len( str, wrapper ) { 1599 var new_str, str_ex_spaces ; 1600 var field = $(wrapper).find('.pewc-form-field'); 1601 // Don't include spaces 1602 if( pewc_vars.remove_spaces != 'yes' ) { 1603 str_ex_spaces = str.replace(/\s/g, ""); 1604 } else { 1605 str_ex_spaces = str; 1606 } 1607 1608 var str_len = str_ex_spaces.length; 1609 // Exclude alphanumerics if selected 1610 if( $(field).attr('data-alphanumeric') == 1 ) { 1611 str_ex_spaces = str_ex_spaces.replace(/\W/g, ''); 1612 $(field).val(str_ex_spaces); 1613 str_len = str_ex_spaces.length; 1614 } 1615 // Allow alphanumerics but don't charge if selected 1616 if( $(field).attr('data-alphanumeric-charge') == 1 ) { 1617 str_ex_spaces = str_ex_spaces.replace(/\W/g, ''); 1618 // $(field).val(str_ex_spaces); 1619 str_len = str_ex_spaces.length; 1620 } 1621 // If free characters are allowed 1622 var freechars = $(field).attr('data-freechars'); 1623 str_len -= freechars; 1624 str_len = Math.max(0,str_len); 1625 return str_len; 1626 } 1627 1628 function pewc_disable_child_product_quantities() { 1629 $( '.woocommerce-cart-form__cart-item.pewc-child-product' ).each( function() { 1630 if( pewc_vars.disable_qty || pewc_vars.multiply_independent == 'yes' ) { 1631 $(this).find('.product-quantity input').attr('disabled',true); 1632 } 1633 }); 1634 } 1635 1636 // Disable quantity fields in Barn2 Fast Cart 1637 $('body').on('click', 'a.wfc-open-cart-button', function( e ) { 1638 var timeout = setTimeout( 1639 function() { 1640 $( '.wfc-cart-form__cart-item.pewc-child-product' ).each( function() { 1641 if( pewc_vars.disable_qty || pewc_vars.multiply_independent == 'yes' ) { 1642 $(this).find('.product-quantity input').attr('disabled',true); 1643 } 1644 }); 1645 }, 1646 250 1647 ); 1648 } ); 1649 1650 // only do this if there are actually child products 1651 if ( $('.woocommerce-cart-form__cart-item.pewc-child-product').length > 0 ) { 1652 // call function on page load 1653 pewc_disable_child_product_quantities(); 1654 // when cart is updated, disable quantities again 1655 $('body').on('updated_cart_totals', pewc_disable_child_product_quantities); 1656 } 1657 1658 // If child product is selected, manage allowable purchase quantity 1659 // Applies to radio and select 1660 $('body').on('change','.products-quantities-independent .pewc-child-select-field',function(){ 1661 var number_field = $(this).closest('.child-product-wrapper').find('.pewc-child-quantity-field'); 1662 if ( $( this ).val() != '') { 1663 // select field is not blank, update quantity 1664 if( $(number_field).val() == 0 ) { 1665 // Automatically enter a quantity when a product is selected 1666 $(number_field).val(1); 1667 }; 1668 } else { 1669 // reset number field 1670 $( number_field ).val(0); 1671 } 1672 //var available_stock = $(this).find(':selected').data('stock'); 1673 //if( available_stock ) { 1674 // var number = $(number_field).attr('max',available_stock); 1675 // if( $(number).val() > available_stock ) { 1676 // $(number_field).val(available_stock); 1677 // } 1678 //} else { 1679 // $(number_field).removeAttr('max'); 1680 //} 1681 // 3.27.3 1682 pewc_update_independent_quantity_input_max( $( this ), number_field ); 1683 }); 1684 1685 // 3.27.3, created a separate function so that we can call this on page load 1686 function pewc_update_independent_quantity_input_max( select_field, number_field) { 1687 1688 var available_stock = $( select_field ).find( ':selected' ).data( 'stock' ); 1689 if( available_stock ) { 1690 var number = $( number_field ).attr( 'max', available_stock ); 1691 if( $( number ).val() > available_stock ) { 1692 $( number_field ).val( available_stock ); 1693 } 1694 } else { 1695 $( number_field ).removeAttr( 'max' ); 1696 } 1697 1698 } 1699 1700 $('body').on('change input keyup paste click','.products-quantities-independent .pewc-child-quantity-field',function( e ) { 1701 e.stopPropagation(); // this prevents the click event from bubbling up to the event attached to the layer 1702 if ( $( this ).closest( '.pewc-item' ).hasClass( 'pewc-item-products-select' ) ) { 1703 // this is a Products select field 1704 var selIndex = 0; 1705 if( $(this).val() > 0 ) { 1706 var selField = $( this ).closest( '.pewc-item' ).find( 'select.pewc-child-select-field' ); 1707 // find first select option with value if not already selected 1708 selIndex = selField.prop( 'selectedIndex' ); 1709 if ( selIndex < 1 && selField.val() == '' ) { 1710 $( this ).closest( '.pewc-item' ).find( 'select.pewc-child-select-field option' ).each( function( index, element ) { 1711 if ( $(this).val() != '' && selIndex < 1 ) { 1712 selIndex = index; 1713 return; 1714 } 1715 }); 1716 } 1717 } 1718 $( this ).closest( '.pewc-item' ).find( 'select.pewc-child-select-field' ).prop( 'selectedIndex', selIndex ); 1719 } else { 1720 // Ensure this child product is selected 1721 // for checkbox images 1722 if( $(this).val() > 0 ) { 1723 var checkbox = $(this).closest('.pewc-checkbox-wrapper').find('input[type=checkbox]').prop('checked',true).trigger( 'change' ); 1724 } else { 1725 var checkbox = $(this).closest('.pewc-checkbox-wrapper').find('input[type=checkbox]').prop('checked',fal
1725se).trigger( 'change' ); 1726 } 1727 } 1728 var available_stock = $(this).find(':selected').data('stock'); 1729 // $( 'body' ).trigger( 'pewc_update_child_quantity', [ $(this).closest('.pewc-checkbox-image-wrapper').find('input[type=checkbox]') ] ); 1730 $( 'body' ).trigger( 'pewc_update_child_quantity', [ $(this).closest('.pewc-checkbox-wrapper').find('input[type=checkbox]') ] ); 1731 pewc_update_total_js(); 1732 }); 1733 1734 // 3.24.8, Products and Product Categories fields, Radio Images/Radio List layout, independent quantity. Since the quantity input is now outside .products-quantities-independent, the script above doesn't get triggered. 1735 $( 'body' ).on( 'change input keyup paste click', '.pewc-item-products-radio.pewc-item-products-independent .pewc-child-quantity-field, .pewc-item-products-radio-list.pewc-item-products-independent .pewc-child-quantity-field', function( e ){ 1736 var item_field_wrapper = $( this ).closest( '.pewc-item-field-wrapper' ); 1737 var pewc_item_wrapper = item_field_wrapper.closest( '.pewc-item' ); 1738 var radio_type = ''; 1739 var number_checked = 0; 1740 1741 if ( pewc_item_wrapper.hasClass( 'pewc-item-products-radio' ) ) { 1742 radio_type = 'radio images'; 1743 number_checked = item_field_wrapper.find( '.pewc-radio-images-wrapper .pewc-radio-image-wrapper.checked' ).length; 1744 } else { 1745 radio_type = 'radio list'; 1746 number_checked = item_field_wrapper.find( '.pewc-radio-wrapper input.pewc-radio-form-field:checked' ).length; 1747 } 1748 1749 var number_value = $( this ).val(); 1750 if ( number_value > 0 && number_checked < 1 ) { 1751 // we don't have a product selected, select the first one? 1752 if ( radio_type == 'radio images' ) { 1753 item_field_wrapper.find( '.pewc-radio-images-wrapper .pewc-radio-image-wrapper' ).each( function(){ 1754 if ( ! $( this ).hasClass( 'checked' ) ) { 1755 $( this ).addClass( 'checked' ); 1756 } 1757 $( this ).find( 'input.pewc-radio-form-field' ).prop( 'checked', true ); 1758 return false; // break the loop since we only want to select the first one 1759 }); 1760 } else { 1761 // radio list 1762 item_field_wrapper.find( '.pewc-radio-list-wrapper .pewc-radio-wrapper input.pewc-radio-form-field' ).each( function(){ 1763 $( this ).prop( 'checked', true ); 1764 return false; // break the loop since we only want to select the first one 1765 }); 1766 } 1767 } else if ( number_value < 1 && number_checked > 0 ) { 1768 // de-select all products 1769 if ( radio_type == 'radio images' ) { 1770 item_field_wrapper.find( '.pewc-radio-images-wrapper .pewc-radio-image-wrapper.checked' ).each( function(){ 1771 $( this ).removeClass( 'checked' ); 1772 $( this ).find( 'input.pewc-radio-form-field' ).prop( 'checked', false ); 1773 }); 1774 } else { 1775 // radio list 1776 item_field_wrapper.find( '.pewc-radio-list-wrapper .pewc-radio-wrapper input.pewc-radio-form-field:checked' ).each( function(){ 1777 $( this ).prop( 'checked', false ); 1778 }); 1779 } 1780 } 1781 }); 1782 1783 $('body').on('change input keyup paste','.pewc-item-products-independent.pewc-child-qty-target .pewc-child-quantity-field',function() { 1784 // This runs when the user manually updates a child product quantity that has been set by a calculation field (independent quantities, radio items only) 1785 // If the calculation field has a reverse formula, use the result to set the source field value 1786 var wrapper = $( this ).closest( '.pewc-item' ); 1787 // This is the ID of the calculation field that triggers this quantity update 1788 var triggered_by = $( wrapper ).attr( 'data-child-qty-triggered-by' ); 1789 // Get the "reverse formula" - i.e. the method to calculate how to update the source input field 1790 var reverse_field_id = $( '.pewc-field-' + triggered_by ).attr( 'data-reverse-formula-field' ); 1791 var reverse_formula = calculations.get_formula_by_id( reverse_field_id ); 1792 // Do this calc "live" to avoid any race conditions with other fields getting updated 1793 calc_field = $( '.pewc-field-' + reverse_field_id ); 1794 calc_field_id = $( calc_field ).attr( 'data-field-id' ); 1795 price_wrapper = $( calc_field ).find( '.pewc-calculation-price-wrapper' ); 1796 calc_field_id = $( calc_field ).attr( 'data-field-id' ); 1797 formula = $( price_wrapper ).find( '.pewc-data-formula' ).val(); 1798 fields = $( price_wrapper ).find( '.pewc-data-fields' ).val(); 1799 round = $( price_wrapper ).find( '.pewc-formula-round' ).val(); 1800 decimals = $( price_wrapper ).find( '.pewc-decimal-places' ).val(); 1801 if( fields ) { 1802 fields = JSON.parse( fields ); 1803 } 1804 var reverse_result = calculations.evaluate_formula( fields, reverse_formula, round, decimals, calc_field_id ); 1805 // Update the "source" input field with the result of the reverse calculation 1806 // The source input is the number field used in the main calculation field 1807 var source_field_id = $( '.pewc-field-' + triggered_by ).attr( 'data-reverse-input-field' ); 1808 $( '.pewc-field-' + source_field_id ).find( 'input' ).val( reverse_result ); 1809 1810 // Check if the calculation can be overridden by manual quantity updates 1811 if( $( '.pewc-field-' + triggered_by ).hasClass( 'pewc-quantity-overrides' ) ) { 1812 // Only set the quantity of this field with the result of the calculation once - to allow users to override the calculation by updating the quantity manually 1813 $( wrapper ).addClass( 'pewc-quantity-updated' ); 1814 } 1815 1816 }); 1817 $( 'body' ).on( 'pewc_update_child_quantity', function( e, el ) { 1818 // This is triggered when the quantity field for a child product is updated 1819 var child_qty = $( el ).closest('.pewc-checkbox-wrapper').find('input[type=number]').val(); 1820 if( child_qty > 0 ) { 1821 $( el ).closest('.pewc-checkbox-image-wrapper').addClass('checked'); 1822 } else { 1823 $( el ).closest('.pewc-checkbox-image-wrapper').removeClass('checked'); 1824 } 1825 }); 1826 $( 'body' ).on( 'click', '.products-quantities-independent .pewc-checkbox-form-field', function( e ) { 1827 // aou-products-column-new, added 2nd condition 1828 if( $( this ).closest( '.pewc-checkbox-images-wrapper' ).hasClass( 'pewc-force-quantity' ) || $( this ).closest( '.pewc-checkbox-image-wrapper' ).find( '.pewc-column-attributes-select' ).length > 0 ) { 1829 e.stopPropagation(); 1830 e.preventDefault(); // 3.25.7, prevent the hidden input checkbox from being unchecked and deselected 1831 return; 1832 } 1833 // this is triggered when clicking the child product's image 1834 if( $(this).is(':checked') ){ 1835 var number = $(this).closest('.pewc-checkbox-wrapper').find('input[type=number]').val(); 1836 if( number==0 ) { 1837 var default_quantity = $(this).closest( '.pewc-checkbox-wrapper' ).find( 'input[type=number]' ).attr( 'data-default-quantity' ); 1838 if( default_quantity == undefined || pewc_vars.set_child_quantity_default != 'yes' ) { 1839 default_quantity = 1; 1840 } 1841 $(this).closest('.pewc-checkbox-wrapper').find('input[type=number]').val( default_quantity ); 1842 //$(this).closest('.pewc-checkbox-image-wrapper').addClass('checked'); // commented out in 3.13.2, this is handled when the wrapper itself is clicked 1843 } 1844 } else { 1845 var number = $(this).closest('.pewc-checkbox-wrapper').find('input[type=number]').val(0); 1846 //$(this).closest('.pewc-checkbox-image-wrapper').removeClass('checked'); // commented out in 3.13.2 1847 } 1848 e.stopPropagation(); // added in 3.13.2. this may be triggered when the wrapper is clicked. Prevents infinite loop 1849 }); 1850 $( 'body' ).on( 'click', '.products-quantities-linked .pewc-checkbox-form-field, .products-quantities-one-only .pe
1850wc-checkbox-form-field', function( e ) { 1851 e.stopPropagation(); // 3.13.3, prevents infinite loop 1852 if( $(this).is(':checked') ){ 1853 $(this).closest('.pewc-checkbox-image-wrapper').addClass('checked'); 1854 } else { 1855 $(this).closest('.pewc-checkbox-image-wrapper').removeClass('checked'); 1856 } 1857 }); 1858 1859 // Toggle class on label when text swatch element is updated 1860 $( 'body' ).on( 'change', '.pewc-text-swatch input', function( e ) { 1861 var field_type = $( this ).closest( '.pewc-item' ).attr( 'data-field-type' ); 1862 if( field_type == 'radio' ) { 1863 $( this ).closest( 'ul' ).find( 'label' ).removeClass( 'active-swatch' ); 1864 } 1865 1866 if( $( this ).prop( 'checked' ) == true ) { 1867 $( this ).closest( 'label' ).addClass( 'active-swatch' ); 1868 } else { 1869 $( this ).closest( 'label' ).removeClass( 'active-swatch' ); 1870 } 1871 }); 1872 1873 $( 'body' ).on( 'click', '.pewc-radio-image-wrapper, .pewc-checkbox-image-wrapper', function( e ) { 1874 var wrapper = $( this ); 1875 if( $( wrapper ).hasClass( 'pewc-checkbox-disabled' ) ) { 1876 return; 1877 } 1878 if( $( wrapper ).closest( '.pewc-components-wrapper' ).hasClass( 'pewc-force-quantity' ) ) { 1879 return; 1880 } 1881 1882 // aou-products-column-new, disable the click event for Column layout with attributes selection 1883 if ( $( wrapper ).find( '.pewc-column-attributes-select' ).length > 0 ) { 1884 return; 1885 } 1886 1887 // 1888 var radio; 1889 var is_image_swatch_checkbox = $( wrapper ).closest( '.pewc-item' ).hasClass( 'pewc-item-image-swatch-checkbox' ); 1890 var is_checkbox = $( wrapper ).hasClass( 'pewc-checkbox-image-wrapper' ); 1891 // Remove all checked for radio button 1892 if( ! is_image_swatch_checkbox && ! is_checkbox ) { 1893 var checked = $( wrapper ).find( '.pewc-radio-form-field' ).prop( 'checked' ); 1894 var group = $( wrapper ).closest( '.pewc-radio-images-wrapper' ).find( '.pewc-radio-image-wrapper' ).removeClass( 'checked' ); 1895 if( ! checked ) { 1896 $( wrapper ).addClass( 'checked' ); 1897 //radio = $( wrapper ).find( '.pewc-radio-form-field' ).trigger( 'click' ); 1898 } 1899 // Defer the heavy synchronous chain (conditions, price update) so the browser can 1900 // paint the checked class before running the condition check / price recalculation. 1901 radio = $( wrapper ).find( '.pewc-radio-form-field' ); 1902 setTimeout( function() { radio.trigger( 'click' ); }, 0 ); // moved here 3.9.5 for lightbox 1903 } else { 1904 // Checkbox 1905 if ( is_checkbox ) { 1906 // added in 3.13.2 for Products checkbox images 1907 e.preventDefault(); // this helps avoid the conflict with clicking the child product image 1908 radio = $( wrapper ).find( '.pewc-checkbox-form-field' ); 1909 $( wrapper ).toggleClass( 'checked' ); 1910 if ( is_image_swatch_checkbox ) { 1911 // 4.3.1, Swatch fields with Allow multiple enable wasn't getting added. trigger( 'click' ) below also causes infinite loop with the new Swatch template 1912 var checked = $( radio ).prop( 'checked' ); 1913 var new_checked = ! checked; 1914 setTimeout( function() { $( radio ).prop( 'checked', new_checked ).trigger( 'change' ); }, 0 ); 1915 } else { 1916 // keeping this here in case Products field need this 1917 setTimeout( function() { $( radio ).trigger( 'click' ); }, 0 ); // this triggers the click event attached to .products-quantities-independent .pewc-checkbox-form-field 1918 } 1919 e.stopPropagation(); 1920 } else { 1921 radio = $( wrapper ).find( '.pewc-radio-form-field' ); 1922 var checked = $( radio ).prop( 'checked' ); 1923 $( wrapper ).toggleClass( 'checked' ); 1924 var new_checked = ! checked; 1925 setTimeout( function() { $( radio ).prop( 'checked', new_checked ).trigger( 'click' ); }, 0 ); // click added 3.9.5 1926 } 1927 } 1928 1929 }).on( 'click', '.pewc-radio-image-wrapper .pewc-radio-form-field', function( e ) { 1930 // aou-products-column-new, disable the click event for Column layout with attributes selection 1931 var wrapper = $( this ).closest( '.pewc-radio-image-wrapper' ); 1932 if ( $( wrapper ).find( '.pewc-column-attributes-select' ).length > 0 ) { 1933 return; 1934 } 1935 var is_image_swatch_checkbox = $( this ).closest( '.pewc-item' ).hasClass( 'pewc-item-image-swatch-checkbox' ); 1936 if( ! is_image_swatch_checkbox ) { 1937 // Stop propagation for radio buttons 1938 e.stopPropagation(); 1939 // Deselect the radio button 1940 var checked = $( this ).closest( '.pewc-radio-image-wrapper' ).hasClass( 'checked' ); 1941 if( ! checked ) { 1942 $( this ).prop( 'checked', false ).trigger( 'change' ); // added on 3.9.5 for lightbox 1943 // pewc_update_total_js() removed: trigger(change) above fires pewc_update_total_js_debounced via .pe
1943wc-form-field handler 1944 } 1945 } else { 1946 e.stopPropagation(); // added on 3.9.5, for checkbox in lightbox 1947 $( this ).closest( '.pewc-radio-image-wrapper' ).toggleClass( 'checked' ); // originally here before 3.9.5 1948 } 1949 $form = $( this ).closest( 'form' ); 1950 add_on_images.update_add_on_image( $( this ), $form ); 1951 }); 1952 1953 $( 'body' ).on( 'click' , '.products-quantities-independent .pewc-radio-form-field', function() { 1954 if($(this).is(':checked')) { 1955 var number_field = $(this).closest('.pewc-item-field-wrapper').find('input[type=number]'); 1956 var number = $(number_field).val(); 1957 if( number == 0 ) { 1958 $( number_field ).val( 1 ); 1959 } 1960 if( $(this).attr('data-stock') > 0 ) { 1961 // Ensure the quantity field doesn't display more than the available stock 1962 $(number_field).attr( 'max', $(this).attr('data-stock') ); 1963 if( $(number_field).val() > $(this).attr('data-stock') ) { 1964 $(number_field).val( $(this).attr('data-stock') ); 1965 } 1966 } 1967 } else { 1968 //var number = $(this).closest( '.pewc-radio-images-wrapper' ).find( 'input[type=number]' ).val( 0 ); 1969 var number = $(this).closest( '.pewc-item-field-wrapper' ).find( 'input[type=number]' ).val( 0 ); // 3.24.8, change quantity to 0 for Products and Product Categories field, Radio Images layout, independent quantity 1970 } 1971 }); 1972 1973 // 3.12.0, handler for enabling/disabling the add-to-cart button 1974 function pewc_toggle_add_to_cart_button( eventType, disabled, caller ) { 1975 1976 var button = $( 'body' ).find( 'form.cart .single_add_to_cart_button' ); 1977 var disable_class = 'pewc-disabled-by-'+caller; 1978 1979 if ( button.length < 1 ) return; // do nothing 1980 1981 // 4.3.14, it is possible to have more than one button e.g. Add to Quote button 1982 button.each( function(){ 1983 var curr_button = $( this ); 1984 if ( disabled ) { 1985 // always disable button 1986 curr_button.attr( 'disabled', true ); 1987 if ( ! curr_button.hasClass( disable_class ) ) { 1988 curr_button.addClass( disable_class ); 1989 1990 // 3.21.5 1991 var button_text = pewc_vars.calculating_text; 1992 if ( caller === 'upload' ) { 1993 button_text = pewc_vars.uploading_text; 1994 } 1995 pewc_update_add_to_cart_button_text( curr_button, button_text, disabled ); 1996 } 1997 } else { 1998 // remove the disable_class added by the caller when it enabled it previously 1999 curr_button.removeClass( disable_class ); 2000 // if we're trying to enable the add-to-cart button, check first if it hasn't been disabled by other plugins (example, by the calculation table) 2001 if ( curr_button.attr( 'class' ).indexOf( 'pewc-disabled-by' ) == -1 ) { 2002 // our special class was not found, safe to enable again 2003 curr_button.attr( 'disabled', false ); 2004 var default_text = pewc_vars.default_add_to_cart_text; 2005 if ( curr_button.attr( 'data-pewc-orig-button-text' ) ) { 2006 default_text = curr_button.attr( 'data-pewc-orig-button-text' ); 2007 } 2008 pewc_update_add_to_cart_button_text( curr_button, default_text ); 2009 } 2010 } 2011 }); 2012 2013 } 2014 $( 'body' ).on( 'pewc_toggle_add_to_cart_button', pewc_toggle_add_to_cart_button ); 2015 2016 function pewc_update_add_to_cart_button_text( button, button_text, disabled=false ) { 2017 if ( button.is( 'button' ) ) { 2018 if ( disabled && ! button.attr( 'data-pewc-orig-button-text' ) ) { 2019 // 4.3.14, save first the original text e.g. could be Add to Quote 2020 button.attr( 'data-pewc-orig-button-text', button.text() ); 2021 } 2022 button.text( button_text ); 2023 } else { 2024 if ( disabled && ! button.attr( 'data-pewc-orig-button-text' ) ) { 2025 // 4.3.14, save first the original text 2026 button.attr( 'data-pewc-orig-button-text', button.val() ); 2027 } 2028 button.val( button_text ); // maybe an input type submit button 2029 } 2030 } 2031 2032 var calculations = { 2033 2034 init: function() { 2035 2036 if( pewc_vars.calculations_timer > 0 ) { 2037 if ( pewc_vars.event_driven_conditions === 'yes' ) { 2038 // 4.3.5: bind recalculate to field change events instead of polling every 500ms. 2039 // These are the same triggers used by the non-optimised path but run within the 2040 // optimised context so we don't fall back to legacy condition-checking behaviour. 2041 $( 'body' ).on( 'keyup input change paste', 'form.cart .qty', this.recalculate ); 2042 $( 'body' ).on( 'keyup input change paste', 'form.cart .pewc-item.pewc-calculation-trigger, .pewc-form-field.pewc-calculation-trigger, .pewc-field-triggers-condition .pewc-form-field, .pewc-field-triggers-condition .pewc-radio-form-field', this.recalculate ); 2043 $( 'body' ).on( 'keyup input change paste', '.pewc-number-uploads', this.recalculate ); 2044 $( 'body' ).on( 'pewc_trigger_calculations', this.recalculate ); 2045 $( 'body' ).on( 'pewc_conditions_checked', this.recalculate ); 2046 $( 'body' ).one( 'pewc_after_update_total_js', this.recalculate ); 2047 } else { 2048 var interval = setInterval( 2049 this.recalculate, 2050 pewc_vars.calculations_timer 2051 ); 2052 } 2053 2054 // since 3.12.0, disable add-to-cart button while recalculating 2055 if ( pewc_vars.disable_button_recalculate == 'yes' ) { 2056 $( 'body' ).on( 'keyup input change paste', 'form.cart .qty', this.disable_add_to_cart_button ); 2057 $( 'body' ).on( 'keyup input change paste', 'form.cart .pewc-item.pewc-calculation-trigger, .pewc-form-field.pewc-calculation-trigger, .pewc-field-triggers-condition .pewc-form-field, .pewc-field-triggers-condition .pewc-radio-form-field', this.disable_add_to_cart_button ); 2058 $( 'body' ).on( 'keyup input change paste', '.pewc-number-uploads', this.disable_add_to_cart_button ); 2059 $( 'body' ).on( 'pewc_trigger_calculations', this.disable_add_to_cart_button ); 2060 $( 'body' ).on( 'pewc_conditions_checked', this.disable_add_to_cart_button ); 2061 } 2062 } else { 2063 // $( 'body' ).one( 'keyup input change paste', '.pewc-number-field.pewc-calculation-trigger, .pewc-field-triggers-condition .pewc-number-field', this.recalculate ); 2064 $( 'body' ).on( 'keyup input change paste', 'form.cart .qty', this.recalculate ); 2065 $( 'body' ).on( 'keyup input change paste', 'form.cart .pewc-item.pewc-calculation-trigger, .pewc-form-field.pewc-calculation-trigger, .pewc-field-triggers-condition .pewc-form-field, .pewc-field-triggers-condition .pewc-radio-form-field', this.recalculate ); 2066 $( 'body' ).on( 'keyup input change paste', '.pewc-number-uploads', this.recalculate ); 2067 $( 'body' ).on( 'pewc_trigger_calculations', this.recalculate ); 2068 $( 'body' ).on( 'pewc_conditions_checked', this.recalculate ); 2069 } 2070 2071 }, 2072 2073 // 3.12.0 2074 disable_add_to_cart_button: function( e ) { 2075 // 3.12.2. Only disable if product has calculation fields 2076 var num_calcs = $( '.pewc-product-extra-groups-wrap .pewc-item-calculation' ).not( '.pewc-hidden-field' ).length; 2077 2078 if( parseFloat( num_calcs ) < 1 ) { 2079 return; 2080 } 2081 pewc_toggle_add_to_cart_button( e, true, 'calculation_recalculate' ); 2082 }, 2083 2084 recalculate: function( e ) { 2085 2086 // If we don't have any calculation fields, just bounce 2087 var num_calcs = parseInt( $( '.pewc-product-extra-groups-wrap .pewc-item-calculation' ).not( '.pewc-hidden-field' ).length ); 2088 var num_formulas_in_field_prices = parseInt( $( '.pewc-product-extra-groups-wrap .pewc-field-price-has-formula' ).not( '.pewc-hidden-field' ).length ); 2089 var num_formulas_in_option_prices = parseInt( $( '.pewc-product-extra-groups-wrap .pewc-field-option-price-has-formula' ).not( '.pewc-hidden-field' ).length ); 2090 2091 if( num_calcs < 1 && num_formulas_in_field_prices < 1 && num_formulas_in_option_prices < 1 ) { 2092 return; 2093 } 2094 2095 var calc_field, price_wrapper, dimensions_wrapper, formula, tags, calc_formula, replace, calc_field_id, calc_value, prev_calc_value; 2096 2097 var calc_fields = []; 2098 2099 var update = 0; 2100 2101 if ( pewc_vars.calculations_timer > 0 && pewc_vars.disable_button_recalculate == 'yes' ) { 2102 // 3.12.0, we use this to determine if we have to enable or disable the add-to-cart button 2103 var pewc_total_calc_price_start = $( '#pewc_total_calc_price' ).val(); 2104 } 2105 2106 // Find any calculation fields 2107 $( 'body' ).find( 'form.cart .pewc-item-calculation' ).not( '.pewc-hidden-field' ).each( function() { 2108 2109 if( $( this ).hasClass( 'pewc-variation-dependent' ) && ! $( this ).hasClass( 'active' ) ) { 2110 return; 2111 } 2112 2113 var group = $( this ).closest( '.pewc-group-wrap' ); 2114 if( $( group ).hasClass( 'pewc-group-hidden' ) ) { 2115 return; 2116 } 2117 2118 var group_id = $( group ).attr( 'data-group-id' ); 2119
2120 calc_field = $( this ); 2121 var field_id = $( calc_field ).attr( 'data-id' ); 2122 calc_field_id = $( calc_field ).attr( 'data-field-id' ); 2123 price_wrapper = $( calc_field ).find( '.pewc-calculation-price-wrapper' ); 2124 formula = $( price_wrapper ).find( '.pewc-data-formula' ).val(); 2125 fields = $( price_wrapper ).find( '.pewc-data-fields' ).val(); 2126 tags = $( price_wrapper ).find( '.pewc-data-tag' ).val(); 2127 action = $( price_wrapper ).find( '.pewc-action' ).val(); 2128 round = $( price_wrapper ).find( '.pewc-formula-round' ).val(); 2129 decimals = $( price_wrapper ).find( '.pewc-decimal-places' ).val(); 2130 calc_value = $( price_wrapper ).find( '.pewc-calculation-value' ); 2131 prev_calc_value = calc_value.val(); 2132 2133 if( fields ) { 2134 fields = JSON.parse( fields ); 2135 } 2136 2137 var result = calculations.evaluate_formula( fields, formula, round, decimals, calc_field_id ); 2138 2139 if( result == '*' ) { 2140 $( calc_field ).closest( '.pewc-item-calculation' ).attr( 'data-price', 0 ); 2141 $( price_wrapper ).find( 'span' ).html( pewc_vars.null_signifier ); 2142 calc_value.val( 0 ); 2143 if ( prev_calc_value != 0 ) { 2144 // 3.12.2. Trigger only if the value changed to avoid infinite loop 2145 calc_value.trigger( 'calculation_field_updated' ) 2146 } 2147 if( pewc_vars.disable_button_calcs == 'yes' ) { 2148 calc_fields.push( calc_field_id ); 2149 //$( 'body' ).find( 'form.cart .single_add_to_cart_button' ).attr( 'disabled', true ); 2150 $( 'body' ).trigger( 'pewc_toggle_add_to_cart_button', [ true, 'calculation' ] ); // since 3.12.0 2151 } 2152 } else if( ! result || ! isNaN( result ) ) { 2153 if( pewc_vars.disable_button_calcs == 'yes' ) { 2154 calc_fields = calc_fields.filter( function( item ) { 2155 return item !== calc_field_id; 2156 }); 2157 if( calc_fields.length < 1 ) { 2158 //$( 'body' ).find( 'form.cart .single_add_to_cart_button' ).attr( 'disabled', false ); 2159 $( 'body' ).trigger( 'pewc_toggle_add_to_cart_button', [ false, 'calculation' ] ); // since 3.12.0 2160 } 2161 } 2162 $( price_wrapper ).find( 'span' ).html( result ); 2163 2164 if( action == 'cost' || action == 'price' ) { 2165 $( calc_field ).closest( '.pewc-item-calculation' ).attr( 'data-price', result ); 2166 $( price_wrapper ).find( 'span' ).html( pewc_wc_price( result ) ); 2167 } else if( action == 'qty' ) { 2168 $( 'form.cart' ).find( '.quantity .qty' ).val( result ).trigger( 'pewc_qty_changed' ); 2169 } else if( action == 'child-qty' ) { 2170 // When a calculation updates, check if it should update a child product quantity field (independent, radio buttons only) 2171 // If it does, we update the quantity field 2172 // This is the product field that will have its quantity set 2173 var product_field_id = $( calc_field ).closest( '.pewc-item-calculation' ).find( '.pewc-calculation-price-wrapper' ).attr( 'data-product-field-id' ); 2174 // This is the ID of the child product that will be selected 2175 var child_qty_product_id = $( calc_field ).closest( '.pewc-item-calculation' ).find( '.pewc-calculation-price-wrapper' ).attr( 'data-child-product-id' ); 2176 // Only set the result of this calculation once - don't update quantity if the user has updated it manually themselves 2177 if( ! $( '.pewc-field-' + product_field_id ).hasClass( 'pewc-quantity-updated' ) ) { 2178 $( '.pewc-field-' + product_field_id ).find( '.pewc-child-quantity-field' ).val( result ).trigger( 'pewc_update_child_quantity' ); 2179 var group_name = 'pewc_group_' + group_id + '_' + product_field_id; 2180 // Auto select item (provided an item is not already selected) 2181 if( $( "input[name='" + group_name + "_child_product[]']:checked" ).length < 1 ) { 2182 $( '#' + group_name + '_' + child_qty_product_id ).prop( 'checked', true ); 2183 $( '#' + group_name + '_' + child_qty_product_id ).closest( '.pewc-radio-image-wrapper' ).addClass( 'checked' ); 2184 } 2185 } 2186 } else if ( ! $( calc_field ).hasClass( 'pewc-hidden-calculation' ) ) { 2187 // no-action falls here, don't bother if calc field is hidden 2188 // pewc-result-format is filterable 2189 var result_format = $( price_wrapper ).find( '.pewc-result-format' ).val(); 2190 if ( result_format == 'price' ) { 2191 $( price_wrapper ).find( 'span' ).html( pewc_wc_price( result ) ); 2192 } else if ( result_format == 'price without currency' ) { 2193 $( price_wrapper ).find( 'span' ).html( pewc_wc_price_without_currency( result ) ); 2194 } 2195 } 2196 2197 if( action == 'price' ) { 2198 $( calc_field ).closest( '.pewc-product-extra-groups-wrap' ).find( '#pewc_calc_set_price' ).val( result ).attr( 'data-calc-set', 1 ); // 3.17.2, compatibility with Product Table Ultimate 2199 //$( '#pewc_calc_set_price' ).val( result ).attr( 'data-calc-set', 1 ); // before 3.17.2 2200 } 2201 2202 calc_value.val( result ); 2203 if ( prev_calc_value != result ) { 2204 // 3.12.2. Trigger only if the value changed to avoid infinite loop 2205 calc_value.trigger( 'calculation_field_updated' ); 2206 calc_value.trigger( 'change' ); // 3.17.2, makes this field more responsive to changes by typing 2207 } 2208 } else if( result && isNaN( result ) && result != 'error' ) { 2209 allow_text_calcs_fields = pewc_vars.allow_text_calcs_fields; 2210 if( pewc_vars.allow_text_calcs ) { 2211 $( price_wrapper ).find( 'span' ).html( result ); 2212 calc_value.val( result ); 2213 } else if( allow_text_calcs_fields.includes( parseInt( calc_field_id ) ) ) { 2214 $( price_wrapper ).find( 'span' ).html( result ); 2215 calc_value.val( result ); 2216 } 2217 } 2218 2219 update++; 2220 2221 }); 2222 2223 // 3.26.0 2224 if ( num_formulas_in_field_prices > 0 ) { 2225 calculations.evaluate_field_prices(); 2226 } 2227 if ( num_formulas_in_option_prices > 0 ) { 2228 calculations.evaluate_option_prices(); 2229 } 2230 2231 // Update the totals 2232 if( update > 0 ) { 2233 update = 0; 2234 pewc_update_total_js(); 2235 } 2236 2237 if ( pewc_vars.calculations_timer > 0 && pewc_vars.disable_button_recalculate == 'yes' ) { 2238 // 3.12.0, we use this to determine if we have to enable or disable the add-to-cart button 2239 var pewc_total_calc_price_end = $( '#pewc_total_calc_price' ).val(); 2240 var d = new Date(); 2241 var time = d.getTime(); 2242 2243 if ( pewc_total_calc_price_start != pewc_total_calc_price_end ) { 2244 // maybe we're not done calculating, disable the add-to-cart button 2245 $( 'body' ).trigger( 'pewc_toggle_add_to_cart_button', [ true, 'calculation_recalculate' ] ); 2246 // record the last time there was a change 2247 $( '#pewc_total_calc_price' ).attr( 'data-last-calc-time', time ); 2248 } else { 2249 // maybe we're done calculating, let's wait a second? 2250 if ( isNaN( $( '#pewc_total_calc_price' ).attr( 'data-last-calc-time') ) ) { 2251 // maybe this is not yet created, save a value 2252 $( '#pewc_total_calc_price' ).attr( 'data-last-calc-time', time ); 2253 } else { 2254 var diff = parseFloat( time ) - parseFloat( $( '#pewc_total_calc_price' ).attr( 'data-last-calc-time') ); 2255 if ( isNaN( diff ) || diff < pewc_vars.recalculate_waiting_time ) { 2256 // do nothing if not a number, or less than waiting time (default 0.7 seconds) 2257 } else { 2258 //enable the add-to-cart button 2259 $( 'body' ).trigger( 'pewc_toggle_add_to_cart_button', [ false, 'calculation_recalculate' ] ); 2260 } 2261 } 2262 } 2263 2264 } 2265 2266 }, 2267
2268 evaluate_look_up_table: function( calc_field_id ) { 2269 2270 var result = false; 2271 2272 if( pewc_look_up_fields == undefined ) return false; 2273 2274 var look_up_field = pewc_look_up_fields[calc_field_id]; 2275 2276 var table = look_up_field[0]; 2277 var x_field = look_up_field[1]; 2278 var y_field = look_up_field[2]; 2279 2280 var x_value = this.get_field_value( x_field ); 2281 var y_value = this.get_field_value( y_field ); 2282 2283 var tables = pewc_look_up_tables[table]; 2284 if( tables == undefined ) { 2285 return false; 2286 } 2287 2288 var x_axis = tables[x_value]; 2289 2290 // If there's not an element in the tables array for our x value, find the next one 2291 if( x_axis == undefined && x_value && x_value != undefined ) { 2292 if ( this.exact_match( calc_field_id, 'x' ) ) { 2293 return '*'; // 3.13.0, let's use the null signifier 2294 } else { 2295 x_value = calculations.find_nearest_index( x_value, tables ); 2296 x_axis = tables[x_value]; 2297 } 2298 } else if( x_axis == undefined && x_value==0 && x_value != undefined ) { 2299 x_axis = tables[Object.keys(tables)[0]]; 2300 } 2301 2302 if( x_axis != undefined ) { 2303 2304 var y_axis = tables[y_value]; 2305 2306 // if( y_axis == undefined && y_value && y_value != undefined ) { 2307 if( y_value && y_value != undefined ) { 2308 if ( ! this.exact_match( calc_field_id, 'y' ) ) { 2309 y_value = calculations.find_nearest_index( y_value, x_axis ); 2310 } 2311 } 2312 if( y_value == 'max' ) { 2313 // Get last value in x_axis 2314 result = x_axis[Object.keys(x_axis)[Object.keys(x_axis).length - 1]]; 2315 } else { 2316 result = x_axis[y_value]; 2317 } 2318 2319 if ( this.exact_match( calc_field_id, 'y' ) && result == undefined ) { 2320 result = '*'; // 3.13.0 2321 } 2322 } else { 2323 2324 return false; 2325 2326 } 2327 2328 return result; 2329 2330 }, 2331 2332 get_field_value: function( field_id ) { 2333 2334 var value = 0; 2335 2336 if( $( '.pewc-field-' + field_id ).find( 'input.pewc-number-field' ).length > 0 ) { 2337 return $( '.pewc-field-' + field_id ).find( 'input.pewc-number-field' ).val(); 2338 } else if( $( '.pewc-field-' + field_id ).find( 'select' ).length > 0 ) { 2339 if( ! isNaN( $( '.pewc-field-' + field_id ).find( 'select option:selected' ).attr( 'value' ) ) ) { 2340 // Return the option 'label' if it's numeric 2341 return $( '.pewc-field-' + field_id ).find( 'select option:selected' ).attr( 'value' ); 2342 } else { 2343 // Return the option's 'price' 2344 return $( '.pewc-field-' + field_id ).find( 'select option:selected' ).attr( 'data-option-cost' ); 2345 } 2346 2347 } else if( $( '.pewc-field-' + field_id ).find( 'input.pewc-radio-form-field[type="radio"]:checked' ).length > 0 ) { 2348 return $( '.pewc-field-' + field_id ).find( 'input.pewc-radio-form-field[type="radio"]:checked' ).attr( 'data-option-cost' ); 2349 } 2350 2351 return value; 2352 }, 2353 2354 find_nearest_index: function( value, axis ) { 2355 2356 var keys = Object.keys( axis ); // Just the keys 2357 keys.sort( (a,b) => a-b ); // sort the keys numerically. This is needed if keys have decimals 2358 2359 if( parseFloat( value ) <= parseFloat( keys[0] ) ) { 2360 return keys[0]; 2361 } 2362 2363 // If first element is empty, replace with 0 2364 if( pewc_vars.set_initial_key == 'yes' ) { 2365 if( isNaN( keys[0] ) || keys[0] == '' ) { 2366 keys[0] = 0; 2367 } 2368 } 2369 2370 for( var i=0; i < keys.length; i++ ) { 2371 if( ( parseFloat( value ) > parseFloat( keys[i] ) ) && keys[i+1] !=undefined && ( parseFloat( value ) <= parseFloat( keys[i+1] ) ) ) { // Find the first key that is greater than the value passed in 2372 return keys[i+1]; 2373 } 2374 } 2375 2376 if( keys[( keys.length ) - 1] == 'max' ) { 2377 return 'max'; 2378 } 2379 2380 // Return this as a fallback in case we've gone over the last index 2381 return keys[i]; 2382 2383 }, 2384 2385 exact_match: function( calc_field_id, axis ) { 2386 // since 3.13.0 2387 if ( $( '.pewc-item-calculation.pewc-field-' + calc_field_id ).attr( 'data-exact-match-' + axis ) == 'yes' ) { 2388 return true; 2389 } else { 2390 return false; 2391 } 2392 }, 2393 2394 evaluate_formula: function( fields, formula, round, decimals, calc_field_id ) { 2395 2396 var calc_formula = formula; 2397 2398 if( fields ) { 2399 2400 // Replace any field tags with values 2401 for( var i in fields ) { 2402 2403 // Look for any price values 2404 if( fields[i].indexOf( '_option_price' ) > -1 ) { 2405 var field_id = fields[i].replace( '_option_price', '' ); 2406 // We want the price of the selected option in this field, not its value 2407 var o_price = parseFloat( $( 'form.cart .pewc-field-' + field_id ).attr( 'data-selected-option-price' ) ); 2408 if( isNaN( o_price ) || ( $( 'form.cart .pewc-field-' + field_id ).length == 0 && pewc_vars.zero_missing_field == 'yes' ) ) { 2409 o_price = 0; 2410 } 2411 replace = new RegExp( '{field_' + fields[i] + '}', 'g' ); 2412 calc_formula = calc_formula.replace( replace, o_price ); 2413 } else if ( fields[i].indexOf( '_option_value' ) > -1 ) { 2414 var field_id = fields[i].replace( '_option_value', '' ); 2415 // We want the value of the selected option in this field 2416 var o_value = parseFloat( $( 'form.cart .pewc-field-' + field_id ).attr('data-field-value') ); 2417 if( ( $( 'form.cart .pewc-field-' + field_id ).length == 0 && pewc_vars.zero_missing_field == 'yes' ) || isNaN( o_value ) ) { 2418 o_value = 0; 2419 } 2420 replace = new RegExp( '{field_' + fields[i] + '}', 'g' ); 2421 calc_formula = calc_formula.replace( replace, o_value ); 2422 } else if( fields[i].indexOf( '_field_price' ) > -1 ) { 2423 // We want the price of the field 2424 var field_id = fields[i].replace( '_field_price', '' ); 2425 var f_price = parseFloat( $( 'form.cart .pewc-field-' + field_id ).attr( 'data-field-price' ) ); 2426 if( $( 'form.cart .pewc-field-' + field_id ).length == 0 && pewc_vars.zero_missing_field == 'yes' ) { 2427 f_price = 0; 2428 } 2429 replace = new RegExp( '{field_' + fields[i] + '}', 'g' ); 2430 calc_formula = calc_formula.replace( replace, f_price ); 2431 } else if( fields[i].indexOf( '_number_uploads' ) > -1 ) { 2432 // We want the number of uploads 2433 var field_id = fields[i].replace( '_number_uploads', '' ); 2434 var num_uploads = parseFloat( $( 'form.cart .pewc-field-' + field_id ).find( '.pewc-number-uploads' ).val() ); 2435 if( $( 'form.cart .pewc-field-' + field_id ).length == 0 && pewc_vars.zero_missing_field == 'yes' ) { 2436 num_uploads = 0; 2437 } 2438 replace = new RegExp( '{field_' + fields[i] + '}', 'g' ); 2439 calc_formula = calc_formula.replace( replace, num_uploads ); 2440 } else if( fields[i].indexOf( '_pdf_count' ) > -1 ) { 2441 // Get the number of pages for this uploaded PDF 2442 var field_id = fields[i].replace( '_pdf_count', '' ); 2443 var pdf_count = parseFloat( $( '#field_' + field_id + "_pdf_count" ).val() ); 2444 replace = new RegExp( '{field_' + fields[i] + '}', 'g' ); 2445 calc_formula = calc_formula.replace( replace, pdf_count ); 2446 } else if( fields[i].indexOf( '_weight' ) > -1 ) { 2447 // Get the weight of child products selected in specified field 2448 var field_id = fields[i].replace( '_weight', '' ); 2449 // Find the selected item in the field and get the weight 2450 var weight = $( 'form.cart .pewc-field-' + field_id ).find( 'input:checked').closest( '.pewc-radio-wrapper' ).attr( 'data-
2450product-weight' ); 2451 replace = new RegExp( '{field_' + fields[i] + '}', 'g' ); 2452 calc_formula = calc_formula.replace( replace, weight ); 2453 } else if( fields[i].indexOf( '_length' ) > -1 ) { 2454 // Get the length of child products selected in specified field 2455 var field_id = fields[i].replace( '_length', '' ); 2456 // Find the selected item in the field and get the length 2457 var length = $( 'form.cart .pewc-field-' + field_id ).find( 'input:checked').closest( '.pewc-radio-wrapper' ).attr( 'data-product-length' ); 2458 replace = new RegExp( '{field_' + fields[i] + '}', 'g' ); 2459 calc_formula = calc_formula.replace( replace, length ); 2460 } else if( fields[i].indexOf( '_width' ) > -1 ) { 2461 // Get the width of child products selected in specified field 2462 var field_id = fields[i].replace( '_width', '' ); 2463 // Find the selected item in the field and get the width 2464 var width = $( 'form.cart .pewc-field-' + field_id ).find( 'input:checked').closest( '.pewc-radio-wrapper' ).attr( 'data-product-width' ); 2465 replace = new RegExp( '{field_' + fields[i] + '}', 'g' ); 2466 calc_formula = calc_formula.replace( replace, width ); 2467 } else if( fields[i].indexOf( '_height' ) > -1 ) { 2468 // Get the height of child products selected in specified field 2469 var field_id = fields[i].replace( '_height', '' ); 2470 // Find the selected item in the field and get the height 2471 var height = $( 'form.cart .pewc-field-' + field_id ).find( 'input:checked').closest( '.pewc-radio-wrapper' ).attr( 'data-product-height' ); 2472 replace = new RegExp( '{field_' + fields[i] + '}', 'g' ); 2473 calc_formula = calc_formula.replace( replace, height ); 2474 } else if( fields[i].indexOf( '_quantity' ) > -1 ) { 2475 // Get the quantity of child products in specified field - independent quantities, radio list / images only 2476 var field_id = fields[i].replace( '_quantity', '' ); 2477 // Find the selected item in the field and get the quantity 2478 var quantity = $( 'form.cart .pewc-field-' + field_id ).find( '.pewc-independent-quantity-field').val(); 2479 replace = new RegExp( '{field_' + fields[i] + '}', 'g' ); 2480 calc_formula = calc_formula.replace( replace, quantity ); 2481 } else { 2482 // Look for the value of number fields 2483 var f_val = parseFloat( $( 'form.cart .pewc-number-field-' + fields[i] ).val() ); 2484 if( ! f_val && pewc_vars.zero_missing_field == 'yes' ) { 2485 f_val = 0; 2486 } 2487 if( ! isNaN( f_val ) ) { 2488 if( $( 'form.cart .pewc-field-' + fields[i] ).length == 0 && pewc_vars.zero_missing_field == 'yes' ) { 2489 f_val = 0; 2490 } 2491 replace = new RegExp( '{field_' + fields[i] + '}', 'g' ); 2492 calc_formula = calc_formula.replace( replace, f_val ); 2493 } 2494 } 2495 2496 } 2497 2498 } 2499 2500 if( formula === undefined ) { 2501 console.log( 'formula not defined: ' + calc_field_id ); 2502 return false; 2503 } 2504 2505 var product_price = parseFloat( $('#pewc-product-price').val() ); 2506 // 3.12.0, if action of calculation field is Set Product Price, and if product has an FD bulk discount, use the original product price in the calculation, so that we can then set the discounted price later 2507 if ( typeof pewc_wcfad !== 'undefined' && pewc_wcfad.reset_product_price( formula, calc_field_id ) ) { 2508 product_price = parseFloat( $('#pewc-product-price-original').val() ); 2509 } 2510 var quantity = parseFloat( $( 'form.cart .quantity' ).find( '.qty' ).val() ); 2511 if( formula.includes( "{look_up_table}" ) ) { 2512 calc_formula = calculations.evaluate_look_up_table( calc_field_id ); 2513 } 2514 if( formula.includes( "{product_weight}" ) ) { 2515 var product_weight = parseFloat( $( '#pewc_product_weight' ).val() ); 2516 calc_formula = calc_formula.replace( /{product_weight}/g, parseFloat( product_weight ) ); 2517 } 2518 if( formula.includes( "{product_height}" ) ) { 2519 var product_height = parseFloat( $( '#pewc_product_height' ).val() ); 2520 calc_formula = calc_formula.replace( /{product_height}/g, parseFloat( product_height ) ); 2521 } 2522 if( formula.includes( "{product_length}" ) ) { 2523 var product_length = parseFloat( $( '#pewc_product_length' ).val() ); 2524 calc_formula = calc_formula.replace( /{product_length}/g, parseFloat( product_length ) ); 2525 } 2526 if( formula.includes( "{product_width}" ) ) { 2527 var product_width = parseFloat( $( '#pewc_product_width' ).val() ); 2528 calc_formula = calc_formula.replace( /{product_width}/g, parseFloat( product_width ) ); 2529 } 2530 if( formula.includes( "{product_price}" ) && product_price ) { 2531 calc_formula = calc_formula.replace( /{product_price}/g, parseFloat( product_price ) ); 2532 } 2533 if( formula.includes( "{quantity}" ) && quantity ) { 2534 calc_formula = calc_formula.replace( /{quantity}/g, parseFloat( quantity ) ); 2535 } 2536 if( formula.includes( "{variable_1}" ) && pewc_vars.variable_1 ) { 2537 calc_formula = calc_formula.replace( /{variable_1}/g, parseFloat( pewc_vars.variable_1 ) ); 2538 } 2539 if( formula.includes( "{variable_2}" ) && pewc_vars.variable_2 ) { 2540 calc_formula = calc_formula.replace( /{variable_2}/g, parseFloat( pewc_vars.variable_2 ) ); 2541 } 2542 if( formula.includes( "{variable_3}" ) && pewc_vars.variable_3 ) { 2543 calc_formula = calc_formula.replace( /{variable_3}/g, parseFloat( pewc_vars.variable_3 ) ); 2544 } 2545 if( formula.includes( "{calculated_booking_cost}" ) ) { 2546 var calculated_booking_cost = parseFloat( $( '#calculated_booking_cost' ).val() ); 2547 calc_formula = calc_formula.replace( /{calculated_booking_cost}/g, parseFloat( calculated_booking_cost ) ); 2548 } 2549 if( formula.includes( "{num_units_int}" ) ) { 2550 var num_units_int = parseFloat( $( '#num_units_int' ).val() ); 2551 calc_formula = calc_formula.replace( /{num_units_int}/g, parseFloat( num_units_int ) ); 2552 } 2553 if( formula.includes( "{num_bookings}" ) ) { 2554 var num_units_int = parseFloat( $( '#num_bookings' ).val() ); 2555 calc_formula = calc_formula.replace( /{num_bookings}/g, parseFloat( num_units_int ) ); 2556 } 2557 if( formula.includes( "{total_variations}" ) ) { 2558 var total_variations = parseFloat( $( '#wcbvp_total_variations' ).val() ); 2559 calc_formula = calc_formula.replace( /{total_variations}/g, parseFloat( total_variations ) ); 2560 } 2561 if( formula.includes( "{pa_" ) ) { 2562 var attribute = formula.replace( "{", "" ); 2563 var attribute = attribute.replace( "}", "" );
2564 var attribute_data = pewc_vars.attribute_data; 2565 calc_formula = parseFloat( attribute_data[attribute] ); 2566 } 2567 2568 if( pewc_vars.global_calc_vars ) { 2569 var global_calc_vars = pewc_vars.global_calc_vars; 2570 // Iterate through our global vars 2571 for( var key in global_calc_vars ) { 2572 if( formula.includes( "{" + key + "}" ) ) { 2573 var global_var = "{" + key + "}"; 2574 var global_var_regex = new RegExp( global_var, 'g' ); 2575 calc_formula = calc_formula.replace( global_var_regex, global_calc_vars[key] ); 2576 } 2577 } 2578 } 2579 2580 // Check for ACF fields 2581 if( typeof pewc_acf_fields != 'undefined' ) { 2582 for( var key in pewc_acf_fields ) { 2583 if( formula.includes( "{acf_" + key + "}" ) ) { 2584 var acf_field = "{acf_" + key + "}"; 2585 // Find all instances 2586 var acf_field_regex = new RegExp( acf_field, 'g' ); 2587 calc_formula = calc_formula.replace( acf_field_regex, pewc_acf_fields[key] ); 2588 } 2589 } 2590 } 2591 2592 var result; 2593 2594 if( calc_formula == '*' ) return calc_formula; 2595 2596 if( pewc_vars.allow_text_calcs ) { 2597 return calc_formula; 2598 } 2599 2600 allow_text_calcs_fields = pewc_vars.allow_text_calcs_fields; 2601 if( allow_text_calcs_fields.includes( parseInt( calc_field_id ) ) ) { 2602 return calc_formula; 2603 } 2604 2605 try { 2606 result = math.eval( calc_formula ); 2607 2608 if( round == 'ceil' ) { 2609 result = math.ceil( result ); 2610 } else if( round == 'floor' ) { 2611 result = math.floor( result ); 2612 } 2613 if( pewc_vars.math_round == 'yes' ) { 2614 result = Math.round( result * 100 ) / 100; 2615 } 2616 return result.toFixed( parseFloat( decimals ) ); 2617 } catch( err ) { 2618 // Check all tags have been replaced 2619 return 'error'; 2620 } 2621 2622 }, 2623 2624 get_formula_by_id: function( reverse_field_id ) { 2625 2626 var formula = $( '.pewc-field-' + reverse_field_id ).find( '.pewc-data-formula' ).val(); 2627 return formula; 2628 2629 }, 2630 2631 evaluate_field_prices: function() { 2632 2633 $( 'body' ).find( 'form.cart .pewc-field-price-has-formula' ).not( '.pewc-hidden-field' ).each( function() { 2634 if( $( this ).hasClass( 'pewc-variation-dependent' ) && ! $( this ).hasClass( 'active' ) ) { 2635 return; 2636 } 2637 2638 var group = $( this ).closest( '.pewc-group-wrap' ); 2639 if( $( group ).hasClass( 'pewc-group-hidden' ) ) { 2640 return; 2641 } 2642 2643 var group_id = $( group ).attr( 'data-group-id' ); 2644 2645 var pewc_item = $( this ); 2646 var field_id = $( pewc_item ).attr( 'data-id' ); 2647 var data_field_id = $( pewc_item ).attr( 'data-field-id' ); 2648 //var price_wrapper = $( pewc_item ).find( '.pewc-calculation-price-wrapper' ); 2649 var formula = $( pewc_item ).attr( 'data-field-price-formula' ); 2650 if ( formula == undefined ) { 2651 return; 2652 } 2653 var fields = $( pewc_item ).attr( 'data-field-price-formula-fields' ); 2654 var tags = $( pewc_item ).attr( 'data-field-price-formula-tags' ); 2655 //var action = $( price_wrapper ).find( '.pewc-action' ).val(); 2656 var round = $( pewc_item ).attr( 'data-field-price-formula-round' ); 2657 var decimals = $( pewc_item ).attr( 'data-field-price-formula-decimals' ); 2658 //var calc_value = $( price_wrapper ).find( '.pewc-calculation-value' ); 2659 //var prev_calc_value = calc_value.val(); 2660 2661 if( fields ) { 2662 fields = JSON.parse( fields ); 2663 } 2664 2665 var result = calculations.evaluate_formula( fields, formula, round, decimals, data_field_id ); 2666 if ( isNaN( result ) ) { 2667 result = 0; 2668 } 2669 $( pewc_item ).attr( 'data-price', result ); // data-field-price is field price (data-price) + option-price 2670 if ( 'checkbox' === $( pewc_item ).attr( 'data-field-type' ) ) { 2671 $( pewc_item ).find( '.pewc-checkbox-price' ).html( pewc_wc_price( result, true ) ); 2672 } else { 2673 $( pewc_item ).find( '.pewc-field-price' ).html( pewc_wc_price( result, true ) ); 2674 } 2675 $( pewc_item ).find( 'input[name="' + field_id + '_field_price_calculated"]' ).val( result ); 2676 }); 2677 2678 }, 2679 2680 evaluate_option_prices: function() { 2681 2682 $( 'body' ).find( 'form.cart .pewc-field-option-price-has-formula' ).not( '.pewc-hidden-field' ).each( function() { 2683 if( $( this ).hasClass( 'pewc-variation-dependent' ) && ! $( this ).hasClass( 'active' ) ) { 2684 return; 2685 } 2686 2687 var group = $( this ).closest( '.pewc-group-wrap' ); 2688 if( $( group ).hasClass( 'pewc-group-hidden' ) ) { 2689 return; 2690 } 2691 2692 var group_id = $( group ).attr( 'data-group-id' ); 2693 2694 var pewc_item = $( this ); 2695 var field_id = $( pewc_item ).attr( 'data-id' ); 2696 var data_field_id = $( pewc_item ).attr( 'data-field-id' ); 2697 var round = $( pewc_item ).attr( 'data-field-price-formula-round' ); 2698 var decimals = $( pewc_item ).attr( 'data-field-price-formula-decimals' ); 2699 2700 $( this ).find( '.pewc-option-price-has-formula' ).each( function(){ 2701 var opt = $( this ); 2702 var formula = $( opt ).attr( 'data-option-cost-formula' ); 2703 if ( formula == undefined ) { 2704 return; 2705 } 2706 var fields = $( opt ).attr( 'data-option-price-formula-fields' ); 2707 var tags = $( opt ).attr( 'data-option-price-formula-tags' ); 2708 var index = $( opt ).attr( 'data-option-index' ); 2709 2710 if( fields ) { 2711 fields = JSON.parse( fields ); 2712 } 2713 2714 var result = calculations.evaluate_formula( fields, formula, round, decimals, data_field_id ); 2715 if ( isNaN( result ) ) { 2716 result = 0; 2717 } 2718 if ( $( opt ).attr( 'data-option-cost' ) == result && 'select' === $( pewc_item ).attr( 'data-field-type' ) ) { 2719 return; // no need to update, prevents Select fields from blinking 2720 } 2721 $( opt ).attr( 'data-option-cost', result ); 2722 $( opt ).closest( 'label' ).find( '.pewc-option-cost-label' ).html( pewc_wc_price( result ) ); 2723 if ( 'select' === $( pewc_item ).attr( 'data-field-type' ) ) { 2724 var new_text = $( opt ).val() + pewc_vars.separator + pewc_wc_price( result, true ); 2725 $( this ).text( new_text ); 2726 } else if ( 'select-box' === $( pewc_item ).attr( 'data-field-type' ) ) { 2727 var selectbox = $( '#' + field_id + '_select_box' ); 2728 if ( selectbox.length > 0 ) { 2729 var optprice = 0; 2730 selectbox.find( '.dd-option' ).each( function( index, element ){ 2731 optprice = parseFloat( $( 'input[name="' + field_id + '_option_' + index + '_price_calculated"]' ).val() ); 2732 if ( ! isNaN( optprice ) ) { 2733 $( element ).find( '.dd-option-description' ).html( pewc_wc_price( optprice, true ) ); 2734 } 2735 }); 2736 var selected_value = $( pewc_item ).find( '.dd-selected-value' ).val(); 2737 var select_option_index = 0; 2738 select_option_index = $( 'select#' + field_id + ' option[value="' + selected_value.replace( /"/g, '\\"' ) + '"]').index(); 2739 optprice = parseFloat( $( 'input[name="' + field_id + '_option_' + select_option_index + '_price_calculated"]' ).val() ); 2740 if ( ! isNaN( optprice ) ) { 2741 $( pewc_item ).find( '.dd-selected-description' ).html( pewc_wc_price( optprice, true ) ); 2742 $( pewc_item ).attr( 'data-selected-option-price', optprice ); 2743 } 2744 } 2745 } 2746 $( pewc_item ).find( 'input[name="' + field_id + '_option_' + index + '_price_calculated"]' ).val( result ); 2747 }); 2748 }); 2749 2750 } 2751 2752 } 2753 2754 calculations.init(); 2755 2756 var hidden_groups = { 2757 2758 init: function() { 2759 $( 'body' ).on( 'pewc_conditions_checked', this.check_group_visibility ); 2760 }, 2761 2762 /** 2763 * Check whether to hide or display groups 2764 */ 2765 check_group_visibility: function() { 2766 2767 // Check each group 2768 $( 'body' ).find( '.pewc-group-wrap' ).each( function() { 2769 var all_hidden = true; 2770 var group = $( this ); 2771 $( group ).find( '.pewc-item' ).each( function() { 2772 if( ! $( this ).hasClass( 'pewc-hidden-field' ) ) { 2773 all_hidden = false;
2774 } 2775 }); 2776 if( all_hidden ) { 2777 $( group ).addClass( 'pewc-hidden-group' ); 2778 } else { 2779 $( group ).removeClass( 'pewc-hidden-group' ); 2780 } 2781 }); 2782 2783 } 2784 2785 } 2786 2787 hidden_groups.init(); 2788 2789 var summary_panel = { 2790 2791 init: function() { 2792 $( '.pewc-form-field' ).on( 'change update keyup', this.update_panel ); 2793 }, 2794 2795 update_panel: function( e ) { 2796 var field_id = $( this ).closest( '.pewc-item' ).attr( 'data-field-id' ); 2797 var field_value = $( this ).val(); 2798 }, 2799 2800 } 2801 2802 summary_panel.init(); 2803 2804 /** 2805 * Sets product images for the chosen add-on 2806 */ 2807 var add_on_images = { 2808 2809 init: function() { 2810 2811 var $product = $( 'form.cart' ).closest( '.product' ), 2812 $product_gallery = $product.find( pewc_vars.product_gallery ), 2813 $gallery_nav = $product.find( '.flex-control-nav' ), 2814 $gallery_img = $gallery_nav.find( 'li:eq(0) img' ), 2815 $product_img_wrap = $product_gallery.find( pewc_vars.product_img_wrap ).eq( 0 ), 2816 $product_img = $product_img_wrap.find( 'img' ).eq( 0 ), 2817 $product_link = $product_img_wrap.find( 'a' ).eq( 0 ); 2818 2819 if( add_on_images.replace_image() ) { 2820 // create an attribute where we can track where a replaced image came from 2821 $product_img.attr( 'data-pewc-from-field', '' ); 2822 2823 // 3.17.2, find the first field that has a default value and not hidden, then auto replace main image with the selected swatch. if multiple are selected, pick the first one? 2824 $( document ).ready( function() { 2825 // we need to delay this so that the main image container takes the size of the original product image 2826 add_on_images.replace_main_with_default(); 2827 }); 2828 2829 // when Optimised conditions is enabled, update_add_on_image is run first before a group is hidden, so we do this to reset a main image if the field is inside a group that becomes hidden 2830 $( 'body' ).on( 'pewc_group_visibility_updated', function( e, id, action ) { 2831 add_on_images.check_if_src_hidden( $product_img ); 2832 }); 2833 2834 // 3.21.4, trigger replace main image if field is initially hidden by a condition 2835 $( 'body' ).on( 'pewc_field_visibility_updated', function( e, id, action ) { 2836 var pewc_item = $( '.pewc-item.' + id ); 2837 // 3.26.6, changed condition from data-default-value to data-field-value to accommodate Edit Options 2838 if ( pewc_item.attr( 'data-field-value' ) != '' ) { 2839 // only do this if field has selected value that needs to replace the main image 2840 if ( pewc_item.data( 'field-type' ) === 'image_swatch' ) { 2841 // 3.24.6, find the first checked/selected element
2842 var field = pewc_item.find( 'input[name="' + id + '[]"]:checked' )[0]; 2843 } else { 2844 var field = pewc_item.find( 'input[name="' + id + '[]"]' )[0]; 2845 } 2846 var $form = pewc_item.closest( 'form' ); 2847 add_on_images.update_add_on_image( $( field ), $form ); 2848 } 2849 }); 2850 2851 } 2852 2853 // If we've got parent/child swatches, then hide/show the correct child swatch 2854 $( '.pewc-swatch-parent .pewc-radio-form-field' ).on( 'change', this.change_child ); 2855 2856 // If we've got parent/child swatches, then ensure that all the child swatches are in sync 2857 $( '.pewc-swatch-child .pewc-radio-form-field' ).on( 'change', this.sync_children ); 2858 2859 }, 2860 2861 replace_image: function( field ) { 2862 // 3.17.2 2863 if( pewc_vars.replace_image ) { 2864 // global Replace main image, or the filter pewc_get_add_on_image_action, is used 2865 return pewc_vars.replace_image; 2866 } else if ( field ) { 2867 if ( field.hasClass( 'pewc-replace-main-image' ) ) { 2868 return true; 2869 } 2870 } else { 2871 // if we have just one field that has enabled Replace main image, activate 2872 if ( $( document ).find( '.pewc-replace-main-image' ).length > 0 ) { 2873 return true; 2874 } 2875 } 2876 return false; 2877 }, 2878 2879 save_original_src: function( $product_img ) { 2880 if ( $product_img.attr( 'data-pewc-old-src' ) ) { 2881 return; // already set, do nothing 2882 } 2883 // Set original src values 2884 $product_img.attr( 'data-pewc-old-src', $product_img.attr( 'src' ) ); 2885 // 3.13.3, data-src is used by WooCommerce zoom image 2886 if ( $product_img.attr( 'data-src' ) ) { 2887 $product_img.attr( 'data-pewc-old-data-src', $product_img.attr( 'data-src' ) ); 2888 } else { 2889 $product_img.attr( 'data-pewc-old-data-src', '' ); 2890 } 2891 if ( $product_img.attr( 'srcset' ) ) { 2892 $product_img.attr( 'data-pewc-old-srcset', $product_img.attr( 'srcset' ) ); 2893 } else { 2894 $product_img.attr( 'data-pewc-old-srcset', '' ); 2895 } 2896 // photoswipe gallery 2897 if ( $product_img.attr( 'data-large_image' ) ) { 2898 $product_img.attr( 'data-pewc-old-data-large_image', $product_img.attr( 'data-large_image' ) ); 2899 } else { 2900 $product_img.attr( 'data-pewc-old-data-large_image', '' ); 2901 } 2902 if ( $product_img.attr( 'data-large_image_width' ) ) { 2903 $product_img.attr( 'data-pewc-old-data-large_image_width', $product_img.attr( 'data-large_image_width' ) ); 2904 } else { 2905 $product_img.attr( 'data-pewc-old-data-large_image_width', '' ); 2906 } 2907 if ( $product_img.attr( 'data-large_image_height' ) ) { 2908 $product_img.attr( 'data-pewc-old-data-large_image_height', $product_img.attr( 'data-large_image_height' ) ); 2909 } else { 2910 $product_img.attr( 'data-pewc-old-data-large_image_height', '' ); 2911 } 2912 2913 }, 2914 2915 // 4.3.13, created a separate function outside of save_original_src() 2916 save_original_zoom_src: function( $product_img ) { 2917 2918 if ( $product_img.attr( 'data-pewc-old-zoom' ) ) { 2919 return; // already set, do nothing 2920 } 2921 2922 var zoomImg = $product_img.closest( pewc_vars.product_img_wrap ).find( pewc_vars.product_img_zoom ).eq(0); 2923 if ( zoomImg.length ) { 2924 $product_img.attr( 'data-pewc-old-zoom', zoomImg.attr( pewc_vars.product_img_zoom_src ) ); 2925 } else { 2926 // zoomImg not yet in DOM (e.g. Enfold theme) — fall back to data-src, which jquery.zoom uses to populate zoomImg 2927 $product_img.attr( 'data-pewc-old-zoom', $product_img.attr( 'data-src' ) || $product_img.attr( 'src' ) ); 2928 } 2929 2930 }, 2931 2932 update_add_on_image: function( field, $form ) { 2933 2934 var field_wrapper = $( field ).closest( '.pewc-item' ); 2935 var is_layered = $( field_wrapper ).attr( 'data-field-layered' ); 2936 2937 if( ! add_on_images.replace_image( field_wrapper ) && is_layered != 'yes' ) { 2938 return; 2939 } 2940 2941 var field_type = $( field_wrapper ).attr( 'data-field-type' ); 2942 2943 var $product = $form.closest( '.product' ), 2944 $product_gallery = $product.find( pewc_vars.product_gallery ), 2945 $layer_parent = pewc_vars.layer_parent, 2946 $gallery_nav = $product.find( '.flex-control-nav' ), 2947 $gallery_img = $gallery_nav.find( 'li:eq(0) img' ), 2948 $product_img_wrap = $product_gallery.find( pewc_vars.product_img_wrap ).eq( 0 ), 2949 $product_img = $product_img_wrap.find( 'img' ).eq( 0 ), 2950 $product_link = $product_img_wrap.find( 'a' ).eq( 0 ); 2951 2952 if( ! $( field_wrapper ).hasClass( 'pewc-has-field-image' ) && field_type != 'image_swatch' && field_type != 'select-box' ) { 2953 // the clicked field is not an image swatch, select box, or does not have a field image, but let's check if we need to replace the main image with the original one 2954 add_on_images.check_if_src_hidden( $product_img ); 2955 return; 2956 } 2957 2958 // 3.21.4, Ignore fields in hidden groups 2959 if ( $( field_wrapper ).closest( '.pewc-group-wrap' ).hasClass( 'pewc-group-hidden' ) ) { 2960 add_on_images.check_if_src_hidden( $product_img ); 2961 return; 2962 } 2963 2964 // 3.21.4, Ignore hidden variation-dependent fields and hidden fields 2965 if( ( $( field_wrapper ).hasClass( 'pewc-variation-dependent' ) && ! $( field_wrapper ).hasClass( 'active' ) ) || $( field_wrapper ).hasClass( 'pewc-hidden-field' ) ) { 2966 add_on_images.check_if_src_hidden( $product_img ); 2967 return; 2968 } 2969 2970 var add_on_image_wrapper; 2971 var add_on_image_src; 2972 var add_on_image_large_image, add_on_image_large_image_width, add_on_image_large_image_height; 2973 var turn = 'off'; 2974 2975 var add_on_image_field = '', add_on_image_option = ''; 2976 2977 if( field_type == 'checkbox' && $( field ).prop( 'checked' ) && add_on_images.replace_image( field_wrapper ) != 'replace_image_swatch_only' ) { 2978 turn = 'on'; 2979 add_on_image_wrapper = $( field_wrapper ).find( '.pewc-item-field-image-wrapper' ); 2980 add_on_image_src = $( add_on_image_wrapper ).attr( 'data-image-full-size' ); 2981 add_on_image_srcset = add_on_image_src; 2982 // photoswipe gallery 2983 add_on_image_large_image = $( add_on_image_wrapper ).attr( 'data-image-full-size' ); 2984 add_on_image_large_image_width = $( add_on_image_wrapper ).attr( 'data-large_image_width' ); 2985 add_on_image_large_image_height = $( add_on_image_wrapper ).attr( 'data-large_image_height' ); 2986 // 3.27.4, for Checkbox field, maybe we only need to detect this class to know it's checked? 2987 add_on_image_field = 'pewc-add-on-image-' + $( field_wrapper ).attr( 'data-field-id' ); 2988 } 2989 if( field_type == 'image_swatch') { 2990 add_on_image_wrapper = field.closest( '.pewc-radio-image-wrapper' ); 2991 2992 if ( add_on_image_wrapper.hasClass( 'checked' ) ) {
2993 add_on_image_src = add_on_image_wrapper.find( 'img' ).attr( 'data-src' ); 2994 add_on_image_srcset = add_on_image_src; 2995 // photoswipe gallery 2996 add_on_image_large_image = add_on_image_wrapper.find( 'img' ).attr( 'data-large_image' ); 2997 add_on_image_large_image_width = add_on_image_wrapper.find( 'img' ).attr( 'data-large_image_width' ); 2998 add_on_image_large_image_height = add_on_image_wrapper.find( 'img' ).attr( 'data-large_image_height' ); 2999 3000 if (add_on_image_src != undefined) { 3001 turn = 'on'; 3002 // 3.27.5 3003 if ( $( field_wrapper ).hasClass( 'pewc-item-radio' ) ) { 3004 $product_img.closest( '.' + pewc_vars.layer_parent ).removeClass(function(index, className) { 3005 return (className.match(/(^|\s)pewc\-add\-on\-image\-\S+/g) || []).join(' '); 3006 }); 3007 } 3008 // 3.27.4 3009 add_on_image_field = 'pewc-add-on-image-' + $( field_wrapper ).attr( 'data-field-id' ); 3010 add_on_image_option = add_on_image_field + '-' + $( field ).attr( 'id' ).replace( $( field_wrapper ).attr( 'data-id' ) + '_', '' ); 3011 } 3012 } 3013 } else if ( field_type == 'select-box' && add_on_images.replace_image( field_wrapper ) != 'replace_image_swatch_only' ) { 3014 // 3.13.7 3015 if ( field_wrapper.find( 'input.dd-selected-value' ).val() != '' ) { 3016 // check if the full image exists 3017 var src_image = field_wrapper.find( 'input.dd-selected-image-full' ); 3018 if ( src_image.length > 0 ) { 3019 add_on_image_src = src_image.val(); 3020 } else { 3021 src_image = field_wrapper.find( 'img.dd-selected-image' ); 3022 add_on_image_src = src_image.attr( 'src' ); 3023 } 3024 add_on_image_srcset = add_on_image_src; 3025 // photoswipe gallery 3026 add_on_image_large_image = add_on_image_src; 3027 add_on_image_large_image_width = src_image.attr( 'data-imgsrc-width' ); 3028 add_on_image_large_image_height = src_image.attr( 'data-imgsrc-height' ); 3029 3030 if ( add_on_image_src != undefined) { 3031 turn = 'on'; 3032 // 3.27.4, always remove first for Select Box, so that the previous option selected is removed first 3033 $product_img.closest( '.' + pewc_vars.layer_parent ).removeClass(function(index, className) { 3034 return (className.match(/(^|\s)pewc\-add\-on\-image\-\S+/g) || []).join(' '); 3035 }); 3036 add_on_image_field = 'pewc-add-on-image-' + $( field_wrapper ).attr( 'data-field-id' ); 3037 add_on_image_option = add_on_image_field + '-index-' + $( field_wrapper ).find( 'select' ).prop( 'selectedIndex' ); 3038 } 3039 } 3040 } 3041 3042 if( is_layered == 'yes' ) { 3043 // This is a layered image so we are going to create/update layers 3044 var field_id = $( field_wrapper ).attr( 'data-field-id' ); 3045 var layer_id = 'pewc-layer-' + field_id; 3046 var layer_index = $( field_wrapper ).attr( 'data-field-index' ); 3047 // This is the wrapper, e.g. woocommerce-product-gallery__wrapper 3048 // Add our cloned image into a div within this wrapper 3049 // The wrapper can be absolutely positioned over the main image 3050 var swatch_src = $( add_on_image_wrapper ).find( 'img' ).attr( 'data-large_image' ); 3051 // Check for an alternative image to replace the main image 3052 if( $( add_on_image_wrapper ).find( 'img' ).attr( 'data-alt_image' ).length > 0 ) { 3053 swatch_src = $( add_on_image_wrapper ).find( 'img' ).attr( 'data-alt_image' ); 3054 } 3055 if( $( '.' + layer_id ).length === 0 && $( add_on_image_wrapper ).hasClass( 'checked' ) ) { 3056 // Get the selected swatch image src 3057 var layer_image = '<img class="pewc-layer-image" src="' + swatch_src + '">'; 3058 // Make the layer 3059 // var layer = $product_img.clone().insertAfter( $product_img ).addClass( layer_id ); 3060 $( $( '.' + $layer_parent ) ).append( '<div class="pewc-image-layer ' + layer_id + '" style="z-index:' + ( layer_index + 1 ) * 10 + '">' + layer_image + '</div>' ); 3061 } else if( $( '.' + layer_id ).length !== 0 && $( add_on_image_wrapper ).hasClass( 'checked' ) ) { 3062 // Layer exists but need to update the image inside 3063 // swatch_src = $( add_on_image_wrapper ).find( 'img' ).attr( 'data-large_image' ); 3064 $( '.' + layer_id ).find( 'img' ).attr( 'src', swatch_src ); 3065 } else if( ! $( add_on_image_wrapper ).hasClass( 'checked' ) ) { 3066 $( '.' + layer_id ).remove(); 3067 } 3068 3069 // 3.27.8, add special classes 3070 if ( add_on_image_field != '' && ! $( '.' + pewc_vars.layer_parent ).hasClass( add_on_image_field ) ) { 3071 $product_img.closest( '.' + pewc_vars.layer_parent ).addClass( add_on_image_field ); 3072 } 3073 if ( add_on_image_option != '' && ! $( '.' + pewc_vars.layer_parent ).hasClass( add_on_image_option ) ) { 3074 $product_img.closest( '.' + pewc_vars.layer_parent ).addClass( add_on_image_option ); 3075 } 3076 3077 } else if ( add_on_image_src && turn == 'on' ) { 3078 3079 // maybe save original 3080 add_on_images.save_original_src( $product_img ); 3081 add_on_images.save_original_zoom_src( $product_img ); 3082
3083 $product_img.attr( 'data-pewc-from-field', $( field_wrapper ).attr( 'data-id' ) ); 3084 $product_img.attr( 'src', add_on_image_src ); 3085 $product_img.attr( 'srcset', add_on_image_srcset ); 3086 $product_img.attr( 'data-src', add_on_image_src ); // 3.13.3, used by WC zoomImg 3087 // replace photoswipe gallery 3088 $product_img.attr( 'data-large_image', add_on_image_large_image ); 3089 $product_img.attr( 'data-large_image_width', add_on_image_large_image_width ); 3090 $product_img.attr( 'data-large_image_height', add_on_image_large_image_height ); 3091 3092 // replace zoom image 3093 //var zoomImg = $product_img.closest( pewc_vars.product_img_wrap ).find( pewc_vars.product_img_zoom ).eq(0); 3094 //if ( zoomImg ) { 3095 // zoomImg.attr( pewc_vars.product_img_zoom_src, add_on_image_src ); 3096 //} 3097 3098 // 4.3.13, newer version, waits for zoomImg to be ready 3099 var $wrap = $product_img.closest( pewc_vars.product_img_wrap ); 3100 var zoomImg = $wrap.find( pewc_vars.product_img_zoom ).eq(0); 3101 3102 if ( zoomImg.length ) { 3103 add_on_images.save_original_zoom_src( $product_img ); 3104 zoomImg.attr( pewc_vars.product_img_zoom_src, add_on_image_src ); 3105 } else if ( $wrap[0] ) { 3106 var _src = add_on_image_src; 3107 var zoomObserver = new MutationObserver( function() { 3108 var $z = $wrap.find( pewc_vars.product_img_zoom ).eq(0); 3109 if ( $z.length ) { 3110 zoomObserver.disconnect(); 3111 add_on_images.save_original_zoom_src( $product_img ); 3112 $z.attr( pewc_vars.product_img_zoom_src, _src ); 3113 } 3114 } ); 3115 zoomObserver.observe( $wrap[0], { childList: true, subtree: true } ); 3116 } 3117 3118 // 3.27.4, add special classes 3119 if ( add_on_image_field != '' && ! $( '.' + pewc_vars.layer_parent ).hasClass( add_on_image_field ) ) { 3120 $product_img.closest( '.' + pewc_vars.layer_parent ).addClass( add_on_image_field ); 3121 } 3122 if ( add_on_image_option != '' && ! $( '.' + pewc_vars.layer_parent ).hasClass( add_on_image_option ) ) { 3123 $product_img.closest( '.' + pewc_vars.layer_parent ).addClass( add_on_image_option ); 3124 } 3125 } else { 3126 // 3.27.4, remove all our special classes, it will be added back if we still have a swatch selected 3127 $product_img.closest( '.' + pewc_vars.layer_parent ).removeClass(function(index, className) { 3128 return (className.match (/(^|\s)pewc\-add\-on\-image\-\S+/g) || []).join(' '); 3129 }); 3130 add_on_images.replace_main_with_default( $product_img, false ); // 3.24.7, let's try to find an active swatch first before resetting the main image 3131 } 3132 3133 // 3.13.2 bring back the focus on the main image to see the selected image swatch 3134 if ( pewc_vars.replace_image_focus == 'yes' ) { 3135 var control_list_selector = '.' + pewc_vars.control_container + ' ' + pewc_vars.control_list; 3136 $( control_list_selector ).first().find( pewc_vars.control_element ).trigger( 'click' ); // 3.25.6, changed from click() to trigger('click') because click() is deprecated 3137 $( 'body' ).trigger( 'pewc_update_add_on_image_focus_on_main_image' ); // 3.23.1, for other sliders that have a different way of focusing on the first image e.g. Flickity 3138 } 3139 }, 3140 3141 // If we are using secondary images, then hide/show the correct child swatch field 3142 change_child: function( e ) { 3143 3144 var parent_swatch = e.target; 3145 var parent_index = $( parent_swatch ).closest( '.pewc-item' ).find( '.pewc-radio-image-wrapper.checked input' ).attr( 'data-option-index' ); 3146 if( ! isNaN( parent_index ) ) { 3147 $( '.pewc-swatch-child' ).addClass( 'pewc-visibility-hidden' ); 3148 $( '.pewc-swatch-child-' + parent_index ).removeClass( 'pewc-visibility-hidden' ); 3149 var active_layer_id = $( '.pewc-swatch-child-' + parent_index ).attr( 'data-field-id' ); 3150 // Get the selected child index 3151 var selected_input = $( '.pewc-swatch-child' ).not( '.pewc-visibility-hidden' ).closest( '.pewc-item' ).find( '.pewc-radio-image-wrapper.checked input' ); 3152 var index = $( selected_input ).attr( 'data-option-index' ); 3153 // Trigger the child swatch 3154 // var selected = $( '.pewc-swatch-child-' + parent_index ).find( '.pewc-radio-image-wrapper-' + index + ' input' ).prop( 'checked' ); 3155 3156 $( '.pewc-swatch-child-' + parent_index ).find( '.pewc-radio-image-wrapper.pewc-radio-form-field' ).prop('checked', false); 3157 3158 // When we change the child, we need to hide unwanted image layers on the main image 3159 $( '.pewc-layer-' + active_layer_id ).show(); 3160 // Hide the other child swatch layers 3161 var child_swatch_ids = JSON.parse( pewc_vars.child_swatch_ids ); 3162 for( var i in child_swatch_ids ) { 3163 if( child_swatch_ids[i] != active_layer_id ) { 3164 $( '.pewc-layer-' + child_swatch_ids[i] ).fadeOut( 150 ); 3165 } 3166 } 3167 // Find any layers that we need to hide 3168 // $( '.pewc-show-for' ).each( function( layer_index, element ) { 3169 // // This layer only shows when a specific field is visible 3170 // var show_for = $( this ).attr( 'data-show-for' ); 3171 // var layer_id = $( this ).attr( 'data-field-id' ); 3172 // if( show_for != active_layer_id ) { 3173 // $( '.pewc-layer-' + layer_id ).fadeOut( 150 ); 3174 // } else { 3175 // $( '.pewc-layer-' + layer_id ).fadeIn( 150 ); 3176 // } 3177 // }); 3178 // $( '.pewc-image-layer' ).not( '.pewc-layer-' + active_layer_id ).fadeOut( 250 ); 3179 3180 3181 // if( ! selected ) { 3182 $( '.pewc-swatch-child-' + parent_index ).find( '.pewc-radio-image-wrapper-' + index + ' input' ).addClass( 'here-' + parent_index + '-' + index ).trigger( 'click' ); 3183 // selected = $( '.pewc-swatch-child-' + parent_index ).find( '.pewc-radio-image-wrapper-' + index + ' input' ).prop( 'checked' ); 3184 $( '.pewc-swatch-child-' + parent_index ).find( '.pewc-radio-image-wrapper-' + index + ' input' ).trigger( 'change' ); 3185 // if( selected ) { 3186 // $( '.pewc-swatch-child-' + parent_index ).find( '.pewc-radio-image-wrapper-' + index + ' input' ).prop( 'checked', false ).trigger( 'change' ); 3187 // selected = $( '.pewc-swatch-child-' + parent_index ).find( '.pewc-radio-image-wrapper-' + index + ' input' ).prop( 'checked' ); 3188 // $( '.pewc-swatch-child-' + parent_index ).find( '.pewc-radio-image-wrapper-' + index + ' input' ).addClass( 'here-' + parent_index + '-' + index ).trigger( 'click' ); 3189 // selected = $( '.pewc-swatch-child-' + parent_index ).find( '.pewc-radio-image-wrapper-' + index + ' input' ).prop( 'checked' ); 3190 // } 3191 3192 // } 3193 3194 } 3195 3196 }, 3197 3198 // If we've updated a child swatch, we need to ensure that other child swatches have the same value 3199 sync_children: function( e ) { 3200 3201 // Get the active parent index 3202 var parent_index = $( '.pewc-swatch-parent' ).find( '.pewc-radio-image-wrapper.checked input' ).attr( 'data-option-index' ); 3203 var child_swatch = e.target; 3204 // Get the index of the selected child swatch
3205 var index = $( child_swatch ).closest( '.pewc-item' ).find( '.pewc-radio-image-wrapper.checked input' ).attr( 'data-option-index' ); 3206 if( ! isNaN( index ) ) { 3207 // Ensure that all other child swatch fields have the same item selected 3208 $( '.pewc-swatch-child' ).find( '.pewc-radio-image-wrapper' ).removeClass( 'checked' ); 3209 $( '.pewc-swatch-child' ).find( '.pewc-radio-image-wrapper-' + index ).addClass( 'checked' ).find( 'input' ); 3210 // Need to ensure that the correct main image is displayed 3211 // Trigger a click on the currently visible selected swatch 3212 var input = $( '.pewc-swatch-child-' + parent_index ).find( '.pewc-radio-image-wrapper-' + index + ' input' ); 3213 $( '.pewc-swatch-child-' + parent_index ).find( '.pewc-radio-image-wrapper-' + index + ' input' ).trigger( 'click' ); 3214 } 3215 3216 }, 3217 3218 check_if_src_hidden: function( $product_img ) { 3219 if ( $product_img.attr('data-pewc-from-field') != '' ) { 3220 3221 // main image is using an image from a field, check if the field where it came from is currently hidden. if so, put back the original main image 3222 var pewc_from_field = $( ".pewc-item."+$product_img.attr('data-pewc-from-field') ); 3223 3224 if ( pewc_from_field.hasClass( 'pewc-hidden-field') || pewc_from_field.closest( '.pewc-group-wrap' ).hasClass( 'pewc-group-hidden') || ( pewc_from_field.hasClass( 'pewc-variation-dependent' ) && ! pewc_from_field.hasClass( 'active' ) ) ) { 3225 // field is hidden, reset image 3226 // 3.21.4, added variation-dependent fields 3227 //add_on_images.reset_main_image( $product_img ); 3228 add_on_images.replace_main_with_default( $product_img ); // 3.24.7, let's try to find an active swatch first before resetting the main image 3229 } 3230 } 3231 }, 3232 3233 reset_main_image: function ( $product_img ) { 3234 $product_img.attr( 'data-pewc-from-field', '' ); 3235 $product_img.attr( 'src', $product_img.attr( 'data-pewc-old-src' ) ); 3236 $product_img.attr( 'srcset', $product_img.attr( 'data-pewc-old-srcset' ) ); 3237 $product_img.attr( 'data-src', $product_img.attr( 'data-pewc-old-data-src' ) ); // 3.13.3 3238 // photoswipe gallery 3239 $product_img.attr( 'data-large_image', $product_img.attr( 'data-pewc-old-data-large_image' ) ); 3240 $product_img.attr( 'data-large_image_width', $product_img.attr( 'data-pewc-old-data-large_image_width' ) ); 3241 $product_img.attr( 'data-large_image_height', $product_img.attr( 'data-pewc-old-data-large_image_height' ) ); 3242 // zoom image 3243 var zoomImg = $product_img.closest( pewc_vars.product_img_wrap ).find( pewc_vars.product_img_zoom ).eq(0); 3244 if ( zoomImg ) { 3245 zoomImg.attr( pewc_vars.product_img_zoom_src, $product_img.attr( 'data-pewc-old-zoom' ) ); 3246 } 3247 }, 3248 3249 replace_main_with_default: function( $product_img='', is_layered=true ) { 3250 // 3.17.2 3251 var replace_fields = [ 'image_swatch', 'select-box', 'checkbox' ]; 3252 var replaced = false; 3253 3254 $( '.pewc-item' ).each( function( index, element ) { 3255 // 3.20.1 3256 var layered_image = $(this).hasClass( 'pewc-layered-image' ); 3257 3258 // Replace main image is not active for this field, skip 3259 // 3.27.2, added ! layered_image condition, so that layer images work even if they don't enable Replace main image on the field setting 3260 if ( ! add_on_images.replace_image( $(this) ) && ! layered_image ) { 3261 return; 3262 } 3263 3264 // 3.25.4, skip layered images when resetting normal swatch fields? 3265 if ( layered_image && ! is_layered ) { 3266 return; 3267 } 3268 3269 // Main image has been replaced, we can skip 3270 // 3.20.1, don't skip if this is a layered image 3271 if ( replaced && ! layered_image ) { 3272 return; 3273 } 3274 3275 // Ignore fields in hidden groups 3276 if ( $( this ).closest( '.pewc-group-wrap' ).hasClass( 'pewc-group-hidden' ) ) { 3277 return; 3278 } 3279 3280 // Ignore hidden variation-dependent fields and hidden fields 3281 if( ( $( this ).hasClass( 'pewc-variation-dependent' ) && ! $( this ).hasClass( 'active' ) ) || $( this ).hasClass( 'pewc-hidden-field' ) ) { 3282 return; 3283 } 3284 3285 if ( replace_fields.indexOf( $( this ).attr( 'data-field-type' ) ) > -1 && $( this ).attr( 'data-field-value' ) != '' ) { 3286 // 3.22.1, replaced data-default value with data-field-value in the condition so that the main image is also replaced when editing add-ons via Edit options on the cart 3287 var field_type = $( this ).attr( 'data-field-type' ); 3288 if ( field_type == 'image_swatch' ) { 3289 // find the first checked input, that must be the default 3290 $( this ).find( '.pewc-radio-form-field' ).each( function( index, element ){ 3291 // 3.20.1, allow multiple layered images with default values 3292 if ( $( this ).is( ':checked' ) && ( ! replaced || layered_image ) ) { 3293 // 3.26.15, only replace if option has an image 3294 if ( $( this ).closest( '.pewc-radio-image-wrapper' ).find( 'img' ).attr( 'data-src' ) ) { 3295 add_on_images.update_add_on_image( $( this ), $(this).closest( 'form' ) ); 3296 replaced = true; 3297 return; 3298 } 3299 } 3300 }); 3301 } else if ( field_type == 'checkbox' ) { 3302 if ( $( this ).find( '.pewc-form-field' ).is( ':checked' ) && $( this ).find( '.pewc-item-field-image-wrapper' ).length > 0 ) { 3303 // 4.3.0, only do this if checkbox has an image, prevent an infinite loop 3304 add_on_images.update_add_on_image( $( this ).find( '.pewc-form-field' ), $(this).closest( 'form' ) ); 3305 replaced = true; 3306 return; 3307 } 3308 } else if ( field_type == 'select-box' ) { 3309 add_on_images.update_add_on_image( $( this ).find( 'select.pewc-form-field' ), $(this).closest( 'form' ) ); 3310 replaced = true; 3311 return; 3312 } 3313 } 3314 }); 3315 3316 // 3.24.7, if we didn't find a swatch, reset the main image 3317 if ( ! replaced && $product_img != '' ) { 3318 add_on_images.reset_main_image( $product_img ); 3319 } 3320 }, 3321 3322 } 3323 3324 add_on_images.init(); 3325 3326 var tooltips = { 3327 3328 init: function() { 3329 3330 if( pewc_vars.enable_tooltips == 'yes' && ! pewc_vars.dequeue_tooltips ) { 3331 $( '.tooltip' ).tooltipster( 3332 { 3333 theme: 'tooltipster-shadow', 3334 side: 'right', 3335 contentAsHTML: pewc_vars.contentAsHTML, 3336 autoClose : pewc_vars.autoClose, 3337 interactive : pewc_vars.interactive,
3338 hideOnClick : pewc_vars.hideOnClick, 3339 trigger : pewc_vars.trigger, 3340 triggerOpen : pewc_vars.triggerOpen, 3341 triggerClose: pewc_vars.triggerClose 3342 } 3343 ); 3344 } 3345 3346 } 3347 3348 } 3349 3350 tooltips.init(); 3351 3352 var quickview = { 3353 3354 init: function() { 3355 $( 'body' ).on( 'click', '.pewc-show-quickview', this.show_quickview ); 3356 $( 'body' ).on( 'click', '#pewc-quickview-background, .pewc-close-quickview', this.hide_quickview ); 3357 }, 3358 3359 show_quickview: function( e ) { 3360 e.stopPropagation(); 3361 if( pewc_vars.quickview == 'yes' ) { 3362 // Open the link in a new tab 3363 e.preventDefault(); 3364 $( 'body' ).addClass( 'pewc-quickview-active' ); 3365 } 3366 3367 // $( '.pewc-quickview-product-wrapper' ).hide(); 3368 $( '#pewc-quickview-' + $(this).closest( 'li.pewc-item' ).attr( 'data-id' ) + '_' + $( this ).attr( 'data-child-product-id' ) ).css( 'left', '50%' ); 3369 }, 3370 3371 hide_quickview: function( e ) { 3372 e.preventDefault(); 3373 $( 'body' ).removeClass( 'pewc-quickview-active' ); 3374 $( '.pewc-quickview-product-wrapper' ).css( 'left', '-5000px' ); 3375 } 3376 3377 } 3378 3379 quickview.init(); 3380 3381 var check_time = { 3382 3383 interval_id: null, 3384 3385 init: function() { 3386 var today = new Date(); 3387 var loaded = $( '.pewc-cl-wrapper' ).first().attr( 'data-today' ); 3388 today.setHours(0,0,0,0); 3389 if( today > loaded ) { 3390 $( '.pewc-cl-wrapper' ).addClass( 'disabled' ); 3391 $( '.pewc-cl-wrapper' ).find( '.pewc-radio-form-field' ).prop( 'disabled', true ); 3392 } 3393 // check_time.check(); 3394 check_time.interval_id = setInterval( 3395 function() { 3396 check_time.check(); 3397 }, 3398 5000 3399 ); 3400 $( '.pewc-cl-wrapper' ).find( 'input' ).on( 'change', this.update_date ); 3401 3402 // Auto-select the default option in each calendar list field so that 3403 // calculations using {field_XXX_option_price} have a value on page load. 3404 // data-default-value holds the day offset (e.g. "6"), matching data-offset on each radio. 3405 $( 'form.cart .pewc-item-calendar-list' ).each( function() { 3406 var $field = $( this ); 3407 if ( $field.find( 'input[type=radio]:checked' ).length === 0 ) { 3408 var default_val = $field.attr( 'data-default-value' ); 3409 var $enabled = $field.find( '.pewc-cl-wrapper:not(.disabled) input[type=radio]:enabled' );
3410 var $target = ( default_val !== '' && default_val !== undefined ) 3411 ? $enabled.filter( '[data-offset="' + default_val + '"]' ) 3412 : $(); 3413 if ( ! $target.length ) { 3414 $target = $enabled.first(); 3415 } 3416 if ( $target.length ) { 3417 $target.prop( 'checked', true ).trigger( 'change' ); 3418 } 3419 } 3420 } ); 3421 }, 3422 3423 check: function() { 3424 $( '.pewc-cl-has-time' ).each( function() { 3425 var hour = $( this ).attr( 'data-hour' ); 3426 var min = $( this ).attr( 'data-minute' ); 3427 if( ! hour || ! min ) { 3428 return; 3429 } 3430 if( check_time.is_after( hour, min ) ) { 3431 clearInterval( check_time.interval_id ); 3432 var now = new Date(); 3433 var client_minutes = now.getHours() * 60 + now.getMinutes(); 3434 var url = new URL( window.location.href ); 3435 url.searchParams.set( 'pewc_client_minutes', client_minutes ); 3436 window.location.replace( url.toString() ); 3437 return false; // Break out of .each() 3438 } 3439 }); 3440 }, 3441 3442 is_after: function( hour, min ) { 3443 let ms_today = Date.now() - new Date().setHours(0,0,0,0); 3444 return ms_today > (hour*3.6e6 + min*6e4); 3445 }, 3446 3447 update_date: function() { 3448 var field_id = $( this ).closest( '.pewc-item' ).attr( 'data-field-id' ); 3449 var id = $( this ).closest( '.pewc-item' ).attr( 'data-id' ); 3450 $( '#pewc_cl_' + field_id ).val( $( this ).attr( 'data-date' ) ); 3451 $( '#pewc_cl_price_' + field_id ).val( $( this ).closest( '.pewc-item' ).attr( 'data-field-price' ) ); 3452 $( '#pewc_cl_offset_' + id ).val( $( this ).attr( 'data-offset' ) ); 3453 } 3454 3455 } 3456 3457 check_time.init(); 3458 3459 3460})(jQuery); 3461 3462// 3.21.4, moved outside so that other scripts can use this function 3463function pewc_wc_price_without_currency( price ) { 3464 3465 var price_settings = { 3466 decimal: pewc_vars.decimal_separator, 3467 thousand: pewc_vars.thousand_separator, 3468 precision: pewc_vars.decimals, 3469 format: '%v' 3470 }; 3471 3472 if ( pewc_vars.price_trim_zeros == 'yes' && price == parseInt( price ) ) { 3473 // 3.21.3, trim zeros if filter is active 3474 price_settings.precision = 0; 3475 } 3476 3477 // since 3.12.0 3478 price = accounting.formatMoney( price, price_settings ); 3479 3480 return price; 3481 3482} 3483 3484// 3.21.4, moved outside so that other scripts can use this function 3485function pewc_wc_price( price, price_only=false, update_pewc_total_calc_price=true ) { 3486 3487 if ( update_pewc_total_calc_price ) { 3488 jQuery( '#pewc_total_calc_price' ).val( price ); // Used in Bookings for WooCommerce 3489 } 3490 3491 // since 3.12.0 3492 var currency_html = '<span class="woocommerce-Price-currencySymbol">%s</span>'; 3493 var currency_format = ''; 3494 if ( price_only ) { 3495 currency_html = '%s'; 3496 } 3497 3498 if( pewc_vars.currency_pos == 'left' ) { 3499 currency_format = currency_html+'%v'; 3500 } else if( pewc_vars.currency_pos == 'right' ) { 3501 currency_format = '%v'+currency_html; 3502 } else if( pewc_vars.currency_pos == 'left_space' ) { 3503 currency_format = currency_html+' %v'; 3504 } else if( pewc_vars.currency_pos == 'right_space' ) { 3505 currency_format = '%v '+currency_html; 3506 } 3507 3508 var price_settings = { 3509 symbol: pewc_vars.currency_symbol, 3510 decimal: pewc_vars.decimal_separator, 3511 thousand: pewc_vars.thousand_separator, 3512 precision: pewc_vars.decimals, 3513 format: currency_format 3514 }; 3515 3516 if ( pewc_vars.price_trim_zeros == 'yes' && price == parseInt( price ) ) { 3517 // 3.21.3, trim zeros if filter is active 3518 price_settings.precision = 0; 3519 } 3520 3521 price = accounting.formatMoney( price, price_settings ); 3522 3523 if ( ! price_only ) { 3524 return '<span class="woocommerce-Price-amount amount"><bdi>' + price + '</bdi></span>'; 3525 } 3526 3527 return price; 3528 3529} 3530 3531// 3.21.7 3532function pewc_wcfad_apply_discount() { 3533 return typeof pewc_wcfad !== 'undefined' && pewc_wcfad.apply_discount(); 3534} 3535 3536// 3.27.0 3537function pewc_is_booking_product() { 3538 3539 return ( jQuery( '#num_units_int' ).length > 0 ); 3540 3541} 3542 3543// 3.27.0, for compatibility with Bookings for WooCommerce 3544function pewc_get_quantity( qty=1, type='' ) { 3545 3546 if ( pewc_wcbvp_variation_grid() ) { 3547 // 4.1.1, return the total variations selected when using Better Variations grid mode 3548 qty = jQuery( '#wcbvp_total_variations' ).val(); 3549 if ( qty < 1 ) qty = 1; // so that the add-on price updates even if no variations have been selected yet 3550 } else if( jQuery( 'form.cart .quantity .qty' ).val() && 'one-only' !== type ) { 3551 qty = jQuery( 'form.cart .quantity .qty' ).val(); 3552 } else if ( pewc_is_booking_product() ) { 3553 // for Booking products, where the quantity field is not available 3554 qty = 1; // 3.27.11, changed to 1 so that "Price per booking unit" setting is respected. Previously jQuery( '#num_units_int' ).val(); 3555 if ( jQuery( '#num_bookings' ).length > 0 && ! isNaN( jQuery( '#num_bookings' ).val() ) && 'linked' === type ) { 3556 // also multiply by quantity?
3557 qty = qty * jQuery( '#num_bookings' ).val(); 3558 } 3559 } 3560 3561 return qty; 3562 3563} 3564 3565// 4.1.1, Better Variations grid mode 3566function pewc_wcbvp_variation_grid() { 3567 return ( jQuery( 'body' ).find( '.wcbvp-grid-quantity-field' ).length > 0 ); 3568} 3569 3570// 4.3.3, separated into a function and moved here so that repeatable groups can access it 3571function pewc_accordion_click( header ){ 3572 var is_open = jQuery( header ).closest( '.pewc-group-wrap' ).hasClass( 'group-active' ); 3573 3574 if ( jQuery( header ).closest( '.pewc-group-wrap' ).hasClass( 'pewc-disabled-group') ) { 3575 return; 3576 } 3577 if( pewc_vars.close_accordion == 'yes' ) { 3578 jQuery( '.pewc-group-wrap' ).removeClass( 'group-active' ); 3579 } 3580 // Don't reopen group if we've just closed it, only if close_accordion snippet is active 3581 if( ! is_open || pewc_vars.close_accordion != 'yes' ) { 3582 jQuery( header ).closest('.pewc-group-wrap').toggleClass('group-active'); 3583 } 3584}
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.