1jQuery(document).ready(function($){ 2 3 var focus_qty, 4 xoo_is_dragging = 0; 5 6 7 // HONINGonline performance: 8 // Geen geforceerde wc_fragment_refresh op document load. WooCommerce mag 9 // zijn eigen cart-hash/sessionStorage gebruiken en refresht alleen wanneer 10 // de opgeslagen fragments echt ontbreken of ongeldig zijn. 11 12 //Block cart on fragment refresh 13 $(document.body).on('wc_fragment_refresh',block_popup); 14 15 //Unblock cart 16 var fadenotice = null; 17 $(document.body).on('wc_fragments_refreshed wc_fragments_loaded',function(){ 18 unblock_popup(); 19 $('.xoo-cp-atcn').show(); 20 clearTimeout(fadenotice); 21 fadenotice = setTimeout(function(){ 22 $('.xoo-cp-atcn').slideUp('slow'); 23 },2500) 24 }); 25 26 27 //Notice Function 28 function show_notice(notice_type,notice){ 29 $('.xoo-cp-notice').html(notice).attr('class','xoo-cp-notice').addClass('xoo-cp-nt-'+notice_type); 30 $('.xoo-cp-notice-box').fadeIn('fast'); 31 clearTimeout(fadenotice); 32 var fadenotice = setTimeout(function(){ 33 $('.xoo-cp-notice-box').fadeOut('slow'); 34 },3000); 35 }; 36 37 38 39 //Custom ScrollBar 40 $(".xoo-cp-container-scroll").mCustomScrollbar({ 41 scrollEasing:"linear", 42 theme: xoo_cp_localize.sbtheme, 43 mouseWheel:{ scrollAmount: 500}, 44 45 }); 46 47 //Open cart pop up 48 function open_popup(){ 49 $('.xoo-cp-opac').show(); 50 $('.xoo-cp-modal').addClass('xoo-cp-active'); 51 $('body').addClass('xoo-cp-popup-active'); 52 } 53 54 55 //Open cart when click on basket 56 $('body').on('click','.xoo-cp-basket , .xoo-cp-sc-cont',function(){ 57 if(xoo_is_dragging){return;} 58 open_popup(); 59 }); 60 61 62 63 // HONINGonline UX: tijdens add-to-cart blijft de huidige pagina zichtbaar. 64 // Op de geklikte bestelknop tonen we drie bewegende wachtpuntjes. Pas nadat 65 // WooCommerce de definitieve fragments/prijs/count heeft teruggegeven, opent 66 // de popup. Zo is er directe klikfeedback zonder een halflege popup/spinner. 67 function set_add_to_cart_waiting(atc_btn){ 68 var $button = atc_btn && atc_btn.jquery ? atc_btn : $(atc_btn || []); 69 70 if(!$button.length || $button.data('ho-cart-busy')){ 71 return false; 72 } 73 74 $button 75 .data('ho-cart-busy', true) 76 .attr('aria-busy', 'true') 77 .attr('aria-disabled', 'true') 78 .addClass('ho-atc-waiting'); 79 80 if(!$button.find('.ho-atc-dots').length){ 81 $button.append('<span class="ho-atc-dots" aria-hidden="true"><span></span><span></span><span></span></span>'); 82 } 83 84 // Veiligheidsnet bij een onverwacht afgebroken request. 85 var timer = window.setTimeout(function(){ 86 clear_add_to_cart_waiting($button); 87 }, 15000); 88 $button.data('ho-cart-busy-timer', timer); 89 90 return true; 91 } 92 93 function clear_add_to_cart_waiting(atc_btn){ 94 var $button = atc_btn && atc_btn.jquery ? atc_btn : $(atc_btn || []); 95 96 if(!$button.length){ 97 return; 98 } 99 100 $button.each(function(){ 101 var $this = $(this); 102 var timer = $this.data('ho-cart-busy-timer'); 103 if(timer){ 104 window.clearTimeout(timer); 105 } 106 107 $this 108 .removeData('ho-cart-busy') 109 .removeData('ho-cart-busy-timer') 110 .removeAttr('aria-busy') 111 .removeAttr('aria-disabled') 112 .removeClass('ho-atc-waiting'); 113 114 $this.find('.ho-atc-dots').remove(); 115 }); 116 } 117 118 // Zowel WooCommerce's gewone AJAX-knoppen als onze single-product AJAX-flow 119 // sturen dit event vlak voordat de request begint. 120 $(document.body).on('adding_to_cart.honingonline_waiting', function(event, atc_btn){ 121 set_add_to_cart_waiting(atc_btn); 122 }); 123 124 // Alle andere added_to_cart-handlers mogen eerst de fragments vervangen. 125 // Daarna openen we pas de volledig bijgewerkte popup in het volgende frame. 126 $(document.body).on('added_to_cart',function(event,fragments,hash,atc_btn){ 127 var $button = atc_btn && atc_btn.jquery ? atc_btn : $(atc_btn || []); 128 129 window.setTimeout(function(){ 130 window.requestAnimationFrame(function(){ 131 clear_add_to_cart_waiting($button.length ? $button : $('.ho-atc-waiting')); 132 open_popup(); 133 }); 134 }, 0); 135 }); 136 137 // Als een standaard WooCommerce add-to-cart-request technisch faalt en dus 138 // geen added_to_cart-event uitstuurt, moet de knop wel weer bruikbaar worden. 139 $(document).ajaxError(function(event, jqxhr, settings){ 140 var url = settings && settings.url ? String(settings.url) : ''; 141 if(url.indexOf('wc-ajax=add_to_cart') !== -1 || url.indexOf('wc-ajax=xoo_cp_add_to_cart') !== -1){ 142 clear_add_to_cart_waiting($('.ho-atc-waiting')); 143 } 144 }); 145 146 147 //CLose Popup 148 function close_popup(e){ 149 $.each(e.target.classList,function(key,value){ 150 if(value == 'xoo-cp-close' || value == 'xoo-cp-modal'){ 151 e.preventDefault(); 152 $('.xoo-cp-opac').hide(); 153 $('.xoo-cp-modal').removeClass('xoo-cp-active'); 154 $('body').removeClass('xoo-cp-popup-active'); 155 } 156 }) 157 } 158
159 $(document).on('click','.xoo-cp-close , .xoo-cp-modal',close_popup); 160 161 //Block popup 162 function block_popup(){ 163 $('.xoo-cp-outer').show(); 164 $('.xoo-cp-container').attr('aria-busy', 'true'); 165 $('body').addClass('ho-cart-request-pending'); 166 } 167 168 //Unblock popup 169 function unblock_popup(){ 170 $('.xoo-cp-outer').hide(); 171 $('.xoo-cp-container').removeAttr('aria-busy'); 172 $('body').removeClass('ho-cart-request-pending'); 173 } 174 175 //Reset cart button/form 176 function reset_cart(atc_btn){ 177 $('.xoo-cp-added',atc_btn).remove(); 178 var qty_elem = atc_btn.parents('form.cart').find('.qty'); 179 if(qty_elem.length > 0) qty_elem.val(qty_elem.attr('min') || 1); 180 $('.added_to_cart').remove(); 181 } 182 183 184 //Custom refresh fragments 185 function refresh_fragments(response){ 186 var fragments = response.fragments, 187 cart_hash = response.cart_hash; 188 189 //Set fragments 190 $.each( response.fragments, function( key, value ) { 191 $( key ).replaceWith( value ); 192 $( key ).stop( true ).css( 'opacity', '1' ).unblock(); 193 }); 194 195 if(typeof wc_cart_fragments_params !== 'undefined' && wc_cart_fragments_params){ 196 var cart_hash_key = wc_cart_fragments_params.cart_hash_key || (wc_cart_fragments_params.ajax_url.toString() + '-wc_cart_hash'); 197 //Set cart hash 198 sessionStorage.setItem( wc_cart_fragments_params.fragment_name, JSON.stringify( fragments ) ); 199 localStorage.setItem( cart_hash_key, cart_hash ); 200 sessionStorage.setItem( cart_hash_key, cart_hash ); 201 } 202 203 $(document.body).trigger('wc_fragments_loaded'); 204 } 205 206 //Add to cart function 207 function add_to_cart(atc_btn,form_data){ 208 209 // De popup blijft tijdens de request gesloten. adding_to_cart zet alleen 210 // de nette drie-puntjes-feedback op de bestelknop. 211 // Trigger event. 212 $( document.body ).trigger( 'adding_to_cart', [ atc_btn, form_data ] ); 213 214 $.ajax({ 215 url: xoo_cp_localize.wc_ajax_url.toString().replace( '%%endpoint%%', 'xoo_cp_add_to_cart' ), 216 type: 'POST', 217 data: $.param(form_data), 218 success: function(response){ 219 220 if(response.fragments){ 221 // WooCommerce werkt eerst de fragments bij; onze added_to_cart-handler 222 // opent daarna pas de volledig gereedstaande popup. 223 $( document.body ).trigger( 'added_to_cart', [ response.fragments, response.cart_hash, atc_btn ] ); 224 atc_btn.append('<span class="xoo-cp-icon-check xoo-cp-added"></span>'); 225 } 226 else if(response.error){ 227 clear_add_to_cart_waiting(atc_btn); 228 show_notice('error',response.error); 229 open_popup(); 230 } 231 else{ 232 clear_add_to_cart_waiting(atc_btn); 233 console.log(response); 234 } 235 236 //Reset to default 237 if(xoo_cp_localize.reset_cart) reset_cart(atc_btn); 238 239 }, 240 error: function(){ 241 clear_add_to_cart_waiting(atc_btn); 242 show_notice('error','Het winkelmandje kon niet worden bijgewerkt. Probeer het opnieuw.'); 243 open_popup(); 244 unblock_popup(); 245 } 246 }) 247 } 248 249 250 //Add to cart on single page 251 $(document).on('submit','form.cart',function(e){ 252 e.preventDefault(); 253 var form = $(this); 254 var atc_btn = form.find( 'button[type="submit"]'); 255 256 if(atc_btn.data('ho-cart-busy')){ 257 return; 258 } 259 260 $('.xoo-cp-added',atc_btn).remove(); 261 262 var form_data = form.serializeArray(); 263 hasProductId = false; 264 265 //Check for woocommerce custom quantity code 266 //https://docs.woocommerce.com/document/override-loop-template-and-show-quantities-next-to-add-to-cart-buttons/ 267 $.each( form_data, function( key, form_item ){ 268 if( form_item.name === 'productID' || form_item.name === 'add-to-cart' ){ 269 if( form_item.value ){ 270 hasProductId = true; 271 return false; 272 } 273 } 274 }) 275 276 //If no product id found , look for the form action URL 277 if( !hasProductId ){ 278 var is_url = form.attr('action').match(/add-to-cart=([0-9]+)/), 279 productID = is_url ? is_url[1] : false; 280 } 281 282 // if button as name add-to-cart get it and add to form 283 if( atc_btn.attr('name') && atc_btn.attr('name') == 'add-to-cart' && atc_btn.attr('value') ){ 284 var productID = atc_btn.attr('value'); 285 } 286 287 if( productID ){ 288 form_data.push({name: 'add-to-cart', value: productID}); 289 } 290 291 form_data.push({name: 'action', value: 'xoo_cp_add_to_cart'}); 292 293 add_to_cart(atc_btn,form_data);//Ajax add to cart 294 }) 295 296 297 //Update cart 298 function update_cart(cart_key,new_qty){ 299 block_popup(); 300 $.ajax({ 301 url: xoo_cp_localize.wc_ajax_url.toString().replace( '%%endpoint%%', 'xoo_cp_update_cart' ), 302 type: 'POST', 303 data: { 304 cart_key: cart_key, 305 new_qty: new_qty 306 }, 307 success: function(response){ 308 if(response.fragments){ 309 refresh_fragments(response); 310 } 311 else{ 312 show_notice('error',response.error); 313 } 314 315 unblock_popup(); 316 } 317 318 }) 319 } 320 321 322 //Save Quantity on focus 323 $(document).on('focusin','.xoo-cp-qty',function(){ 324 focus_qty = $(this).val(); 325 }) 326 327 328 //Qty input on change 329 $(document).on('change','.xoo-cp-qty',function(e){ 330 var _this = $(this); 331 var new_qty = parseFloat($(this).val()); 332 var step = parseFloat($(this).attr('step')); 333 var min_value = parseFloat($(this).attr('min')); 334 var max_value = parseFloat($(this).attr('max')); 335 var invalid = false;
336 337 338 if(new_qty === 0){ 339 _this.parents('.xoo-cp-pdetails').find('.xoo-cp-remove-pd').trigger('click'); 340 return; 341 } 342 //Check If valid number 343 else if(isNaN(new_qty) || new_qty < 0){ 344 invalid = true; 345 } 346 347 //Check maximum quantity 348 else if(new_qty > max_value && max_value > 0){ 349 alert('Maximum Quantity: '+max_value); 350 invalid = true; 351 } 352 353 //Check Minimum Quantity 354 else if(new_qty < min_value){ 355 invalid = true; 356 } 357 358 //Check Step 359 else if((new_qty % step) !== 0){ 360 alert('Quantity can only be purchased in multiple of '+step); 361 invalid = true; 362 } 363 364 //Update if everything is fine. 365 else{ 366 var cart_key = $(this).parents('tr').data('xoo_cp_key'); 367 update_cart(cart_key,new_qty); 368 } 369 370 if(invalid === true){ 371 $(this).val(focus_qty); 372 } 373 374 }) 375 376 //Plus minus buttons 377 $(document).on('click', '.xcp-chng' ,function(){ 378 var _this = $(this); 379 var qty_element = _this.siblings('.xoo-cp-qty'); 380 qty_element.trigger('focusin'); 381 var input_qty = parseFloat(qty_element.val()); 382 383 var step = parseFloat(qty_element.attr('step')); 384 var min_value = parseFloat(qty_element.attr('min')); 385 var max_value = parseFloat(qty_element.attr('max')); 386 387 if(_this.hasClass('xcp-plus')){ 388 var new_qty = input_qty + step; 389 390 if(new_qty > max_value && max_value > 0){ 391 alert('Maximum Quantity: '+max_value); 392 return; 393 } 394 } 395 else if(_this.hasClass('xcp-minus')){ 396 397 var new_qty = input_qty - step; 398 if(new_qty === 0){ 399 _this.parents('.xoo-cp-pdetails').find('.xoo-cp-remove .xcp-icon').trigger('click'); 400 return; 401 } 402 else if(new_qty < min_value){ 403 return; 404 } 405 else if(input_qty < 0){ 406 alert('Invalid'); 407 return; 408 } 409 } 410 411 var cart_key = $(this).parents('tr').data('xoo_cp_key'); 412 413 update_cart(cart_key,new_qty); 414 }) 415 416 417 418 //Remove item from cart 419 $(document).on('click','.xoo-cp-remove-pd',function(e){ 420 e.preventDefault(); 421 var cart_key = $(this).parents('tr').data('xoo_cp_key'); 422 update_cart(cart_key,0); 423 }) 424 425 426 //Drag basket 427 if(xoo_cp_localize.drag_basket){ 428 $('.xoo-cp-basket').mousedown(function(e){ 429 430 var start = e.timeStamp; 431 window.my_dragging = {}; 432 my_dragging.pageX0 = e.pageX; 433 my_dragging.pageY0 = e.pageY; 434 my_dragging.elem = this; 435 my_dragging.offset0 = $(this).offset(); 436 function handle_dragging(e){ 437 var left = my_dragging.offset0.left + (e.pageX - my_dragging.pageX0); 438 var top = my_dragging.offset0.top + (e.pageY - my_dragging.pageY0); 439 $(my_dragging.elem) 440 .offset({top: top, left: left}); 441 } 442 function handle_mouseup(e){ 443 444 var end = e.timeStamp; 445 if((end-start) > 200){ 446 xoo_is_dragging = 1; 447 } 448 else{ 449 xoo_is_dragging = 0; 450 } 451 452 453 $('body') 454 .off('mousemove', handle_dragging) 455 .off('mouseup', handle_mouseup); 456 } 457 $('body') 458 .on('mouseup', handle_mouseup) 459 .on('mousemove', handle_dragging); 460 }); 461 } 462 463 //Undo 464 $(document).on('click','.xoo-cp-undo',function(){ 465 block_popup(); 466 var cart_key = $(this).data('xoo_ckey'); 467 if(!cart_key) return; 468 $.ajax({ 469 url: xoo_cp_localize.wc_ajax_url.toString().replace( '%%endpoint%%', 'xoo_cp_undo_item' ), 470 type: 'POST', 471 data: { 472 cart_key: cart_key, 473 }, 474 success: function(response){ 475 if(response.fragments){ 476 $( document.body ).trigger( 'added_to_cart', [ response.fragments, response.cart_hash] ); 477 } 478 else if(response.error){ 479 show_notice('error',response.error) 480 } 481 else{ 482 console.log(response); 483 } 484 unblock_popup(); 485 } 486 }) 487 }) 488 489 490 //Empty cart 491 $(document).on('click','.xoo-cp-empct',function(){ 492 block_popup(); 493 $.ajax({ 494 url: xoo_cp_localize.adminurl, 495 type: 'POST', 496 data: { 497 action: 'xoo_cp_empty_cart' 498 }, 499 success: function(response){ 500 if(response.fragments){ 501 refresh_fragments(response); 502 } 503 else{ 504 console.log(response); 505 } 506 unblock_popup(); 507 } 508 }) 509 510 }) 511 512})
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.