1/** 2 * WooCommerce Instagram Product - Template JavaScript 3 * 4 * Handles image picker initialization, AJAX pagination, 5 * form validation, and selection persistence. 6 * 7 * @package WooInsProduct 8 * @since 1.2.0 9 */ 10 11/* global jQuery, wooInsData */ 12 13(function ($) { 14 'use strict'; 15 16 /** 17 * Update the selection display (counts, per-post amounts, overlays). 18 * 19 * @param {number} insLikes Total likes/views to distribute. 20 */ 21 function updateSelectionDisplay(insLikes) { 22 var values = $('.image-picker').val(); 23 24 if (values != null && values.length > 0) { 25 var count = values.length; 26 var likesPerPost = Math.round(insLikes / count); 27 28 $('span.ins_selected_posts').text(count); 29 $('span.ins_likes').text(likesPerPost); 30 $('span.append_span').text(' + ' + likesPerPost); 31 } else { 32 $('span.ins_selected_posts').text('0'); 33 $('span.ins_likes').text('0'); 34 $('span.append_span').text(''); 35 } 36 } 37 38 /** 39 * Ensure all thumbnails have an append_span element. 40 * Avoids duplicates by checking if one already exists. 41 */ 42 function ensureAppendSpans() { 43 $('.thumbnail p').each(function () { 44 if (!$(this).find('.append_span').length) { 45 $(this).append('<span class="append_span" style="display:none;"></span>'); 46 } 47 }); 48 } 49 50 /** 51 * Initialize image picker with callbacks for selection tracking. 52 * Called on initial load and after AJAX appends new options. 53 * 54 * Preserves existing selections when reinitializing (load more). 55 */ 56 function loadImagePicker() { 57 var insLikes = parseInt($('.image-picker').closest('form').find('input[name="qty"]').val(), 10) || 0; 58 var noLikesMsg = $('.image-picker').data('no-likes-msg') || ''; 59 60 // Save current selections before reinitializing 61 var currentSelections = $('select.image-picker').val() || []; 62 63 $('.image-picker').imagepicker({ 64 limit_reached: function () { 65 alert(noLikesMsg); 66 }, 67 show_label: true, 68 hide_select: true, 69 initialized: function () { 70 $('.loaded_1').fadeOut('slow'); 71 $('.s_btn').removeClass('btn-busy'); 72 73 // Restore selections after reinitialization 74 if (currentSelections.length > 0) { 75 $('select.image-picker').val(currentSelections); 76 // Sync visual state with select value 77 currentSelections.forEach(function (val) { 78 $('select.image-picker option').filter(function () { 79 return $(this).val() === val; 80 }).prop('selected', true); 81 }); 82 // Re-trigger image picker to reflect selections 83 $('select.image-picker').data('picker').sync_picker_with_select(); 84 } 85 86 ensureAppendSpans(); 87 updateSelectionDisplay(insLikes); 88 }, 89 clicked: function () { 90 ensureAppendSpans(); 91 updateSelectionDisplay(insLikes); 92 } 93 }); 94 95 ensureAppendSpans(); 96 } 97 98 /** 99 * Validate form: ensure at least one post is selected. 100 * 101 * @return {boolean} True if valid, false otherwise. 102 */ 103 function notifyEmpty() { 104 var form = document.forms['myForm']; 105 if (!form) { 106 return false; 107 } 108 109 var x = form['fname[]']; 110 if (!x || x.value === '' || (x.selectedOptions && x.selectedOptions.length === 0)) { 111 alert(wooInsData.selectPostAlert); 112 return false; 113 } 114 115 document.getElementById('myForm').submit(); 116 return true; 117 } 118 119 // Expose globally for form onsubmit attribute 120 window.notifyempty = notifyEmpty; 121 window.loadImagePicker = loadImagePicker; 122 123 $(document).ready(function () { 124 // Initialize image picker if present 125 if ($('.image-picker').length) { 126 loadImagePicker(); 127 } 128 129 // Show all thumbnails 130 $('ul.thumbnails.image_picker_selector li').show(); 131 132 // Load More button - AJAX pagination 133 $('#loadMore').on('click', function (e) { 134 var that = this; 135 e.preventDefault(); 136 137 var offset = $(this).attr('data-offset'); 138 var insName = $(this).attr('data-ins-name'); 139 var productId = $(this).attr('data-product-id'); 140 var isLoading = $(this).attr('data-is-loading'); 141 142 if (isLoading === 'true') { 143 return; 144 } 145 146 var formData = { 147 action: 'prismLoadIgPosts', 148 _nonce: wooInsData.nonce, 149 ins_name: insName, 150 product_id: productId, 151 offset: offset 152 }; 153 154 $.ajax({ 155 dataType: 'json', 156 type: 'POST', 157 data: formData, 158 url: wooInsData.ajaxUrl, 159 beforeSend: function () { 160 $('.loaded_2').fadeIn('slow'); 161 $(that).addClass('disabled'); 162 $(that).attr('data-is-loading', 'true'); 163 }, 164 complete: function () { 165 $('.loaded_2').fadeOut('slow'); 166 $(that).attr('data-is-loading', 'false'); 167 $(that).removeClass('disabled'); 168 }, 169 success: function (response) { 170 var items = response.items; 171 var nextOffset = response.nextOffset; 172 173 if (items) { 174 // Save current selections before appending & reinitializing 175 var savedSelections = $('select.image-picker').val() || []; 176 177 $('#loadMore').attr('data-offset', nextOffset); 178 $('select.image-picker').append(items); 179 180 // Restore selections on the <select> before reinit 181 $('select.image-picker').val(savedSelections); 182 183 loadImagePicker(); 184 } 185 186 if (!nextOffset) { 187 $('#loadMore').fadeOut('slow'); 188 } 189 } 190 }); 191 }); 192 193 // Submit button validation and loading state 194 $('.s_btn').on('click', function (e) { 195 e.preventDefault(); 196 197 var form = document.forms['myForm']; 198 if (!form) { 199 return false;
200 } 201 202 var x = form['fname[]']; 203 if (!x || x.value === '' || (x.selectedOptions && x.selectedOptions.length === 0)) { 204 alert(wooInsData.selectPostAlert); 205 return false; 206 } 207 208 $(this).addClass('btn-busy'); 209 // Double rAF ensures a repaint before navigation (spinner visible on mobile) 210 requestAnimationFrame(function () { 211 requestAnimationFrame(function () { 212 form.submit(); 213 }); 214 }); 215 }); 216 217 // Add to cart button loading state (Step 0 "Suivant" and Step 2 "Procéder au paiement") 218 $(document).on('click', 'button.single_add_to_cart_button', function (e) { 219 e.preventDefault(); 220 var form = $(this).closest('form')[0]; 221 var $form = $(form); 222 223 // Validate required fields (e.g., speed_of_delivery on Step 2) 224 if (!form.checkValidity()) { 225 form.reportValidity(); 226 return; 227 } 228 229 // Step 0: ensure a variation is selected (variation_id must not be 0) 230 var variationInput = $form.find('input.variation_id'); 231 if (variationInput.length && (!variationInput.val() || variationInput.val() === '0')) { 232 // Highlight the variation selects to draw attention 233 $form.find('table.variations select').css('border-color', '#c0392b'); 234 setTimeout(function () { 235 $form.find('table.variations select').css('border-color', ''); 236 }, 2000); 237 return; 238 } 239 240 var insNameInput = $('input[name="ins_name"]'); 241 // If there's an ins_name field, only activate spinner when it has a value 242 if (insNameInput.length === 0 || insNameInput.val() !== '') { 243 $(this).addClass('btn-busy').addClass('disabled'); 244 // Double rAF ensures a repaint before navigation (spinner visible on mobile) 245 requestAnimationFrame(function () { 246 requestAnimationFrame(function () { 247 form.submit(); 248 }); 249 }); 250 } 251 }); 252 }); 253 254 // Show "Prix :" label only when a variation is selected 255 $(document).on('found_variation', '.variations_form', function () { 256 $('.wooins-step0-price-label').show(); 257 }); 258 $(document).on('hide_variation reset_data', '.variations_form', function () { 259 $('.wooins-step0-price-label').hide(); 260 }); 261 262})(jQuery);
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.