1/* Get RestroPress Cookie */ 2function rp_getCookie(cname) { 3 var name = cname + "="; 4 var ca = document.cookie.split(';'); 5 for (var i = 0; i < ca.length; i++) { 6 var c = ca[i]; 7 while (c.charAt(0) == ' ') c = c.substring(1); 8 if (c.indexOf(name) != -1) { 9 var value = c.substring(name.length, c.length); 10 try { 11 return decodeURIComponent(value.replace(/\+/g, '%20')); 12 } catch (error) { 13 return value; 14 } 15 } 16 } 17 return ""; 18} 19function remove_show_service_options() { 20 jQuery('#rpressModal') 21 .removeClass('show-service-options'); 22} 23/* Set default addons */ 24function rp_checked_default_subaddon() { 25 if (jQuery('#fooditem-details .rp-addons-data-wrapper .food-item-list.active').length > 0) { 26 jQuery('#fooditem-details .rp-addons-data-wrapper .food-item-list.active').each(function () { 27 var element = jQuery(this).find('input'); 28 if (element.hasClass('checked')) { 29 jQuery(this).find('input').prop('checked', true); 30 } 31 }); 32 } 33} 34/* Set RestroPress Cookie */ 35function rp_setCookie(cname, cvalue, ex_time) { 36 var d = new Date(); 37 d.setTime(d.getTime() + (ex_time * 60 * 1000)); 38 var expires = "expires=" + d.toUTCString(); 39 document.cookie = cname + "=" + cvalue + "; " + expires + ";path=/"; 40} 41function rp_clearCookie(cname) { 42 document.cookie = cname + "=; expires=Thu, 01 Jan 1970 00:00:00 UTC;path=/"; 43} 44function rp_is_old_ui_ux_enabled() { 45 return (typeof rp_scripts !== 'undefined') && String(rp_scripts.old_ui_ux || '')
45=== '1'; 46} 47function rp_format_currency_value(value) { 48 var numeric = parseFloat(value); 49 if (isNaN(numeric)) { 50 numeric = 0; 51 } 52 53 var decimalPlaces = parseInt(rp_scripts.currency_decimals, 10); 54 if (isNaN(decimalPlaces)) { 55 decimalPlaces = 2; 56 } 57 58 if (String(rp_scripts.currency_value_type || 'float') === 'round') { 59 decimalPlaces = 0; 60 numeric = Math.round(numeric); 61 } 62 63 var amount = numeric.toFixed(decimalPlaces); 64 var decimalSeparator = rp_scripts.decimal_separator || '.'; 65 var thousandsSeparator = rp_scripts.thousands_separator || ','; 66 67 if (decimalSeparator !== '.') { 68 amount = amount.split('.').join(decimalSeparator); 69 } 70 71 var amountParts = amount.split(decimalSeparator); 72 amountParts[0] = amountParts[0].replace(/\B(?=(\d{3})+(?!\d))/g, thousandsSeparator); 73 amount = amountParts.join(decimalSeparator); 74 75 if (rp_scripts.currency_pos === 'before') { 76 return rp_scripts.currency_sign + amount; 77 } 78 79 return amount + rp_scripts.currency_sign; 80} 81function rp_clear_service_selection_cookies(includeAddressContext) { 82 var cookieKeys = [ 83 'service_type', 84 'service_time', 85 'service_time_text', 86 'service_date', 87 'delivery_date', 88 'service_date_manual' 89 ]; 90 91 if (includeAddressContext) { 92 cookieKeys = cookieKeys.concat([ 93 'delivery_zip', 94 'delivery_location', 95 'delivery_address', 96 'branch', 97 'branch_name' 98 ]); 99 } 100 101 for (var i = 0; i < cookieKeys.length; i++) { 102 rp_clearCookie(cookieKeys[i]); 103 } 104} 105function rp_clear_old_ui_service_cookies() { 106 rp_clear_service_selection_cookies(true); 107} 108/* Get RestroPress Storage Data */ 109function rp_get_storage_data() { 110 var oldUiUxEnabled = rp_is_old_ui_ux_enabled(); 111 var $ = (typeof jQuery !== 'undefined') ? jQuery : null; 112 if (oldUiUxEnabled && $) { 113 var cartQty = parseInt((typeof rp_scripts !== 'undefined' ? rp_scripts.cart_quantity : 0) || 0, 10); 114 var hasCartItemElements = $('ul.rpress-cart > li.rpress-cart-item').length > 0; 115 if (cartQty === 0 && !hasCartItemElements && !window.rpJustSelectedService) { 116 return false; 117 } 118 } 119 120 var serviceType = (rp_getCookie('service_type') || '') 121 .toString() 122 .trim() 123 .toLowerCase(); 124 if (!serviceType || (serviceType !== 'delivery' && serviceType !== 'pickup')) { 125 return false; 126 } 127 128 if (!oldUiUxEnabled) { 129 return true; 130 } 131 132 var $ = (typeof jQuery !== 'undefined') ? jQuery : null; 133 var serviceTime = (rp_getCookie('service_time') || '') 134 .toString() 135 .trim(); 136 var serviceDate = (rp_getCookie('service_date') || rp_getCookie('delivery_date') || '') 137 .toString() 138 .trim(); 139 var deliveryZip = (rp_getCookie('delivery_zip') || '') 140 .toString() 141 .trim(); 142 var deliveryLocation = (rp_getCookie('delivery_location') || '') 143 .toString() 144 .trim(); 145 var deliveryAddress = (rp_getCookie('delivery_address') || '') 146 .toString() 147 .trim(); 148 var branchId = (rp_getCookie('branch') || '') 149 .toString() 150 .trim(); 151 var branchName = (rp_getCookie('branch_name') || '') 152 .toString() 153 .trim(); 154 155 var hasDateSelect = false; 156 var hasTimeSelect = false; 157 var hasBranchSelector = false; 158 var hasLocationField = false; 159 var hasZipField = false; 160 var hasAddressField = false; 161 162 if ($) { 163 var $servicePanel = $('.delivery-settings-wrapper#nav-' + serviceType); 164 if (!$servicePanel.length) { 165 $servicePanel = $('.delivery-settings-wrapper.active, .delivery-settings-wrapper.show').first(); 166 } 167 if (!$servicePanel.length) { 168 $servicePanel = $(document); 169 } 170 171 hasDateSelect = $servicePanel.find('.rpress_get_delivery_dates').length > 0; 172 hasTimeSelect = $servicePanel.find('.rpress_get_delivery_hours, .rpress-pickup-hours, #rpress-' + serviceType + '-hours, .rpress-allowed-delivery-hrs').length > 0; 173 hasBranchSelector = $('select[name="branch"], #rp-location, #rpress_location').length > 0; 174 hasLocationField = $('input#rp_delivery_location, input[name="rp_delivery_location"]').length > 0; 175 hasZipField = $('input#rp_delivery_zone, input[name="rp_delivery_zone"]').length > 0; 176 hasAddressField = $('input#rp_delivery_address, input[name="rp_delivery_address"], input#rp_street_address').length > 0; 177 } 178 179 var isServiceTimeDisabled = false;
180 if (window.rp_otil_vars) { 181 isServiceTimeDisabled = 182 (serviceType === 'pickup' && window.rp_otil_vars.disable_pickup_time === '1') || 183 (serviceType === 'delivery' && window.rp_otil_vars.disable_delivery_time === '1'); 184 } 185 186 if (hasDateSelect && !serviceDate) { 187 return false; 188 } 189 190 if (hasTimeSelect && !isServiceTimeDisabled && !serviceTime) { 191 return false; 192 } 193 194 if (hasBranchSelector && !branchId && !branchName) { 195 return false; 196 } 197 198 if (serviceType === 'delivery') { 199 if (hasLocationField && !deliveryLocation) { 200 return false; 201 } 202 203 if (hasZipField && !deliveryZip) { 204 return false; 205 } 206 207 if (hasAddressField && !deliveryAddress && !branchName) { 208 return false; 209 } 210 } 211 212 return true; 213} 214/* Display Dynamic Addon Price Based on Selected Variation */ 215function show_dymanic_pricing(container, ele) { 216 var price_key = ele.val(); 217 if (price_key !== 'undefined') { 218 var $wrapper = jQuery('#' + container + ' .rp-addons-data-wrapper'); 219 jQuery('#' + container + ' .rp-addons-data-wrapper .food-item-list') 220 .removeClass('active'); 221 jQuery('#' + container + ' .rp-addons-data-wrapper .food-item-list.list_' + price_key) 222 .addClass('active'); 223 // remove border from the last active only 224 $wrapper.find('.food-item-list.active').last().css('border-bottom', '0'); 225 } 226} 227/* Calculate Live Price On Click */ 228function update_modal_live_price(fooditem_container) { 229 //Add changes code 230 var single_price = parseFloat(jQuery('#rpressModal .cart-item-price') 231 .attr('data-price')); 232 var quantity = parseInt(jQuery('input[name=quantity]') 233 .val()); 234 /* Act on the variations */ 235 jQuery('#' + fooditem_container + ' .rp-variable-price-wrapper .food-item-list') 236 .each(function () { 237 var element = jQuery(this) 238 .find('input'); 239 if (element.is(':checked')) { 240 // Dynamic addon Price 241 show_dymanic_pricing(fooditem_container, element); 242 var attrs = element.attr('data-value'); 243 var attrs_arr = attrs.split('|'); 244 var price = attrs_arr[2]; 245 single_price = parseFloat(price); 246 } 247 }); 248 /* Act on the addons */ 249 jQuery('#' + fooditem_container + ' .rp-addons-data-wrapper .food-item-list.active') 250 .each(function () { 251 var element = jQuery(this) 252 .find('input'); 253 if (element.is(':checked')) { 254 var attrs = element.val(); 255 var attrs_arr = attrs.split('|'); 256 var price = attrs_arr[2]; 257 if (price != '') { 258 single_price = parseFloat(single_price) + parseFloat(price); 259 } 260 } 261 }); 262 /* Updating as per current quantity */ 263 total_price = single_price * quantity; 264 /* Update the price in Submit Button */ 265 total_price_v = rp_format_currency_value(total_price); 266 jQuery('#rpressModal .cart-item-price') 267 .html(total_price_v); 268 269 jQuery('#rpressModal .cart-item-price') 270 .attr('data-current', single_price.toFixed(2)); 271} 272function isStoreOpen() { 273 if (typeof rp_scripts === 'undefined') return true; // fail-safe 274 275 if (rp_scripts.always_open === '1') return true; 276 277 if (rp_scripts.open_hours === '' || rp_scripts.close_hours === '') return false; // no hours set, assume close 278 279 var open = rp_scripts.open_hours; 280 var close = rp_scripts.close_hours; 281 282 function parseTime(t) { 283 if (typeof t !== 'string') return null; 284 285 var d = new Date(); 286 var time = t.toLowerCase().replace(/\s/g, ''); 287 var match12 = time.match(/^(\d{1,2}):(\d{2})(am|pm)$/); 288 var match24 = time.match(/^(\d{1,2}):(\d{2})$/); 289 var hours; 290 var minutes; 291 292 if (match12) { 293 hours = parseInt(match12[1], 10); 294 minutes = parseInt(match12[2], 10); 295 if (match12[3] === 'pm' && hours < 12) hours += 12; 296 if (match12[3] === 'am' && hours === 12) hours = 0; 297 } else if (match24) { 298 hours = parseInt(match24[1], 10); 299 minutes = parseInt(match24[2], 10); 300 } else { 301 return null; 302 } 303 304 if (hours > 23 || minutes > 59) return null; 305 306 d.setHours(hours, minutes, 0, 0); 307 return d; 308 } 309 310 var now = new Date(); 311 var openTime = parseTime(open); 312 var closeTime = parseTime(close); 313 314 if (!openTime || !closeTime) return false;
315 316 if (closeTime.getTime() === openTime.getTime()) return false; 317 318 // Handle overnight windows (for example 18:00 to 02:00). 319 if (closeTime < openTime) { 320 return (now >= openTime || now <= closeTime); 321 } 322 323 return (now >= openTime && now <= closeTime); 324} 325/* RestroPress Frontend Functions */ 326jQuery(function ($) { 327 if (rp_is_old_ui_ux_enabled()) { 328 $('body').addClass('rp-old-ui-ux-enabled'); 329 } else { 330 $('body').removeClass('rp-old-ui-ux-enabled'); 331 } 332 333 // The delivery zip / postcode field (from the Delivery Fee extension) is a 334 // plain text input, so the browser paints its address-autofill control (the 335 // stray "..." box) inside the schedule popup. Turn autofill off on those 336 // fields so the input stays clean. Re-run on focus in case the field is 337 // injected after load. 338 function rpDisableZipAutofill(scope) { 339 $(scope || document) 340 .find('input#rp_delivery_zone, input[name="rp_delivery_zone"], #rpress-postcode, #rpress_postcode, input[name="rpress_postcode"]') 341 .attr({ autocomplete: 'off', 'data-lpignore': 'true', 'data-1p-ignore': 'true' }); 342 } 343 rpDisableZipAutofill(); 344 $(document).on('focusin', 'input#rp_delivery_zone, input[name="rp_delivery_zone"]', function () { 345 $(this).attr({ autocomplete: 'off', 'data-lpignore': 'true', 'data-1p-ignore': 'true' }); 346 }); 347 348 function rp_has_rpress_interactive_ui() { 349 return $('#rpressDateTime, #rpressModal, #rpress_checkout_wrap, .rpress-section').length > 0; 350 } 351 352 function rp_has_visible_open_modal($modals) { 353 var hasVisible = false; 354 $modals.each(function () { 355 var $modal = $(this); 356 var isOpen = $modal.hasClass('is-open') || $modal.attr('aria-hidden') === 'false'; 357 if (!isOpen) { 358 return; 359 } 360 if ($modal.find('.modal__container:visible').length > 0 || $modal.is(':visible')) { 361 hasVisible = true; 362 } 363 }); 364 return hasVisible; 365 } 366 367 function rp_reset_stuck_modal_state() { 368 if (!rp_has_rpress_interactive_ui()) { 369 return; 370 } 371 372 var $serviceModal = $('#rpressDateTime'); 373 var $itemModal = $('#rpressModal'); 374 var $modals = $serviceModal.add($itemModal); 375 var $overlays = $('.modal__overlay, .micromodal-overlay, .modal-overlay'); 376 var modalVisible = rp_has_visible_open_modal($modals); 377 var hasStaleOpenState = $modals.filter(function () { 378 var $modal = $(this); 379 return ( 380 $modal.hasClass('is-open') || 381 $modal.attr('aria-hidden') === 'false' || 382 $modal.hasClass('show-service-options') || 383 $modal.hasClass('show-order-details') 384 ); 385 }).length > 0; 386 var bodyLocked = $('body').hasClass('modal-open') || $('body').css('overflow') === 'hidden' || $('html').css('overflow') === 'hidden'; 387 388 // If no modal is actually visible, force-clear stale overlays/locks. 389 if (!modalVisible && (hasStaleOpenState || $overlays.length > 0 || bodyLocked)) { 390 $modals 391 .removeClass('is-open loading show-service-options show-order-details rpress-order-details-context') 392 .attr('aria-hidden', 'true'); 393 394 $('html, body') 395 .removeClass('modal-open') 396 .css('overflow', ''); 397 } 398 } 399 400 rp_reset_stuck_modal_state(); 401 setTimeout(rp_reset_stuck_modal_state, 200); 402 setTimeout(rp_reset_stuck_modal_state, 600); 403 404 $(document).on('rpress_checked_slots rp-checkout-update-service-option', function () { 405 setTimeout(rp_reset_stuck_modal_state, 100); 406 }); 407 408 function rp_fix_footer_click_intercept() { 409 var footer = document.getElementById('site-footer'); 410 if (!footer) { 411 return; 412 } 413 414 var selectors = [ 415 '#editDateTime', 416 '.rpress-category-link', 417 '.rpress-checkout-cart', 418 '.rpress_go_to_checkout', 419 '.rpress-cart .rpress_checkout a', 420 '#rpress_purchase_form input[type="text"]', 421 '#rpress_checkout_wrap' 422 ]; 423 424 var candidate = null; 425 for (var i = 0; i < selectors.length; i++) { 426 var node = document.querySelector(selectors[i]); 427 if (!node) { 428 continue; 429 } 430 var rect = node.getBoundingClientRect(); 431 if (rect.width > 0 && rect.height > 0) { 432 candidate = node; 433 break; 434 } 435 } 436 437 if (!candidate) { 438 return; 439 } 440 441 var r = candidate.getBoundingClientRect(); 442 var hit = document.elementFromPoint(r.left + (r.width / 2), r.top + (r.height / 2)); 443 if (hit && (hit === footer || footer.contains(hit))) { 444 var main = document.querySelector('main, #content, .site-main'); 445 if (main) { 446 main.style.position = 'relative'; 447 main.style.zIndex = '3'; 448 } 449 footer.style.position = 'relative'; 450 footer.style.zIndex = '1'; 451 } 452 } 453 454 rp_fix_footer_click_intercept(); 455 setTimeout(rp_fix_footer_click_intercept, 120); 456 $(window).on('resize.rpFooterFix load.rpFooterFix', rp_fix_footer_click_intercept); 457 $(document).ajaxComplete(function () { 458 setTimeout(rp_fix_footer_click_intercept, 60); 459 }); 460 461 function rp_update_mobile_cart_summary(total, quantity) { 462 var parsedQty = parseInt(quantity, 10); 463 if (isNaN(parsedQty) || parsedQty < 0) { 464 parsedQty = 0; 465 } 466 467 var formattedTotal = (typeof total === 'string' && total.length) 468 ? total 469 : rp_format_currency_value(0); 470 471 $('.rp-mb-price').text(formattedTotal); 472 $('.rp-mb-quantity').text(parsedQty); 473 $('span.rpress-cart-quantity').text(parsedQty); 474 475 var hasItems = parsedQty > 0; 476 if (hasItems) { 477 $('.rpress-mobile-cart-icons').css('display', 'flex'); 478 $('.rpress.item-order').show(); 479 } else { 480 $('.rpress-mobile-cart-icons').hide(); 481 } 482 483 $('.container-actionmenu').toggleClass('cart-has-items', hasItems); 484 } 485 486 function rp_refresh_sidebar_cart_summary(summaryHtml) { 487 var $summaryTarget = $('.rpress-cart-summary-area').first(); 488 if ($summaryTarget.length) { 489 $summaryTarget.html((typeof summaryHtml === 'string') ? summaryHtml : ''); 490 return; 491 } 492 493 var $cart = $('ul.rpress-cart'); 494 if (!$cart.length) { 495 return; 496 } 497 498 $cart.find('div.rpress-cart-total-wrap, li.cart_item.rpress_checkout, li.cart_item.rpress_subtotal, li.cart_item.rpress_cart_tax, li.cart_item.rpress_user_discount, li.cart_item.rpress_cart_fee, li.cart_item.rpress_total, li.rpress-delivery-fee') 499 .remove(); 500 501 if (typeof summaryHtml === 'string' && summaryHtml.length) { 502 $cart.append(summaryHtml); 503 } 504 } 505 506 function rp_get_first_field_value($scope, selectors) { 507 var $root = ($scope && $scope.length) ? $scope : $(document); 508 var value = ''; 509 var $fields = $root.find(selectors); 510 511 $fields.filter(':visible').each(function () { 512 value = ($(this).val() || '').toString().trim(); 513 return !value; 514 }); 515 516 if (value) { 517 return value; 518 } 519 520 $fields.each(function () { 521 value = ($(this).val() || '').toString().trim(); 522 return !value; 523 }); 524 525 if (!value && $root[0] !== document) { 526 $fields = $(selectors); 527 528 $fields.filter(':visible').each(function () { 529 value = ($(this).val() || '').toString().trim(); 530 return !value; 531 }); 532 533 if (value) { 534 return value; 535 } 536 537 $fields.each(function () { 538 value = ($(this).val() || '').toString().trim(); 539 return !value; 540 }); 541 } 542 543 return value; 544 } 545 546 function rp_encode_cookie_value(value) { 547 if (!value) { 548 return ''; 549 } 550 551 try { 552 return encodeURIComponent(decodeURIComponent(String(value).replace(/\+/g, '%20'))); 553 } catch (error) { 554 return encodeURIComponent(String(value)); 555 } 556 } 557 558 function rp_persist_delivery_context_for_update($scope, response, serviceType) { 559 if (String(serviceType || '').toLowerCase() !== 'delivery') { 560 return; 561 } 562 563 response = response || {}; 564 var expireTime = rp_scripts.expire_cookie_time; 565 var deliveryZip = response.delivery_zip || rp_get_first_field_value( 566 $scope,
567 'input[id="rp_delivery_zone"], input[name="rp_delivery_zone"], #rpress-postcode, #rpress_postcode, input[name="rpress_postcode"]' 568 ); 569 var deliveryLocation = response.delivery_location || response.delivery_address || rp_get_first_field_value( 570 $scope, 571 'input[id="rp_delivery_location"], input[name="rp_delivery_location"], #rpress-delivery-address, input[name="rpress_delivery_address"]' 572 ); 573 var deliveryLatLng = response.delivery_latlng || rp_get_first_field_value( 574 $scope, 575 'input[id="rp_delivery_latllng"], input[name="rp_delivery_latllng"]' 576 ); 577 var branchId = response.branch || response.branch_id || rp_get_first_field_value( 578 $scope, 579 'select[name="branch"], #rp-location, #rpress_location, input[name="rpress_location"]:checked, input[name="rpress_location_pickup"]:checked' 580 ); 581 582 if (deliveryZip) { 583 rp_setCookie('delivery_zip', deliveryZip, expireTime); 584 } 585 586 if (deliveryLocation) { 587 var encodedLocation = rp_encode_cookie_value(deliveryLocation); 588 rp_setCookie('delivery_location', encodedLocation, expireTime); 589 rp_setCookie('delivery_address', encodedLocation, expireTime); 590 } 591 592 if (deliveryLatLng) { 593 rp_setCookie('delivery_latlng', deliveryLatLng, expireTime); 594 } 595 596 if (branchId) { 597 rp_setCookie('branch', branchId, expireTime); 598 rp_setCookie('rpress_chosen_location_id', branchId, expireTime); 599 } 600 } 601 602 function rp_decode_cookie_value(value) { 603 if (!value) { 604 return ''; 605 } 606 607 try { 608 return decodeURIComponent(String(value).replace(/\+/g, '%20')).trim(); 609 } catch (error) { 610 return String(value).trim(); 611 } 612 } 613 614 function rp_is_delivery_fee_extension_active() { 615 return typeof window.DeliveryFeeVars !== 'undefined' && window.DeliveryFeeVars !== null; 616 } 617 618 function rp_is_old_ui_delivery_context_invalid(serviceType, $scope) { 619 if (!rp_is_old_ui_ux_enabled()) { 620 return false; 621 } 622 623 if (String(serviceType || '').toLowerCase() !== 'delivery') { 624 return false; 625 } 626 627 if (!rp_is_delivery_fee_extension_active()) { 628 return false; 629 } 630 631 if (!rp_has_valid_delivery_fee_context(serviceType, $scope)) { 632 return true; 633 } 634 635 return String(window.rpDeliveryFeeValidationState || '') === 'invalid'; 636 } 637 638 function rp_has_valid_delivery_fee_context(serviceType, $scope) { 639 if (String(serviceType || '').toLowerCase() !== 'delivery') { 640 return true; 641 } 642 643 if (!rp_is_delivery_fee_extension_active()) { 644 return true; 645 } 646 647 var method = String((window.DeliveryFeeVars.delivery_fee_method || 'zip_based')).toLowerCase(); 648 var $context = ($scope && $scope.length) ? $scope : $(document); 649 650 var deliveryZip = rp_get_first_field_value( 651 $context, 652 'input[id="rp_delivery_zone"], input[name="rp_delivery_zone"], #rpress-postcode, #rpress_postcode, input[name="rpress_postcode"]' 653 ) || rp_decode_cookie_value(rp_getCookie('delivery_zip')); 654 655 var deliveryLocation = rp_get_first_field_value( 656 $context, 657 'input[id="rp_delivery_location"], input[name="rp_delivery_location"], #rpress-delivery-address, input[name="rpress_delivery_address"]' 658 ) || rp_decode_cookie_value(rp_getCookie('delivery_location')) || rp_decode_cookie_value(rp_getCookie('delivery_address')); 659 660 if (method === 'location_based') { 661 return !!deliveryLocation; 662 } 663 664 return !!deliveryZip; 665 } 666 667 function rp_get_delivery_fee_context_error(serviceType) { 668 if (String(serviceType || '').toLowerCase() !== 'delivery') { 669 return ''; 670 } 671 672 var method = String((window.DeliveryFeeVars && window.DeliveryFeeVars.delivery_fee_method) || 'zip_based').toLowerCase(); 673 if (method === 'location_based') { 674 return (window.DeliveryFeeVars && (window.DeliveryFeeVars.error_empty_address || window.DeliveryFeeVars.error_invalid_location)) || 'Please enter your location'; 675 } 676 677 return (window.DeliveryFeeVars && window.DeliveryFeeVars.error_empty_zip) || 'Please enter your zip/postal code'; 678 } 679 680 function rp_open_legacy_service_options_modal(fooditemId) { 681 if (!$('#rpressModal').length || !rp_scripts || !rp_scripts.ajaxurl || !rp_scripts.service_type_nonce) { 682 return false;
683 } 684 685 $('#rpressModal') 686 .addClass('show-service-options') 687 .removeClass('rpress-delivery-options rpress-food-options checkout-error'); 688 689 $.ajax({ 690 type: "POST", 691 data: { 692 action: 'rpress_show_delivery_options', 693 fooditem_id: fooditemId || '', 694 security: rp_scripts.service_type_nonce 695 }, 696 dataType: "json", 697 url: rp_scripts.ajaxurl, 698 success: function (response) { 699 if (!response || !response.data) { 700 return; 701 } 702 703 var $modal = $('#rpressModal'); 704 if (fooditemId) { 705 $modal.attr('data-pending-fooditem-id', fooditemId); 706 $modal.attr('data-service-modal-context', 'add-to-cart'); 707 } 708 $modal.find('.modal-title').html(response.data.html_title || ''); 709 $modal.find('.modal-body').html(response.data.html || ''); 710 if (typeof window.rp_prepare_old_ui_modal_selection === 'function') { 711 window.rp_prepare_old_ui_modal_selection($modal.find('.modal-body')); 712 } 713 MicroModal.show('rpressModal', { 714 disableScroll: true 715 }); 716 $(document.body).trigger('opened_service_options', [response.data]); 717 } 718 }); 719 720 return true; 721 } 722 723 function rp_get_delivery_change_helper_html() { 724 if (!rp_is_old_ui_ux_enabled()) { 725 return ''; 726 } 727 728 return '' + 729 '<span class="rp-delivery-change-helper">' + 730 '<span class="rp-delivery-change-tooltip-icon" tabindex="0" aria-label="Delivery address help">?</span>' + 731 '<span class="rp-delivery-change-tooltip-text">Change service type, date and time</span>' + 732 '</span>'; 733 } 734 735 function rp_ensure_order_details_modal() { 736 var $modal = $('#rpressModal').first(); 737 if ($modal.length) { 738 return $modal; 739 } 740 741 var modalHtml = [ 742 '<div class="modal micromodal-slide" id="rpressModal" aria-hidden="true">', 743 ' <div class="modal__overlay" tabindex="-1" data-micromodal-close>', 744 ' <div class="modal__container modal-content" role="dialog" aria-modal="true">', 745 ' <header class="modal__header modal-header">', 746 ' <h2 class="modal__title modal-title"></h2>', 747 ' <button class="modal__close" aria-label="Close modal" data-micromodal-close></button>', 748 ' </header>', 749 ' <main class="modal__content modal-body"></main>', 750 ' </div>', 751 ' </div>', 752 '</div>' 753 ].join(''); 754 755 $('body').append(modalHtml); 756 return $('#rpressModal').first(); 757 } 758 759 // Show order details on popup 760 $(document) 761 .on('click', '.rpress-view-order-btn', function (e) { 762 e.preventDefault(); 763 var self = $(this); 764 var $modal = rp_ensure_order_details_modal(); 765 if (!$modal.length) { 766 return; 767 } 768 var isDashboardOrHistory = self.closest('.user-dashboard-wrapper, #rpress_user_history').length > 0; 769 var action = 'rpress_show_order_details'; 770 var order_id = self.attr('data-order-id'); 771 var data = { 772 action: action, 773 order_id: order_id, 774 security: rp_scripts.order_details_nonce 775 }; 776 $modal 777 .addClass('show-order-details'); 778 if (isDashboardOrHistory) { 779 $modal.addClass('rpress-order-details-context'); 780 } else { 781 $modal.removeClass('rpress-order-details-context'); 782 } 783 $.ajax({ 784 type: "POST", 785 data: data, 786 dataType: "json", 787 url: rp_scripts.ajaxurl, 788 beforeSend: (jqXHR, object) => { 789 self.addClass('rp-loading'); 790 self.find('.rp-ajax-toggle-text') 791 .addClass('rp-text-visibility'); 792 }, 793 complete: (jqXHR, object) => { 794 self.removeClass('rp-loading'); 795 self.find('.rp-ajax-toggle-text') 796 .removeClass('rp-text-visibility'); 797 }, 798 success: function (response) { 799 if (!response || response.success !== true || !response.data || typeof response.data.html !== 'string') { 800 return; 801 } 802 $modal.find('.modal__container') 803 .html(response.data.html); 804 if (typeof MicroModal !== 'undefined' && typeof MicroModal.show === 'function') { 805 MicroModal.show('rpressModal', { 806 disableScroll: true 807 }); 808 } else { 809 $modal 810 .addClass('is-open') 811 .attr('aria-hidden', 'false'); 812 $('html, body') 813 .addClass('modal-open') 814 .css('overflow', 'hidden'); 815 } 816 }, 817 error: function () { 818 $modal.removeClass('show-order-details rpress-order-details-context'); 819 } 820 }) 821 }); 822 $(document).on('click', '#rpressModal.show-order-details .modal__close', function (e) { 823 e.preventDefault(); 824 if (typeof MicroModal !== 'undefined' && typeof MicroModal.close === 'function') { 825 MicroModal.close('rpressModal'); 826 } else { 827 $('#rpressModal') 828 .removeClass('is-open show-order-details rpress-order-details-context') 829 .attr('aria-hidden', 'true'); 830 $('html, body') 831 .removeClass('modal-open') 832 .css('overflow', ''); 833 } 834 }); 835 // Sticky category menu on mobile 836 $(window) 837 .resize(function () { 838 if ($(window) 839 .width() > 769) { 840 $('.sticky-sidebar.cat-lists') 841 .removeClass('rp-mobile-cat'); 842 } else { 843 $('.sticky-sidebar.cat-lists') 844 .addClass('rp-mobile-cat'); 845 } 846 }) 847 .resize(); 848 // Hide Mneu on Click Float Cart 849 $(document) 850 .on('click', '.rpress-category-item', function () { 851 $('.rp-mb-cat-ft-btn') 852 .click(); 853 }); 854 // Hide Mneu on Click Items 855 $(document) 856 .on('click', '.rpress-mobile-cart-icons', function () { 857 $('.rp-cat-overlay') 858 .click(); 859 }); 860 // RP Hide overlay 861 $(document) 862 .on('click', '.rp-cat-overlay', function () { 863 $('.rp-mb-cat-ft-btn') 864 .click(); 865 }); 866 // Toggel mobile category menu 867 $('.rp-mb-cat-ft-btn') 868 .on('click', function () { 869 $('.rp-mb-cat-ft-btn') 870 .toggleClass('rp-close-menu'); 871 $('.sticky-sidebar.cat-lists') 872 .toggleClass('rp-hide'); 873 $('body') 874 .toggleClass('rp-cat-no-scroll'); 875 if ($('.sticky-sidebar.cat-lists') 876 .hasClass('rp-hide')) 877 $('body') 878 .append('<div class="rp-cat-overlay"></div>'); 879 else 880 $('.rp-cat-overlay') 881 .remove(); 882 }); 883 $('.rp-mb-cat-ft-btn') 884 .click(function () { 885 $('.rp-mobile-cat') 886 .toggle('fast'); 887 if ($(this) 888 .hasClass('rp-close-menu')) { 889 $('.rp-mb-cat-txt') 890 .html(`<i class="fa fa-cutlery" aria-hidden="true"></i> ${rpress_scripts.close}`); 891 } else { 892 $('.rp-mb-cat-txt') 893 .html(`<i class="fa fa-cutlery" aria-hidden="true"></i> ${rpress_scripts.menu}`); 894 } 895 }); 896 //Remove loading from modal 897 $('#rpressModal') 898 .removeClass('loading'); 899 //Remove service options from modal 900 $('#rpressModal') 901 .removeClass('show-service-options'); 902 $('#rpressModal') 903 .removeClass('minimum-order-notice'); 904 $('#rpressModal') 905 .on('hidden.bs.modal', function () { 906 $('#rpressModal') 907 .removeClass('show-service-options'); 908 $('#rpressModal') 909 .removeClass('minimum-order-notice'); 910 }); 911 var ServiceType = rp_scripts.service_options; 912 if (ServiceType == 'delivery_and_pickup') { 913 ServiceType = 'delivery'; 914 } 915 function rp_get_active_service_time_select($scope, preferredServiceType) { 916 var $root = ($scope && $scope.length) ? $scope : $(document); 917 var serviceType = (preferredServiceType || '') 918 .toLowerCase(); 919 var $select = $(); 920 921 if (serviceType) { 922 $select = $root.find('.delivery-settings-wrapper#nav-' + serviceType + ' .rpress-hrs') 923 .first(); 924 if ($select.length) { 925 return $select; 926 } 927 928 // Service pane exists but does not render a time selector (for example closed service).
929 // Do not fall back to another service selector in this case. 930 if ($root.find('.delivery-settings-wrapper#nav-' + serviceType).length) { 931 return $select; 932 } 933 } 934 935 $select = $root.find('.delivery-settings-wrapper.active .rpress-hrs') 936 .first(); 937 if ($select.length) { 938 return $select; 939 } 940 941 $select = $root.find('.delivery-settings-wrapper.show .rpress-hrs') 942 .first(); 943 if ($select.length) { 944 return $select; 945 } 946 947 $select = $root.find('.delivery-settings-wrapper:visible .rpress-hrs') 948 .first(); 949 if ($select.length) { 950 return $select; 951 } 952 953 return $root.find('#rpress-delivery-hours, .rpress-hrs') 954 .first(); 955 } 956 function rp_restore_service_time_select($select, serviceTime, allowFallbackSelection) { 957 if (!$select || !$select.length) { 958 return ''; 959 } 960 961 var requestedTime = (serviceTime || '') 962 .trim(); 963 var selectedValue = ''; 964 var shouldFallback = (allowFallbackSelection !== false); 965 966 if (requestedTime && $select.find('option[value="' + requestedTime + '"]').length) { 967 selectedValue = requestedTime; 968 } else if (requestedTime) { 969 var $matchingOption = $select.find('option') 970 .filter(function () { 971 return $(this) 972 .text() 973 .trim() === requestedTime; 974 }) 975 .first(); 976 if ($matchingOption.length) { 977 selectedValue = $matchingOption.val(); 978 } 979 } 980 981 if (!selectedValue) { 982 var currentSelectedTime = ($select.val() || '') 983 .toString() 984 .trim(); 985 if (currentSelectedTime && $select.find('option[value="' + currentSelectedTime + '"]').length) { 986 selectedValue = currentSelectedTime; 987 } 988 } 989 990 if (!selectedValue && shouldFallback) { 991 var $firstSelectableOption = $select.find('option') 992 .filter(function () { 993 var optionValue = ($(this) 994 .val() || '') 995 .toString() 996 .trim(); 997 return optionValue !== '' && !$(this) 998 .prop('disabled'); 999 }) 1000 .first(); 1001 1002 if (!$firstSelectableOption.length) { 1003 $firstSelectableOption = $select.find('option') 1004 .first(); 1005 } 1006 1007 selectedValue = $firstSelectableOption.val() || ''; 1008 } 1009 1010 $select.val(selectedValue || ''); 1011 1012 return selectedValue; 1013 } 1014 function rp_restore_service_date_select($select, serviceDate, allowFallbackSelection) { 1015 if (!$select || !$select.length) { 1016 return ''; 1017 } 1018 1019 var requestedDate = (serviceDate || '') 1020 .toString() 1021 .trim(); 1022 var selectedValue = ''; 1023 var shouldFallback = (allowFallbackSelection !== false); 1024 1025 if (requestedDate && $select.find('option[value="' + requestedDate + '"]').length) { 1026 selectedValue = requestedDate; 1027 } else if (requestedDate) { 1028 var $matchingOption = $select.find('option') 1029 .filter(function () { 1030 return ($(this) 1031 .text() || '') 1032 .toString() 1033 .trim() === requestedDate; 1034 }) 1035 .first(); 1036 if ($matchingOption.length) { 1037 selectedValue = $matchingOption.val(); 1038 } 1039 } 1040 1041 if (!selectedValue) { 1042 var currentSelectedDate = ($select.val() || '') 1043 .toString() 1044 .trim(); 1045 if (currentSelectedDate && $select.find('option[value="' + currentSelectedDate + '"]').length) { 1046 selectedValue = currentSelectedDate; 1047 } 1048 } 1049 1050 if (!selectedValue && shouldFallback) { 1051 var $firstSelectableOption = $select.find('option') 1052 .filter(function () { 1053 var optionValue = ($(this) 1054 .val() || '') 1055 .toString() 1056 .trim(); 1057 return optionValue !== '' && !$(this) 1058 .prop('disabled'); 1059 }) 1060 .first(); 1061 1062 if (!$firstSelectableOption.length) { 1063 $firstSelectableOption = $select.find('option') 1064 .first(); 1065 } 1066 1067 selectedValue = ($firstSelectableOption.val() || '') 1068 .toString() 1069 .trim(); 1070 } 1071 1072 $select.val(selectedValue || ''); 1073 1074 return selectedValue; 1075 } 1076 function rp_remove_select_placeholder($select) { 1077 if (!$select || !$select.length) { 1078 return; 1079 } 1080 $select.find('option[data-rp-placeholder="1"]').remove(); 1081 } 1082 function rp_prepare_old_ui_modal_selection($scope) { 1083 if (!rp_is_old_ui_ux_enabled()) { 1084 return; 1085 } 1086 1087 var $root = ($scope && $scope.length) ? $scope : $(document); 1088 var selectedServiceType = (rp_getCookie('service_type') || '') 1089 .toString() 1090 .trim() 1091 .toLowerCase(); 1092 var selectedServiceDate = (rp_getCookie('service_date') || rp_getCookie('delivery_date') || '') 1093 .toString() 1094 .trim(); 1095 var selectedServiceTime = (rp_getCookie('service_time') || rp_getCookie('service_time_text') || '') 1096 .toString() 1097 .trim(); 1098 var requiresServiceChoice = $root.find('#rpressdeliveryTab .single-service-selected').length > 1; 1099 1100 if (!selectedServiceType && requiresServiceChoice) { 1101 selectedServiceType = rp_get_active_service_type( 1102 $root, 1103 (rp_scripts && rp_scripts.default_service) ? rp_scripts.default_service : 'delivery' 1104 ); 1105 1106 if (!selectedServiceType) { 1107 var $firstServiceTab = $root.find('#rpressdeliveryTab .single-service-selected') 1108 .first(); 1109 if ($firstServiceTab.length) { 1110 selectedServiceType = String($firstServiceTab.data('service-type') || '') 1111 .toLowerCase(); 1112 } 1113 } 1114 } 1115 1116 if (selectedServiceType) { 1117 rp_sync_service_ui_state($root, selectedServiceType, false); 1118 } 1119 1120 $root.find('.rpress_get_delivery_dates').each(function () { 1121 var $dateSelect = $(this); 1122 rp_remove_select_placeholder($dateSelect); 1123 rp_restore_service_date_select($dateSelect, selectedServiceDate, true); 1124 }); 1125 1126 $root.find('.delivery-settings-wrapper').each(function () { 1127 var $pane = $(this); 1128 var paneServiceType = String($pane.attr('id') || '') 1129 .replace(/^nav-/, '') 1130 .toLowerCase(); 1131 1132 $pane.find('.rpress-hrs').each(function () { 1133 var $timeSelect = $(this); 1134 if (rp_is_service_time_hidden(paneServiceType)) { 1135 return; 1136 } 1137 rp_remove_select_placeholder($timeSelect); 1138 rp_restore_service_time_select($timeSelect, selectedServiceTime, true); 1139 }); 1140 }); 1141 } 1142 function rp_is_service_time_hidden(serviceType) { 1143 var normalizedServiceType = String(serviceType || '') 1144 .toLowerCase(); 1145 if (!window.rp_otil_vars) { 1146 return false;
1147 } 1148 1149 return ( 1150 (normalizedServiceType === 'pickup' && window.rp_otil_vars.disable_pickup_time === '1') || 1151 (normalizedServiceType === 'delivery' && window.rp_otil_vars.disable_delivery_time === '1') 1152 ); 1153 } 1154 function rp_get_asap_fallback_time(serviceType) { 1155 var normalizedServiceType = String(serviceType || '') 1156 .toLowerCase(); 1157 var fallbackTime = 'ASAP'; 1158 1159 if (normalizedServiceType === 'pickup' && window.rp_otil_vars && window.rp_otil_vars.pickup_asap_text) { 1160 fallbackTime += ' ' + window.rp_otil_vars.pickup_asap_text; 1161 } else if (normalizedServiceType === 'delivery' && window.rp_otil_vars && window.rp_otil_vars.delivery_asap_text) { 1162 fallbackTime += ' ' + window.rp_otil_vars.delivery_asap_text; 1163 } 1164 1165 return fallbackTime; 1166 } 1167 1168 function rp_is_date_like_text(value) { 1169 return /^\d{1,4}([./-])\d{1,2}\1\d{1,4}$/.test( 1170 (value || '') 1171 .toString() 1172 .trim() 1173 ); 1174 } 1175 1176 function rp_get_active_service_closed_message($scope, serviceType) { 1177 var normalizedServiceType = String(serviceType || '') 1178 .toLowerCase(); 1179 var $root = ($scope && $scope.length) ? $scope : $(document); 1180 var selectors = []; 1181 1182 if (normalizedServiceType) { 1183 selectors = selectors.concat([ 1184 '.delivery-settings-wrapper#nav-' + normalizedServiceType + '.active.show .rpress-service-closed-message .rpress-closed-message-text', 1185 '.delivery-settings-wrapper#nav-' + normalizedServiceType + '.active.show .rpress-service-closed-message', 1186 '.delivery-settings-wrapper#nav-' + normalizedServiceType + ' .rpress-service-closed-message .rpress-closed-message-text', 1187 '.delivery-settings-wrapper#nav-' + normalizedServiceType + ' .rpress-service-closed-message', 1188 '.rpress-service-closed-message[data-service-type="' + normalizedServiceType + '"] .rpress-closed-message-text', 1189 '.rpress-service-closed-message[data-service-type="' + normalizedServiceType + '"]' 1190 ]); 1191 } 1192 1193 selectors = selectors.concat([ 1194 '.delivery-settings-wrapper.active.show .rpress-service-closed-message .rpress-closed-message-text', 1195 '.delivery-settings-wrapper.active.show .rpress-service-closed-message' 1196 ]); 1197 1198 for (var i = 0; i < selectors.length; i++) { 1199 var message = $root.find(selectors[i]) 1200 .first() 1201 .text() 1202 .trim(); 1203 if (!message && !$root.is(document)) { 1204 message = $(document) 1205 .find(selectors[i]) 1206 .first() 1207 .text() 1208 .trim(); 1209 } 1210 if (message && !rp_is_date_like_text(message)) { 1211 return message; 1212 } 1213 } 1214 1215 return ''; 1216 } 1217 1218 function rp_update_inline_service_display(selection, oldUiUxEnabled) { 1219 if (!selection) { 1220 return; 1221 } 1222 1223 var $deliveryDate = $('#deliveryDate'); 1224 var $deliveryTime = $('#deliveryTime'); 1225 var $summaryWrap = $deliveryDate.closest('.rpress_order-address-wrap'); 1226 1227 if (selection.serviceClosedMessage) { 1228 $summaryWrap.addClass('rpress-store-closed-inline'); 1229 $deliveryDate 1230 .addClass('rp-store-timing-notice rpress-closed-summary-text') 1231 .text(selection.serviceClosedMessage); 1232 $deliveryTime.text(''); 1233 return; 1234 } 1235 1236 $summaryWrap.removeClass('rpress-store-closed-inline'); 1237 $deliveryDate.removeClass('rp-store-timing-notice rpress-closed-summary-text'); 1238 1239 if (selection.serviceDateText && (!oldUiUxEnabled || rp_getCookie('service_date') || rp_getCookie('delivery_date'))) { 1240 $deliveryDate.text(selection.serviceDateText); 1241 } 1242 if (selection.serviceTimeText && (!oldUiUxEnabled || rp_getCookie('service_time') || rp_getCookie('service_time_text'))) { 1243 $deliveryTime.text(selection.serviceTimeText); 1244 } 1245 } 1246 1247 function rp_apply_service_defaults($scope, preferredServiceType, persistCookies, requireExplicitSelection, preferCurrentSelection) { 1248 var shouldPersistCookies = (persistCookies !== false); 1249 var enforceManualSelection = (requireExplicitSelection === true); 1250 var shouldPreferCurrentSelection = (preferCurrentSelection === true); 1251 var $root = ($scope && $scope.length) ? $scope : $(document); 1252 var serviceType = rp_get_active_service_type($root, preferredServiceType); 1253 serviceType = rp_sync_service_ui_state($root, serviceType, shouldPersistCookies) || serviceType; 1254 1255 var requestedServiceDate = (rp_getCookie('service_date') || rp_getCookie('delivery_date') || '') 1256 .toString() 1257 .trim(); 1258 var requestedServiceDateText = (rp_getCookie('delivery_date') || '') 1259 .toString() 1260 .trim(); 1261 if (requestedServiceDateText && !/\d/.test(requestedServiceDateText)) { 1262 requestedServiceDateText = ''; 1263 } 1264 var $activeDateSelect = rp_get_active_service_date_select($root, serviceType); 1265 var serviceDate = ''; 1266 var serviceDateText = ''; 1267 var serviceClosedMessage = rp_get_active_service_closed_message($root, serviceType); 1268 1269 if (shouldPreferCurrentSelection && $activeDateSelect.length) { 1270 requestedServiceDate = ($activeDateSelect.val() || '') 1271 .toString() 1272 .trim(); 1273 } 1274 1275 if ($activeDateSelect.length) { 1276 serviceDate = rp_restore_service_date_select( 1277 $activeDateSelect, 1278 requestedServiceDate, 1279 !enforceManualSelection 1280 ); 1281 serviceDateText = ($activeDateSelect.find('option:selected') 1282 .text() || '') 1283 .toString() 1284 .trim(); 1285 } else { 1286 serviceDate = requestedServiceDate; 1287 serviceDateText = requestedServiceDateText || requestedServiceDate; 1288 } 1289 1290 if (!$activeDateSelect.length && !serviceDateText) { 1291 var fallbackDateText = ($('#deliveryDate').first().text() || '') 1292 .toString() 1293 .trim() 1294 .replace(/,\s*$/, ''); 1295 if (fallbackDateText) { 1296 serviceDateText = fallbackDateText; 1297 } 1298 } 1299 1300 if (serviceDate && shouldPersistCookies) { 1301 rp_setCookie('service_date', serviceDate, rp_scripts.expire_cookie_time); 1302 if (!serviceClosedMessage) { 1303 rp_setCookie('delivery_date', serviceDateText || serviceDate, rp_scripts.expire_cookie_time); 1304 } 1305 } 1306 1307 var requestedServiceTime = (rp_getCookie('service_time') || rp_getCookie('service_time_text') || '') 1308 .toString() 1309 .trim(); 1310 var $activeTimeSelect = rp_get_active_service_time_select($root, serviceType); 1311 var serviceTime = ''; 1312 var serviceTimeText = ''; 1313 var isServiceTimeHidden = rp_is_service_time_hidden(serviceType); 1314 1315 if (shouldPreferCurrentSelection && $activeTimeSelect.length) { 1316 requestedServiceTime = ($activeTimeSelect.val() || '') 1317 .toString() 1318 .trim(); 1319 } 1320 1321 if (isServiceTimeHidden) { 1322 serviceTime = rp_get_asap_fallback_time(serviceType); 1323 serviceTimeText = serviceTime; 1324 } else if ($activeTimeSelect.length) { 1325 serviceTime = rp_restore_service_time_select( 1326 $activeTimeSelect, 1327 requestedServiceTime, 1328 !enforceManualSelection 1329 ); 1330 serviceTimeText = ($activeTimeSelect.find('option:selected') 1331 .text() || '') 1332 .toString() 1333 .trim(); 1334 } else { 1335 serviceTime = requestedServiceTime; 1336 serviceTimeText = requestedServiceTime; 1337 } 1338 1339 if (!$activeTimeSelect.length) { 1340 var fallbackTimeText = ($('#deliveryTime').first().text() || '') 1341 .toString() 1342 .trim(); 1343 if (fallbackTimeText) { 1344 serviceTimeText = fallbackTimeText; 1345 } 1346 } 1347 1348 if (serviceTime && shouldPersistCookies) { 1349 rp_setCookie('service_time', serviceTime, rp_scripts.expire_cookie_time); 1350 rp_setCookie('service_time_text', serviceTimeText || serviceTime, rp_scripts.expire_cookie_time); 1351 } 1352 1353 return { 1354 serviceType: serviceType, 1355 serviceDate: serviceDate, 1356 serviceDateText: serviceClosedMessage || serviceDateText, 1357 serviceClosedMessage: serviceClosedMessage, 1358 serviceTime: serviceTime, 1359 serviceTimeText: serviceTimeText 1360 }; 1361 } 1362 function rp_get_active_service_type($scope, fallbackServiceType) { 1363 var $root = ($scope && $scope.length) ? $scope : $(document); 1364 var serviceType = ''; 1365 var $activeServiceTab = $root.find('#rpressdeliveryTab .single-service-selected[aria-selected="true"]') 1366 .first(); 1367 1368 if (!$activeServiceTab.length) { 1369 $activeServiceTab = $root.find('#rpressdeliveryTab .nav-item.active .single-service-selected') 1370 .first(); 1371 } 1372 1373 if (!$activeServiceTab.length) { 1374 $activeServiceTab = $root.find('#rpressdeliveryTab .single-service-selected.active') 1375 .first(); 1376 } 1377 1378 if ($activeServiceTab.length) { 1379 serviceType = String($activeServiceTab.data('service-type') || '') 1380 .toLowerCase(); 1381 } 1382 1383 if (!serviceType) { 1384 var $activeServicePane = $root.find('.delivery-settings-wrapper.active[id^="nav-"], .delivery-settings-wrapper.show[id^="nav-"]') 1385 .first(); 1386 if ($activeServicePane.length) { 1387 serviceType = String($activeServicePane.attr('id') || '') 1388 .replace(/^nav-/, '') 1389 .toLowerCase(); 1390 } 1391 } 1392 1393 if (!serviceType) { 1394 var $serviceTabsWrapper = $root.find('.rpress-tabs-wrapper.service-option-delivery, .rpress-tabs-wrapper.service-option-pickup') 1395 .first(); 1396 if ($serviceTabsWrapper.length) { 1397 if ($serviceTabsWrapper.hasClass('service-option-delivery')) { 1398 serviceType = 'delivery'; 1399 } else if ($serviceTabsWrapper.hasClass('service-option-pickup')) { 1400 serviceType = 'pickup'; 1401 } 1402 } 1403 } 1404 1405 if (!serviceType) { 1406 serviceType = String( 1407 fallbackServiceType || rp_getCookie('service_type') || rp_scripts.default_service || 'delivery' 1408 ) 1409 .toLowerCase(); 1410 } 1411 1412 if (serviceType !== 'delivery' && serviceType !== 'pickup') { 1413 serviceType = 'delivery'; 1414 } 1415 1416 return serviceType; 1417 } 1418 function rp_sync_service_ui_state($scope, serviceType, persist
1418Cookie) { 1419 var normalizedServiceType = String(serviceType || '') 1420 .toLowerCase(); 1421 1422 if (normalizedServiceType !== 'delivery' && normalizedServiceType !== 'pickup') { 1423 return ''; 1424 } 1425 1426 var $root = ($scope && $scope.length) ? $scope : $(document); 1427 var $wrappers = $root.find('.rpress-tabs-wrapper'); 1428 1429 if (!$wrappers.length && $root.hasClass('rpress-tabs-wrapper')) { 1430 $wrappers = $root; 1431 } 1432 1433 $wrappers.each(function () { 1434 var $wrapper = $(this); 1435 var $serviceTab = $wrapper.find('#rpressdeliveryTab .single-service-selected[data-service-type="' + normalizedServiceType + '"]') 1436 .first(); 1437 1438 $wrapper.removeClass('service-option-delivery service-option-pickup') 1439 .addClass('service-option-' + normalizedServiceType); 1440 1441 if ($serviceTab.length) { 1442 $wrapper.find('#rpressdeliveryTab .nav-item').removeClass('active'); 1443 $wrapper.find('#rpressdeliveryTab .single-service-selected') 1444 .removeClass('active') 1445 .attr('aria-selected', 'false'); 1446 1447 $serviceTab 1448 .addClass('active') 1449 .attr('aria-selected', 'true'); 1450 $serviceTab.closest('.nav-item').addClass('active'); 1451 1452 var targetPane = $serviceTab.attr('href'); 1453 if (targetPane && targetPane.charAt(0) === '#') { 1454 $wrapper.find('.delivery-settings-wrapper').removeClass('active show'); 1455 $wrapper.find(targetPane).addClass('active show'); 1456 } 1457 1458 var serviceHeadingLabel = ($serviceTab.find('.rpress-service-tab-label').first().text() || $serviceTab.text() || '') 1459 .toString() 1460 .trim(); 1461 var $serviceHeading = $wrapper.find('.rpress-checkout-service-heading').first(); 1462 if ($serviceHeading.length) { 1463 $serviceHeading 1464 .removeClass('is-service-delivery is-service-pickup') 1465 .addClass('is-service-' + normalizedServiceType); 1466 if (serviceHeadingLabel) { 1467 $serviceHeading.find('.rpress-checkout-service-heading-text') 1468 .text(serviceHeadingLabel); 1469 } 1470 } 1471 } 1472 }); 1473 1474 if (persistCookie !== false) { 1475 rp_setCookie('service_type', normalizedServiceType, rp_scripts.expire_cookie_time); 1476 } 1477 1478 return normalizedServiceType; 1479 } 1480 function rp_sync_service_selection_cookies($scope, preferredServiceType) { 1481 var defaults = rp_apply_service_defaults($scope, preferredServiceType); 1482 if (!defaults.serviceTimeText) { 1483 defaults.serviceTimeText = ($('#deliveryTime') 1484 .first() 1485 .text() || '') 1486 .toString() 1487 .trim(); 1488 if (defaults.serviceTimeText) { 1489 rp_setCookie('service_time_text', defaults.serviceTimeText, rp_scripts.expire_cookie_time); 1490 } 1491 } 1492 1493 return defaults; 1494 } 1495 function rp_get_active_service_date_select($scope, preferredServiceType) { 1496 var $root = ($scope && $scope.length) ? $scope : $(document); 1497 var serviceType = (preferredServiceType || '') 1498 .toLowerCase(); 1499 var $select = $(); 1500 1501 if (serviceType) { 1502 $select = $root.find('.delivery-settings-wrapper#nav-' + serviceType + ' .rpress_get_delivery_dates') 1503 .first(); 1504 if ($select.length) { 1505 return $select; 1506 } 1507 } 1508 1509 $select = $root.find('.delivery-settings-wrapper.active .rpress_get_delivery_dates') 1510 .first(); 1511 if ($select.length) { 1512 return $select; 1513 } 1514 1515 $select = $root.find('.delivery-settings-wrapper.show .rpress_get_delivery_dates') 1516 .first(); 1517 if ($select.length) { 1518 return $select; 1519 } 1520 1521 $select = $root.find('.delivery-settings-wrapper:visible .rpress_get_delivery_dates') 1522 .first(); 1523 if ($select.length) { 1524 return $select; 1525 } 1526 1527 return $root.find('.rpress_get_delivery_dates') 1528 .first(); 1529 } 1530 // Expose helpers for other frontend blocks that execute in separate jQuery scopes. 1531 window.rp_get_active_service_type = rp_get_active_service_type; 1532 window.rp_sync_service_ui_state = rp_sync_service_ui_state; 1533 window.rp_sync_service_selection_cookies = rp_sync_service_selection_cookies; 1534 window.rp_get_active_service_time_select = rp_get_active_service_time_select; 1535 window.rp_restore_service_time_select = rp_restore_service_time_select; 1536 window.rp_restore_service_date_select = rp_restore_service_date_select; 1537 window.rp_apply_service_defaults = rp_apply_service_defaults; 1538 window.rp_update_inline_service_display = rp_update_inline_service_display; 1539 window.rp_is_service_time_hidden = rp_is_service_time_hidden; 1540 window.rp_is_old_ui_ux_enabled = rp_is_old_ui_ux_enabled; 1541 window.rp_clear_service_selection_cookies = rp_clear_service_selection_cookies; 1542 window.rp_clear_old_ui_service_cookies = rp_clear_old_ui_service_cookies; 1543 window.rp_prepare_old_ui_modal_selection = rp_prepare_old_ui_modal_selection; 1544 1545 // When add button is hidden or in grid view, clicking a food card should behave like clicking add button. 1546 $(document).on('click', 'body.rpress-add-button-hidden .rpress-section .rpress_fooditem, .rpress_fooditems_grid .rpress_fooditem, .rpress-grid.rpress_fooditem', function (e) { 1547 var $target = $(e.target); 1548 if ($target.closest('a, button, input, select, textarea, label, .rpress_fooditem_buy_button, .rpress_purchase_submit_wrapper, .rpress_fooditem_quantity_wrapper, .rpress-thumbnail-popup').length) { 1549 return; 1550 } 1551 1552 var $card = $(this); 1553 if ($card.hasClass('product_not_available')) { 1554 return; 1555 } 1556 1557 var $addButton = $card.find('.rpress-add-to-cart') 1558 .first(); 1559 1560 if (!$addButton.length || $addButton.hasClass('rp-loading') || $addButton.prop('disabled')) { 1561 return; 1562 } 1563 1564 e.preventDefault(); 1565 $addButton.trigger('click'); 1566 }); 1567 1568 // Add to Cart (delegated to support AJAX category filtering & dynamic grid rendering) 1569 $(document).on('click', '.rpress-add-to-cart', function (e) { 1570 e.preventDefault(); 1571 var _self = $(this); 1572 var fooditem_id = _self.attr('data-fooditem-id'); 1573 var oldUiUxEnabled = rp_is_old_ui_ux_enabled(); 1574 var hasRequiredServiceContext = rp_get_storage_data(); 1575 if (window.rpJustSelectedService) { 1576 window.rpJustSelectedService = false;
1577 hasRequiredServiceContext = true; 1578 } 1579 var $serviceTypeScope = $('.rpress-delivery-wrap .rpress-tabs-wrapper:visible').first(); 1580 var activeServiceTypeForValidation = rp_get_active_service_type( 1581 $serviceTypeScope.length ? $serviceTypeScope : $(document), 1582 rp_getCookie('service_type') || rp_scripts.default_service || 'delivery' 1583 ); 1584 activeServiceTypeForValidation = rp_sync_service_ui_state($(document), activeServiceTypeForValidation) || activeServiceTypeForValidation; 1585 var forceOldUiServiceModal = rp_is_old_ui_delivery_context_invalid(activeServiceTypeForValidation, $(document)); 1586 1587 if (oldUiUxEnabled && (!hasRequiredServiceContext || forceOldUiServiceModal)) { 1588 if (forceOldUiServiceModal) { 1589 tata.error('Error', rp_get_delivery_fee_context_error(activeServiceTypeForValidation), { position: "tr" }); 1590 } 1591 rp_open_legacy_service_options_modal(fooditem_id); 1592 return; 1593 } 1594 1595 if (activeServiceTypeForValidation === 'delivery') { 1596 var delivery_zip = rp_getCookie('delivery_zip'); 1597 var delivery_location = rp_getCookie('delivery_location'); 1598 var delivery_address = rp_getCookie('delivery_address'); 1599 1600 if (!delivery_zip) { 1601 var $rp_delivery_zone = $('input#rp_delivery_zone'); // adjust selector if needed 1602 // Check if the delivery zone input exists and has a value 1603 if ($rp_delivery_zone.length > 0 && !$rp_delivery_zone.val().trim()) { 1604 // Show error 1605 tata.error('Error', 'Please enter ZIP code', { position: "tr" }); 1606 1607 // Trigger Edit button click after 1 second 1608 setTimeout(function () { 1609 $('#editDateTime').trigger('click'); 1610 }, 500); 1611 1612 return; // stop further execution 1613 } 1614 } 1615 1616 if (!delivery_location) { 1617 var $rp_delivery_location = $('input#rp_delivery_location'); // adjust selector if needed 1618 if (!delivery_address) { 1619 // Check if the delivery zone input exists and has a value 1620 if ($rp_delivery_location.length > 0 && !$rp_delivery_location.val().trim()) { 1621 // Show error 1622 tata.error('Error', 'Please enter location', { position: "tr" }); 1623 1624 // Trigger Edit button click after 1 second 1625 setTimeout(function () { 1626 $('#editDateTime').trigger('click'); 1627 }, 500); 1628 1629 return; // stop further execution 1630 } 1631 } 1632 } 1633 } 1634 1635 var $serviceScope = $('.rpress-delivery-wrap .rpress-tabs-wrapper:visible') 1636 .first(); 1637 var syncedSelection = rp_sync_service_selection_cookies( 1638 $serviceScope.length ? $serviceScope : $(document) 1639 ); 1640 var serviceType = syncedSelection.serviceType; 1641 1642 var $serviceControlsScope = $('#rpressDateTime-content'); 1643 if (!$serviceControlsScope.length) { 1644 $serviceControlsScope = $('#rpressDateTime'); 1645 } 1646 if (!$serviceControlsScope.length) { 1647 $serviceControlsScope = $(document); 1648 } 1649 1650 var normalizedSelection = rp_apply_service_defaults($serviceControlsScope, serviceType); 1651 serviceType = normalizedSelection.serviceType || serviceType; 1652 var serviceDate = (normalizedSelection.serviceDate || '') 1653 .toString() 1654 .trim(); 1655 var serviceTime = (normalizedSelection.serviceTime || '') 1656 .toString() 1657 .trim(); 1658 1659 var getClosedMessage = function () { 1660 var selectors = [ 1661 '.delivery-settings-wrapper#nav-' + serviceType + '.active.show .rpress-service-closed-message .rpress-closed-message-text:visible', 1662 '.delivery-settings-wrapper#nav-' + serviceType + '.active.show .rpress-service-closed-message:visible', 1663 '.delivery-settings-wrapper#nav-' + serviceType + ' .rpress-service-closed-message .rpress-closed-message-text:visible', 1664 '.delivery-settings-wrapper#nav-' + serviceType + ' .rpress-service-closed-message:visible', 1665 '#rpressDateTime .delivery-settings-wrapper.active.show .rpress-service-closed-message .rpress-closed-message-text:visible', 1666 '#rpressDateTime .delivery-settings-wrapper.active.show .rpress-service-closed-message:visible', 1667 '.delivery-settings-wrapper#nav-' + serviceType + '.active.show .rpress-service-closed-message .rpress-closed-message-text', 1668 '.delivery-settings-wrapper#nav-' + serviceType + '.active.show .rpress-service-closed-message', 1669 '#rpressDateTime .delivery-settings-wrapper.active.show .rpress-service-closed-message .rpress-closed-message-text', 1670 '#rpressDateTime .delivery-settings-wrapper.active.show .rpress-service-closed-message' 1671 ]; 1672 for (var i = 0; i < selectors.length; i++) { 1673 var message = $(selectors[i]) 1674 .first() 1675 .text() 1676 .trim(); 1677 if (message && !/^\d{1,4}([./-])\d{1,2}\1\d{1,4}$/.test(message)) { 1678 return message; 1679 } 1680 } 1681 return ''; 1682 }; 1683 1684 var serviceClosedMessage = getClosedMessage(); 1685 if (serviceClosedMessage) { 1686 tata.error('Error', serviceClosedMessage, { position: "tr" }); 1687 return; 1688 } 1689 1690 var isServiceTimeDisabled = rp_is_service_time_hidden(serviceType); 1691 1692 if (!isServiceTimeDisabled && !serviceTime) { 1693 var closedMessage = serviceClosedMessage || getClosedMessage(); 1694 if (closedMessage) { 1695 tata.error('Error', closedMessage, { position: "tr" }); 1696 } else { 1697 $('#editDateTime').trigger('click'); 1698 var $serviceDateModal = $('#rpressDateTime'); 1699 var isDateTimeModalVisible = $serviceDateModal.length && 1700 ($serviceDateModal.hasClass('is-open') || $serviceDateModal.attr('aria-hidden') === 'false') && 1701 $serviceDateModal.find('.modal__container:visible').length > 0; 1702 1703 if (!isDateTimeModalVisible) { 1704 var $legacyServiceChange = $('.delivery-change:visible').first(); 1705 if (!$legacyServiceChange.length) { 1706 $legacyServiceChange = $('.delivery-change').first(); 1707 } 1708 if ($legacyServiceChange.length) { 1709 $legacyServiceChange.trigger('click'); 1710 } 1711 } 1712 } 1713 return; 1714 } 1715 var rp_get_delivery_data = hasRequiredServiceContext; 1716 $('#rpressModal') 1717 .removeClass('rpress-delivery-options rpress-food-options checkout-error'); 1718 $('#rpressModal .qty') 1719 .val('1'); 1720 $('#rpressModal')
1721 .find('.cart-action-text') 1722 .html(rp_scripts.add_to_cart); 1723 if (!rp_get_delivery_data) { 1724 var action = 'rpress_show_delivery_options'; 1725 var security = rp_scripts.service_type_nonce; 1726 $('#rpressModal') 1727 .addClass('show-service-options'); 1728 } else { 1729 $('#rpressModal') 1730 .removeClass('show-service-options'); 1731 var action = 'rpress_show_products'; 1732 var security = rp_scripts.show_products_nonce; 1733 } 1734 var foodItemName = _self.attr('data-title'); 1735 var price = _self.attr('data-price'); 1736 var variable_price = _self.attr('data-variable-price'); 1737 var data = { 1738 action: action, 1739 fooditem_id: fooditem_id, 1740 security: security, 1741 service_type: serviceType, 1742 selected_date: serviceDate, 1743 selected_time: serviceTime 1744 }; 1745 $.ajax({ 1746 type: "POST", 1747 data: data, 1748 dataType: "json", 1749 url: rp_scripts.ajaxurl, 1750 beforeSend: (jqXHR, status) => { 1751 _self.addClass('rp-loading'); 1752 _self.find('.add-icon').addClass('icon-loading-toggle'); 1753 _self.find('.rp-ajax-toggle-text') 1754 .addClass('rp-text-visibility'); 1755 }, 1756 xhrFields: { 1757 withCredentials: true 1758 }, 1759 complete: (jqXHR, object) => { 1760 _self.removeClass('rp-loading'); 1761 _self.find('.add-icon').removeClass('icon-loading-toggle'); 1762 _self.find('.rp-ajax-toggle-text') 1763 .removeClass('rp-text-visibility'); 1764 1765 }, 1766 success: function (response) { 1767 if (response?.success === false && response?.data?.status === 'error') { 1768 tata.error('Error', response?.data?.error_msg, { position: "tr" }); 1769 return; 1770 } 1771 MicroModal.show('rpressModal', { 1772 disableScroll: true 1773 }); 1774 $('#rpressModal').removeClass('loading'); 1775 1776 $('#rpressModal .modal-title') 1777 .html(response.data.html_title); 1778 $('#rpressModal .modal-body') 1779 .html(response.data.html); 1780 $('#rpressModal .cart-item-price') 1781 .html(response.data.price); 1782 $('#rpressModal .item-description') 1783 .html(response.data.description); 1784 1785 // Set the image only when one exists. An empty src makes the browser 1786 // re-request the page URL and render a broken image, so remove the 1787 // attribute and hide the element when the item has no photo. 1788 var $itemImage = $('#rpressModal .item-image'); 1789 if (response.data.image_url) { 1790 $itemImage.attr('src', response.data.image_url).prop('hidden', false); 1791 } else { 1792 $itemImage.removeAttr('src').prop('hidden', true); 1793 } 1794 $('#rpressModal .cart-item-price') 1795 .attr('data-price', response.data.price_raw); 1796 // Trigger event so themes can refresh other areas. 1797 $(document.body) 1798 .trigger('opened_service_options', [response.data]); 1799 $('#rpressModal') 1800 .find('.submit-fooditem-button') 1801 .attr('data-cart-action', 'add-cart'); 1802 $('#rpressModal') 1803 .find('.cart-action-text') 1804 .html(rp_scripts.add_to_cart); 1805 if (fooditem_id !== '' && price !== '') { 1806 $('#rpressModal') 1807 .find('.submit-fooditem-button') 1808 .attr('data-item-id', fooditem_id); 1809 $('#rpressModal') 1810 .find('.submit-fooditem-button') 1811 .attr('data-title', foodItemName); 1812 $('#rpressModal') 1813 .find('.submit-fooditem-button') 1814 .attr('data-item-price', price); 1815 $('#rpressModal') 1816 .find('.submit-fooditem-button') 1817 .attr('data-item-qty', 1); 1818 } 1819 update_modal_live_price('fooditem-details'); 1820 rp_checked_default_subaddon(); 1821 } 1822 }); 1823 }); 1824 // Update Cart 1825 // The whole cart item body is a role="button" edit trigger; Enter/Space fire it. 1826 $('.rpress-sidebar-cart') 1827 .on('keydown', '.rpress-edit-from-cart', function (e) { 1828 if (e.which === 13 || e.which === 32) { 1829 e.preventDefault(); 1830 $(this).trigger('click'); 1831 } 1832 }) 1833 .on('click', '.rpress-edit-from-cart', function (e) { 1834 e.preventDefault(); 1835 var _self = $(this); 1836 _self.parents('.rpress-cart-item') 1837 .addClass('edited'); 1838 var CartItemId = _self.attr('data-remove-item'); 1839 var FoodItemId = _self.attr('data-item-id'); 1840 var FoodItemName = _self.attr('data-item-name'); 1841 var FoodQuantity = _self.parents('.rpress-cart-item') 1842 .find('.rpress-cart-item-qty') 1843 .text(); 1844 var action = 'rpress_edit_cart_fooditem'; 1845 var security = rp_scripts.edit_cart_fooditem_nonce; 1846 var data = { 1847 action: action, 1848 cartitem_id: CartItemId, 1849 fooditem_id: FoodItemId, 1850 fooditem_name: FoodItemName, 1851 security: security, 1852 }; 1853 if (CartItemId !== '') { 1854 $.ajax({ 1855 type: "POST", 1856 data: data, 1857 dataType: "json", 1858 url: rp_scripts.ajaxurl, 1859 beforeSend: (jqXHR, status) => { 1860 _self.addClass('rp-loading'); 1861 _self.find('.rp-ajax-toggle-text') 1862 .addClass('rp-text-visibility'); 1863 }, 1864 complete: (jqXHR, object) => { 1865 _self.removeClass('rp-loading'); 1866 _self.find('.rp-ajax-toggle-text') 1867 .removeClass('rp-text-visibility'); 1868 }, 1869 xhrFields: { 1870 withCredentials: true 1871 }, 1872 success: function (response) { 1873 MicroModal.show('rpressModal', { 1874 disableScroll: true 1875 }); 1876 $('#rpressModal') 1877 .removeClass('checkout-error'); 1878 $('#rpressModal') 1879 .removeClass('show-service-options'); 1880 $('#rpressModal') 1881 .removeClass('loading'); 1882 $('#rpressModal .modal-title') 1883 .html(response.data.html_title); 1884 $('#rpressModal') 1885 .find(".qty")
1886 .val(FoodQuantity); 1887 $('#rpressModal .item-description').html(response.data.description); 1888 $('#rpressModal') 1889 .find('.submit-fooditem-button') 1890 .attr('data-item-id', FoodItemId); 1891 $('#rpressModal') 1892 .find('.submit-fooditem-button') 1893 .attr('data-title', FoodItemName); 1894 // Set the image only when one exists (empty src re-requests the page 1895 // URL and shows a broken image); hide the element otherwise. 1896 var $editItemImage = $('#rpressModal .item-image'); 1897 if (response.data.image_url) { 1898 $editItemImage.attr('src', response.data.image_url).prop('hidden', false); 1899 } else { 1900 $editItemImage.removeAttr('src').prop('hidden', true); 1901 } 1902 $('#rpressModal') 1903 .find('.submit-fooditem-button') 1904 .attr('data-cart-key', CartItemId); 1905 $('#rpressModal') 1906 .find('.submit-fooditem-button') 1907 .attr('data-cart-action', 'update-cart'); 1908 $('#rpressModal') 1909 .find('.submit-fooditem-button') 1910 .find('.cart-action-text') 1911 .html(rp_scripts.update_cart); 1912 $('#rpressModal') 1913 .find('.submit-fooditem-button') 1914 .find('.cart-item-price') 1915 .html(response.data.price); 1916 $('#rpressModal') 1917 .find('.submit-fooditem-button') 1918 .find('.cart-item-price') 1919 .attr('data-price', response.data.price_raw); 1920 $('#rpressModal') 1921 .find('.submit-fooditem-button') 1922 .attr('data-item-qty', FoodQuantity); 1923 $('#rpressModal .modal-body') 1924 .html(response.data.html); 1925 1926 // Auto-check addons that were already selected. 1927 if (response.data.addon_items) { 1928 $.each(response.data.addon_items, function (i, addon) { 1929 var addonId = addon.addon_id; 1930 var qty = addon.quantity; 1931 1932 // Find all checkboxes that belong to this addon_id (multiple clones may exist) 1933 var $checkboxes = $('#rpressModal .modal-body input[type="checkbox"][value^="' + addonId + '|"]'); 1934 1935 if ($checkboxes.length) { 1936 $checkboxes.each(function (index, checkbox) { 1937 var $cb = $(checkbox); 1938 $cb.prop('checked', true); 1939 1940 // Go to its quantity input inside .food-item-list 1941 var $qtyInput = $cb.closest('.food-item-list').find('.addon_qty'); 1942 1943 if ($qtyInput.length) { 1944 $qtyInput.val(qty); // set correct quantity 1945 1946 // Ã°à ¸ââ¬ÂÃÂ¥ Optional: also mark its parent .food-item-list as "active" if your UI needs it 1947 $cb.closest('.food-item-list').addClass('active'); 1948 } 1949 }); 1950 } 1951 }); 1952 } 1953 update_modal_live_price('fooditem-update-details'); 1954 } 1955 }); 1956 } 1957 }); 1958 // Add to Cart / Update Cart Button From Popup 1959 $(document).on('click', '.submit-fooditem-button', function (e) { 1960 e.preventDefault(); 1961 var self = $(this); 1962 var cartAction = self.attr('data-cart-action'); 1963 var text = self.find('span.cart-action-text').text(); 1964 var validation = ''; 1965 // Checking the Required & Max addon settings for Addons 1966 if (jQuery('.addons-wrapper').length > 0) { 1967 jQuery('.addons-wrapper').each(function (index, el) { 1968 var _self = jQuery(this); 1969 var addon = _self.attr('data-id'); 1970 var is_required = _self.children('input.addon_is_required').val(); 1971 var max_addons = _self.children('input.addon_max_limit').val(); 1972 var min_addons = _self.children('input.addon_min_limit').val(); 1973 var checked = _self.find('.food-item-list.active input:checked').length; 1974 1975 var customValidation = { 1976 isValid: true, 1977 message: '', 1978 element: _self, 1979 minAddons: min_addons, 1980 maxAddons: max_addons, 1981 checkedAddons: checked 1982 }; 1983 1984 // Trigger custom validation hook 1985 $(document).trigger('rpress_addon_validation', customValidation); 1986 _self.find('.rp-addon-error') 1987 .removeClass('rp-addon-error'); 1988 if (is_required == 'yes' && checked == 0) { 1989 _self.find('.rp-addon-required').addClass('rp-addon-error'); 1990 validation = 1; 1991 }
1991 else if (max_addons != 0 && checked > max_addons) { 1992 _self.find('.rp-addon-required').addClass('rp-addon-error'); 1993 _self.find('.rp-max-addon').addClass('rp-addon-error'); 1994 _self.find(".rpress-addon-category").addClass('rp-addon-error'); 1995 1996 validation = 1; 1997 } else if (min_addons != 0 && checked < min_addons) { 1998 _self.find('.rp-addon-required').addClass('rp-addon-error'); 1999 _self.find('.rp-min-addon').addClass('rp-addon-error'); 2000 _self.find(".rpress-addon-category").addClass('rp-addon-error'); 2001 2002 validation = 1; 2003 } else if (!customValidation.isValid) { 2004 _self.find('.rp-addon-required').addClass('rp-addon-error'); 2005 _self.find('.rp-min-addon').addClass('rp-addon-error'); 2006 _self.find(".rpress-addon-category").addClass('rp-addon-error'); 2007 validation = 1; 2008 } 2009 2010 if (validation === 1) { 2011 var $error = $('#rpressModal .rp-addon-error').first(); 2012 if ($error.length) { 2013 $error[0].scrollIntoView({ behavior: 'smooth', block: 'start' }); 2014 } 2015 } 2016 2017 if (validation != '') { 2018 self.removeClass('disable_click'); 2019 self.find('.cart-action-text') 2020 .text(text); 2021 return false; 2022 } 2023 }); 2024 } 2025 if (cartAction == 'add-cart' && validation == '') { 2026 self.addClass('disable_click'); 2027 var this_form = self.parents('.modal') 2028 .find('form#fooditem-details .food-item-list.active input'); 2029 var itemId = self.attr('data-item-id'); 2030 var itemName = self.attr('data-title'); 2031 var itemQty = self.attr('data-item-qty'); 2032 var FormData = this_form.serializeArray(); 2033 var SpecialInstruction = self.parents('.modal') 2034 .find('textarea.special-instructions') 2035 .val(); 2036 var action = 'rpress_add_to_cart'; 2037 var data = { 2038 action: action, 2039 fooditem_id: itemId, 2040 fooditem_qty: itemQty, 2041 special_instruction: SpecialInstruction, 2042 post_data: FormData, 2043 security: rp_scripts.add_to_cart_nonce 2044 }; 2045 const float_menu = $(".container-actionmenu"); 2046 2047 if (itemId !== '') { 2048 $.ajax({ 2049 type: "POST", 2050 data: data, 2051 dataType: "json", 2052 url: rp_scripts.ajaxurl, 2053 xhrFields: { 2054 withCredentials: true 2055 }, 2056 beforeSend: (jqXHR, object) => { 2057 self.addClass('rp-loading'); 2058 self.find('.rp-ajax-toggle-text') 2059 .addClass('rp-text-visibility') 2060 if (float_menu.length > 0) { 2061 float_menu.removeClass("cart-has-items"); 2062 } 2063 }, 2064 complete: (jqXHR, object) => { 2065 self.removeClass('rp-loading'); 2066 self.find('.rp-ajax-toggle-text') 2067 .removeClass('rp-text-visibility') 2068 }, 2069 success: function (response) { 2070 if (response) { 2071 $('.rpress-mobile-cart-icons') 2072 .css({ 2073 display: 'flex' 2074 }); 2075 self.removeClass('disable_click'); 2076 self.find('.cart-action-text') 2077 .text(text); 2078 var serviceType = rp_getCookie('service_type'); 2079 var serviceTime = rp_getCookie('service_time'); 2080 var serviceTimeText = rp_getCookie('service_time_text'); 2081 var serviceDate = rp_getCookie('delivery_date'); 2082 $('ul.rpress-cart') 2083 .find('li.cart_item.empty') 2084 .remove(); 2085 $('ul.rpress-cart') 2086 .find('li.cart_item.rpress_subtotal') 2087 .remove(); 2088 $('ul.rpress-cart') 2089 .find('li.cart_item.cart-sub-total') 2090 .remove(); 2091 $('ul.rpress-cart') 2092 .find('li.cart_item.rpress_cart_tax') 2093 .remove(); 2094 $('ul.rpress-cart') 2095 .find('li.cart_item.rpress-cart-meta.rpress-delivery-fee') 2096 .remove(); 2097 $('ul.rpress-cart') 2098 .find('li.cart_item.rpress-cart-meta.rpress_subtotal') 2099 .remove(); 2100 $('ul.rpress-cart').append(response.cart_item); 2101 if (float_menu.length > 0) { 2102 float_menu.addClass("cart-has-items"); 2103 } 2104 2105 rp_update_mobile_cart_summary(response.total, response.cart_quantity); 2106 if (serviceType !== undefined) { 2107 serviceLabel = window.localStorage.getItem('serviceLabel'); 2108 var orderInfo = '<span class="delMethod">' + serviceLabel + ', ' + serviceDate + '</span>'; 2109 if (serviceTime !== undefined) { 2110 // Check if the string contains 'ASAP' 2111 if (serviceTime.includes('ASAP')) { 2112 // Remove 'ASAP' from the string 2113 serviceTimeText = serviceTime.replace('ASAP', ''); 2114 serviceTimeText = rp_scripts.asap_txt + ' ' + serviceTimeText; 2115 } 2116 orderInfo += '<span class="delTime">, ' + serviceTimeText + '</span>'; 2117 } 2118 $('.delivery-items-options') 2119 .find('.delivery-opts') 2120 .html(orderInfo); 2121 if ($('.delivery-wrap .delivery-change') 2122 .length == 0) { 2123 var changeText = rp_is_old_ui_ux_enabled() ? 'Change' : (rp_scripts.change_txt || 'Change?'); 2124 var helperHtml = rp_is_old_ui_ux_enabled() ? rp_get_delivery_change_helper_html() : ''; 2125 $("<a href='#' class='delivery-change'><span class='rp-ajax-toggle-text'>" + changeText + "</span></a>" + helperHtml) 2126 .insertAfter(".delivery-opts"); 2127 } 2128 } 2129 $('.delivery-items-options') 2130 .css('display', 'block'); 2131 // Always reveal the cart summary/checkout once an item is added. 2132 // The ".rpress.item-order" header is now always present in the 2133 // template, so the removeClass below must not be gated by it or 2134 // the checkout button stays hidden until a page refresh. 2135 $('div.rpress-sidebar-main-wrap div.rpress-sidebar-cart-wrap').removeClass('empty-cart'); 2136 if ($('div.rpress.item-order').length == 0) { 2137 var orderitems = $('<div class="rpress item-order"><h4>Ordered menu</h4><span>1 items</span></div>'); 2138 $('div.rpress-sidebar-main-wrap div.rpress-sidebar-cart-wrap').prepend(orderitems); 2139 } 2140 if ($('li.rpress-cart-item') 2141 .length > 0) { 2142 $('a.rpress-clear-cart') 2143 .show(); 2144 } else { 2145 $('a.rpress-clear-cart') 2146 .hide(); 2147 } 2148 if (typeof response.cart_summary === 'string') { 2149 rp_refresh_sidebar_cart_summary(response.cart_summary); 2150 } 2151 $(document.body) 2152 .trigger('rpress_added_to_cart', [response]); 2153 MicroModal.close('rpressModal'); 2154 tata.success(window.rp_scripts.success, self.attr('data-title') + window.rp_scripts.added_to_cart, { 2155 position: "tr" 2156 }) 2157 } 2158 } 2159 }) 2160 } 2161 } 2162 if (cartAction == 'update-cart' && validation == '') { 2163 2164 self.addClass('disable_click'); 2165 var this_form = self.parents('.modal') 2166 .find('form#fooditem-update-details .food-item-list.active input'); 2167 var itemId = self.attr('data-item-id'); 2168 var itemPrice = self.attr('data-item-price'); 2169 var cartKey = self.attr('data-cart-key'); 2170 var itemQty = self.attr('data-item-qty'); 2171 var FormData = this_form.serializeArray(); 2172 var SpecialInstruction = self.parents('.modal') 2173 .find('textarea.special-instructions') 2174 .val(); 2175 var action = 'rpress_update_cart_items'; 2176 var data = { 2177 action: action, 2178 fooditem_id: itemId, 2179 fooditem_qty: itemQty, 2180 fooditem_cartkey: cartKey, 2181 special_instruction: SpecialInstruction, 2182 post_data: FormData, 2183 security: rp_scripts.update_cart_item_nonce 2184 }; 2185 2186 if (itemId !== '') { 2187 $.ajax({ 2188 type: "POST", 2189 data: data, 2190 dataType: "json", 2191 url: rp_scripts.ajaxurl, 2192 xhrFields: { 2193 withCredentials: true 2194 }, 2195 success: function (response) { 2196 self.removeClass('disable_click');
2197 self.find('.cart-action-text') 2198 .text(text); 2199 if (response) { 2200 html = response.cart_item; 2201 $('ul.rpress-cart') 2202 .find('li.cart_item.empty') 2203 .remove(); 2204 $('.rpress-cart >li.rpress-cart-item') 2205 .each(function (index, item) { 2206 $(this) 2207 .find("[data-cart-item]") 2208 .attr('data-cart-item', index); 2209 $(this) 2210 .attr('data-cart-key', index); 2211 $(this) 2212 .attr('data-remove-item', index); 2213 }); 2214 $('ul.rpress-cart') 2215 .find('li.edited') 2216 .replaceWith(function () { 2217 let obj = $(html); 2218 obj.attr('data-cart-key', response.cart_key); 2219 obj.find(".rpress-edit-from-cart") 2220 .attr("data-cart-item", response.cart_key); 2221 obj.find(".rpress-edit-from-cart") 2222 .attr("data-remove-item", response.cart_key); 2223 obj.find("a.rpress_remove_from_cart") 2224 .attr("data-cart-item", response.cart_key); 2225 obj.find("a.rpress_remove_from_cart") 2226 .attr("data-remove-item", response.cart_key); 2227 return obj; 2228 }); 2229 $('ul.rpress-cart') 2230 .find('.cart-total') 2231 .html(response.total); 2232 $('ul.rpress-cart') 2233 .find('.cart-subtotal') 2234 .html(response.subtotal); 2235 $('ul.rpress-cart') 2236 .find('.cart-tax') 2237 .html(response.tax); 2238 rp_update_mobile_cart_summary(response.total, response.cart_quantity); 2239 if (typeof response.cart_summary === 'string') { 2240 rp_refresh_sidebar_cart_summary(response.cart_summary); 2241 } 2242 $(document.body) 2243 .trigger('rpress_items_updated', [response]); 2244 MicroModal.close('rpressModal'); 2245 } 2246 } 2247 }); 2248 } 2249 } 2250 }); 2251 2252 // --- Sidebar cart quantity stepper ------------------------------------- 2253 // The â / value / + control on each sidebar cart line. +/â hit the 2254 // rpress_cart_item_quantity AJAX (keyed by cart_key, preserves add-ons); at 2255 // qty 1 the â morphs into a trash and reuses the existing remove flow. 2256 function rpSetStepperState($stepper) { 2257 var q = parseInt($stepper.find('.rp-qty-val').text(), 10) || 1; 2258 $stepper.toggleClass('is-one', q <= 1); 2259 } 2260 function rpSyncSteppers(scope) { 2261 $(scope || document).find('.rpress-qty-stepper').each(function () { 2262 rpSetStepperState($(this)); 2263 }); 2264 } 2265 function rpApplyCartItemResponse(response) { 2266 if (!response || typeof response.cart_item !== 'string' || response.cart_item === '') { 2267 return; 2268 } 2269 var $new = $(response.cart_item); 2270 $new.attr('data-cart-key', response.cart_key); 2271 var $old = $('ul.rpress-cart > li.rpress-cart-item[data-cart-key="' + response.cart_key + '"]').first(); 2272 if ($old.length) { 2273 $old.replaceWith($new); 2274 } 2275 rpSyncSteppers($new); 2276 if (typeof response.cart_summary === 'string') { 2277 rp_refresh_sidebar_cart_summary(response.cart_summary); 2278 } 2279 rp_update_mobile_cart_summary(response.total, response.cart_quantity); 2280 $(document.body).trigger('rpress_items_updated', [response]); 2281 } 2282 function rpChangeCartQty($stepper, newQty) { 2283 if ($stepper.hasClass('rp-qty-busy')) { return; } 2284 $stepper.addClass('rp-qty-busy'); 2285 $.ajax({ 2286 type: 'POST', 2287 url: rp_scripts.ajaxurl, 2288 dataType: 'json', 2289 xhrFields: { withCredentials: true }, 2290 data: { 2291 action: 'rpress_cart_item_quantity', 2292 cart_key: $stepper.attr('data-cart-key'), 2293 quantity: newQty, 2294 security: rp_scripts.update_cart_item_nonce 2295 }, 2296 success: function (response) { 2297 $stepper.removeClass('rp-qty-busy'); 2298 rpApplyCartItemResponse(response); 2299 }, 2300 error: function () { 2301 $stepper.removeClass('rp-qty-busy'); 2302 } 2303 }); 2304 } 2305 $('body').on('click', '.rpress-qty-stepper .rp-qty-inc', function (e) { 2306 e.preventDefault(); 2307 var $stepper = $(this).closest('.rpress-qty-stepper'); 2308 var q = parseInt($stepper.find('.rp-qty-val').text(), 10) || 1; 2309 rpChangeCartQty($stepper, q + 1); 2310 }); 2311 $('body').on('click', '.rpress-qty-stepper .rp-qty-dec', function (e) { 2312 e.preventDefault(); 2313 var $stepper = $(this).closest('.rpress-qty-stepper'); 2314 var q = parseInt($stepper.find('.rp-qty-val').text(), 10) || 1; 2315 if (q <= 1) { 2316 $stepper.closest('.rpress-cart-item').find('.rpress-remove-from-cart').trigger('click'); 2317 return; 2318 } 2319 rpChangeCartQty($stepper, q - 1); 2320 }); 2321 $(function () { rpSyncSteppers(document); }); 2322 $(document.body).on('rpress_items_updated rpress_cart_item_removed rpress_cart_item_added', function () { 2323 rpSyncSteppers(document); 2324 }); 2325 // ----------------------------------------------------------------------- 2326 2327 // Add Service Date and Time 2328 $('body') 2329 .on('click', '.rpress-delivery-opt-update', function (e) { 2330 e.preventDefault(); 2331 var _self = $(this); 2332 var foodItemId = (_self.attr('data-food-id') || '') 2333 .toString() 2334 .trim(); 2335 if (!foodItemId) { 2336 foodItemId = ($('#rpressModal').attr('data-pending-fooditem-id') || '') 2337 .toString() 2338 .trim(); 2339 } 2340 var $updateScope = _self.parents('.rpress-tabs-wrapper') 2341 .first(); 2342 if (!$updateScope.length) { 2343 $updateScope = $('#rpressDateTime .rpress-tabs-wrapper') 2344 .first(); 2345 } 2346 2347 var serviceType = ''; 2348 var serviceLabel = ''; 2349 var $activeServiceTab = $updateScope.find('.nav-item.active a, .single-service-selected.active') 2350 .first(); 2351 if (!$activeServiceTab.length) { 2352 $activeServiceTab = $('.rpress-tabs-wrapper') 2353 .find('.nav-item.active a, .single-service-selected.active') 2354 .first(); 2355 } 2356 if ($activeServiceTab.length) { 2357 serviceType = ($activeServiceTab.attr('data-service-type') || '') 2358 .toString() 2359 .toLowerCase(); 2360 serviceLabel = ($activeServiceTab.text() || '') 2361 .toString() 2362 .trim(); 2363 window.localStorage.setItem('serviceLabel', serviceLabel); 2364 } 2365 2366 var oldUiUxEnabled = rp_is_old_ui_ux_enabled(); 2367 var hasMultipleServiceTabs = $updateScope.find('#rpressdeliveryTab .single-service-selected').length > 1; 2368 if (oldUiUxEnabled && hasMultipleServiceTabs && !serviceType) { 2369 tata.error('Error', 'Please select a service type', { position: "tr" }); 2370 return false;
2371 } 2372 2373 var normalizedSelection = rp_apply_service_defaults( 2374 $updateScope.length ? $updateScope : $(document), 2375 serviceType, 2376 true, 2377 oldUiUxEnabled, 2378 true 2379 ); 2380 2381 serviceType = normalizedSelection.serviceType || serviceType || rp_getCookie('service_type') || rp_scripts.default_service || 'delivery'; 2382 if (oldUiUxEnabled) { 2383 var isDeliveryFeeContextValid = rp_has_valid_delivery_fee_context(serviceType, $updateScope); 2384 if (!isDeliveryFeeContextValid) { 2385 tata.error('Error', rp_get_delivery_fee_context_error(serviceType), { position: "tr" }); 2386 rp_open_legacy_service_options_modal(foodItemId); 2387 return false; 2388 } 2389 } 2390 var serviceTime = normalizedSelection.serviceTime; 2391 var serviceTimeText = normalizedSelection.serviceTimeText || serviceTime; 2392 var serviceDate = normalizedSelection.serviceDate; 2393 var hasServiceDateSelect = rp_get_active_service_date_select( 2394 $updateScope.length ? $updateScope : $(document), 2395 serviceType 2396 ).length > 0; 2397 var hasServiceTimeSelect = rp_get_active_service_time_select( 2398 $updateScope.length ? $updateScope : $(document), 2399 serviceType 2400 ).length > 0; 2401 if (oldUiUxEnabled && hasServiceDateSelect && !serviceDate) { 2402 tata.error('Error', 'Please select a date', { position: "tr" }); 2403 return false; 2404 } 2405 if (oldUiUxEnabled && hasServiceTimeSelect && !rp_is_service_time_hidden(serviceType) && !serviceTime) { 2406 tata.error('Error', 'Please select a time', { position: "tr" }); 2407 return false; 2408 } 2409 var sDate = serviceDate || rp_getCookie('service_date') || ''; 2410 var action = 'rpress_check_service_slot'; 2411 var data = { 2412 action: action, 2413 serviceType: serviceType, 2414 serviceTime: serviceTime, 2415 service_date: sDate, 2416 security: rp_scripts.service_type_nonce, 2417 }; 2418 $.ajax({ 2419 type: "POST", 2420 data: data, 2421 dataType: "json", 2422 url: rpress_scripts.ajaxurl, 2423 xhrFields: { 2424 withCredentials: true 2425 }, 2426 beforeSend: (jqXHR, status) => { 2427 _self.addClass('rp-loading'); 2428 _self.find('.rp-ajax-toggle-text') 2429 .addClass('rp-text-visibility'); 2430 }, 2431 complete: (jqXHR, oject) => { 2432 _self.removeClass('rp-loading'); 2433 _self.find('.rp-ajax-toggle-text') 2434 .removeClass('rp-text-visibility'); 2435 }, 2436 success: function (response) { 2437 _self.removeClass('rp-loading'); 2438 _self.find('.rp-ajax-toggle-text') 2439 .removeClass('rp-text-visibility'); 2440 if (response.status == 'error') { 2441 _self.text(rpress_scripts.update); 2442 if (oldUiUxEnabled) { 2443 window.rpDeliveryFeeValidationState = 'invalid'; 2444 } 2445 tata.error(rp_scripts.error, response.error_msg || response.msg || rp_scripts.closed_message); 2446 return false; 2447 } else { 2448 if (oldUiUxEnabled) { 2449 window.rpDeliveryFeeValidationState = 'valid'; 2450 } 2451 rp_setCookie('service_type', serviceType, rp_scripts.expire_cookie_time); 2452 if (serviceDate) { 2453 rp_setCookie('service_date', serviceDate, rp_scripts.expire_cookie_time); 2454 rp_setCookie('delivery_date', normalizedSelection.serviceDateText || serviceDate, rp_scripts.expire_cookie_time); 2455 rp_setCookie('service_date_manual', serviceDate, rp_scripts.expire_cookie_time); 2456 } 2457 if (serviceTime) { 2458 rp_setCookie('service_time', serviceTime, rp_scripts.expire_cookie_time); 2459 rp_setCookie('service_time_text', serviceTimeText, rp_scripts.expire_cookie_time); 2460 } else { 2461 rp_setCookie('service_time', '', rp_scripts.expire_cookie_time); 2462 rp_setCookie('service_time_text', '', rp_scripts.expire_cookie_time); 2463 } 2464 if (oldUiUxEnabled) { 2465 rp_persist_delivery_context_for_update($updateScope, response, serviceType); 2466 if (!rp_has_valid_delivery_fee_context(serviceType, $updateScope)) { 2467 tata.error('Error', rp_get_delivery_fee_context_error(serviceType), { position: "tr" }); 2468 rp_open_legacy_service_options_modal(foodItemId); 2469 return false;
2470 } 2471 } 2472 var $modal = $('#rpressModal'); 2473 $modal.removeClass('show-service-options loading'); 2474 if (foodItemId) { 2475 window.rpJustSelectedService = true; 2476 $modal.removeAttr('data-pending-fooditem-id data-service-modal-context'); 2477 if (typeof MicroModal !== 'undefined') { 2478 MicroModal.close('rpressModal'); 2479 } 2480 $modal.find('.modal-title').empty(); 2481 $modal.find('.modal-body').empty(); 2482 setTimeout(function () { 2483 var $targetBtn = $('#rpress_fooditem_' + foodItemId).find('.rpress-add-to-cart').first(); 2484 if (!$targetBtn.length) { 2485 $targetBtn = $('.rpress-add-to-cart[data-fooditem-id="' + foodItemId + '"]').first(); 2486 } 2487 if ($targetBtn.length) { 2488 $targetBtn.trigger('click'); 2489 } 2490 }, 150); 2491 } else { 2492 $modal.removeAttr('data-pending-fooditem-id data-service-modal-context'); 2493 if (typeof MicroModal !== 'undefined') { 2494 MicroModal.close('rpressModal'); 2495 } 2496 $modal.find('.modal-title').empty(); 2497 $modal.find('.modal-body').empty(); 2498 var selectedDateLabel = normalizedSelection.serviceDateText || rp_getCookie('delivery_date') || serviceDate || ''; 2499 if (serviceType && serviceTime) { 2500 $('.delivery-wrap .delivery-opts') 2501 .html('<span class="delMethod">' + serviceLabel + ',</span> <span class="delTime"> ' + selectedDateLabel + ', ' + serviceTimeText + '</span>'); 2502 } else if (serviceType) { 2503 $('.delivery-items-options') 2504 .find('.delivery-opts') 2505 .html('<span class="delMethod">' + serviceLabel + ',</span> <span class="delTime"> ' + selectedDateLabel + '</span>'); 2506 } 2507 } 2508 //Trigger checked slot event so that it can be used by theme/plugins 2509 if (typeof response.total !== 'undefined') { 2510 rp_update_mobile_cart_summary(response.total, response.cart_quantity); 2511 } 2512 if (typeof response.cart_summary === 'string') { 2513 rp_refresh_sidebar_cart_summary(response.cart_summary); 2514 } 2515 $(document.body) 2516 .trigger('rpress_checked_slots', [response]); 2517 // Refresh checkout fragments without forcing a full page reload loop. 2518 if (rpress_scripts.is_checkout == '1') { 2519 $(document.body).trigger('rp-refresh-checkout-service'); 2520 } 2521 } 2522 } 2523 }); 2524 }); 2525 $('body') 2526 .on('click', '.rpress-editaddress-submit-btn', function (e) { 2527 e.preventDefault(); 2528 var _self = $(this); 2529 var foodItemId = _self.attr('data-food-id'); 2530 var $updateScope = _self.parents('.rpress-tabs-wrapper') 2531 .first(); 2532 if (!$updateScope.length) { 2533 $updateScope = $('#rpressDateTime .rpress-tabs-wrapper') 2534 .first(); 2535 } 2536 var serviceType = ''; 2537 var serviceLabel = ''; 2538 var $activeServiceTab = $updateScope.find('.nav-item.active a, .single-service-selected.active') 2539 .first(); 2540 if (!$activeServiceTab.length) { 2541 $activeServiceTab = $('.rpress-tabs-wrapper') 2542 .find('.nav-item.active a, .single-service-selected.active') 2543 .first(); 2544 } 2545 if ($activeServiceTab.length) { 2546 serviceType = ($activeServiceTab.attr('data-service-type') || '') 2547 .toString() 2548 .toLowerCase(); 2549 serviceLabel = ($activeServiceTab.text() || '') 2550 .toString() 2551 .trim(); 2552 window.localStorage.setItem('serviceLabel', serviceLabel); 2553 } 2554 2555 var oldUiUxEnabled = rp_is_old_ui_ux_enabled(); 2556 var hasMultipleServiceTabs = $updateScope.find('#rpressdeliveryTab .single-service-selected').length > 1; 2557 if (oldUiUxEnabled && hasMultipleServiceTabs && !serviceType) { 2558 tata.error('Error', 'Please select a service type', { position: "tr" }); 2559 return false;
2560 } 2561 2562 var normalizedSelection = rp_apply_service_defaults( 2563 $updateScope.length ? $updateScope : $(document), 2564 serviceType, 2565 true, 2566 oldUiUxEnabled, 2567 true 2568 ); 2569 2570 serviceType = normalizedSelection.serviceType || serviceType || rp_getCookie('service_type') || rp_scripts.default_service || 'delivery'; 2571 var serviceTime = normalizedSelection.serviceTime; 2572 var serviceTimeText = normalizedSelection.serviceTimeText || serviceTime; 2573 var serviceDate = normalizedSelection.serviceDate; 2574 var hasServiceDateSelect = rp_get_active_service_date_select( 2575 $updateScope.length ? $updateScope : $(document), 2576 serviceType 2577 ).length > 0; 2578 var hasServiceTimeSelect = rp_get_active_service_time_select( 2579 $updateScope.length ? $updateScope : $(document), 2580 serviceType 2581 ).length > 0; 2582 if (oldUiUxEnabled && hasServiceDateSelect && !serviceDate) { 2583 tata.error('Error', 'Please select a date', { position: "tr" }); 2584 return false; 2585 } 2586 if (oldUiUxEnabled && hasServiceTimeSelect && !rp_is_service_time_hidden(serviceType) && !serviceTime) { 2587 tata.error('Error', 'Please select a time', { position: "tr" }); 2588 return false; 2589 } 2590 var sDate = serviceDate || rp_getCookie('service_date') || ''; 2591 var action = 'rpress_check_service_slot'; 2592 var data = { 2593 action: action, 2594 serviceType: serviceType, 2595 serviceTime: serviceTime, 2596 service_date: sDate, 2597 security: rp_scripts.service_type_nonce, 2598 }; 2599 $.ajax({ 2600 type: "POST", 2601 data: data, 2602 dataType: "json", 2603 url: rpress_scripts.ajaxurl, 2604 xhrFields: { 2605 withCredentials: true 2606 }, 2607 beforeSend: (jqXHR, status) => { 2608 _self.addClass('rp-loading'); 2609 _self.find('.rp-ajax-toggle-text') 2610 .addClass('rp-text-visibility'); 2611 }, 2612 complete: (jqXHR, oject) => { 2613 _self.removeClass('rp-loading'); 2614 _self.find('.rp-ajax-toggle-text') 2615 .removeClass('rp-text-visibility'); 2616 }, 2617 success: function (response) { 2618 _self.removeClass('rp-loading'); 2619 _self.find('.rp-ajax-toggle-text') 2620 .removeClass('rp-text-visibility'); 2621 if (response.status == 'error') { 2622 _self.text(rpress_scripts.update); 2623 if (oldUiUxEnabled) { 2624 window.rpDeliveryFeeValidationState = 'invalid'; 2625 } 2626 tata.error(rp_scripts.error, response.error_msg || response.msg || rp_scripts.closed_message); 2627 return false; 2628 } else { 2629 if (oldUiUxEnabled) { 2630 window.rpDeliveryFeeValidationState = 'valid'; 2631 } 2632 rp_setCookie('service_type', serviceType, rp_scripts.expire_cookie_time); 2633 if (serviceDate) { 2634 rp_setCookie('service_date', serviceDate, rp_scripts.expire_cookie_time); 2635 rp_setCookie('delivery_date', normalizedSelection.serviceDateText || serviceDate, rp_scripts.expire_cookie_time); 2636 rp_setCookie('service_date_manual', serviceDate, rp_scripts.expire_cookie_time); 2637 } 2638 if (serviceTime) { 2639 rp_setCookie('service_time', serviceTime, rp_scripts.expire_cookie_time); 2640 rp_setCookie('service_time_text', serviceTimeText || serviceTime, rp_scripts.expire_cookie_time); 2641 } else { 2642 rp_setCookie('service_time', '', rp_scripts.expire_cookie_time); 2643 rp_setCookie('service_time_text', '', rp_scripts.expire_cookie_time); 2644 } 2645 if (oldUiUxEnabled) { 2646 rp_persist_delivery_context_for_update($updateScope, response, serviceType); 2647 } 2648 $('#rpressModal') 2649 .removeClass('show-service-options'); 2650 if (foodItemId) { 2651 $('#rpressModal') 2652 .addClass('loading'); 2653 $('#rpress_fooditem_' + foodItemId) 2654 .find('.rpress-add-to-cart') 2655 .trigger('click'); 2656 MicroModal.close('rpressModal'); 2657 } else { 2658 MicroModal.close('rpressModal'); 2659 var selectedDateLabel = normalizedSelection.serviceDateText || rp_getCookie('delivery_date') || serviceDate || ''; 2660 if (serviceType && serviceTime) { 2661 $('.delivery-wrap .delivery-opts') 2662 .html('<span class="delMethod">' + serviceLabel + ',</span> <span class="delTime"> ' + selectedDateLabel + ', ' + serviceTimeText + '</span>'); 2663 } else if (serviceType) { 2664 $('.delivery-items-options') 2665 .find('.delivery-opts') 2666 .html('<span class="delMethod">' + serviceLabel + ',</span> <span class="delTime"> ' + selectedDateLabel + '</span>'); 2667 } 2668 } 2669 2670 //Trigger checked slot event so that it can be used by theme/plugins 2671 if (typeof response.total !== 'undefined') { 2672 rp_update_mobile_cart_summary(response.total, response.cart_quantity); 2673 } 2674 if (typeof response.cart_summary === 'string') { 2675 rp_refresh_sidebar_cart_summary(response.cart_summary); 2676 } 2677 $(document.body) 2678 .trigger('rpress_checked_slots', [response]); 2679 // Refresh checkout fragments without forcing a full page reload loop. 2680 if (rpress_scripts.is_checkout == '1') { 2681 $(document.body).trigger('rp-refresh-checkout-service'); 2682 } 2683 } 2684 2685 // Close the modal 2686 MicroModal.close('rpressDateTime'); 2687 } 2688 }); 2689 }); 2690 // Open modal when button is clicked 2691 $(document).on('click', '#editDateTime', function (e) { 2692 e.preventDefault(); 2693 var self = $(this); 2694 2695 var openLegacyServiceOptionsModal = function () { 2696 var $serviceChange = $('.delivery-change:visible').first(); 2697 if (!$serviceChange.length) { 2698 $serviceChange = $('.delivery-change').first(); 2699 } 2700 2701 if ($serviceChange.length) { 2702 $serviceChange.trigger('click'); 2703 return true; 2704 } 2705 2706 if (!$('#rpressModal').length || !rp_scripts || !rp_scripts.ajaxurl || !rp_scripts.service_type_nonce) { 2707 return false;
2708 } 2709 2710 $('#rpressModal').addClass('show-service-options'); 2711 $.ajax({ 2712 type: "POST", 2713 data: { 2714 action: 'rpress_show_delivery_options', 2715 security: rp_scripts.service_type_nonce 2716 }, 2717 dataType: "json", 2718 url: rp_scripts.ajaxurl, 2719 success: function (response) { 2720 if (!response || !response.data) { 2721 return; 2722 } 2723 $('#rpressModal .modal-title').html(response.data.html_title || ''); 2724 $('#rpressModal .modal-body').html(response.data.html || ''); 2725 if (typeof window.rp_prepare_old_ui_modal_selection === 'function') { 2726 window.rp_prepare_old_ui_modal_selection($('#rpressModal .modal-body')); 2727 } 2728 MicroModal.show('rpressModal', { 2729 disableScroll: true 2730 }); 2731 $(document.body).trigger('opened_service_options', [response.data]); 2732 } 2733 }); 2734 2735 return true; 2736 }; 2737 2738 // Old UI/UX uses the legacy popup flow. 2739 if (rp_is_old_ui_ux_enabled()) { 2740 if (openLegacyServiceOptionsModal()) { 2741 return; 2742 } 2743 } 2744 2745 var $dateTimeModal = $('#rpressDateTime'); 2746 var hasDateTimeMarkup = $dateTimeModal.length && 2747 $dateTimeModal.find('.modal__overlay').length > 0 && 2748 $dateTimeModal.find('.modal__container').length > 0; 2749 2750 if (!hasDateTimeMarkup) { 2751 if (openLegacyServiceOptionsModal()) { 2752 return; 2753 } 2754 } 2755 2756 var serviceType = rp_getCookie('service_type') || rp_scripts.default_service || 'delivery'; 2757 var shouldPersistDefaults = !rp_is_old_ui_ux_enabled(); 2758 if (shouldPersistDefaults) { 2759 rp_setCookie('service_type', serviceType, rp_scripts.expire_cookie_time); 2760 } 2761 rp_apply_service_defaults( 2762 $('#rpressDateTime-content'), 2763 serviceType, 2764 shouldPersistDefaults, 2765 rp_is_old_ui_ux_enabled() 2766 ); 2767 if (typeof window.rp_prepare_old_ui_modal_selection === 'function') { 2768 window.rp_prepare_old_ui_modal_selection($('#rpressDateTime-content')); 2769 } 2770 2771 $('.rpress-mobile-cart-icons').hide(); 2772 2773 MicroModal.show('rpressDateTime', { 2774 disableScroll: true 2775 }); 2776 2777 }); 2778 $('body').on('click', '.rpress-editaddress-submit-btn', function (e) { 2779 e.preventDefault(); 2780 2781 var $modal = $('#rpressDateTime-content'); 2782 if (!$modal.length) { 2783 $modal = $('#rpressDateTime'); 2784 } 2785 var activeServiceType = rp_getCookie('service_type') || rp_scripts.default_service || 'delivery'; 2786 var selection = rp_apply_service_defaults($modal.length ? $modal : $(document), activeServiceType, true, false, true); 2787 var selectedDateText = (selection.serviceDateText || rp_getCookie('delivery_date') || '') 2788 .toString() 2789 .trim(); 2790 var selectedTimeText = (selection.serviceTimeText || selection.serviceTime || rp_getCookie('service_time_text') || '') 2791 .toString() 2792 .trim(); 2793 2794 if (selectedDateText) { 2795 $('#deliveryDate').text(selectedDateText); 2796 } 2797 2798 if (selectedTimeText) { 2799 $('#deliveryTime').text(selectedTimeText); 2800 } 2801 2802 $('.rpress-mobile-cart-icons').show(); 2803 }); 2804 // Update Service Date and Time 2805 $(document).on('click', '.delivery-change', function (e) { 2806 e.preventDefault(); 2807 var self = $(this); 2808 var action = 'rpress_show_delivery_options'; 2809 var ServiceType = rp_getCookie('service_type'); 2810 var ServiceTime = rp_getCookie('service_time'); 2811 var text = self.text(); 2812 var data = { 2813 action: action, 2814 security: rp_scripts.service_type_nonce 2815 } 2816 $('#rpressModal').addClass('show-service-options'); 2817 $.ajax({ 2818 type: "POST", 2819 data: data, 2820 dataType: "json", 2821 url: rp_scripts.ajaxurl, 2822 beforeSend: (jqXHR, obj) => { 2823 self.addClass('rp-loading'); 2824 self.find('.rp-ajax-toggle-text') 2825 .addClass('rp-text-visibility') 2826 }, 2827 complete: (jqXHR, obj) => { 2828 self.removeClass('rp-loading'); 2829 self.find('.rp-ajax-toggle-text') 2830 .removeClass('rp-text-visibility') 2831 }, 2832 success: function (response) { 2833 // self.text(text); 2834 $('#rpressModal .modal-title') 2835 .html(response.data.html_title); 2836 $('#rpressModal .modal-body') 2837 .html(response.data.html); 2838 if (typeof window.rp_prepare_old_ui_modal_selection === 'function') { 2839 window.rp_prepare_old_ui_modal_selection($('#rpressModal .modal-body')); 2840 } 2841 MicroModal.show('rpressModal', { 2842 disableScroll: true 2843 }); 2844 if ($('.rpress-tabs-wrapper') 2845 .length) { 2846 if (ServiceTime !== '') { 2847 $('.rpress-delivery-wrap') 2848 .find('select#rpress-' + ServiceType + '-hours') 2849 .val(ServiceTime); 2850 } 2851 $('.rpress-delivery-wrap') 2852 .find('a#nav-' + ServiceType + '-tab') 2853 .trigger('click'); 2854 } 2855 // Trigger event so themes can refresh other areas. 2856 $(document.body).trigger('opened_service_options', [response.data]); 2857 } 2858 }) 2859 }); 2860 // Remove Item from Cart 2861 $(document) 2862 .on('click', '.rpress-remove-from-cart', function (event) { 2863 if ($('.rpress-remove-from-cart') 2864 .length == 1 && !confirm(rp_scripts.confirm_empty_cart)) { 2865 return false;
2866 } 2867 var $this = $(this), 2868 item = $this.data('cart-item'), 2869 action = $this.data('action'), 2870 id = $this.data('fooditem-id'), 2871 security = rp_scripts.edit_cart_fooditem_nonce, 2872 data = { 2873 action: action, 2874 cart_item: item, 2875 security: security 2876 }; 2877 $.ajax({ 2878 type: "POST", 2879 data: data, 2880 dataType: "json", 2881 url: rpress_scripts.ajaxurl, 2882 xhrFields: { 2883 withCredentials: true 2884 }, 2885 success: function (response) { 2886 if (response.removed) { 2887 // Remove the $this cart item 2888 $("[data-cart-item='" + item + "']") 2889 .closest('.rpress-cart-item, .rpress_cart_item') 2890 .remove(); 2891 // Check to see if the purchase form(s) for this fooditem is present on this page 2892 if ($('[id^=rpress_purchase_' + id + ']') 2893 .length) { 2894 $('[id^=rpress_purchase_' + id + '] .rpress_go_to_checkout') 2895 .hide(); 2896 $('[id^=rpress_purchase_' + id + '] a.rpress-add-to-cart') 2897 .show() 2898 .removeAttr('data-rpress-loading'); 2899 if (rpress_scripts.quantities_enabled == '1') { 2900 $('[id^=rpress_purchase_' + id + '] .rpress_fooditem_quantity_wrapper') 2901 .show(); 2902 } 2903 } 2904 rp_update_mobile_cart_summary(response.total, response.cart_quantity); 2905 $(document.body) 2906 .trigger('rpress_quantity_updated', [response.cart_quantity]); 2907 if (rpress_scripts.taxes_enabled) { 2908 $('.cart_item.rpress_subtotal span') 2909 .html(response.subtotal); 2910 $('.cart_item.rpress_cart_tax span') 2911 .html(response.tax); 2912 } 2913 $('.cart_item.rpress_total span.rpress-cart-quantity') 2914 .html(response.cart_quantity); 2915 $('.cart_item.rpress_total span.cart-total') 2916 .html(response.total); 2917 if (typeof response.cart_summary === 'string') { 2918 rp_refresh_sidebar_cart_summary(response.cart_summary); 2919 } 2920 if (response.cart_quantity == 0) { 2921 rp_clear_service_selection_cookies(false); 2922 $('#deliveryDate').text(''); 2923 $('#deliveryTime').text(''); 2924 $('.delivery-items-options').hide(); 2925 $('li.rpress-cart-meta, .cart_item.rpress_subtotal, .rpress-cart-number-of-items, .cart_item.rpress_checkout, .cart_item.rpress_cart_tax, .cart_item.rpress_total') 2926 .hide(); 2927 $('.rpress-cart') 2928 .each(function () { 2929 var cart_wrapper = $(this) 2930 .parent(); 2931 if (cart_wrapper) { 2932 cart_wrapper.addClass('cart-empty') 2933 cart_wrapper.removeClass('cart-not-empty'); 2934 } 2935 if ($(this).is('ul')) { 2936 $(this) 2937 .append('<li class="cart_item empty">' + rpress_scripts.empty_cart_message + '</li>'); 2938 } 2939 }); 2940 } 2941 $(document.body) 2942 .trigger('rpress_cart_item_removed', [response]); 2943 $('ul.rpress-cart > li.rpress-cart-item') 2944 .each(function (index, item) { 2945 $(this) 2946 .find("[data-cart-item]") 2947 .attr('data-cart-item', index); 2948 $(this) 2949 .find("[data-remove-item]") 2950 .attr('data-remove-item', index); 2951 $(this) 2952 .attr('data-cart-key', index); 2953 }); 2954 // check if no item in cart left 2955 if ($('li.rpress-cart-item') 2956 .length == 0) { 2957 $('div.rpress.item-order').hide(); 2958 $('li.rpress-cart-meta') 2959 .hide(); 2960 $('li.delivery-items-options') 2961 .hide(); 2962 $('a.rpress-clear-cart') 2963 .hide(); 2964 } 2965 } 2966 } 2967 }); 2968 return false;
2969 }); 2970 // Clear All Fooditems from Cart 2971 $(document) 2972 .on('click', 'a.rpress-clear-cart', function (e) { 2973 e.preventDefault(); 2974 if (confirm(rp_scripts.confirm_empty_cart)) { 2975 var self = $(this); 2976 var old_text = self.html(); 2977 var action = 'rpress_clear_cart'; 2978 var data = { 2979 security: rp_scripts.clear_cart_nonce, 2980 action: action 2981 } 2982 $.ajax({ 2983 type: "POST", 2984 data: data, 2985 dataType: "json", 2986 url: rp_scripts.ajaxurl, 2987 xhrFields: { 2988 withCredentials: true 2989 }, 2990 beforeSend: (jqXHR, object) => { 2991 self.addClass('rp-loading') 2992 self.find('.rp-ajax-toggle-text') 2993 .addClass('rp-text-visibility') 2994 }, 2995 complete: (jqXHR, object) => { 2996 self.removeClass('rp-loading') 2997 self.find('.rp-ajax-toggle-text') 2998 .removeClass('rp-text-visibility') 2999 }, 3000 success: function (response) { 3001 if (response.status == 'success') { 3002 rp_clear_service_selection_cookies(false); 3003 $('#deliveryDate').text(''); 3004 $('#deliveryTime').text(''); 3005 rp_update_mobile_cart_summary(rp_format_currency_value(0), 0); 3006 $(document.body) 3007 .trigger('rpress_quantity_updated', [0]); 3008 $(".rpress-sidebar-main-wrap") 3009 .css("left", "100%") 3010 .removeClass('rp-cart-drawer-open'); 3011 $('body').removeClass('rp-mobile-cart-open'); 3012 $('ul.rpress-cart') 3013 .find('li.cart_item.rpress_total') 3014 .css('display', 'none'); 3015 $('ul.rpress-cart') 3016 .find('li.cart_item.rpress_checkout') 3017 .css('display', 'none'); 3018 $('ul.rpress-cart') 3019 .find('li.rpress-cart-item') 3020 .remove(); 3021 $('ul.rpress-cart') 3022 .find('li.cart_item.empty') 3023 .remove(); 3024 $('ul.rpress-cart') 3025 .find('li.rpress_subtotal') 3026 .remove(); 3027 $('ul.rpress-cart') 3028 .find('li.rpress_cart_tax') 3029 .remove(); 3030 $('ul.rpress-cart') 3031 .find('li.rpress-delivery-fee') 3032 .remove(); 3033 rp_refresh_sidebar_cart_summary(''); 3034 $('ul.rpress-cart') 3035 .append(response.response); 3036 $('.rpress-cart-number-of-items') 3037 .css('display', 'none'); 3038 $('.delivery-items-options') 3039 .css('display', 'none'); 3040 self.hide(); 3041 tata.success(window.rp_scripts.success, window.rp_scripts.success_empty_cart, { 3042 position: "tr" 3043 }) 3044 } 3045 } 3046 }); 3047 } 3048 }); 3049 // Proceed to Checkout 3050 $(document) 3051 .on('click', '.cart_item.rpress_checkout a', function (e) { 3052 e.preventDefault(); 3053 rp_sync_service_selection_cookies($('.rpress-delivery-wrap .rpress-tabs-wrapper:visible').first()); 3054 var checkoutServiceType = ( 3055 rp_getCookie('service_type') || 3056 rp_get_active_service_type($('.rpress-delivery-wrap .rpress-tabs-wrapper:visible').first(), rp_scripts.default_service || 'delivery') || 3057 rp_scripts.default_service || 3058 'delivery' 3059 ).toString().toLowerCase(); 3060 if (rp_is_old_ui_ux_enabled()) { 3061 if (rp_is_old_ui_delivery_context_invalid(checkoutServiceType, $('#rpress_checkout_wrap').length ? $('#rpress_checkout_wrap') : $(document))) { 3062 tata.error('Error', rp_get_delivery_fee_context_error(checkoutServiceType), { position: "tr" }); 3063 rp_open_legacy_service_options_modal(''); 3064 return false; 3065 } 3066 if (!rp_has_valid_delivery_fee_context(checkoutServiceType, $('#rpress_checkout_wrap').length ? $('#rpress_checkout_wrap') : $(document))) { 3067 tata.error('Error', rp_get_delivery_fee_context_error(checkoutServiceType), { position: "tr" }); 3068 rp_open_legacy_service_options_modal(''); 3069 return false;
3070 } 3071 } 3072 var CheckoutUrl = rp_scripts.checkout_page; 3073 var _self = $(this); 3074 var OrderText = _self.text(); 3075 var action = 'rpress_proceed_checkout'; 3076 var data = { 3077 action: action, 3078 security: rp_scripts.proceed_checkout_nonce, 3079 } 3080 3081 $.ajax({ 3082 type: "POST", 3083 data: data, 3084 dataType: "json", 3085 url: rp_scripts.ajaxurl, 3086 beforeSend: function () { 3087 _self.addClass('rp-loading'); 3088 _self.children('.rp-ajax-toggle-text') 3089 .addClass('rp-text-visibility'); 3090 }, 3091 success: function (response) { 3092 if (response.status == 'error') { 3093 if (response.error_msg) { 3094 errorString = response.error_msg; 3095 } 3096 tata.error(rp_scripts.error, errorString); 3097 _self.removeClass('rp-loading'); 3098 _self.children('.rp-ajax-toggle-text') 3099 .removeClass('rp-text-visibility'); 3100 if (response && response.error_type === "service_time_not_set") { 3101 $("#editDateTime").trigger('click'); 3102 return; 3103 } 3104 } else { 3105 window.location.replace(rp_scripts.checkout_page) 3106 return; 3107 } 3108 } 3109 }) 3110 }); 3111 $(document) 3112 .on('click', 'span.special-instructions-link', function (e) { 3113 e.preventDefault(); 3114 $(this) 3115 .parent('div') 3116 .find('.special-instructions') 3117 .toggleClass('hide'); 3118 }); 3119 $('body') 3120 .on('click', '.rpress-filter-toggle', function () { 3121 $('div.rpress-filter-wrapper') 3122 .toggleClass('active'); 3123 }); 3124 function rp_get_mobile_cart_quantity_value() { 3125 var quantityText = $('.rp-mb-quantity').first().text(); 3126 var quantity = parseInt(quantityText, 10); 3127 3128 if (isNaN(quantity) || quantity < 0) { 3129 quantity = 0; 3130 } 3131 3132 return quantity; 3133 } 3134 3135 function rp_open_mobile_cart_drawer() { 3136 $(".rpress-sidebar-main-wrap") 3137 .css("left", "0%") 3138 .addClass('rp-cart-drawer-open'); 3139 $('body').addClass('rp-mobile-cart-open'); 3140 $('.rpress-mobile-cart-icons').hide(); 3141 } 3142 3143 function rp_close_mobile_cart_drawer() { 3144 $(".rpress-sidebar-main-wrap") 3145 .css("left", "100%") 3146 .removeClass('rp-cart-drawer-open'); 3147 $('body').removeClass('rp-mobile-cart-open'); 3148 3149 if (rp_get_mobile_cart_quantity_value() > 0) { 3150 $('.rpress-mobile-cart-icons').css('display', 'flex'); 3151 } else { 3152 $('.rpress-mobile-cart-icons').hide(); 3153 } 3154 } 3155 3156 $(".rp-cart-left-wrap") 3157 .click(function () { 3158 rp_open_mobile_cart_drawer(); 3159 }); 3160 //Triggering cart 3161 $(".rp-cart-right-wrap") 3162 .click(function () { 3163 $(".cart_item.rpress_checkout a") 3164 .trigger('click'); 3165 }); 3166 $(".close-cart-ic") 3167 .click(function () { 3168 rp_close_mobile_cart_drawer(); 3169 }); 3170 // Show Image on Modal 3171 if ($.fn.fancybox) { 3172 $(".rpress-thumbnail-popup") 3173 .fancybox({ 3174 openEffect: 'elastic', 3175 closeEffect: 'elastic', 3176 helpers: { 3177 title: { 3178 type: 'inside' 3179 } 3180 } 3181 }); 3182 } 3183 if ($(window) 3184 .width() > 991) { 3185 var totalHeight = $('header:eq(0)') 3186 .length > 0 ? $('header:eq(0)') 3187 .height() + 30 : 120; 3188 if ($(".sticky-sidebar") 3189 .length != '') { 3190 $('.sticky-sidebar') 3191 .rpressStickySidebar({ 3192 additionalMarginTop: totalHeight, 3193 minWidth: 992 3194 }); 3195 } 3196 } else { 3197 var totalHeight = $('header:eq(0)') 3198 .length > 0 ? $('header:eq(0)') 3199 .height() + 30 : 70; 3200 } 3201}); 3202/* Make Addons and Variables clickable for Live Price */ 3203jQuery(document) 3204 .ajaxComplete(function () { 3205 jQuery('#fooditem-details .food-item-list input') 3206 .on('click', function (event) { 3207 update_modal_live_price('fooditem-details'); 3208 }); 3209 jQuery('#fooditem-update-details .food-item-list input') 3210 .on('click', function (event) { 3211 update_modal_live_price('fooditem-update-details'); 3212 }); 3213 }); 3214/* RestroPress Sticky Sidebar - Imported from rp-sticky-sidebar.js */ 3215function rp_get_dynamic_scroll_offset() { 3216 var isOrderOnlineView = jQuery('body').hasClass('order-online') || jQuery('.order-online .rpress-section').length > 0; 3217 var overlayBottom = 0; 3218 var selectors = ['#wpadminbar']; 3219 var basePadding = 12; 3220 var viewportWidth = window.innerWidth || jQuery(window).width() || 1024; 3221 var offsetCap = viewportWidth <= 1024 ? 96 : 180; 3222 3223 if (!isOrderOnlineView) { 3224 selectors.push('header:eq(0)'); 3225 } 3226 3227 selectors = selectors.concat([ 3228 '.order-online .rpress-section .make-me-sticky:visible', 3229 '.desktop-scroll-menu .make-me-sticky:visible', 3230 '.mobile-scroll-menu .make-me-sticky:visible', 3231 '.rpress-mobile-menu-wrap .make-me-sticky:visible' 3232 ]); 3233
3234 selectors.forEach(function (selector) { 3235 jQuery(selector).each(function () { 3236 var $element = jQuery(this); 3237 if (!$element.is(':visible')) { 3238 return; 3239 } 3240 3241 var position = ($element.css('position') || '').toLowerCase(); 3242 if (position !== 'fixed' && position !== 'sticky') { 3243 return; 3244 } 3245 3246 var rect = this.getBoundingClientRect ? this.getBoundingClientRect() : null; 3247 if (!rect || rect.height <= 0 || rect.bottom <= 0) { 3248 return; 3249 } 3250 3251 // Count only bars occupying the top viewport band. 3252 if (rect.top > 140) { 3253 return; 3254 } 3255 3256 overlayBottom = Math.max(overlayBottom, rect.bottom); 3257 }); 3258 }); 3259 3260 return Math.max(0, Math.min(offsetCap, Math.round(overlayBottom + basePadding))); 3261} 3262 3263function rp_resolve_category_target($trigger, preferredSelector) { 3264 if (!$trigger || !$trigger.length) { 3265 return jQuery(); 3266 } 3267 3268 var selector = ''; 3269 var dataId = parseInt($trigger.data('id'), 10); 3270 if (!isNaN(dataId) && dataId > 0) { 3271 selector = '#menu-category-' + dataId; 3272 } else if (typeof preferredSelector === 'string' && preferredSelector.length > 0) { 3273 selector = preferredSelector; 3274 } else { 3275 selector = $trigger.attr('href') || ''; 3276 } 3277 3278 if (!selector) { 3279 return jQuery(); 3280 } 3281 3282 if (selector.charAt(0) !== '#') { 3283 selector = '#' + selector; 3284 } 3285 3286 var $scope = $trigger.closest('.rpress-section'); 3287 var $target = jQuery(); 3288 3289 if ($scope.length) { 3290 $target = $scope.find(selector + '.rpress-element-title').first(); 3291 if (!$target.length) { 3292 $target = $scope.find(selector).first(); 3293 } 3294 } 3295 3296 if (!$target.length) { 3297 $target = jQuery(selector + '.rpress-element-title:visible').first(); 3298 } 3299 if (!$target.length) { 3300 $target = jQuery(selector + '.rpress-element-title').first(); 3301 } 3302 if (!$target.length) { 3303 $target = jQuery(selector + ':visible').first(); 3304 } 3305 if (!$target.length) { 3306 $target = jQuery(selector).first(); 3307 } 3308 3309 // Fallback for theme overrides that still use slug anchors like "#beer". 3310 if (!$target.length && selector.charAt(0) === '#') { 3311 var slug = selector.substring(1); 3312 if (slug && slug.indexOf('menu-category-') !== 0) { 3313 if ($scope.length) { 3314 $target = $scope.find('.menu-category-wrap[data-cat-id="' + slug + '"]').first().closest('.rpress-element-title'); 3315 } 3316 if (!$target.length) { 3317 $target = jQuery('.menu-category-wrap[data-cat-id="' + slug + '"]:visible').first().closest('.rpress-element-title'); 3318 } 3319 if (!$target.length) { 3320 $target = jQuery('.menu-category-wrap[data-cat-id="' + slug + '"]').first().closest('.rpress-element-title'); 3321 } 3322 } 3323 } 3324 3325 var normalizeCategoryLabel = function (text) { 3326 return (text || '') 3327 .replace(/\(\s*\d+\s*\)/g, '') 3328 .replace(/\s+\d+\s*$/, '') 3329 .replace(/\s+/g, ' ') 3330 .trim() 3331 .toLowerCase(); 3332 }; 3333 3334 var getLinkLabel = function () { 3335 if (!$trigger || !$trigger.length) { 3336 return ''; 3337 } 3338 var $clone = $trigger.clone(); 3339 $clone.find('span').remove(); 3340 return normalizeCategoryLabel($clone.text()); 3341 }; 3342 3343 var getHeadingLabel = function ($heading) { 3344 if (!$heading || !$heading.length) { 3345 return ''; 3346 } 3347 var $title = $heading.find('h5.rpress-cat').first(); 3348 return normalizeCategoryLabel($title.length ? $title.text() : $heading.text()); 3349 }; 3350 3351 // Guard against mismatched link->href mappings by validating label vs heading. 3352 if ($target.length) { 3353 var linkLabel = getLinkLabel(); 3354 var targetLabel = getHeadingLabel($target); 3355 var mismatch = ( 3356 linkLabel && 3357 targetLabel && 3358 targetLabel.indexOf(linkLabel) === -1 && 3359 linkLabel.indexOf(targetLabel) === -1 3360 ); 3361 3362 if (mismatch) { 3363 var $candidateHeadings = $scope.length 3364 ? $scope.find('.rpress-element-title') 3365 : jQuery('.rpress-element-title'); 3366 3367 var $matchingByLabel = $candidateHeadings.filter(function () { 3368 var label = getHeadingLabel(jQuery(this)); 3369 return label === linkLabel || label.indexOf(linkLabel) !== -1 || linkLabel.indexOf(label) !== -1; 3370 }).first(); 3371 3372 if ($matchingByLabel.length) { 3373 $target = $matchingByLabel; 3374 } else { 3375 var $siblings = $trigger.closest('ul').find('a'); 3376 var linkIndex = $siblings.index($trigger); 3377 if (linkIndex >= 0 && linkIndex < $candidateHeadings.length) { 3378 $target = $candidateHeadings.eq(linkIndex); 3379 } 3380 } 3381 } 3382 } 3383 3384 return $target; 3385} 3386 3387function rp_scroll_to_category_target($target) { 3388 if (!$target || !$target.length) { 3389 return; 3390 } 3391 3392 var $page = jQuery('html, body');
3393 var initialOffset = rp_get_dynamic_scroll_offset(); 3394 var initialDestination = Math.max(0, $target.offset().top - initialOffset); 3395 3396 $page.stop(true).animate({ 3397 scrollTop: initialDestination 3398 }, 420, function () { 3399 var raf = window.requestAnimationFrame || function (cb) { 3400 window.setTimeout(cb, 16); 3401 }; 3402 3403 raf(function () { 3404 if (!$target.length) { 3405 return; 3406 } 3407 3408 var liveOffset = rp_get_dynamic_scroll_offset(); 3409 var rect = $target[0].getBoundingClientRect(); 3410 var delta = rect.top - liveOffset; 3411 3412 if (Math.abs(delta) > 3) { 3413 var correctedDestination = Math.max(0, jQuery(window).scrollTop() + delta); 3414 $page.stop(true).animate({ 3415 scrollTop: correctedDestination 3416 }, 160); 3417 } 3418 }); 3419 }); 3420} 3421 3422function rp_close_action_menu_if_open() { 3423 var container = document.querySelector('.container-actionmenu'); 3424 var burger = document.getElementById('actionburger'); 3425 var menu = document.querySelector('.actionmenu'); 3426 3427 if (!container || !burger || !menu) { 3428 return; 3429 } 3430 3431 if (!burger.classList.contains('is-expanded')) { 3432 return; 3433 } 3434 3435 burger.classList.remove('is-expanded'); 3436 menu.classList.remove('slides-up'); 3437 menu.classList.add('slides-down'); 3438 3439 var icon = burger.querySelector('i'); 3440 var textNode = burger.querySelector('.menu-text'); 3441 var menuText = burger.getAttribute('data-text-menu') || 'Menu'; 3442 var menuIcon = burger.getAttribute('data-icon-menu') || 'fa fa-cutlery'; 3443 3444 if (icon) { 3445 icon.className = menuIcon; 3446 } 3447 if (textNode) { 3448 textNode.textContent = menuText; 3449 } 3450} 3451 3452jQuery(function ($) { 3453 if ($(window).width() > 991) { 3454 if ($(".sticky-sidebar").length > 0) { 3455 $('.sticky-sidebar').rpressStickySidebar({ 3456 additionalMarginTop: rp_get_dynamic_scroll_offset(), 3457 minWidth: 992 3458 }); 3459 } 3460 } 3461 // Category Navigation 3462 $('body') 3463 .on('click', '.rpress-category-link', function (e) { 3464 e.preventDefault(); 3465 var $target = rp_resolve_category_target($(this)); 3466 if (!$target.length) { 3467 return; 3468 } 3469 rp_scroll_to_category_target($target); 3470 }); 3471 $('.rpress-category-item') 3472 .on('click', function () { 3473 $('.rpress-category-item') 3474 .removeClass('current'); 3475 $(this) 3476 .addClass('current'); 3477 }); 3478}); 3479jQuery(function ($) { 3480 // Dedicated handler for bottom mobile action-menu category links. 3481 // This ensures the action-menu path always scrolls via controlled offset logic. 3482 $('body') 3483 .off('click.rpActionMenuCategory', '.container-actionmenu .actionmenu a[href^="#menu-category-"]') 3484 .on('click.rpActionMenuCategory', '.container-actionmenu .actionmenu a[href^="#menu-category-"]', function (e) { 3485 e.preventDefault(); 3486 e.stopPropagation(); 3487 e.stopImmediatePropagation(); 3488 3489 var $link = $(this); 3490 var $target = rp_resolve_category_target($link, $link.attr('href') || ''); 3491 var selectedHref = $link.attr('href') || ''; 3492 var selectedTermId = selectedHref.replace('#menu-category-', ''); 3493 3494 // Keep all category nav UIs in sync immediately on click. 3495 $('.container-actionmenu .actionmenu .cd-dropdown-content a').removeClass('mnuactive'); 3496 $link.addClass('mnuactive'); 3497 3498 if (selectedTermId) { 3499 $('.pn-ProductNav_Link').removeAttr('aria-selected'); 3500 $('.pn-ProductNav_Link[href="#menu-category-' + selectedTermId + '"]') 3501 .attr('aria-selected', 'true') 3502 .addClass('mnuactive'); 3503 3504 $('.rpress-category-lists .rpress-category-link').removeClass('active'); 3505 $('.rpress-category-lists .rpress-category-link').parent().removeClass('current'); 3506 var $listMatch = $('.rpress-category-lists .rpress-category-link[data-id="' + selectedTermId + '"]').first(); 3507 if ($listMatch.length) { 3508 $listMatch.addClass('active'); 3509 $listMatch.parent().addClass('current'); 3510 } 3511 } 3512 3513 rp_close_action_menu_if_open(); 3514 3515 if ($target.length) { 3516 setTimeout(function () { 3517 rp_scroll_to_category_target($target); 3518 }, 60); 3519 } 3520 3521 return false;
3522 }); 3523 3524 // Smooth scroll for category dropdown and horizontal nav 3525 $('body').on('click', '.cd-dropdown-content a, .pn-ProductNav_Link', function (e) { 3526 e.preventDefault(); 3527 e.stopPropagation(); 3528 3529 const $link = $(this); 3530 const targetSelector = $link.attr('href') || ''; 3531 const $target = rp_resolve_category_target($link, targetSelector); 3532 const isActionMenuLink = $link.closest('.container-actionmenu').length > 0; 3533 const isCdDropdownLink = $link.closest('.cd-dropdown').length > 0; 3534 const selectedTermId = targetSelector.replace('#menu-category-', ''); 3535 3536 if (isActionMenuLink) { 3537 rp_close_action_menu_if_open(); 3538 } 3539 3540 if (isCdDropdownLink) { 3541 $('.cd-dropdown').removeClass('dropdown-is-active'); 3542 $('.cd-dropdown-trigger').removeClass('dropdown-is-active'); 3543 $('body').removeClass('cd-overlay-open'); 3544 $('.rpress-cat-overlay').remove(); 3545 $('.rpress-mobile-cart-icons').show(); 3546 } 3547 3548 if ($target.length) { 3549 setTimeout(function () { 3550 rp_scroll_to_category_target($target); 3551 }, (isActionMenuLink || isCdDropdownLink) ? 80 : 0); 3552 } 3553 3554 if (selectedTermId) { 3555 $('.rpress-category-lists .rpress-category-link').removeClass('active'); 3556 $('.rpress-category-lists .rpress-category-link').parent().removeClass('current'); 3557 var $listLink = $('.rpress-category-lists .rpress-category-link[data-id="' + selectedTermId + '"]').first(); 3558 if ($listLink.length) { 3559 $listLink.addClass('active'); 3560 $listLink.parent().addClass('current'); 3561 } 3562 } 3563 3564 // Set aria-selected on horizontal nav 3565 if ($link.hasClass('pn-ProductNav_Link')) { 3566 $('.pn-ProductNav_Link').removeAttr('aria-selected'); 3567 $link.attr('aria-selected', 'true'); 3568 } 3569 3570 // Highlight dropdown item 3571 if ($link.closest('.cd-dropdown-content').length) { 3572 $('.cd-dropdown-content li a').removeClass('mnuactive'); 3573 $link.addClass('mnuactive'); 3574 } 3575 }); 3576 3577}); 3578 3579/* Cart Quantity Changer - Imported from cart-quantity-changer.js */ 3580jQuery(function ($) { 3581 //quantity Minus 3582 var liveQtyVal; 3583 jQuery(document) 3584 .on('click', '.qtyminus', function (e) { 3585 // Stop acting like a button 3586 e.preventDefault(); 3587 // Get the field name 3588 fieldName = 'quantity'; 3589 // Get its current value 3590 var currentVal = parseInt(jQuery('input[name=' + fieldName + ']') 3591 .val()); 3592 // If it isn't undefined or its greater than 0 3593 if (!isNaN(currentVal) && currentVal > 1) { 3594 // Decrement one only if value is > 1 3595 jQuery('input[name=' + fieldName + ']') 3596 .val(currentVal - 1); 3597 jQuery('.qtyplus') 3598 .removeAttr('style'); 3599 liveQtyVal = currentVal - 1; 3600 } else { 3601 // Otherwise put a 0 there 3602 jQuery('input[name=' + fieldName + ']') 3603 .val(1); 3604 jQuery('.qtyminus') 3605 .css('cursor', 'not-allowed'); 3606 liveQtyVal = 1; 3607 } 3608 console.log(liveQtyVal); 3609 3610 jQuery(this) 3611 .parents('footer.modal-footer') 3612 .find('a.submit-fooditem-button') 3613 .attr('data-item-qty', liveQtyVal); 3614 jQuery(this) 3615 .parents('footer.modal__footer') 3616 .find('a.submit-fooditem-button') 3617 .attr('data-item-qty', liveQtyVal); 3618 // Updating live price as per quantity 3619 var total_price = parseFloat(jQuery('#rpressModal .cart-item-price') 3620 .attr('data-current')); 3621 var new_price = parseFloat(total_price * liveQtyVal); 3622 new_price_v = rp_format_currency_value(new_price); 3623 jQuery('#rpressModal .cart-item-price') 3624 .html(new_price_v); 3625 }); 3626 jQuery(document) 3627 .on('click', '.qtyplus', function (e) { 3628 // Stop acting like a button 3629 e.preventDefault(); 3630 // Get the field name 3631 fieldName = 'quantity'; 3632 // Get its current value 3633 var currentVal = parseInt(jQuery('input[name=' + fieldName + ']').val()); 3634 // If is not undefined 3635 if (!isNaN(currentVal)) { 3636 jQuery('input[name=' + fieldName + ']') 3637 .val(currentVal + 1); 3638 jQuery('.qtyminus') 3639 .removeAttr('style'); 3640 liveQtyVal = currentVal + 1; 3641 } else { 3642 // Otherwise put a 0 there 3643 jQuery('input[name=' + fieldName + ']') 3644 .val(1); 3645 liveQtyVal = 1; 3646 } 3647 jQuery(this) 3648 .parents('footer.modal__footer') 3649 .find('a.submit-fooditem-button') 3650 .attr('data-item-qty', liveQtyVal); 3651 jQuery(this) 3652 .parents('footer.modal__footer') 3653 .find('a.submit-fooditem-button') 3654 .attr('data-item-qty', liveQtyVal); 3655 // Updating live price as per quantity 3656 var total_price = parseFloat(jQuery('#rpressModal .cart-item-price') 3657 .attr('data-current')); 3658 var new_price = parseFloat(total_price * liveQtyVal); 3659 new_price_v = rp_format_currency_value(new_price); 3660 jQuery('#rpressModal .cart-item-price') 3661 .html(new_price_v); 3662 }); 3663 jQuery(document) 3664 .on("input", ".qty", function () { 3665 this.value = this.value.replace(/\D/g, ''); 3666 }); 3667 jQuery(document) 3668 .on('keyup', '.qty', function (e) { 3669 // Updating live price as per quantity 3670 liveQtyVal = jQuery(this) 3671 .val(); 3672 var total_price = parseFloat(jQuery('#rpressModal .cart-item-price') 3673 .attr('data-current')); 3674 var new_price = parseFloat(total_price * liveQtyVal); 3675 new_price_v = rp_format_currency_value(new_price); 3676 jQuery('#rpressModal .cart-item-price') 3677 .html(new_price_v); 3678 }); 3679}); 3680jQuery(function ($) { 3681 // Detect whether list or grid is currently visible 3682 function getCurrentViewContainer() { 3683 if ($('.rpress_fooditems_list:visible').length) { 3684 return $('.rpress_fooditems_list'); 3685 } else if ($('.rpress_fooditems_grid:visible').length) { 3686 return $('.rpress_fooditems_grid'); 3687 } else { 3688 return $('.rpress_fooditems_list'); // default fallback 3689 } 3690 } 3691 3692 // Step 1: Add searchable data attribute to all .rpress-title-holder elements (in both views) 3693 $('.rpress-title-holder').each(function () { 3694 $(this).attr('data-search-term', $(this).text().toLowerCase()); 3695 }); 3696 3697 // Step 2: Live search 3698 $('#rpress-food-search').on('keyup', function () { 3699 var searchTerm = $(this).val().toLowerCase(); 3700 var $viewContainer = getCurrentViewContainer(); 3701 var visibleTermIds = []; 3702 3703 // Reset states 3704 $viewContainer.find('.rpress-element-title').removeClass('matched not-matched'); 3705 3706 $viewContainer.find('.rpress_fooditem').each(function () { 3707 var $foodItem = $(this); 3708 var $titleHolder = $foodItem.find('.rpress-title-holder'); 3709 var itemText = $titleHolder.data('search-term') || $titleHolder.text().toLowerCase(); 3710 var termId = $foodItem.attr('data-term-id'); 3711 3712 if (searchTerm === '' || itemText.includes(searchTerm)) { 3713 $foodItem.show(); 3714 visibleTermIds.push(termId); 3715 } else { 3716 $foodItem.hide(); 3717 } 3718 }); 3719 3720 // Show/hide category headings 3721 $viewContainer.find('.rpress-element-title').each(function () { 3722 var termId = $(this).data('term-id'); 3723 if (visibleTermIds.includes(termId.toString())) { 3724 $(this).show().addClass('matched'); 3725 } else { 3726 $(this).hide().addClass('not-matched'); 3727 } 3728 }); 3729 3730 // === CATEGORY NAVIGATION HIDE/SHOW === 3731 $('.rpress-category-lists .rpress-category-link').each(function () { 3732 var termId = $(this).data('id'); 3733 if (visibleTermIds.includes(termId.toString())) { 3734 $(this).parent().show(); 3735 } else { 3736 $(this).parent().hide(); 3737 } 3738 }); 3739 3740 // Dropdown menu in grid view 3741 $('.cd-dropdown-content a[href^="#menu-category-"]').each(function () { 3742 var termId = $(this).attr('href').replace('#menu-category-', ''); 3743 if (visibleTermIds.includes(termId)) { 3744 $(this).closest('li').show(); 3745 } else { 3746 $(this).closest('li').hide(); 3747 } 3748 }); 3749 3750 // Horizontal nav in grid view 3751 $('.pn-ProductNav_Contents .pn-ProductNav_Link').each(function () { 3752 var termId = $(this).attr('href').replace('#menu-category-', ''); 3753 if (visibleTermIds.includes(termId)) { 3754 $(this).show(); 3755 } else { 3756 $(this).hide(); 3757 } 3758 }); 3759 3760 }); 3761}); 3762 3763/* RestroPress active category highlighter */ 3764jQuery(function ($) { 3765 const rp_category_links = $('.rpress-category-lists .rpress-category-link'); 3766 const rp_category_links_grid = $('#pnProductNavContents .pn-ProductNav_Link, #pnProductNavContentsMobile .pn-ProductNav_Link'); 3767 if (rp_category_links.length > 0) { 3768 function rp_apply_list_active_term(termId) { 3769 if (typeof termId === 'undefined' || termId === null || termId === '') { 3770 return; 3771 } 3772 var normalizedId = String(termId); 3773 var $matchedLink = rp_category_links.filter(function () {
3774 return String($(this).data('id') || '') === normalizedId; 3775 }).first(); 3776 3777 if (!$matchedLink.length) { 3778 return; 3779 } 3780 3781 rp_category_links.removeClass('active'); 3782 $matchedLink.addClass('active'); 3783 3784 rp_category_links.parent().removeClass('current'); 3785 $matchedLink.parent().addClass('current'); 3786 } 3787 3788 function rp_detect_active_term_from_scroll() { 3789 var anchorLine = rp_get_dynamic_scroll_offset() + 2; 3790 var activeTermId = ''; 3791 var firstVisibleTermId = ''; 3792 3793 $('.rpress-element-title[id^="menu-category-"]:visible').each(function () { 3794 var $heading = $(this); 3795 var termId = String($heading.data('term-id') || '').trim(); 3796 if (!termId) { 3797 var fallbackId = String($heading.attr('id') || '').replace('menu-category-', ''); 3798 termId = fallbackId.trim(); 3799 } 3800 if (!termId) { 3801 return; 3802 } 3803 3804 var top = this.getBoundingClientRect().top; 3805 if (!firstVisibleTermId && top > -120) { 3806 firstVisibleTermId = termId; 3807 } 3808 if (top <= anchorLine) { 3809 activeTermId = termId; 3810 } 3811 }); 3812 3813 return activeTermId || firstVisibleTermId || ''; 3814 } 3815 3816 var rp_update_list_active_on_scroll = function () { 3817 rp_apply_list_active_term(rp_detect_active_term_from_scroll()); 3818 }; 3819 3820 // Immediate visual selection for clicked list categories. 3821 $('body') 3822 .off('click.rpListActive', '.rpress-category-lists .rpress-category-link') 3823 .on('click.rpListActive', '.rpress-category-lists .rpress-category-link', function () {
3824 rp_apply_list_active_term($(this).data('id')); 3825 }); 3826 3827 rp_update_list_active_on_scroll(); 3828 window.addEventListener('scroll', rp_update_list_active_on_scroll, { passive: true }); 3829 window.addEventListener('resize', rp_update_list_active_on_scroll); 3830 } 3831 3832 if (rp_category_links_grid.length > 0) { 3833 const header_height = $('header:eq(0)').height(); 3834 // Drive BOTH the desktop and mobile category navs (identical markup, different 3835 // IDs). Previously only the desktop nav was wired, so on mobile the active 3836 // category never highlighted or moved its indicator on scroll. 3837 const navGroups = [ 3838 { $nav: $('#pnProductNav'), $contents: $('#pnProductNavContents'), $indicator: $('#pnIndicator') }, 3839 { $nav: $('#pnProductNavMobile'), $contents: $('#pnProductNavContentsMobile'), $indicator: $('#pnIndicatorMobile') } 3840 ].filter(function (g) { return g.$contents.length; }); 3841 let current_category = rp_category_links_grid.eq(0).attr('href').substr(1); 3842 3843 navGroups.forEach(function (g) { 3844 if (g.$contents.css('position') === 'static') { 3845 g.$contents.css('position', 'relative'); 3846 } 3847 }); 3848 3849 function rpNavGroupVisible(g) { 3850 return g.$contents.length && g.$contents.is(':visible') && g.$contents[0].getBoundingClientRect().width > 0; 3851 } 3852 3853 // ---- helper: position one group's indicator under its active link ---- 3854 function moveIndicatorInGroup(g, $link) { 3855 if (!$link || !$link.length || !g.$indicator.length) return; 3856 const linkRect = $link[0].getBoundingClientRect(); 3857 const contentsRect = g.$contents[0].getBoundingClientRect(); 3858 const left = Math.round(linkRect.left - contentsRect.left + (g.$contents.scrollLeft() || 0)); 3859 const width = Math.round(linkRect.width); 3860 g.$indicator.css({ width: width + 'px', transform: 'translateX(' + left + 'px)' }); 3861 scrollActiveIntoView(g, $link); 3862 } 3863 3864 // ---- move the indicator under the active category in every VISIBLE nav ---- 3865 function moveIndicatorTo(category) { 3866 navGroups.forEach(function (g) { 3867 if (!rpNavGroupVisible(g)) return; // skip the hidden nav (e.g. mobile on desktop) 3868 const $link = g.$contents.find('.pn-ProductNav_Link').filter('[href="#' + category + '"]'); 3869 if ($link.length) moveIndicatorInGroup(g, $link); 3870 }); 3871 } 3872 3873 // ---- helper: scroll a group's scroller so the link is visible/centered ---- 3874 function scrollActiveIntoView(g, $link) { 3875 if (!$link || !$link.length) return; 3876 3877 // Choose real scroller (outer nav) - fallback to contents if outer missing 3878 const $scroller = g.$nav.length ? g.$nav : g.$contents; 3879 if (!$scroller.length) return; 3880 3881 const scrollerEl = $scroller[0]; 3882 const maxScroll = scrollerEl.scrollWidth - scrollerEl.clientWidth; 3883 3884 const linkRect = $link[0].getBoundingClientRect(); 3885 const scrollerRect = scrollerEl.getBoundingClientRect(); 3886 3887 // Current scrollLeft 3888 const currentScroll = $scroller.scrollLeft(); 3889 3890 // left of link relative to scrollable content coordinates: 3891 // (element left on screen - scroller left on screen) + currentScroll 3892 let leftRelativeToScroller = linkRect.left - scrollerRect.left + currentScroll; 3893 3894 // center the link 3895 let desired = leftRelativeToScroller - (scrollerEl.clientWidth / 2) + ($link.outerWidth() / 2); 3896 3897 // clamp 3898 desired = Math.max(0, Math.min(desired, maxScroll)); 3899 3900 // If the inner contents currently has a transform (arrow animation in progress), 3901 // animated scrollLeft may behave unexpectedly. In that case use scrollIntoView fallback: 3902 const contentsTransform = getComputedStyle(g.$contents[0]).transform; 3903 if (contentsTransform && contentsTransform !== 'none') { 3904 // fallback - ask the browser to scroll the nearest scrollable ancestor 3905 try { 3906 $link[0].scrollIntoView({ behavior: 'smooth', inline: 'center', block: 'nearest' }); 3907 return; 3908 } catch (e) { 3909 // if not supported, continue to jQuery animate fallback 3910 } 3911 } 3912 3913 // animate scrollLeft (smooth) 3914 $scroller.stop().animate({ scrollLeft: desired }, 350); 3915 } 3916 3917 // ---- main scanning function (updates current_category + classes) ---- 3918 function RpScrollingCategoriesgrid() { 3919 // determine current category based on section positions 3920 rp_category_links_grid.each(function () { 3921 const section_id = $(this).attr('href').substr(1); 3922 const section = document.getElementById(section_id); 3923 if (section && section.getBoundingClientRect().top < header_height + 40) { 3924 current_category = section_id; 3925 } 3926 }); 3927 3928 // Update active link classes/aria 3929 const $activeLink = rp_category_links_grid 3930 .removeAttr('aria-selected').removeClass('mnuactive') 3931 .filter(`[href="#${current_category}"]`) 3932 .attr('aria-selected', 'true').addClass('mnuactive'); 3933 3934 // Move indicator + ensure visible (in every visible nav) 3935 if ($activeLink.length) { 3936 moveIndicatorTo(current_category); 3937 } 3938 3939 // Sync the dropdown menu 3940 $(".cd-dropdown-content a") 3941 .removeClass("mnuactive") 3942 .filter(`[href="#${current_category}"]`) 3943 .addClass("mnuactive"); 3944 } 3945 3946 // Run once on load 3947 RpScrollingCategoriesgrid(); 3948 3949 // Update on page scroll / resize (throttle-friendly native listeners) 3950 window.addEventListener('scroll', RpScrollingCategoriesgrid, { passive: true }); 3951 window.addEventListener('resize', RpScrollingCategoriesgrid); 3952 3953 // Utility to get current section in view (used elsewhere) 3954 function getCurrentCategoryInView() { 3955 let scrollTop = $(window).scrollTop(); 3956 let current = null; 3957 3958 $(".rpress-category-lists .rpress-category-wrap").each(function () { 3959 if ($(this).offset().top <= scrollTop + 100) { 3960 current = $(this).attr("id"); 3961 } 3962 }); 3963 3964 return current; 3965 } 3966 3967 // On window scroll (content scroll, not nav scroll) âââ‰â¬Â keep dropdown and indicator in sync 3968 $(window).on("scroll", function () { 3969 let current = getCurrentCategoryInView(); 3970 if (!current) return; 3971 3972 const $active = rp_category_links_grid.filter(`[href="#${current}"]`); 3973 if ($active.length) { 3974 moveIndicatorTo(current); 3975 3976 // Sync dropdown 3977 const activeHref = $active.attr("href"); 3978 $(".cd-dropdown-content a").removeClass("mnuactive"); 3979 $(`.cd-dropdown-content a[href="${activeHref}"]`).addClass("mnuactive"); 3980 } 3981 }); 3982 3983 // Nav link click instant feedback 3984 $(document).on("click", ".pn-ProductNav_Link", function (e) { 3985 const $this = $(this); 3986 // Move indicator & scroll into view immediately (in every visible nav) 3987 moveIndicatorTo($this.attr("href").substr(1)); 3988 3989 // Sync dropdown 3990 const activeHref = $this.attr("href"); 3991 $(".cd-dropdown-content a").removeClass("mnuactive"); 3992 $(`.cd-dropdown-content a[href="${activeHref}"]`).addClass("mnuactive"); 3993 }); 3994 3995 } 3996 3997 $(document) 3998 .ready(function () { 3999 var getActiveServiceTimeSelect = (typeof window.rp_get_active_service_time_select === 'function') 4000 ? window.rp_get_active_service_time_select 4001 : function ($scope, preferredServiceType) { 4002 var $root = ($scope && $scope.length) ? $scope : $(document); 4003 var serviceType = (preferredServiceType || '').toLowerCase(); 4004 var $select = $(); 4005 4006 if (serviceType) { 4007 $select = $root.find('.delivery-settings-wrapper#nav-' + serviceType + ' .rpress-hrs').first(); 4008 if ($select.length) { 4009 return $select; 4010 } 4011 } 4012 4013 $select = $root.find('.delivery-settings-wrapper.active .rpress-hrs').first(); 4014 if ($select.length) { 4015 return $select; 4016 } 4017 4018 return $root.find('#rpress-delivery-hours, .rpress-hrs').first(); 4019 }; 4020 4021 var restoreServiceTimeSelect = (typeof window.rp_restore_service_time_select === 'function') 4022 ? window.rp_restore_service_time_select 4023 : function ($select, serviceTime) { 4024 if (!$select || !$select.length) { 4025 return ''; 4026 } 4027 4028 var requestedTime = (serviceTime || '').trim(); 4029 var selectedValue = ''; 4030 4031 if (requestedTime && $select.find('option[value="' + requestedTime + '"]').length) { 4032 selectedValue = requestedTime; 4033 } else if (requestedTime) { 4034 var $matchingOption = $select.find('option').filter(function () { 4035 return $(this).text().trim() === requestedTime; 4036 }).first(); 4037 if ($matchingOption.length) { 4038 selectedValue = $matchingOption.val(); 4039 } 4040 } 4041 4042 if (!selectedValue) { 4043 var $firstSelectableOption = $select.find('option').filter(function () { 4044 var optionValue = ($(this).val() || '').toString().trim(); 4045 return optionValue !== '' && !$(this).prop('disabled'); 4046 }).first(); 4047 if (!$firstSelectableOption.length) { 4048 $firstSelectableOption = $select.find('option').first(); 4049 } 4050 selectedValue = $firstSelectableOption.val() || ''; 4051 } 4052 4053 if (selectedValue) { 4054 $select.val(selectedValue); 4055 } 4056 4057 return selectedValue; 4058 }; 4059 var applyServiceDefaults = (typeof window.rp_apply_service_defaults === 'function') 4060 ? window.rp_apply_service_defaults 4061 : null; 4062 4063 var checkoutUpdateInFlight = false;
4064 var lastCheckoutServiceType = ''; 4065 var checkoutServiceTabSelector = '#rpress_checkout_wrap .single-service-selected, .rp-checkout-service-option .single-service-selected, #rpress_checkout_order_details .rpress-delivery-options .single-service-selected, .rpress-delivery-options .single-service-selected, #rpressdeliveryTab .single-service-selected'; 4066 var checkoutServiceTimeSelector = '#rpress_checkout_wrap .rpress-hrs, .rp-checkout-service-option .rpress-hrs, #rpress_checkout_order_details .rpress-delivery-options .rpress-hrs, .rpress-hrs'; 4067 var getCheckoutServiceScope = function () { 4068 var $scope = $('.rp-checkout-service-option').first(); 4069 if ($scope.length) { 4070 return $scope; 4071 } 4072 4073 $scope = $('#rpress_checkout_order_details .rpress-delivery-options .rpress-tabs-wrapper').first(); 4074 if ($scope.length) { 4075 return $scope; 4076 } 4077 4078 $scope = $('#rpress_checkout_order_details .rpress-tabs-wrapper').first(); 4079 if ($scope.length) { 4080 return $scope; 4081 } 4082 4083 $scope = $('#rpress_checkout_wrap .rpress-delivery-options .rpress-tabs-wrapper').first(); 4084 if ($scope.length) { 4085 return $scope; 4086 } 4087 4088 $scope = $('.rpress-delivery-wrap .rpress-tabs-wrapper').first(); 4089 if ($scope.length) { 4090 return $scope; 4091 } 4092 4093 return $('#rpress_checkout_wrap').first(); 4094 }; 4095 var findCheckoutServiceTab = function (serviceType) { 4096 serviceType = (serviceType || '').toLowerCase(); 4097 if (!serviceType) { 4098 return $(); 4099 } 4100 4101 var $scope = getCheckoutServiceScope(); 4102 if (!$scope.length) { 4103 return $(); 4104 } 4105 4106 return $scope.find('#rpressdeliveryTab .single-service-selected[data-service-type="' + serviceType + '"]') 4107 .first(); 4108 }; 4109 var syncCheckoutServiceTabs = function (serviceType) { 4110 serviceType = (serviceType || '').toLowerCase(); 4111 if (!serviceType) { 4112 return; 4113 } 4114 4115 var $activeServiceTab = findCheckoutServiceTab(serviceType); 4116 if (!$activeServiceTab.length) { 4117 return; 4118 } 4119 4120 var $wrapper = $activeServiceTab.closest('.rpress-tabs-wrapper'); 4121 $wrapper.find('#rpressdeliveryTab .nav-item').removeClass('active'); 4122 $wrapper.find('#rpressdeliveryTab .single-service-selected') 4123 .removeClass('active') 4124 .attr('aria-selected', 'false'); 4125 4126 $activeServiceTab 4127 .addClass('active') 4128 .attr('aria-selected', 'true'); 4129 $activeServiceTab.closest('.nav-item').addClass('active'); 4130 4131 var targetTab = $activeServiceTab.attr('href'); 4132 if (targetTab && targetTab.charAt(0) === '#') { 4133 $wrapper.find('.delivery-settings-wrapper').removeClass('active show'); 4134 $wrapper.find(targetTab).addClass('active show'); 4135 } 4136 4137 var checkoutServiceLabel = ($activeServiceTab.find('.rpress-service-tab-label').first().text() || $activeServiceTab.text() || '') 4138 .toString() 4139 .trim(); 4140 var $checkoutServiceHeading = $wrapper.find('.rpress-checkout-service-heading').first(); 4141 if ($checkoutServiceHeading.length) { 4142 $checkoutServiceHeading 4143 .removeClass('is-service-delivery is-service-pickup') 4144 .addClass('is-service-' + serviceType); 4145 if (checkoutServiceLabel) { 4146 $checkoutServiceHeading.find('.rpress-checkout-service-heading-text') 4147 .text(checkoutServiceLabel); 4148 } 4149 } 4150 }; 4151 4152 var refreshCheckoutServiceOption = async function () { 4153 if ($('#rpress_checkout_order_details').length === 0) { 4154 return; 4155 } 4156 4157 if (!rp_scripts.update_service_nonce) { 4158 return; 4159 } 4160 4161 if (checkoutUpdateInFlight) { 4162 return; 4163 } 4164 4165 checkoutUpdateInFlight = true; 4166 $('#rpress_checkout_order_details') 4167 .addClass('rp-loading'); 4168 4169 try { 4170 const requestBody = new URLSearchParams(); 4171 requestBody.set('action', 'rpress_checkout_update_service_option'); 4172 requestBody.set('security', rp_scripts.update_service_nonce); 4173 4174 const promiseData = await fetch(rp_scripts.ajaxurl, { 4175 method: 'POST', 4176 credentials: 'same-origin', 4177 headers: { 4178 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8' 4179 }, 4180 body: requestBody.toString() 4181 }); 4182 if (!promiseData.ok) { 4183 throw new Error('Checkout refresh request failed'); 4184 } 4185 4186 const html = await promiseData.json(); 4187 if (!html || !html.success || !html.data) { 4188 throw new Error('Invalid checkout refresh payload'); 4189 } 4190 4191 $('#rpress_checkout_order_details') 4192 .replaceWith(html.data['order_html']); 4193 $('#rpress_checkout_cart_wrap') 4194 .html(html.data['cart_html']); 4195 $('.rpress_cart_amount') 4196 .replaceWith(html.data['total_amount']); 4197 var restoredServiceType = rp_getCookie('service_type') || lastCheckoutServiceType; 4198 syncCheckoutServiceTabs(restoredServiceType); 4199 var $checkoutScope = getCheckoutServiceScope();
4200 if (applyServiceDefaults) { 4201 applyServiceDefaults($checkoutScope.length ? $checkoutScope : $(document), restoredServiceType); 4202 } else { 4203 var $activeTimeSelect = getActiveServiceTimeSelect($checkoutScope, restoredServiceType); 4204 restoreServiceTimeSelect($activeTimeSelect, rp_getCookie('service_time')); 4205 } 4206 $(document.body) 4207 .trigger('rp-checkout-update-service-option', [html]); 4208 } catch (e) { 4209 // Skip transient checkout refresh failures. 4210 } finally { 4211 checkoutUpdateInFlight = false; 4212 $('#rpress_checkout_order_details') 4213 .removeClass('rp-loading'); 4214 } 4215 }; 4216 4217 // Infinate scroll for order history page 4218 createObserver(); 4219 //Select service type on checkout page 4220 let chkServiceType = (rp_getCookie('service_type') || '') 4221 .toLowerCase(); 4222 if (!chkServiceType) { 4223 var $initialCheckoutScope = getCheckoutServiceScope(); 4224 chkServiceType = ($initialCheckoutScope.find('#rpressdeliveryTab .single-service-selected.active') 4225 .first() 4226 .data('service-type') || '') 4227 .toLowerCase(); 4228 if (chkServiceType) { 4229 rp_setCookie('service_type', chkServiceType, rp_scripts.expire_cookie_time); 4230 } 4231 } 4232 if (chkServiceType) { 4233 syncCheckoutServiceTabs(chkServiceType); 4234 const $serviceTab = findCheckoutServiceTab(chkServiceType); 4235 lastCheckoutServiceType = chkServiceType; 4236 if ($serviceTab.length) { 4237 var $checkoutScope = getCheckoutServiceScope(); 4238 if (applyServiceDefaults) { 4239 applyServiceDefaults($checkoutScope.length ? $checkoutScope : $(document), chkServiceType); 4240 } else { 4241 var $activeTimeSelect = getActiveServiceTimeSelect($checkoutScope, chkServiceType); 4242 restoreServiceTimeSelect($activeTimeSelect, rp_getCookie('service_time')); 4243 } 4244 } 4245 } 4246 $(document) 4247 .off('click.rpressCheckoutService', checkoutServiceTabSelector) 4248 .on('click.rpressCheckoutService', checkoutServiceTabSelector, async function (event) { 4249 const $clickedTab = $(this); 4250 if (!$clickedTab.closest('#rpress_checkout_wrap, .rp-checkout-service-option, #rpress_checkout_order_details, .rpress-delivery-wrap, .rpress-tabs-wrapper, .rpress-delivery-options, #rpressdeliveryTab, #rpressDateTime').length) { 4251 return; 4252 } 4253 4254 event.preventDefault(); 4255 const serviceType_ = String($clickedTab 4256 .data('service-type') || '') 4257 .toLowerCase(); 4258 4259 if (!serviceType_) { 4260 return; 4261 } 4262 4263 if (serviceType_ === lastCheckoutServiceType && $('#rpress_checkout_order_details').length > 0) { 4264 return; 4265 } 4266 4267 lastCheckoutServiceType = serviceType_; 4268 syncCheckoutServiceTabs(serviceType_); 4269 rp_setCookie('service_type', serviceType_, rp_scripts.expire_cookie_time); 4270 var $checkoutScope = getCheckoutServiceScope(); 4271 if (applyServiceDefaults) { 4272 applyServiceDefaults($checkoutScope.length ? $checkoutScope : $(document), serviceType_); 4273 } else { 4274 var $activeTimeSelect = getActiveServiceTimeSelect($checkoutScope, serviceType_); 4275 if ($activeTimeSelect.length) { 4276 var selectedTime = $activeTimeSelect.val() || ''; 4277 var selectedTimeText = $activeTimeSelect.find('option:selected') 4278 .text() 4279 .trim(); 4280 if (selectedTime) { 4281 rp_setCookie('service_time', selectedTime, rp_scripts.expire_cookie_time); 4282 } 4283 if (selectedTimeText) { 4284 rp_setCookie('service_time_text', selectedTimeText, rp_scripts.expire_cookie_time); 4285 } 4286 } 4287 } 4288 await refreshCheckoutServiceOption(); 4289 }); 4290 //set cookies on checkout page onchange service type 4291 $(document) 4292 .off('change.rpressCheckoutServiceTime', checkoutServiceTimeSelector) 4293 .on('change.rpressCheckoutServiceTime', checkoutServiceTimeSelector, function (event) { 4294 if (!$(this).closest('#rpress_checkout_wrap, .rp-checkout-service-option, #rpress_checkout_order_details, .rpress-delivery-wrap, .rpress-tabs-wrapper, .rpress-delivery-options, #rpressdeliveryTab, #rpressDateTime').length) { 4295 return; 4296 } 4297 4298 if (!event.originalEvent) { 4299 return; 4300 } 4301 var $checkoutScope = getCheckoutServiceScope(); 4302 $checkoutScope.find('.rpress-delivery-opt-update') 4303 .first() 4304 .trigger('click'); 4305 }); 4306 $(document.body) 4307 .off('rp-refresh-checkout-service.rpress') 4308 .on('rp-refresh-checkout-service.rpress', function () { 4309 refreshCheckoutServiceOption(); 4310 }); 4311 $(document.body) 4312 .off('rpress_checkout_error.rpressScroll') 4313 .on('rpress_checkout_error.rpressScroll', function () { 4314 setTimeout(function () { 4315 var $errors = $('.rpress_errors:visible, .rpress-errors-wrap:visible, .rpress-alert-error:visible, .rpress-error:visible').first(); 4316 if ($errors.length) { 4317 var targetTop = Math.max(0, $errors.offset().top - 120); 4318 $('html, body').stop().animate({ scrollTop: targetTop }, 400); 4319 } 4320 }, 50); 4321 }); 4322 //Remove the additional service date dropdown 4323 if (typeof rp_st_vars !== 'undefined' && rp_st_vars.enabled_sevice_type == 'delivery_and_pickup') { 4324 $('.delivery-settings-wrapper#nav-pickup .delivery-time-wrapper:eq(0)') 4325 .remove(); 4326 } 4327 var selectedServiceType = chkServiceType || rp_getCookie('service_type'); 4328 var $checkoutScope = getCheckoutServiceScope();
4329 if (applyServiceDefaults) { 4330 applyServiceDefaults($checkoutScope.length ? $checkoutScope : $(document), selectedServiceType); 4331 } else { 4332 var serviceTime = rp_getCookie('service_time'); 4333 if (serviceTime) { 4334 var $activeTimeSelect = getActiveServiceTimeSelect($checkoutScope, selectedServiceType); 4335 restoreServiceTimeSelect($activeTimeSelect, serviceTime); 4336 } 4337 } 4338 }) 4339 4340 var rpressClearingFees = false; 4341 $(document).on('click', 'a.rpress_cart_remove_item_btn', function (e) { 4342 var btnCount = $('.rpress_cart_remove_item_btn').length; 4343 4344 // Check if there's only one element 4345 if (btnCount === 1 && !rpressClearingFees) { 4346 e.preventDefault(); 4347 e.stopImmediatePropagation(); 4348 var $btn = $(this); 4349 rpressClearingFees = true; 4350 4351 var postData = { 4352 action: 'rpress_remove_fees_after_empty_cart', 4353 security: rp_scripts.clear_cart_nonce, 4354 gateway: rpress_gateway 4355 }; 4356 4357 $.ajax({ 4358 type: "POST", 4359 data: postData, 4360 dataType: "json", 4361 url: rpress_global_vars.ajaxurl, 4362 success: function (response) { 4363 // Trigger a click event on the same button 4364 $btn.click(); 4365 } 4366 }).fail(function (data) { 4367 rpressClearingFees = false; 4368 }); 4369 } 4370 }); 4371 // 4372}); 4373let page = 1; 4374let rpressOrderHistoryLoading = false; 4375const infinateCallback = async function (entries, observer) { 4376 for (var i = 0; i < entries.length; i++) {
4377 let cahnge = entries[i]; 4378 if (cahnge.isIntersecting && !rpressOrderHistoryLoading) { 4379 rpressOrderHistoryLoading = true; 4380 const $loadContainer = jQuery('#rp-order-history-infi-load-container'); 4381 $loadContainer 4382 .html('<h2 class="rp-infi-load"><div class="rp-infi-loading">Loading...</div></h2>'); 4383 page = page + 1; 4384 try { 4385 const data = await fetch(`${rp_scripts.ajaxurl}?action=rpress_more_order_history&security=${rp_scripts.order_details_nonce}&paged=${page}`); 4386 const html = await data.json(); 4387 const responseData = html && html.data ? html.data : {}; 4388 const $historyGrid = jQuery('#rpress_user_history .rpress-order-history-grid, #rpress_user_history .repress-history-inner') 4389 .first(); 4390 if (responseData.html && $historyGrid.length) { 4391 $historyGrid.append(responseData.html); 4392 } 4393 if (String(responseData.found_post || '0') === '0') { 4394 $loadContainer.hide(); 4395 observer.unobserve(cahnge.target); 4396 } else { 4397 $loadContainer.empty(); 4398 } 4399 } catch (error) { 4400 page = Math.max(1, page - 1); 4401 $loadContainer.empty(); 4402 if (window.console && window.console.log) { 4403 console.log(error); 4404 } 4405 } finally { 4406 rpressOrderHistoryLoading = false; 4407 } 4408 } 4409 } 4410} 4411const createObserver = () => { 4412 const options = { 4413 threshold: 0, 4414 } 4415 const lastDiv = document.getElementById('rp-order-history-infi-load-container'); 4416 if (!lastDiv) return; 4417 const observer = new IntersectionObserver(infinateCallback, options); 4418 observer.observe(lastDiv) 4419} 4420// Refresh page after coming from prev page 4421if (performance.navigation.type == 2) { 4422 var navReloadKey = 'rpress_nav_reloaded'; 4423 if (!window.sessionStorage.getItem(navReloadKey)) { 4424 window.sessionStorage.setItem(navReloadKey, '1'); 4425 location.reload(true); 4426 } 4427} else { 4428 window.sessionStorage.removeItem('rpress_nav_reloaded'); 4429} 4430jQuery('.rpress_fooditems_list').find('.rpress_fooditem_inner').each(function (index, item) { 4431 if (0 === jQuery(this).find('.rpress-thumbnail-holder').length) { 4432 jQuery(this).addClass('no-thumbnail-img'); 4433 } 4434}); 4435jQuery(document).ready(function ($) { 4436 $(document).on('change', '.rp-variable-price-option', function () { 4437 rp_checked_default_subaddon(); 4438 }); 4439}); 4440 4441jQuery(document).ready(function ($) { 4442 function rp_get_mobile_cart_quantity_from_dom() { 4443 var selectors = [ 4444 '.rp-mb-quantity', 4445 '.rpress-cart-head-count .rpress-cart-quantity', 4446 'span.rpress-cart-quantity' 4447 ]; 4448 4449 for (var i = 0; i < selectors.length; i++) { 4450 var rawValue = $(selectors[i]).first().text(); 4451 if (!rawValue) { 4452 continue; 4453 } 4454 4455 var parsedValue = parseInt(String(rawValue).replace(/[^0-9-]/g, ''), 10); 4456 if (!isNaN(parsedValue) && parsedValue >= 0) { 4457 return parsedValue; 4458 } 4459 } 4460 4461 var cartItemCount = $('ul.rpress-cart > li.rpress-cart-item').length; 4462 return cartItemCount > 0 ? cartItemCount : 0; 4463 } 4464 4465 function rp_sync_mobile_cart_bar_state() { 4466 var $mobileCartBar = $('.rpress-mobile-cart-icons'); 4467 var $actionMenuContainer = $('.container-actionmenu'); 4468 var $mobileCartDrawer = $('.rpress-sidebar-main-wrap'); 4469 4470 if (!$mobileCartBar.length && !$actionMenuContainer.length) { 4471 return; 4472 } 4473 4474 var quantity = rp_get_mobile_cart_quantity_from_dom(); 4475 var hasItems = quantity > 0; 4476 var isTransientlyHidden = $('body').hasClass('rp-mobile-cart-open') || 4477 $('body').hasClass('cd-overlay-open') || 4478 $('.cd-dropdown').hasClass('dropdown-is-active') || 4479 $('#rpressDateTime.is-open, #rpressModal.is-open, #rpressDateTime[aria-hidden="false"], #rpressModal[aria-hidden="false"]').length > 0; 4480 4481 if ($mobileCartBar.length) { 4482 if (!hasItems) { 4483 $mobileCartDrawer 4484 .css('left', '100%') 4485 .removeClass('rp-cart-drawer-open'); 4486 $('body').removeClass('rp-mobile-cart-open'); 4487 $mobileCartBar.hide(); 4488 } else if (!isTransientlyHidden) { 4489 $mobileCartBar.css('display', 'flex'); 4490 } 4491 } 4492 4493 $actionMenuContainer.toggleClass('cart-has-items', hasItems); 4494 } 4495 4496 rp_sync_mobile_cart_bar_state(); 4497 setTimeout(rp_sync_mobile_cart_bar_state, 120); 4498 $(window).on('load pageshow resize', rp_sync_mobile_cart_bar_state); 4499 $(document.body).on('rpress_items_updated rpress_quantity_updated rpress_cart_item_removed rpress_checked_slots', function () { 4500 setTimeout(rp_sync_mobile_cart_bar_state, 20); 4501 }); 4502 4503 $(document.body).on('rpress_cart_item_removed', function (event, response) { 4504 var isCheckout = false;
4505 if (typeof rp_scripts !== 'undefined' && rp_scripts.is_checkout === '1') { 4506 isCheckout = true; 4507 } else if (typeof rpress_scripts !== 'undefined' && rpress_scripts.is_checkout === '1') { 4508 isCheckout = true; 4509 } 4510 4511 if (isCheckout) { 4512 if (response && response.cart_quantity == 0) { 4513 var pleaseWaitText = (typeof rp_scripts !== 'undefined' && rp_scripts.please_wait) ? rp_scripts.please_wait : 'Please Wait...'; 4514 $('#rpress_checkout_wrap').html('<div class="rpress-empty-cart-loading" style="text-align:center; padding: 50px 0;"><div class="rpress-loading-spinner" style="border: 4px solid rgba(0,0,0,.1); width: 36px; height: 36px; border-radius: 50%; border-left-color: #ED5575; animation: spin 1s linear infinite; margin: 0 auto 15px auto;"></div><p>' + pleaseWaitText + '</p></div>'); 4515 if (!$('#rpress-spinner-style').length) { 4516 $('head').append('<style id="rpress-spinner-style">@keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } }</style>'); 4517 } 4518 window.location.reload(); 4519 } else { 4520 $(document.body).trigger('rp-refresh-checkout-service.rpress'); 4521 } 4522 } 4523 }); 4524 4525 // Handle tab switching and cookie update on service tab click 4526 $(document) 4527 .off('click.rpressServiceTabs', '.rpress-tabs-wrapper .nav-link') 4528 .on('click.rpressServiceTabs', '.rpress-tabs-wrapper .nav-link', function (e) { 4529 var $this = $(this); 4530 var $wrapper = $this.closest('.rpress-tabs-wrapper'); 4531 4532 // Checkout has a dedicated service-switch flow; skip the generic tab updater here. 4533 if ($wrapper.closest('.rp-checkout-service-option, #rpress_checkout_order_details').length) { 4534 return; 4535 } 4536 4537 e.preventDefault(); 4538 4539 // Remove active class from all nav-items and nav-links 4540 $wrapper.find('.nav-item').removeClass('active'); 4541 $wrapper.find('.nav-link').removeClass('active'); 4542 4543 // Add active class to clicked tab 4544 $this.addClass('active'); 4545 $this.closest('.nav-item').addClass('active'); 4546 4547 // Show the tab content if needed 4548 var targetTab = $this.attr('href'); 4549 if (targetTab) { 4550 var $targetPane = $wrapper.closest('.rpress-time-preference-wrap, .rpress-delivery-wrap, .rp-checkout-service-option, #rpress_checkout_order_details') 4551 .find(targetTab) 4552 .first(); 4553 4554 if (!$targetPane.length) { 4555 $targetPane = $(targetTab).first(); 4556 } 4557 4558 if ($targetPane.length) { 4559 var $tabContent = $targetPane.closest('.tab-content'); 4560 if ($tabContent.length) { 4561 $tabContent.find('.tab-pane').removeClass('active show'); 4562 } else { 4563 $wrapper.find('.tab-pane').removeClass('active show'); 4564 } 4565 $targetPane.addClass('active show'); 4566 } 4567 } 4568 4569 // Update cookies for service type and label 4570 var serviceType = String($this.data('service-type') || '') 4571 .toLowerCase(); 4572 var serviceLabel = $this.text().trim(); 4573 var oldUiUxEnabled = (typeof window.rp_is_old_ui_ux_enabled === 'function') && window.rp_is_old_ui_ux_enabled(); 4574 if (serviceType) { 4575 rp_setCookie('service_type', serviceType, rp_scripts.expire_cookie_time); 4576 var $dateTimeModal = $('#rpressDateTime'); 4577 var isDateTimeModalOpen = $dateTimeModal.length && 4578 ($dateTimeModal.hasClass('is-open') || $dateTimeModal.attr('aria-hidden') === 'false'); 4579 4580 updataModalOnServiceTypeChange(serviceType); 4581 if (oldUiUxEnabled) { 4582 if (typeof window.rp_prepare_old_ui_modal_selection === 'function') { 4583 window.rp_prepare_old_ui_modal_selection($wrapper.length ? $wrapper : $(document)); 4584 } 4585 } else if (typeof window.rp_apply_service_defaults === 'function') { 4586 window.rp_apply_service_defaults($wrapper.length ? $wrapper : $(document), serviceType); 4587 } 4588 } 4589 if (typeof Cookies !== 'undefined') { 4590 Cookies.set('service_label', serviceLabel, { expires: 1 }); 4591 } 4592 4593 // Optionally update UI somewhere else if needed 4594 $('.delivery-opts').html('<span class="delMethod">' + serviceLabel + '</span>'); 4595 }); 4596 4597 /** 4598 * Fire a ajax call to update the modal 4599 * on change of service type 4600 * @author RestroPress 4601 * @param {string} service_type 4602 */ 4603 var rpModalSwitchRequestSeq = 0; 4604 const updataModalOnServiceTypeChange = function (service_type) { 4605 var requestedServiceType = String(service_type || '') 4606 .toLowerCase(); 4607 var requestSeq = ++rpModalSwitchRequestSeq; 4608 4609 $.get(`${rp_scripts.ajaxurl}?action=rpress_update_modal_on_service_switch&service_type=${service_type}&security=${rp_scripts.service_type_nonce}`, function (res) { 4610 // Ignore stale out-of-order responses from earlier service switches. 4611 if (requestSeq !== rpModalSwitchRequestSeq) { 4612 return; 4613 } 4614 4615 if (res && res.success && res.data.modal_html && res.data.time_option_html) { 4616 rp_setCookie('service_type', requestedServiceType, rp_scripts.expire_cookie_time); 4617 4618 var $existingDateTimeModal = $("#rpressDateTime"); 4619 var wasDateTimeModalOpen = $existingDateTimeModal.length && 4620 ($existingDateTimeModal.hasClass('is-open') || $existingDateTimeModal.attr('aria-hidden') === 'false'); 4621 4622 if (wasDateTimeModalOpen) { 4623 var $newModal = $(res.data.modal_html); 4624 var $newContainer = $newModal.find('.modal__container'); 4625 if ($newContainer.length) { 4626 $("#rpressDateTime .modal__container").html($newContainer.html()); 4627 } 4628 } else { 4629 $("#rpressDateTime").replaceWith(res.data.modal_html); 4630 } 4631 4632 $(".rpress-option-col.rpress-edit-address-wrap").html( 4633 `<span class="left-brdr"></span>${res.data.time_option_html}` 4634 ); 4635 4636 if (typeof window.rp_prepare_old_ui_modal_selection === 'function') { 4637 window.rp_prepare_old_ui_modal_selection($('#rpressDateTime-content')); 4638 } 4639 if (typeof window.rp_apply_service_defaults === 'function') { 4640 var oldUiUxEnabled = (typeof window.rp_is_old_ui_ux_enabled === 'function') && window.rp_is_old_ui_ux_enabled(); 4641 var selection = window.rp_apply_service_defaults( 4642 $('#rpressDateTime-content'), 4643 requestedServiceType, 4644 !oldUiUxEnabled, 4645 oldUiUxEnabled 4646 ); 4647 if (selection && selection.serviceDateText) { 4648 $("#deliveryDate").text(selection.serviceDateText); 4649 } 4650 if (selection && selection.serviceTimeText) { 4651 $("#deliveryTime").text(selection.serviceTimeText); 4652 } 4653 } 4654 4655 } 4656 }); 4657 }; 4658}); 4659 4660/* Global cross-page order status watcher for browser notifications */ 4661(function (window) { 4662 "use strict"; 4663 4664 if (typeof window.rp_scripts === "undefined" || !window.fetch || !window.URLSearchParams) { 4665 return; 4666 } 4667 4668 var STORAGE_KEY = "rpress_live_order_tracker_v1"; 4669 var TERMINAL_STATUSES = { 4670 completed: true, 4671 cancelled: true, 4672 failed: true 4673 }; 4674 4675 var pollTimer = null; 4676 var pusherClient = null; 4677 var pollRequestInFlight = false;
4678 4679 function parseJson(value) { 4680 if (!value) { 4681 return null; 4682 } 4683 4684 try { 4685 return JSON.parse(value); 4686 } catch (e) { 4687 return null; 4688 } 4689 } 4690 4691 function readTracker() { 4692 if (!window.localStorage) { 4693 return null; 4694 } 4695 4696 return parseJson(window.localStorage.getItem(STORAGE_KEY)); 4697 } 4698 4699 function writeTracker(tracker) { 4700 if (!window.localStorage || !tracker) { 4701 return; 4702 } 4703 4704 try { 4705 window.localStorage.setItem(STORAGE_KEY, JSON.stringify(tracker)); 4706 } catch (e) { 4707 // Ignore storage failures. 4708 } 4709 } 4710 4711 function clearTracker() { 4712 if (!window.localStorage) { 4713 return; 4714 } 4715 4716 try { 4717 window.localStorage.removeItem(STORAGE_KEY); 4718 } catch (e) { 4719 // Ignore storage failures. 4720 } 4721 } 4722 4723 function isValidTracker(tracker) { 4724 if (!tracker || !tracker.payment_id || !tracker.payment_key || !tracker.security) { 4725 return false; 4726 } 4727 4728 if (tracker.expires_at && Date.now() > parseInt(tracker.expires_at, 10)) { 4729 return false; 4730 } 4731 4732 return true; 4733 } 4734 4735 function getNotifiedStorageKey(paymentId) { 4736 return "rpress_live_order_notified_" + String(paymentId); 4737 } 4738 4739 function markNotified(paymentId, statusKey) { 4740 if (!window.localStorage || !paymentId || !statusKey) { 4741 return; 4742 } 4743 4744 try { 4745 window.localStorage.setItem(getNotifiedStorageKey(paymentId), String(statusKey)); 4746 } catch (e) { 4747 // Ignore storage failures. 4748 } 4749 } 4750 4751 function shouldNotify(paymentId, statusKey) { 4752 if (!window.localStorage || !paymentId || !statusKey) { 4753 return true; 4754 } 4755 4756 var storageKey = getNotifiedStorageKey(paymentId); 4757 var lastStatus = null; 4758 4759 try { 4760 lastStatus = window.localStorage.getItem(storageKey); 4761 if (lastStatus === String(statusKey)) { 4762 return false; 4763 } 4764 window.localStorage.setItem(storageKey, String(statusKey)); 4765 return true; 4766 } catch (e) { 4767 return true; 4768 } 4769 } 4770 4771 function showBrowserNotification(orderNumber, statusLabel) { 4772 if (!("Notification" in window) || Notification.permission !== "granted") { 4773 return; 4774 } 4775 4776 var title = "Order update #" + orderNumber; 4777 var body = "Status: " + statusLabel; 4778 4779 if ("serviceWorker" in navigator) { 4780 navigator.serviceWorker.getRegistration().then(function (registration) { 4781 if (registration && typeof registration.showNotification === "function") { 4782 registration.showNotification(title, { 4783 body: body, 4784 tag: "rpress-order-" + orderNumber 4785 }); 4786 return; 4787 } 4788 4789 try { 4790 new Notification(title, { body: body }); 4791 } catch (e) { 4792 // Ignore browser-level notification errors. 4793 } 4794 }).catch(function () { 4795 try { 4796 new Notification(title, { body: body }); 4797 } catch (e) { 4798 // Ignore browser-level notification errors. 4799 } 4800 }); 4801 return; 4802 } 4803 4804 try { 4805 new Notification(title, { body: body }); 4806 } catch (e) { 4807 // Ignore browser-level notification errors. 4808 } 4809 } 4810 4811 function handleIncomingStatus(data, notifyOnChange) { 4812 if (!data || !data.payment_id || !data.status) { 4813 return; 4814 } 4815 4816 var tracker = readTracker(); 4817 if (!isValidTracker(tracker) || parseInt(tracker.payment_id, 10) !== parseInt(data.payment_id, 10)) { 4818 return; 4819 } 4820 4821 var previousStatus = tracker.status || ""; 4822 tracker.status = data.status; 4823 tracker.status_label = data.status_label || data.status; 4824 tracker.order_number = data.order_number || tracker.order_number; 4825 tracker.updated_at_unix = data.updated_at_unix || tracker.updated_at_unix || 0; 4826 var statusChanged = previousStatus !== tracker.status; 4827 4828 if (notifyOnChange && statusChanged && shouldNotify(tracker.payment_id, tracker.status)) { 4829 showBrowserNotification(tracker.order_number || tracker.payment_id, tracker.status_label); 4830 } 4831 4832 if (TERMINAL_STATUSES[tracker.status]) { 4833 clearTracker(); 4834 stopWatchers(); 4835 return; 4836 } 4837 4838 if (!tracker.expires_at || Date.now() > parseInt(tracker.expires_at, 10)) { 4839 tracker.expires_at = Date.now() + (6 * 60 * 60 * 1000); 4840 } 4841 4842 writeTracker(tracker); 4843 } 4844 4845 function fetchLatestStatus() { 4846 if (pollRequestInFlight) { 4847 return; 4848 } 4849 4850 var tracker = readTracker(); 4851 if (!isValidTracker(tracker)) { 4852 stopWatchers(); 4853 clearTracker(); 4854 return; 4855 } 4856 4857 var body = new URLSearchParams(); 4858 body.set("action", "rpress_receipt_order_status"); 4859 body.set("payment_id", String(tracker.payment_id)); 4860 body.set("payment_key", String(tracker.payment_key)); 4861 body.set("security", String(tracker.security)); 4862 4863 pollRequestInFlight = true; 4864 fetch(window.rp_scripts.ajaxurl, { 4865 method: "POST", 4866 credentials: "same-origin", 4867 headers: { 4868 "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8" 4869 }, 4870 body: body.toString() 4871 }) 4872 .then(function (response) { 4873 return response.json(); 4874 }) 4875 .then(function (result) { 4876 if (!result || !result.success || !result.data) { 4877 return; 4878 } 4879 4880 handleIncomingStatus(result.data, true); 4881 }) 4882 .catch(function () { 4883 // Ignore transient errors. 4884 }) 4885 .then(function () { 4886 pollRequestInFlight = false;
4887 }); 4888 } 4889 4890 function startPolling() { 4891 if (pollTimer) { 4892 return; 4893 } 4894 4895 fetchLatestStatus(); 4896 pollTimer = window.setInterval(fetchLatestStatus, 10000); 4897 } 4898 4899 function stopPolling() { 4900 if (pollTimer) { 4901 window.clearInterval(pollTimer); 4902 pollTimer = null; 4903 } 4904 } 4905 4906 function stopWatchers() { 4907 stopPolling(); 4908 4909 if (pusherClient && typeof pusherClient.disconnect === "function") { 4910 pusherClient.disconnect(); 4911 pusherClient = null; 4912 } 4913 } 4914 4915 function connectPusher(tracker) { 4916 var realtime = tracker.realtime || {}; 4917 if (!realtime.enabled || !realtime.key || !realtime.channel || !realtime.event || typeof window.Pusher === "undefined") { 4918 return false; 4919 } 4920 4921 var options = { 4922 forceTLS: !!realtime.forceTLS 4923 }; 4924 4925 if (realtime.cluster) { 4926 options.cluster = realtime.cluster; 4927 } 4928 4929 if (realtime.wsHost) { 4930 options.wsHost = realtime.wsHost; 4931 } 4932 4933 if (realtime.wsPort) { 4934 options.wsPort = parseInt(realtime.wsPort, 10); 4935 } 4936 4937 if (realtime.wssPort) { 4938 options.wssPort = parseInt(realtime.wssPort, 10); 4939 } 4940 4941 try { 4942 pusherClient = new window.Pusher(realtime.key, options); 4943 } catch (e) { 4944 return false; 4945 } 4946 4947 var channel = pusherClient.subscribe(realtime.channel); 4948 4949 channel.bind(realtime.event, function (payload) { 4950 handleIncomingStatus(payload || {}, true); 4951 }); 4952 4953 channel.bind("pusher:subscription_error", function () { 4954 startPolling(); 4955 }); 4956 4957 if (pusherClient.connection && typeof pusherClient.connection.bind === "function") { 4958 pusherClient.connection.bind("error", function () { 4959 startPolling(); 4960 }); 4961 } 4962 4963 return true; 4964 } 4965 4966 function loadScript(url, callback) { 4967 if (!url) { 4968 callback(false); 4969 return; 4970 } 4971 4972 var scripts = document.getElementsByTagName("script"); 4973 for (var i = 0; i < scripts.length; i++) { 4974 if (scripts[i].src === url) { 4975 callback(true); 4976 return; 4977 } 4978 } 4979 4980 var script = document.createElement("script"); 4981 script.src = url; 4982 script.async = true; 4983 script.onload = function () { 4984 callback(true); 4985 }; 4986 script.onerror = function () { 4987 callback(false); 4988 }; 4989 document.head.appendChild(script); 4990 } 4991 4992 function startWatcher() { 4993 var tracker = readTracker(); 4994 if (!isValidTracker(tracker)) { 4995 clearTracker(); 4996 return; 4997 } 4998 4999 if (tracker.status && TERMINAL_STATUSES[tracker.status]) { 5000 clearTracker(); 5001 return; 5002 } 5003 5004 if (tracker.status) { 5005 markNotified(tracker.payment_id, tracker.status); 5006 } 5007 5008 var realtime = tracker.realtime || {}; 5009 if (!realtime.enabled) { 5010 startPolling(); 5011 return; 5012 } 5013 5014 if (typeof window.Pusher !== "undefined") { 5015 if (connectPusher(tracker)) { 5016 window.setTimeout(fetchLatestStatus, 1200); 5017 } else { 5018 startPolling(); 5019 } 5020 return; 5021 } 5022 5023 loadScript(realtime.script_url, function (loaded) { 5024 if (!loaded) { 5025 startPolling(); 5026 return; 5027 } 5028 5029 if (connectPusher(tracker)) { 5030 window.setTimeout(fetchLatestStatus, 1200); 5031 } else { 5032 startPolling(); 5033 } 5034 }); 5035 } 5036 5037 startWatcher(); 5038 window.addEventListener("beforeunload", stopWatchers); 5039})(window); 5040 5041 5042 5043/*---foodmenutab---*/ 5044var SETTINGS = { 5045 navBarTravelling: false, 5046 navBarTravelDirection: "", 5047 navBarTravelDistance: 150 5048}; 5049
5050var colours = { 5051 0: "#867100", 5052 1: "#7F4200", 5053 2: "#99813D", 5054 3: "#40FEFF", 5055 4: "#14CC99", 5056 5: "#00BAFF", 5057 6: "#0082B2", 5058 7: "#B25D7A", 5059 8: "#00FF17", 5060 9: "#006B49", 5061 10: "#00B27A", 5062 11: "#996B3D", 5063 12: "#CC7014", 5064 13: "#40FF8C", 5065 14: "#FF3400", 5066 15: "#ECBB5E", 5067 16: "#ECBB0C", 5068 17: "#B9D912", 5069 18: "#253A93", 5070 19: "#125FB9" 5071}; 5072 5073document.documentElement.classList.remove("no-js"); 5074document.documentElement.classList.add("js"); 5075 5076function initProductNav(config) { 5077 const nav = document.getElementById(config.nav); 5078 const contents = document.getElementById(config.contents); 5079 const indicator = document.getElementById(config.indicator); 5080 const leftBtn = document.getElementById(config.leftBtn); 5081 const rightBtn = document.getElementById(config.rightBtn); 5082 5083 if (!nav || !contents || !indicator || !leftBtn || !rightBtn) return; 5084 5085 nav.setAttribute("data-overflowing", determineOverflow(contents, nav)); 5086 moveIndicator(nav.querySelector('[aria-selected="true"]'), indicator, colours[0], contents); 5087 5088 let ticking = false; 5089 nav.addEventListener("scroll", function () { 5090 if (!ticking) { 5091 window.requestAnimationFrame(function () { 5092 nav.setAttribute("data-overflowing", determineOverflow(contents, nav)); 5093 ticking = false; 5094 }); 5095 } 5096 ticking = true; 5097 }); 5098 5099 leftBtn.addEventListener("click", function () { 5100 if (SETTINGS.navBarTravelling) return; 5101 const overflow = determineOverflow(contents, nav); 5102 if (overflow === "left" || overflow === "both") { 5103 const availableScrollLeft = nav.scrollLeft; 5104 const distance = availableScrollLeft < SETTINGS.navBarTravelDistance * 2 5105 ? availableScrollLeft 5106 : SETTINGS.navBarTravelDistance; 5107 5108 contents.style.transform = `translateX(${distance}px)`; 5109 contents.classList.remove("pn-ProductNav_Contents-no-transition"); 5110 SETTINGS.navBarTravelDirection = "left"; 5111 SETTINGS.navBarTravelling = true; 5112 } 5113 nav.setAttribute("data-overflowing", determineOverflow(contents, nav)); 5114 }); 5115 5116 rightBtn.addEventListener("click", function () { 5117 if (SETTINGS.navBarTravelling) return; 5118 const overflow = determineOverflow(contents, nav); 5119 if (overflow === "right" || overflow === "both") { 5120 const navBarRightEdge = contents.getBoundingClientRect().right; 5121 const scrollerRightEdge = nav.getBoundingClientRect().right; 5122 const availableScrollRight = Math.floor(navBarRightEdge - scrollerRightEdge); 5123 const distance = availableScrollRight < SETTINGS.navBarTravelDistance * 2 5124 ? availableScrollRight 5125 : SETTINGS.navBarTravelDistance; 5126 5127 contents.style.transform = `translateX(-${distance}px)`; 5128 contents.classList.remove("pn-ProductNav_Contents-no-transition"); 5129 SETTINGS.navBarTravelDirection = "right"; 5130 SETTINGS.navBarTravelling = true; 5131 } 5132 nav.setAttribute("data-overflowing", determineOverflow(contents, nav)); 5133 }); 5134 5135 contents.addEventListener("transitionend", function () { 5136 const tr = getComputedStyle(contents).transform; 5137 const amount = Math.abs(parseInt(tr.split(",")[4]) || 0); 5138 contents.style.transform = "none"; 5139 contents.classList.add("pn-ProductNav_Contents-no-transition"); 5140 if (SETTINGS.navBarTravelDirection === "left") { 5141 nav.scrollLeft -= amount; 5142 } else { 5143 nav.scrollLeft += amount; 5144 } 5145 SETTINGS.navBarTravelling = false; 5146 }); 5147 5148 contents.addEventListener("click", function (e) { 5149 if (!e.target.classList.contains('pn-ProductNav_Link')) return; 5150 const links = Array.from(contents.querySelectorAll(".pn-ProductNav_Link")); 5151 links.forEach(link => link.setAttribute("aria-selected", "false")); 5152 e.target.setAttribute("aria-selected", "true"); 5153 moveIndicator(e.target, indicator, colours[links.indexOf(e.target)], contents); 5154 }); 5155 5156 window.addEventListener("resize", function () { 5157 const selected = nav.querySelector('[aria-selected="true"]'); 5158 if (selected) moveIndicator(selected, indicator, null, contents); 5159 }); 5160} 5161 5162function moveIndicator(item, indicator, color, container) { 5163 if (!item || !indicator) return; 5164 const textPosition = item.getBoundingClientRect(); 5165 const containerLeft = container.getBoundingClientRect().left; 5166 const distance = textPosition.left - containerLeft; 5167 const scroll = container.scrollLeft; 5168 indicator.style.transform = `translateX(${distance + scroll}px) scaleX(${textPosition.width * 0.01})`; 5169 if (color) indicator.style.backgroundColor = color; 5170} 5171 5172function determineOverflow(content, container) { 5173 const containerRect = container.getBoundingClientRect(); 5174 const contentRect = content.getBoundingClientRect(); 5175 if ( 5176 containerRect.left > contentRect.left && 5177 containerRect.right < contentRect.right 5178 ) { 5179 return "both"; 5180 } else if (contentRect.left < containerRect.left) { 5181 return "left"; 5182 } else if (contentRect.right > containerRect.right) { 5183 return "right"; 5184 } else { 5185 return "none"; 5186 } 5187} 5188 5189// Initialize both desktop and mobile tab navigations 5190initProductNav({ 5191 nav: 'pnProductNav', 5192 contents: 'pnProductNavContents', 5193 indicator: 'pnIndicator', 5194 leftBtn: 'pnAdvancerLeft', 5195 rightBtn: 'pnAdvancerRight' 5196}); 5197 5198initProductNav({ 5199 nav: 'pnProductNavMobile', 5200 contents: 'pnProductNavContentsMobile', 5201 indicator: 'pnIndicatorMobile', 5202 leftBtn: 'pnAdvancerLeftMobile', 5203 rightBtn: 'pnAdvancerRightMobile' 5204}); 5205 5206jQuery(function ($) { 5207 if (window.location.pathname === '/order-online/') { 5208 $('body').addClass('order-online'); 5209 } 5210 $('.rpress-category-lists .rpress-category-link:first').addClass('current'); 5211 $('.rpress-category-lists li:first').addClass('current'); 5212 5213 $('.cd-dropdown-trigger').on('click', function () { 5214 $('body').toggleClass('cd-overlay-open'); 5215 5216 if ($('body').hasClass('cd-overlay-open')) { 5217 // Add overlay if opening 5218 if ($('.rpress-cat-overlay').length === 0) { 5219 var cdDropdown = $('.cd-dropdown-wrapper .cd-dropdown'); 5220 $('<div class="rpress-cat-overlay"></div>').insertAfter(cdDropdown); 5221 } 5222 } else { 5223 // Remove overlay if closing 5224 $('.rpress-cat-overlay').remove(); 5225 } 5226 }); 5227 $('.cd-close').on('click', function () { 5228 $('body').removeClass('cd-overlay-open'); 5229 $('.rpress-cat-overlay').remove(); 5230 }); 5231 $(document).on('click', '.rpress-editaddress-cancel-btn', function (e) { 5232 if (e) { 5233 e.preventDefault(); 5234 } 5235 $('.rpress-mobile-cart-icons').show(); 5236 if (typeof MicroModal !== 'undefined') {
5237 try { 5238 MicroModal.close('rpressDateTime'); 5239 } catch (err) {} 5240 } 5241 var $modal = $('#rpressDateTime'); 5242 if ($modal.length) { 5243 $modal.removeClass('is-open').attr('aria-hidden', 'true'); 5244 } 5245 }); 5246 $('.cd-dropdown-trigger').on('click', function (event) { 5247 event.preventDefault(); 5248 $('.rpress-mobile-cart-icons').hide(); 5249 toggleNav(); 5250 }); 5251 5252 $('.cd-dropdown .cd-close').on('click', function (event) { 5253 event.preventDefault(); 5254 $('.rpress-mobile-cart-icons').show(); 5255 toggleNav(); 5256 }); 5257 5258 function toggleNav() { 5259 var navIsVisible = (!$('.cd-dropdown').hasClass('dropdown-is-active')); 5260 $('.cd-dropdown').toggleClass('dropdown-is-active', navIsVisible); 5261 $('.cd-dropdown-trigger').toggleClass('dropdown-is-active', navIsVisible); 5262 5263 if (!navIsVisible) { 5264 $('.cd-dropdown').one('transitionend webkitTransitionEnd oTransitionEnd MSTransitionEnd', function () { 5265 $('.has-children ul').addClass('is-hidden'); 5266 $('.move-out').removeClass('move-out'); 5267 $('.is-active').removeClass('is-active'); 5268 }); 5269 } 5270 } 5271 5272 function rp_sync_checkout_service_heading($scope, serviceType) { 5273 var $root = ($scope && $scope.length) ? $scope : $(document); 5274 var $wrapper = $root.closest('.rpress-tabs-wrapper'); 5275 if (!$wrapper.length) { 5276 $wrapper = $root.find('.rpress-tabs-wrapper').first(); 5277 } 5278 if (!$wrapper.length) { 5279 return; 5280 } 5281 5282 var normalizedServiceType = String(serviceType || '') 5283 .toLowerCase(); 5284 if (normalizedServiceType !== 'delivery' && normalizedServiceType !== 'pickup') { 5285 normalizedServiceType = window.rp_get_active_service_type($wrapper, 'delivery'); 5286 } 5287 5288 var $heading = $wrapper.find('.rpress-checkout-service-heading').first(); 5289 if (!$heading.length) { 5290 return; 5291 } 5292 5293 var $activeTab = $wrapper.find('#rpressdeliveryTab .single-service-selected[data-service-type="' + normalizedServiceType + '"]').first(); 5294 var label = $activeTab.find('.rpress-service-tab-label').first().text().trim(); 5295 if (!label) { 5296 label = normalizedServiceType.charAt(0).toUpperCase() + normalizedServiceType.slice(1); 5297 } 5298 5299 $heading.find('.rpress-checkout-service-heading-text').text(label); 5300 $heading.removeClass('is-service-delivery is-service-pickup').addClass('is-service-' + normalizedServiceType); 5301 } 5302 5303 var oldUiUxEnabled = rp_is_old_ui_ux_enabled(); 5304 5305 var serviceType = rp_getCookie('service_type'); 5306 if (serviceType) { 5307 var capitalized = serviceType.charAt(0).toUpperCase() + serviceType.slice(1); 5308 $('.rpress-service-label').text(capitalized); 5309 } 5310 var $initialOrderServiceScope = $('.rpress-delivery-wrap .rpress-tabs-wrapper:visible') 5311 .first(); 5312 var initialServiceType = window.rp_get_active_service_type( 5313 $initialOrderServiceScope.length ? $initialOrderServiceScope : $(document), 5314 serviceType || rp_scripts.default_service || 'delivery' 5315 ); 5316 window.rp_sync_service_ui_state( 5317 $initialOrderServiceScope.length ? $initialOrderServiceScope : $(document), 5318 initialServiceType, 5319 !oldUiUxEnabled 5320 ); 5321 rp_sync_checkout_service_heading( 5322 $initialOrderServiceScope.length ? $initialOrderServiceScope : $(document), 5323 initialServiceType 5324 ); 5325 $(document).on('rp_delivery_fee_validation', function (event, response) { 5326 if (!rp_is_old_ui_ux_enabled()) { 5327 return; 5328 } 5329 response = response || {}; 5330 if (response.status === 'error' || parseInt(response.delivery_fee_error || 0, 10) === 1) { 5331 window.rpDeliveryFeeValidationState = 'invalid'; 5332 return; 5333 } 5334 5335 if (response.status === 'success') { 5336 window.rpDeliveryFeeValidationState = 'valid'; 5337 } 5338 }); 5339 $(document).on('input change', '#rp_delivery_zone, #rp_delivery_location, #rpress-delivery-address, #rpress-postcode, #rpress_postcode', function () { 5340 if (!rp_is_old_ui_ux_enabled()) { 5341 return; 5342 } 5343 window.rpDeliveryFeeValidationState = 'unknown'; 5344 }); 5345 if (!oldUiUxEnabled) { 5346 window.rp_sync_service_selection_cookies( 5347 $initialOrderServiceScope.length ? $initialOrderServiceScope : $(document), 5348 initialServiceType 5349 ); 5350 } 5351 $(document).on('click', '#rpressdeliveryTab .single-service-selected, .single-service-selected', function (e) { 5352 var $serviceTab = $(this); 5353 var selectedServiceType = String($serviceTab.data('service-type') || '') 5354 .toLowerCase(); 5355 5356 if (selectedServiceType) { 5357 var capitalized = selectedServiceType.charAt(0).toUpperCase() + selectedServiceType.slice(1); 5358 $('.rpress-service-label').text(capitalized); 5359 } 5360 5361 setTimeout(function () { 5362 var $serviceScope = $serviceTab.closest('.rpress-tabs-wrapper'); 5363 window.rp_sync_service_ui_state( 5364 $serviceScope.length ? $serviceScope : $(document), 5365 selectedServiceType, 5366 !oldUiUxEnabled 5367 ); 5368 rp_sync_checkout_service_heading( 5369 $serviceScope.length ? $serviceScope : $(document), 5370 selectedServiceType 5371 ); 5372 if (!oldUiUxEnabled) { 5373 var selectedServiceDefaults = window.rp_sync_service_selection_cookies( 5374 $serviceScope.length ? $serviceScope : $(document), 5375 selectedServiceType 5376 ); 5377 if (typeof window.rp_update_inline_service_display === 'function') { 5378 window.rp_update_inline_service_display(selectedServiceDefaults, oldUiUxEnabled); 5379 } 5380 } 5381 }, 0); 5382 }); 5383 5384 setTimeout(function () {
5385 // Do not force change events on checkout; this can retrigger slot checks. 5386 if (String(rpress_scripts.is_checkout) === '1') { 5387 return; 5388 } 5389 5390 var $hours = $("#rpressDateTime #rpress-delivery-hours, #rpressModal #rpress-delivery-hours").first(); 5391 if (!$hours.length) { 5392 return; 5393 } 5394 5395 var selectedVal = $hours.find("option:selected").val(); 5396 if (!selectedVal) { 5397 selectedVal = $hours.find("option:first").val(); 5398 } 5399 5400 if (selectedVal) { 5401 $hours.val(selectedVal); 5402 } 5403 }, 1000); 5404 5405 $(document).on('click', '.rp-variable-price-wrapper .radio-container', function () { 5406 var $radio = $(this).find('input[type="radio"]'); 5407 5408 if ($radio.length) { 5409 var name = $radio.attr('name'); 5410 5411 // Uncheck all radios in this group 5412 $('input[name="' + name + '"]').prop('checked', false); 5413 5414 // Check the clicked one 5415 $radio.prop('checked', true).trigger('change'); 5416 5417 // Optional: manage "checked" class on container 5418 $('.radio-container').removeClass('checked'); 5419 $(this).addClass('checked'); 5420 } 5421 }); 5422}); 5423jQuery(document).ready(function ($) { 5424 $('.menu-category-wrap').first().addClass('first-menu-category-wrap'); 5425 5426 5427 var $nav = $('#pnProductNav'); 5428 5429 function checkOverflow() { 5430 if ($nav.attr('data-overflowing') !== 'right') { 5431 $nav.parent('.pn-ProductNav_Wrapper').addClass('background-hidden'); 5432 } else { 5433 $nav.parent('.pn-ProductNav_Wrapper').removeClass('background-hidden'); 5434 } 5435 } 5436 5437 // Run once on page load 5438 checkOverflow(); 5439 5440 function updateTooManyAdds($span) { 5441 var textOnly = $span.text().trim(); 5442 var $parent = $span.closest('.rpress-price-holder'); 5443 5444 if ($parent.length) { 5445 if (textOnly.length > 3) { 5446 $parent.addClass('too-many-adds'); 5447 } else { 5448 $parent.removeClass('too-many-adds'); 5449 } 5450 } 5451 } 5452 5453 // Initial check on page load 5454 $('span.rpress-add-to-cart-label.rp-ajax-toggle-text').each(function () { 5455 updateTooManyAdds($(this)); 5456 }); 5457 5458 // Observe only the spans 5459 $('span.rpress-add-to-cart-label.rp-ajax-toggle-text').each(function () { 5460 var targetNode = this; 5461 5462 var observer = new MutationObserver(function () { 5463 updateTooManyAdds($(targetNode)); 5464 }); 5465 5466 observer.observe(targetNode, { 5467 characterData: true, 5468 subtree: true, 5469 childList: true 5470 }); 5471 }); 5472}); 5473 5474jQuery(document).ready(function ($) { 5475 5476 var oldUiUxEnabled = rp_is_old_ui_ux_enabled(); 5477 5478 if (oldUiUxEnabled) { 5479 var cartQty = parseInt((typeof rp_scripts !== 'undefined' ? rp_scripts.cart_quantity : 0) || 0, 10); 5480 var hasCartItemElements = $('ul.rpress-cart > li.rpress-cart-item').length > 0; 5481 var isCartEmpty = (cartQty === 0) && !hasCartItemElements; 5482 5483 var isSuccessPage = (typeof rp_scripts !== 'undefined' && String(rp_scripts.is_success_page || '') === '1') || 5484 ($('#rpress_receipt_history, .rpress_purchase_receipt, .rp-order-confirmation-wrap, .rpress-receipt-wrap, .rpress_checkout_receipt').length > 0) || 5485 (window.location.href.indexOf('payment-confirmation') !== -1) || 5486 (window.location.href.indexOf('payment-id') !== -1) || 5487 (window.location.href.indexOf('order-confirmation') !== -1); 5488 5489 if (isSuccessPage || isCartEmpty) { 5490 rp_clear_service_selection_cookies(false); 5491 } 5492 } 5493 var $selectionScope = $('#rpressDateTime-content'); 5494 if (!$selectionScope.length) { 5495 $selectionScope = $('#rpressDateTime'); 5496 } 5497 if (!$selectionScope.length) { 5498 $selectionScope = $('.rpress-delivery-wrap .rpress-tabs-wrapper:visible').first(); 5499 } 5500 5501 var selection = null; 5502 if (oldUiUxEnabled) { 5503 if (typeof window.rp_prepare_old_ui_modal_selection === 'function') { 5504 window.rp_prepare_old_ui_modal_selection($selectionScope.length ? $selectionScope : $(document)); 5505 } 5506 5507 var oldUiServiceType = (rp_getCookie('service_type') || rp_scripts.default_service || 'delivery') 5508 .toString() 5509 .toLowerCase(); 5510 selection = (typeof window.rp_apply_service_defaults === 'function') 5511 ? window.rp_apply_service_defaults( 5512 $selectionScope.length ? $selectionScope : $(document), 5513 oldUiServiceType, 5514 false 5515 ) 5516 : null; 5517 } else { 5518 var serviceType = rp_getCookie('service_type') || rp_scripts.default_service || 'delivery'; 5519 rp_setCookie('service_type', serviceType, rp_scripts.expire_cookie_time); 5520 selection = (typeof window.rp_apply_service_defaults === 'function') 5521 ? window.rp_apply_service_defaults( 5522 $selectionScope.length ? $selectionScope : $(document), 5523 serviceType, 5524 true 5525 ) 5526 : null; 5527 } 5528 5529 if (typeof window.rp_update_inline_service_display === 'function') { 5530 window.rp_update_inline_service_display(selection, oldUiUxEnabled); 5531 } 5532 5533 function initStickyMenu() { 5534 var $menu = $('.desktop-scroll-menu .make-me-sticky'); 5535 var $sidebar = $('.sticky-sidebar'); 5536 5537 if ($(window).width() > 991 && $menu.length > 0) {
5538 // Fixed offset from top â clear the WP admin bar when it's fixed (logged 5539 // in), else the fixed nav sits behind it. Absolute admin bar (â¤600px) or 5540 // logged out reports 0. 5541 var $adminBar = $('#wpadminbar'); 5542 var stickyTop = ($adminBar.length && $adminBar.css('position') === 'fixed') ? ($adminBar.outerHeight() || 0) : 0; 5543 5544 var menuOffset = $menu.offset().top; 5545 5546 $(window).off('.stickyMenu'); // Remove previous events 5547 5548 $(window).on('scroll.stickyMenu', function () { 5549 var scrollTop = $(window).scrollTop(); 5550 5551 if (scrollTop + stickyTop >= menuOffset) { 5552 $menu.css({ 5553 'position': 'fixed', 5554 'top': stickyTop + 'px', 5555 'left': $menu.offset().left + 'px', 5556 'width': $menu.outerWidth(), 5557 'z-index': 999 5558 }); 5559 } else { 5560 $menu.css({ 5561 'position': 'static', 5562 'width': '', 5563 'top': '', 5564 'left': '', 5565 'z-index': '' 5566 }); 5567 } 5568 }); 5569 5570 // Recalculate left & width on resize. Reset the menu to its natural size - 5571 // never force the horizontal category nav to the sidebar's height (that left 5572 // a large empty band around the nav after resizing). 5573 $(window).on('resize.stickyMenu', function () { 5574 $menu.css({ 5575 'position': 'static', 5576 'width': '', 5577 'top': '', 5578 'left': '', 5579 'height': '' 5580 }); 5581 menuOffset = $menu.offset().top; 5582 }); 5583 5584 } else { 5585 // Reset sticky behavior on mobile 5586 $menu.css({ 5587 'position': 'static', 5588 'height': 'auto' 5589 }); 5590 } 5591 } 5592 5593 initStickyMenu(); 5594 $(window).on('resize', initStickyMenu); 5595 /** 5596 * Action Menu Toggle for Mobile 5597 */ 5598 var actionContainer = document.querySelector(".container-actionmenu"); 5599 var burger = document.getElementById("actionburger"); 5600 var menu = document.querySelector(".actionmenu"); 5601 5602 if (actionContainer && burger && menu) { 5603 var toggleActionMenu = function () { 5604 burger.classList.toggle("is-expanded"); 5605 5606 // Get the icon and text elements 5607 var icon = burger.querySelector('i'); 5608 var textNode = burger.querySelector('.menu-text'); 5609 var isExpanded = burger.classList.contains('is-expanded'); 5610 5611 // Get texts and icons from data attributes 5612 var menuText = burger.getAttribute('data-text-menu'); 5613 var closeText = burger.getAttribute('data-text-close'); 5614 var menuIcon = burger.getAttribute('data-icon-menu'); 5615 var closeIcon = burger.getAttribute('data-icon-close'); 5616 5617 if (isExpanded) { 5618 menu.classList.replace("slides-down", "slides-up"); 5619 if (icon) { 5620 icon.className = closeIcon; 5621 } 5622 if (textNode) { 5623 textNode.textContent = closeText; 5624 } 5625 } else { 5626 menu.classList.replace("slides-up", "slides-down"); 5627 if (icon) { 5628 icon.className = menuIcon; 5629 } 5630 if (textNode) { 5631 textNode.textContent = menuText; 5632 } 5633 } 5634 }; 5635 5636 // Toggle only when the menu button itself is clicked. 5637 burger.addEventListener("click", function (event) { 5638 event.preventDefault(); 5639 event.stopPropagation(); 5640 toggleActionMenu(); 5641 }); 5642 5643 } 5644});
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.