1(function ($) { 2 'use strict'; 3 4 /** 5 * This script is used to handle the block based optional fees functionality 6 */ 7 $(document).ready(function ($) { 8 // Event listeners for fee changes on cart and checkout pages 9 $(document).on('change', '.woocommerce-cart .wp-block-woocommerce-checkout-optional-fee-block input[type="checkbox"], .woocommerce-cart .wp-block-woocommerce-checkout-optional-fee-block select, .woocommerce-cart .wp-block-woocommerce-checkout-optional-fee-block input[type="radio"]', function () { 10 addFeeDataInSession(); 11 }); 12 13 14 $(document).on('change', '.woocommerce-checkout .wp-block-woocommerce-checkout-optional-fee-block input[type="checkbox"], .woocommerce-checkout .wp-block-woocommerce-checkout-optional-fee-block select, .woocommerce-checkout .wp-block-woocommerce-checkout-optional-fee-block input[type="radio"]', function () { 15 addFeeDataInSession(); 16 }); 17 18 // Initial load: Apply optional fees and update stored data 19 setTimeout(function () { 20 if (localStorage.getItem('wcpfc_browser_data') !== null) { 21 updateFieldsBasedOnStoredData(); 22 } 23 24 if ($('.woocommerce-checkout .wp-block-woocommerce-checkout-optional-fee-block').length > 0 || $('.woocommerce-cart .wp-block-woocommerce-checkout-optional-fee-block').length > 0) { 25 addFeeDataInSession(); 26 } 27 }, 100); 28 }); 29 30 // Block UI 31 function blockUI() { 32 $('.wp-block-woocommerce-checkout, .wp-block-woocommerce-cart').block({ 33 message: null, 34 overlayCSS: { background: '#fff', opacity: 0.6 } 35 }); 36 } 37 38 // Unblock UI 39 function unblockUI() { 40 $('.wp-block-woocommerce-checkout, .wp-block-woocommerce-cart').unblock(); 41 } 42 43 // Collect fee data from checkboxes, selects, and radios 44 function collectFeeDataOnChange() { 45 46 const data = []; 47 $('.wp-block-woocommerce-checkout-optional-fee-block') 48 .find('input[type="checkbox"]:checked, select, input[type="radio"]:checked') 49 .each(function () { 50 const $this = $(this); 51 const value = $this.val(); 52 53 if ($this.is('input[type="checkbox"]')) { 54 // For checkboxes, we expect a numeric value (fee ID) 55 if (value && !isNaN(value)) { 56 data.push(parseInt(value, 10)); 57 } 58 } else if ($this.is('select') || $this.is('input[type="radio"]')) { 59 // For select inputs, check if the value is 'yes' 60 if (value.toLowerCase() === 'yes') { 61 const feeValue = $this.data('value'); // Using the data-value attribute 62 if (feeValue && !isNaN(feeValue)) { 63 data.push(parseInt(feeValue, 10)); 64 } 65 } 66 } 67 }); 68 69 return data; 70 } 71 72 // Update WooCommerce Blocks checkout with fee data 73 function updateFeeData(data) { 74 75 let feeData = data || []; 76 if (!Array.isArray(feeData) || feeData.length === 0 || feeData === undefined || feeData === null) { 77 feeData = collectFeeDataOnChange(); 78 } 79 80 const { select } = wp.data; 81 const { PAYMENT_STORE_KEY } = window.wc.wcBlocksData; 82 const chosenPaymentMethod = select( PAYMENT_STORE_KEY ).getActivePaymentMethod(); 83 84 wc.blocksCheckout.extensionCartUpdate({ 85 namespace: 'woocommerce-conditional-product-optional-fees', 86 data: { 87 fees_ids: feeData, 88 payment_method: chosenPaymentMethod, 89 } 90 }).then(function () { 91 setTimeout(function () { 92 $(document.body).trigger('wc_fragment_refresh'); 93 }, 300); 94 unblockUI(); 95 }).catch(function (error) { 96 console.error('Error updating fee data:', error); 97 unblockUI(); 98 }); 99 } 100 101 // Add fee data to session 102 function addFeeDataInSession() { 103 104 if (!window || !window.wc || !window.wc.blocksCheckout) { 105 return; 106 } 107 108 const isCartPage = $('.wp-block-woocommerce-cart').length > 0; 109 const isCheckoutPage = $('.wp-block-woocommerce-checkout').length > 0; 110 111 if (!isCartPage && !isCheckoutPage) { return; } 112 113 blockUI(); 114 115 let sendData = []; 116 const data = collectFeeDataOnChange(); 117 118 var checkbox; 119 var radio; 120 var dropdown; 121 var dropdownValue; 122 123 if (isCartPage) { 124 // Select all checkboxes and radio buttons dynamically 125 checkbox = $('.woocommerce-cart .wp-block-woocommerce-checkout-optional-fee-block').find('.input-checkbox'); 126 radio = $('.woocommerce-cart .wp-block-woocommerce-checkout-optional-fee-block').find('input[type="radio"]:checked'); 127 dropdown = $('.woocommerce-cart .wp-block-woocommerce-checkout-optional-fee-block').find('select'); 128 129 // Check if the dropdown exists and has a value 130 dropdownValue = (dropdown.length > 0) ? dropdown.val() : undefined; // Check if the dropdown exists 131 132 // Check if the checkbox is checked, or a "Yes" radio button is selected, or a valid dropdown option is selected 133 if (checkbox.is(':checked') || radio.val() === 'yes' || (dropdownValue !== undefined && dropdownValue === 'Yes')) { 134 localStorage.setItem('wcpfc_browser_data', JSON.stringify(data)); 135 localStorage.setItem('wcpfc_cart_hand_checked', true); 136 sendData = data; 137 } else { 138 localStorage.removeItem('wcpfc_browser_data'); 139 localStorage.setItem('wcpfc_cart_hand_checked', false); 140 sendData = []; 141 } 142 } 143 144 if (isCheckoutPage) { 145 var cartChecked = localStorage.getItem('wcpfc_cart_hand_checked'); 146 if (cartChecked !== null && cartChecked === 'true') { 147 if( data !== null && data.length > 0 ) { 148 localStorage.setItem('wcpfc_browser_data', JSON.stringify(data)); 149 localStorage.setItem('wcpfc_cart_hand_checked', true); 150 sendData = data; 151 } else { 152 localStorage.removeItem('wcpfc_browser_data'); 153 localStorage.setItem('wcpfc_cart_hand_checked', false); 154 sendData = []; 155 } 156 } else { 157 checkbox = $('.woocommerce-checkout .wp-block-woocommerce-checkout-optional-fee-block').find('.input-checkbox'); 158 radio = $('.woocommerce-checkout .wp-block-woocommerce-checkout-optional-fee-block').find('input[type="radio"]:checked'); 159 dropdown = $('.woocommerce-checkout .wp-block-woocommerce-checkout-optional-fee-block').find('select'); 160 dropdownValue = (dropdown.length > 0) ? dropdown.val() : undefined; 161 162 if (checkbox.is(':checked') || radio.val() === 'yes' || (dropdownValue !== undefined && dropdownValue === 'Yes')) { 163 localStorage.setItem('wcpfc_browser_data', JSON.stringify(data)); 164 localStorage.setItem('wcpfc_cart_hand_checked', true); 165 sendData = data; 166 } else { 167 localStorage.removeItem('wcpfc_browser_data'); 168 localStorage.setItem('wcpfc_cart_hand_checked', false); 169 sendData = []; 170 } 171 } 172 } 173 174 updateFeeData(sendData); 175 } 176 177 // Update fields based on stored data 178 function updateFieldsBasedOnStoredData() { 179 180 const isCartPage = $('.wp-block-woocommerce-cart').length > 0; 181 const isCheckoutPage = $('.wp-block-woocommerce-checkout').length > 0; 182 if (!isCheckoutPage && !isCartPage) { return; } 183 184 const storedData = JSON.parse(localStorage.getItem('wcpfc_browser_data')) || []; 185 186 $('.wp-block-woocommerce-checkout-optional-fee-block input[type="checkbox"]').each(function () { 187 updateInputState($(this), storedData); 188 }); 189 190 $('.wp-block-woocommerce-checkout-optional-fee-block select').each(function () { 191 const selectedValue = parseInt($(this).data('value')); 192 $(this).val(storedData.includes(selectedValue) ? 'Yes' : 'No'); 193 }); 194 195 $('.wp-block-woocommerce-checkout-optional-fee-block input[type="radio"]').each(function () { 196 // Find the group of radio buttons by name (each fee ID has a distinct name group) 197 const feeRadioName = $(this).attr('name');
198 // Only run once per group, on the 'yes' button (to avoid duplication) 199 if ($(this).val().toLowerCase() === 'yes') { 200 // Find all radios in the current group 201 const $group = $('input[type="radio"][name="' + feeRadioName + '"]'); 202 // Find the 'yes' and 'no' buttons in this group 203 const $yesRadio = $group.filter(function() { return $(this).val().toLowerCase() === 'yes'; }); 204 const $noRadio = $group.filter(function() { return $(this).val().toLowerCase() === 'no'; }); 205 206 // The fee ID value is stored in data-value for 'yes', or may need to get from any in the group that has a non-empty data-value 207 // Get feeId from yes button (should always have it) 208 const feeId = parseInt($yesRadio.data('value')); 209 const feeApplied = storedData.includes(feeId); 210 211 // Set checked state: only one in group checked at a time 212 if (feeApplied) { 213 $yesRadio.prop('checked', true); 214 $noRadio.prop('checked', false); 215 } else { 216 $yesRadio.prop('checked', false); 217 $noRadio.prop('checked', true); 218 } 219 } 220 }); 221 } 222 223 function updateInputState(inputElement, storedData) { 224 const value = parseInt(inputElement.val()); 225 if (( value === 0 || value === '' || value === null || typeof value === 'undefined') ) { 226 inputElement.prop('checked', true); 227 } else { 228 inputElement.prop('checked', storedData.includes(value)); 229 } 230 } 231 232})(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.