1(function ($) { 2 'use strict'; 3 4 var settings = { 5 blockUiOpt: { 6 message: null, 7 overlayCSS: { 8 background: '#fff', 9 opacity: 0.6 10 } 11 } 12 }; 13 14 var wcCheckout = { 15 init: function () { 16 17 this.customSelect = '.custom-select select'; 18 19 this.applyCouponOnCheckoutPage(); 20 this.customSelectWoo(); 21 }, 22 23 applyCouponOnCheckoutPage: function () { 24 var couponCode = 'input#coupon_code'; 25 26 $('.woocommerce-checkout').on('click', 'button#apply-coupon-btn', function (e) { 27 e.stopPropagation(); 28 29 sendCouponAjaxRequest($(couponCode).val()); 30 }); 31 32 $('form.woocommerce-checkout').bind('checkout_place_order', function (e, param, param2) { 33 if ($(couponCode).is(':focus')) { 34 sendCouponAjaxRequest($(couponCode).val()); 35 return false; 36 } 37 38 return true; 39 }); 40 41 function sendCouponAjaxRequest(couponCode) { 42 var $couponError = $('.cart-coupon-form .coupon-error'); 43 44 $couponError.text(''); 45 46 var data = { 47 security: wc_checkout_params.apply_coupon_nonce, 48 coupon_code: couponCode 49 }; 50 51 if (data.coupon_code === '') { 52 $couponError.text(wc_params.woocommerce_errors.wc_coupon_please_enter); 53 return; 54 } 55 56 // Trigger "adding_coupon" event 57 $(document.body).trigger('adding_coupon', [$(this), data.coupon_code]); 58 59 $('#order_review').block({ 60 message: null, 61 overlayCSS: { 62 opacity: 0.6 63 } 64 }); 65 66 $.ajax({ 67 type: 'POST', 68 url: wc_checkout_params.wc_ajax_url.toString().replace('%%endpoint%%', 'apply_coupon'), 69 data: data, 70 dataType: 'html', 71 success: function (response) { 72 $('#order_review').unblock(); 73 var $response = $('<div>' + response + '</div>'); 74 75 if ($(response).find('.woocommerce-error').length || $(response).hasClass('woocommerce-error')) { 76 $couponError.text($(response).find('li:eq(0)').text().trim()); 77 } else { 78 $(document.body).trigger('update_checkout', {update_shipping_method: false}); 79 } 80 } 81 }); 82 } 83 }, 84 85 customSelectWoo: function () { 86 var $select = $(this.customSelect); 87 88 if ($select.length === 0) { 89 return; 90 } 91 92 $(this.customSelect).selectWoo({ 93 minimumResultsForSearch: 9999 94 }); 95 } 96 }; 97 98 99 var addToCart = { 100 101 init: function () { 102 var self = this; 103 104 self.$simpleForm = $('.product-entry-wrapper form.cart'); 105 self.$variationsForm = $('.product-entry-wrapper form.variations_form.cart'); 106 self.formSubmitBtn = '.single_add_to_cart_button'; 107 self.quantityPlusMinusBtn = '.btn-qty-minus, .btn-qty-plus'; 108 self.miniCartBtn = '.shop-cart-btn'; 109 self.miniCartCloseBtn = '.cart-panel-close-btn'; 110 self.cartPanelAjax = false; 111 112 self.bindEvents(); 113 self.initCartPanel(); 114 }, 115 116 bindEvents: function () { 117 var self = this; 118 119 $(document.body).on('click', self.formSubmitBtn, self.addToCartOnSingle); 120 121 $(document.body).on('click', self.quantityPlusMinusBtn, self.quantityPlusMinus); 122 123 self.$variationsForm.on('reset_data, woocommerce_variation_has_changed', function (e) { 124 self.$variationsForm.find(self.formSubmitBtn).removeClass('added'); 125 self.$variationsForm.find('a.added_to_cart').remove(); 126 }); 127 128 $(document.body).on('quantity_change', self.updateMiniCartPanel); 129 $(document.body).on('input', '.mini-cart-list .mini_cart_item .qty', function (e) { 130 self.updateMiniCartPanel(e, $(this)); 131 }); 132 133 $(document.body).on('added_to_cart', function () { 134 self.toggleCartPanel(true); 135 }); 136 137 }, 138 139 addToCartOnSingle: function (e) { 140 var self = addToCart; 141 142 var $thisButton = $(this), 143 $thisForm = $(this).closest('form'); 144 145 if ($thisButton.is('.disabled')) { 146 return true; 147 } 148 149 if ($thisForm.find('input[name="ajax_add_to_cart"]').length > 0) { 150 151 var $product = $thisForm.find('[name="add-to-cart"]'), 152 $quantity = $thisForm.find('input[name="quantity"]'), 153 $variation = $thisForm.find('input[name="variation_id"]'), 154 data = {}; 155 156 if ($product.length === 0 || $product.val() === '0') { 157 return true; 158 } 159 160 e.preventDefault(); 161 162 // Allow 3rd parties to validate and quit early. 163 if (false === $(document.body).triggerHandler('should_send_ajax_request.adding_to_cart', [$thisButton])) {
164 $(document.body).trigger('ajax_request_not_sent.adding_to_cart', [false, false, $thisButton]); 165 return true; 166 } 167 168 data['quantity'] = $quantity.val(); 169 170 if ($variation.length !== 0 && $variation.val() !== '0') { 171 data['product_id'] = $variation.val(); 172 data['variation_id'] = $variation.val(); 173 } else { 174 data['product_id'] = $product.val(); 175 } 176 177 $thisButton.prop('disabled', true); 178 $thisButton.removeClass('added'); 179 $thisButton.addClass('loading'); 180 181 // Trigger event. 182 $(document.body).trigger('adding_to_cart', [$thisButton, data]); 183 184 $.ajax({ 185 type: 'POST', 186 url: wc_add_to_cart_params.wc_ajax_url.toString().replace('%%endpoint%%', 'add_to_cart'), 187 data: data, 188 dataType: 'json', 189 complete: function () { 190 $thisButton.prop('disabled', false); 191 $thisButton.removeClass('loading'); 192 }, 193 success: function (response) { 194 if (!response) { 195 return; 196 } 197 198 if (response.error && response.product_url) { 199 window.location = response.product_url; 200 return; 201 } 202 203 $thisButton.addClass('added'); 204 205 // Trigger event so themes can refresh other areas. 206 $(document.body).trigger('added_to_cart', [response.fragments, response.cart_hash, $thisButton]); 207 }, 208 }); 209 } 210 }, 211 212 quantityPlusMinus: function (e) { 213 var self = addToCart; 214 215 var $this = $(this), 216 $qty = $this.closest('.quantity').find('.qty'), 217 currentVal = parseFloat($qty.val()), 218 max = parseFloat($qty.attr('max')), 219 min = parseFloat($qty.attr('min')), 220 step = $qty.attr('step'), 221 qtyChanged = false; 222 223 // Format values 224 if (!currentVal || currentVal === '' || currentVal === 'NaN') currentVal = 0; 225 if (max === '' || max === 'NaN') max = ''; 226 if (min === '' || min === 'NaN') min = 0; 227 if (step === 'any' || step === '' || step === undefined || parseFloat(step) === 'NaN') step = 1; 228 229 // Change the value 230 if ($this.data('eq') === 'plus') { 231 if (max && (max === currentVal || currentVal > max)) { 232 $qty.val(max); 233 } else { 234 $qty.val(currentVal + parseFloat(step)); 235 qtyChanged = true; 236 } 237 } else { 238 if (min && (min === currentVal || currentVal < min)) { 239 $qty.val(min); 240 } else if (currentVal > 0) { 241 $qty.val(currentVal - parseFloat(step)); 242 qtyChanged = true; 243 } 244 } 245 246 if (qtyChanged) { 247 // Trigger quantity input "change" event 248 $qty.trigger('change'); 249 $(document.body).trigger('quantity_change', $qty); 250 } 251 }, 252 253 updateMiniCartPanel: function (e, _qty) { 254 var self = addToCart; 255 256 if (!document.body.classList.contains('cart-panel-open')) { 257 return false; 258 } 259 260 var $qty = $(_qty); 261 var $row = $qty.closest('.woocommerce-mini-cart-item') 262 263 // Is an Ajax request already running? 264 if (self.cartPanelAjax) { 265 self.cartPanelAjax.abort(); // Abort current Ajax request 266 } 267 268 $row.addClass('loading'); 269 $row.block({ 270 message: null, 271 overlayCSS: { 272 opacity: 0.6 273 } 274 }); 275 276 var data = {}; 277 data[$qty.attr('name')] = $qty.val(); 278 data['security'] = woocommerce_params.update_cart_item_nonce; 279 280 // Make call to actual form post URL. 281 self.cartPanelAjax = $.ajax({ 282 type: 'POST', 283 url: wc_add_to_cart_params.wc_ajax_url.toString().replace('%%endpoint%%', 'update_cart_item'), 284 data: data, 285 dataType: 'html', 286 error: function (XMLHttpRequest, textStatus, errorThrown) { 287 // Hide any visible thumbnail loaders (no need to hide on "success" since the cart panel is replaced) 288 $('.mini-cart-list .cart_list').children('.loading').removeClass('loading'); 289 }, 290 success: function (response) { 291 // Replace cart fragments 292 $(document.body).trigger('wc_fragment_refresh').trigger('updated_cart_totals'); 293 }, 294 complete: function () { 295 self.cartPanelAjax = null; // Reset Ajax state 296 } 297 }); 298 }, 299 300 initCartPanel: function () { 301 var self = addToCart; 302 303 $(document.body).on('click', self.miniCartBtn, function (e) { 304 e.preventDefault(); 305 self.toggleCartPanel(true); 306 }); 307 308 $(document.body).on('click', self.miniCartCloseBtn + ', .overlay-wrapper', function (e) { 309 if (document.body.classList.contains('cart-panel-open')) { 310 e.preventDefault(); 311 self.toggleCartPanel(false); 312 } 313 }); 314 315 }, 316 317 toggleCartPanel: function (state) { 318 if (state) { 319 document.body.classList.add('overlay-open', 'cart-panel-open'); 320 } else { 321 document.body.classList.add('overlay-closing', 'cart-panel-closing'); 322 323 setTimeout(function () { 324 document.body.classList.remove('overlay-open', 'cart-panel-open', 'overlay-closing', 'cart-panel-closing'); 325 }, 500); 326 } 327 } 328 329 }; 330 331 $(document).ready(function () { 332 wcCheckout.init() 333 addToCart.init() 334 }); 335 336}(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.