1( function ( $ ) { 2 "use strict"; 3 4 const FormBuilder = { 5 6 refund_form_qty_fields: $( '#fr_refund_table, #fr_refund_table_free' ), 7 8 init: function () { 9 $( '#fb-field-type' ).val( '' ); 10 $( '#fb-field-name' ).val( '' ); 11 $( '#fb-field-label' ).val( '' ); 12 }, 13 14 formatMoney: function ( number, decPlaces, decSep, thouSep ) { 15 decPlaces = isNaN( decPlaces = Math.abs( decPlaces ) ) ? 2 : decPlaces, 16 decSep = typeof decSep === "undefined" ? "." : decSep; 17 thouSep = typeof thouSep === "undefined" ? "," : thouSep; 18 var sign = number < 0 ? "-" : ""; 19 var i = String( parseInt( number = Math.abs( Number( number ) || 0 ).toFixed( decPlaces ) ) ); 20 var j = ( j = i.length ) > 3 ? j % 3 : 0; 21 22 return sign + 23 ( j ? i.substr( 0, j ) + thouSep : "" ) + 24 i.substr( j ).replace( /(\decSep{3})(?=\decSep)/g, "$1" + thouSep ) + 25 ( decPlaces ? decSep + Math.abs( number - i ).toFixed( decPlaces ).slice( 2 ) : "" ); 26 }, 27 28 number_format: function ( value ) { 29 return this.formatMoney( value.toString(), fr_front_i18n.price_decimals, fr_front_i18n.decimal_point, fr_front_i18n.thousand_point ); 30 }, 31 32 roundMoney: function ( value ) { 33 const precision = 10 ** fr_front_i18n.price_decimals; 34 35 return Math.round( ( value + Number.EPSILON ) * precision ) / precision; 36 }, 37 38 updateShippingRefundState: function ( table ) { 39 let product_inputs = table.find( '.product_item .qty-input[type="number"]' ); 40 let full_return = product_inputs.length > 0; 41 let has_selected_product = false; 42 product_inputs.each( function () { 43 let quantity = parseInt( $( this ).val() ); 44 full_return = full_return && quantity === parseInt( $( this ).attr( 'max' ) ); 45 has_selected_product = has_selected_product || quantity > 0; 46 } ); 47 48 let shipping_inputs = table.find( '.shipping-refund-checkbox' ); 49 let lowest_cost_left = parseFloat( shipping_inputs.first().attr( 'data-partial-limit' ) ) || 0; 50 shipping_inputs.each( function () { 51 let input = $( this ); 52 let mode = input.attr( 'data-partial-mode' ); 53 let full_price = parseFloat( input.attr( 'data-item-price' ) ) || 0; 54 let automatic_full_return = full_return && 'customer_choice' !== mode; 55 let refund_price = 'lowest_cost' === mode && ! full_return ? Math.min( lowest_cost_left, full_price ) : full_price; 56 57 if ( 'yes' === mode || 'lowest_cost' === mode ) { 58 input.prop( 'checked', has_selected_product ).prop( 'disabled', true ); 59 input.attr( 'data-active-price', refund_price ); 60 } else if ( automatic_full_return ) { 61 input.prop( 'checked', true ).prop( 'disabled', true ); 62 input.attr( 'data-active-price', refund_price ); 63 } else { 64 if ( 'no' === mode ) { 65 input.prop( 'checked', false ); 66 } 67 input.prop( 'disabled', 'no' === mode ); 68 input.attr( 'data-active-price', refund_price ); 69 } 70 if ( 'lowest_cost' === mode && input.prop( 'checked' ) ) { 71 lowest_cost_left -= refund_price; 72 } 73 } ); 74 }, 75 76 calculateRefundTotals: function () { 77 let _this = this; 78 _this.refund_form_qty_fields.on( 'change', '.item-qty input', function () { 79 let table = $( this ).closest( 'table' ); 80 _this.updateShippingRefundState( table ); 81 let qty = $( this ).val(); 82 let qty_max = parseInt( $( this ).attr( 'max' ) ); 83 let value = parseFloat( $( this ).attr( 'data-item-price' ) ) * qty; 84 if ( $( this ).attr( 'type' ) === 'checkbox' ) { 85 if ( $( this ).prop( 'checked' ) ) { 86 value = parseFloat( $( this ).attr( 'data-active-price' ) || $( this ).attr( 'data-item-price' ) ); 87 } else { 88 value = 0; 89 } 90 } 91 92 value = _this.roundMoney( value ); 93 $( this ).closest( 'tr' ).find( '.item-total-refund-qty' ).html( _this.number_format( value ) ); 94 95 let total_amount = 0; 96 let total_qty = 0; 97 let total_amount_wrapper = $( '.refund-total-calc' ); 98 let total_qty_wrapper = $( '.refund-total-qty' ); 99 let total_qty_input = $( '#refund-total-qty-input' ); 100 table.find( '.item-qty input' ).each( function () { 101 let qty = $( this ).val(); 102 let qty_max = parseInt( $( this ).attr( 'max' ) ); 103 let total_value = parseFloat( $( this ).attr( 'data-item-price' ) ) * qty; 104 if ( $( this ).attr( 'type' ) === 'checkbox' ) { 105 if ( $( this ).prop( 'checked' ) ) { 106 total_value = parseFloat( $( this ).attr( 'data-active-price' ) || $( this ).attr( 'data-item-price' ) ); 107 qty = 1; 108 } else { 109 total_value = 0; 110 qty = 0; 111 } 112 } 113 114 115 total_value = _this.roundMoney( parseFloat( total_value ) ); 116 $( this ).closest( 'tr' ).find( '.item-total-refund-qty' ).html( _this.number_format( total_value ) ); 117 total_amount += total_value; 118 total_qty += parseInt( qty ); 119 } ) 120 121 total_amount_wrapper.html( _this.number_format( total_amount ) ); 122 total_qty_wrapper.html( total_qty ); 123 total_qty_input.val( total_qty ); 124 } ); 125 126 $( '.woocommerce-table-refund-details .item-qty input' ).trigger( 'change' ); 127 }, 128 129 validateUploadInput: function () { 130 $( '.refund-front-form' ).find( 'input[type="file"]' ).each( function ( i, v ) { 131 let field = $( v ); 132 const limit = field.attr( 'data-files-limit' ); 133 134 $( this ).on( 'change', () => { 135 const fileLimit = parseInt( limit ); 136 const fileCount = this.files ? this.files.length : 0; 137 let notice_wrapper = field.closest( '.field-row' ).find( '.fr-required-field-notice' ); 138 139 if ( fileCount > fileLimit ) { 140 notice_wrapper.html( `<span class="label-error-required">${fr_front_i18n.files_limit} (limit: ${fileLimit})</span>` ); 141 this.value = ''; 142 } else { 143 notice_wrapper.html( '' ); 144 } 145 } ) 146 } ); 147 }, 148 149 hasRequiredFieldValue: function ( field_row ) { 150 let has_value = false;
151 let fields = field_row.find( 'input[name]:not([type="hidden"]), textarea[name], select[name]' ); 152 153 fields.each( function () { 154 let field = $( this ); 155 let type = field.attr( 'type' ); 156 let value = field.val(); 157 158 if ( type === 'radio' || type === 'checkbox' ) { 159 has_value = has_value || field.prop( 'checked' ); 160 } else if ( type === 'file' ) { 161 has_value = has_value || Boolean( this.files && this.files.length ); 162 } else if ( Array.isArray( value ) ) { 163 has_value = has_value || value.length > 0; 164 } else { 165 has_value = has_value || String( value || '' ).trim() !== ''; 166 } 167 } ); 168 169 return has_value; 170 }, 171 172 validateRefundForm: function () { 173 let _this = this; 174 let required_fields = 'input[name]:not([type="hidden"]), textarea[name], select[name]'; 175 176 $( '.refund-front-form' ).on( 'input change', required_fields, function () { 177 let field_row = $( this ).closest( '.field-required' ); 178 if ( field_row.length && _this.hasRequiredFieldValue( field_row ) ) { 179 field_row.find( '.fr-required-field-notice' ).html( '' ); 180 } 181 } ); 182 183 $( '.refund-front-form' ).submit( function () { 184 let is_valid = true; 185 let qty_total = 0; 186 $( this ).find( '.qty-input' ).each( function ( i, v ) { 187 let qty_value = parseInt( $( this ).val() ); 188 if ( $( this ).attr( 'type' ) === 'checkbox' ) { 189 if ( $( this ).prop( 'checked' ) ) { 190 qty_value = 1; 191 } else { 192 qty_value = 0; 193 } 194 } 195 196 qty_total += parseInt( qty_value ); 197 } ); 198 199 if ( qty_total === 0 ) { 200 is_valid = false; 201 } 202 203 if ( ! is_valid ) { 204 $( '#fr-front-refund-table-errors' ).html( '<ul class="woocommerce-error fr-form-error"><li>' + fr_front_i18n.qty_empty + '</li></ul>' ); 205 } else { 206 $( '#fr-front-refund-table-errors' ).html( '' ); 207 } 208 209 $( this ).find( '.field-required' ).each( function () { 210 let field_row = $( this ); 211 let notice_wrapper = field_row.find( '.fr-required-field-notice' ); 212 if ( _this.hasRequiredFieldValue( field_row ) ) { 213 notice_wrapper.html( '' ); 214 } else { 215 is_valid = false; 216 notice_wrapper.html( '<span class="label-error-required">' + fr_front_i18n.required_field + '</span>' ); 217 } 218 } ); 219 220 return is_valid; 221 } ); 222 }, 223 224 checkAll: function () { 225 let _this = this; 226 227 var button = $( '.check-all-button button' ); 228 var check_text = button.attr( 'data-text-check' ); 229 var uncheck_text = button.attr( 'data-text-uncheck' ); 230 231 if ( _this.isAllInputChecked() ) { 232 button.html( uncheck_text ); 233 button.addClass( 'uncheck' ); 234 } else { 235 button.html( check_text ); 236 button.removeClass( 'uncheck' ); 237 } 238 239 button.on( 'click', function () { 240 if ( ! $( this ).hasClass( 'uncheck' ) ) { 241 $( this ).html( uncheck_text ); 242 _this.checkAllInputs( 'max', true ); 243 $( this ).addClass( 'uncheck' ); 244 } else { 245 $( this ).html( check_text ); 246 _this.checkAllInputs( 'min', false ); 247 $( this ).removeClass( 'uncheck' ); 248 } 249 250 return false; 251 } ); 252 }, 253 254 isAllInputChecked: function () { 255 let is_checked = true; 256 $( '.qty-input:not(.shipping-refund-checkbox)', this.refund_form_qty_fields ).each( function ( i, v ) { 257 let field = $( v ); 258 let qty = field.attr( 'max' ); 259 let type = field.attr( 'type' ); 260 if ( type === 'number' ) { 261 if ( qty !== field.val() ) { 262 is_checked = false; 263 } 264 field.change(); 265 } else if ( type === 'checkbox' ) { 266 if ( ! field.prop( 'checked' ) ) { 267 is_checked = false; 268 } 269 } 270 } ); 271 272 return is_checked; 273 }, 274 275 checkAllInputs: function ( attr, prop ) { 276 $( '.qty-input:not(.shipping-refund-checkbox)', this.refund_form_qty_fields ).each( function ( i, v ) { 277 let field = $( v ); 278 let qty = field.attr( attr ); 279 let type = field.attr( 'type' ); 280 if ( type === 'number' ) { 281 field.val( qty ); 282 field.change(); 283 } else if ( type === 'checkbox' ) { 284 field.prop( 'checked', prop ); 285 field.change(); 286 } 287 } ); 288 }, 289 290 refundCancelButtons: function () { 291 let cancel_button = $( '#fr-cancel-request-section a.cr-button' ); 292 let dismiss_button = $( '#fr-cancel-request-section a.ds-button' ); 293 let confirm_button = $( '#fr-cancel-request-section a.cf-button' ); 294 if ( cancel_button.length ) { 295 cancel_button.click( function () { 296 confirm_button.show(); 297 dismiss_button.show(); 298 cancel_button.hide(); 299 300 return false;
301 } ); 302 } 303 if ( dismiss_button.length ) { 304 dismiss_button.click( function () { 305 confirm_button.hide(); 306 dismiss_button.hide(); 307 cancel_button.show(); 308 309 return false; 310 } ); 311 } 312 }, 313 314 initSelect2: function () { 315 $( document ).ready( function () { 316 let multiselect = $( '.multiselect' ); 317 if ( multiselect.length ) { 318 multiselect.each( function () { 319 let field = $( this ); 320 if ( ! field.hasClass( 'select2-hidden-accessible' ) ) { 321 field.select2( { width: '100%' } ); 322 } 323 } ); 324 } 325 } ); 326 } 327 } 328 329 FormBuilder.init(); 330 FormBuilder.calculateRefundTotals(); 331 FormBuilder.validateRefundForm(); 332 FormBuilder.checkAll(); 333 FormBuilder.refundCancelButtons(); 334 FormBuilder.initSelect2(); 335 FormBuilder.validateUploadInput(); 336 337} )( 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.