1$(document).ready(function () { 2 3 if($('#shopHeaderContainer div.tag--closed').length) { 4 window.modals.TakeawayClosed.show(); 5 } 6 7 // See if there is a hash change. This helps to handle the back button on the mobile site when going through the checkout 8 $(window).on('hashchange', function () { 9 // If there is no hash show the menu 10 var currHash = window.location.hash; 11 12 // Remove any # just incase some phone browsers leave them on 13 currHash = currHash.replace('#', ''); 14 15 switch (currHash) { 16 case 'options-and-extras': 17 // Hide these 18 $('#yourOrder').addClass('hidden-phone'); 19 $('#phoneCartFooter').addClass('hidden-phone'); 20 21 // Show these 22 $('#menuHolder').removeClass('hidden-phone'); 23 $('#options').show(); 24 $('#menu').hide(); 25 break; 26 27 case 'checkout': 28 // Hide these 29 $('#menuHolder').addClass('hidden-phone'); 30 $('#phoneCartFooter').addClass('hidden-phone'); 31 32 // Show these 33 $('#yourOrder').removeClass('hidden-phone'); 34 $('#options').hide(); 35 $('#menu').hide(); 36 break; 37 38 default: 39 // Hide these 40 $('#yourOrder').addClass('hidden-phone'); 41 42 // Show these 43 $('#menuHolder').removeClass('hidden-phone'); 44 $('#phoneCartFooter').removeClass('hidden-phone'); 45 $('#options').hide(); 46 $('#menu').show(); 47 } 48 49 return false; 50 }); 51 52 $(document).on('focus', '.textInput input', function (e) { 53 $(e.target).closest('.textInput').removeClass('iconError'); 54 }); 55 56 let offerPos = 0; 57 let offerAnimating = false; 58 $(document).on('click', '.offers-ribbon .nav.left', function (e) { 59 if (!offerAnimating) { 60 const scroll = $('.offers-ribbon .scroll'); 61 const offers = $('.offers-ribbon .offer'); 62 const totalOffers = offers.length; 63 if (offerPos === 0) { 64 offerPos = totalOffers - 4; 65 scroll.scrollLeft( 66 scroll.scrollLeft() + offers.eq(offerPos).position().left, 67 ); 68 } 69 const nextOffer = offerPos - 1; 70 const offerOffset = offers.eq(nextOffer).position(); 71 72 offerAnimating = true; 73 scroll.animate({ 74 scrollLeft: scroll.scrollLeft() + offerOffset.left, 75 }, 450, function () { 76 offerAnimating = false; 77 }); 78 79 offerPos = nextOffer; 80 } 81 }); 82 83 $(document).ready(function () { 84 const offers = $('.offers-ribbon .offer'); 85 const totalOffers = offers.length; 86 if (totalOffers > 3) { 87 offers.clone().slice(0, 4).map(function () { 88 $(this).addClass('hidden-phone hidden-tablet'); 89 return this; 90 }).appendTo($('.offers-ribbon .scroll')); 91 $('.offers-ribbon .nav').css('display', 'flex'); 92 } 93 }); 94 95 $(document).on('click', '.offers-ribbon .nav.right', function (e) { 96 if (!offerAnimating) { 97 const scroll = $('.offers-ribbon .scroll'); 98 const offers = $('.offers-ribbon .offer'); 99 const totalOffers = offers.length; 100 const nextOffer = offerPos + 1; 101 const offerOffset = offers.eq(nextOffer).position(); 102 103 offerAnimating = true; 104 scroll.animate({ 105 scrollLeft: scroll.scrollLeft() + offerOffset.left, 106 }, 450, function () { 107 offerAnimating = false; 108 if (nextOffer === totalOffers - 4) { 109 scroll.scrollLeft(0); 110 offerPos = 0; 111 } 112 }); 113 114 offerPos = nextOffer; 115 } 116 }); 117 118 $(document).on('keypress', '#discount-code', function (e) { 119 if (e.keyCode === 13) { 120 $('#discount-code-apply-button').trigger('click'); 121 $(e.target).blur(); 122 } 123 }) 124 125 $(document).on('click', '#discount-code-apply-button', function (e) { 126 e.preventDefault(); 127 const field = $('#discount-code'); 128 const fieldValue = field.val().toUpperCase(); 129 const textInput = field.closest('.textInput'); 130 131 // Make the field uppercase 132 field.val(fieldValue); 133 134 $.ajax({ 135 type: 'POST', 136 url: 'checkout/discount_code?ts=' + (new Date().getTime()), 137 data: { 138 'discountCode': fieldValue, 139 }, 140 beforeSend: function () { 141 $('#orderSummary .overlay').show(); 142 textInput 143 .removeClass('iconError') 144 .addClass('iconBusy'); 145 disableButtons(); 146 }, 147 success: function (response) { 148 if (response.error !== undefined) { 149 textInput.addClass('iconError').find('.textInputError').text(response.error); 150 } else { 151 updateBasket(response); 152 } 153 }, 154 complete: function () { 155 $('#orderSummary .overlay').hide(); 156 textInput.removeClass('iconBusy'); 157 enableButtons(); 158 }, 159 }) 160 }) 161 162 // Handle the clicking of the Update PC button so that they can change their postcode 163 $(document).on('click', '.applied-container #delete', function (e) { 164 e.preventDefault(); 165 const discountCode = $(e.target).parent().data('id'); 166 167 $.ajax({ 168 type: 'DELETE', 169 url: 'checkout/discount_code/' + discountCode + '?ts=' + (new Date().getTime()), 170 beforeSend: function () { 171 $('#orderSummary .overlay').show() 172 disableButtons() 173 }, 174 success: function (response) { 175 updateBasket(response) 176 }, 177 complete: function () { 178 $('#orderSummary .overlay').hide() 179 enableButtons() 180 }, 181 }) 182 }); 183 184 // Handle the clicking of the Update PC button so that they can change their postcode 185 $(document).on('click', '#changeDeliveryPc', function (e) { 186 e.preventDefault(); 187 $('#deliveryPcHolder').hide(); 188 $('#updateFullPostcodeHolder').show(); 189 $('#validate_pc').focus(); 190 }); 191 192 // Handle the update of the Postcode 193 $(document).on('click', '#updateFullPostcodeSubmit', function (e) { 194 e.preventDefault(); 195 196 const validatePc = $('#validate_pc'); 197 validatePc.val(validatePc.val().toUpperCase()); 198 const postcode = validatePc.val().replace(/\s/g, ''); 199 200 if (!validPostcode(postcode)) { 201 $('#missingPostcodeAlert').html('Please enter a full valid UK post code.').show(); 202 } else { 203 $('#missingPostcodeAlert').hide(); 204 updateDeliveryPostcode(postcode); 205 } 206 }); 207 208 // Hide the reviews 209 $("#reviewsDialog").dialog({ 210 autoOpen: false, 211 title: "Reviews", 212 maxHeight: 600, 213 modal: true, 214 buttons: [{ 215 text: "Ok", click: function () { 216 $(this).dialog("close"); 217 } 218 }] 219 }); 220 221 // See if the takeaway is open or closed. If closed show a dialog 222 // if ($('#openClosed').text().toLowerCase() === 'closed') { 223 // window.scrollTo(0, 0); 224 // $("#closedDialog").dialog({ 225 // autoOpen: true, 226 // title: "Closed", 227 // maxHeight: 600, 228 // maxWidth: 300, 229 // modal: true, 230 // buttons: [{ 231 // text: "Ok", click: function () { 232 // $(this).dialog("close"); 233 // } 234 // }] 235 // }); 236 // } 237 238 // The reviews dialog initialization 239 $('.openReviewsDialog').click(function (e) { 240 e.preventDefault(); 241 $("#reviewsDialog").dialog("open"); 242 }); 243 244 // Bind a resize event so we can update cart total positions if needed 245 $(window).on('resize scroll', function () { 246 updateBasketPosition(); 247 }); 248 249 $(document).on('click', '#backToTopLink', function (e) { 250 e.preventDefault(); 251 $(window).scrollTop(0); 252 }); 253 254 // Phone Expanding Category Handler 255 $('.catTitle').click(function () { 256 // Toggle the row 257 var productsRow = $(this).nextAll('.catExpander').first(); 258 259 productsRow.toggleClass( 260 'hidden-phone hidden-tablet', 261 !productsRow.hasClass('hidden-phone') 262 ) 263 }); 264 265 // Phone Checkout Button CLick 266 $(document).on('click', '#phoneViewCartButton', function (e) { 267 e.preventDefault(); 268 269 // Add a hash to the url so we can go back in the browser if we are in phone mode 270 window.location.hash = 'checkout'; 271 272 $('html, body').animate({scrollTop: 0}, 0); 273 }); 274 275 // If the phone back to add items is clicked then hide the cart and show the menu again 276 $(document).on('click', '.phoneHideCartButton', function (e) { 277 e.preventDefault(); 278 279 window.history.back(); 280 281 // Scroll to top 282 $('html, body').animate({scrollTop: 0}, 0); 283 }); 284 285 function changeOrderType(orderType) { 286 287 // Set the global field 288 $('#type').val(orderType); 289 290 // Update the session via ajax call 291 $.ajax({ 292 type: 'POST', 293 url: 'update_type?ts=' + (new Date().getTime()), 294 data: { 295 "orderType": orderType 296 }, 297 beforeSend: function () { 298 $('#orderSummary .overlay').show(); 299 disableButtons(); 300 }, 301 success: function (response) { 302 updateBasket(response); 303 if (orderType === 'd') { 304 $('#deliveryTab').show(); 305 $('#collectionTab').hide(); 306 $('.catTitle.type-collection, .menuLink.type-collection').addClass('disabled'); 307 $('.catTitle.type-delivery, .menuLink.type-delivery').removeClass('disabled'); 308 } else { 309 $('#deliveryTab').hide(); 310 $('#collectionTab').show(); 311 $('.catTitle.type-delivery, .menuLink.type-delivery').addClass('disabled'); 312 $('.catTitle.type-collection, .menuLink.type-collection').removeClass('disabled'); 313 } 314 }, 315 complete: function () { 316 $('#orderSummary .overlay').hide(); 317 enableButtons(); 318 } 319 }); 320 } 321 322 // If URL param is set, change the order type (collection OR delivery) 323 const queryString = window.location.search;
324 const urlParams = new URLSearchParams(queryString); 325 if (urlParams.has('order_method')) { 326 const orderType = urlParams.get('order_method') === 'delivery' ? 'd' : 'c'; 327 changeOrderType(orderType); 328 } 329 330 // If order Type changes we need to update the session 331 $(document).on('change', '#basket input[name=orderTypePicker]', function () { 332 changeOrderType($(this).val()); 333 }); 334 335 // Validate the checkout 336 $(document).on('submit', '#basket #checkoutForm', function () { 337 338 //check basket is valid first (collection only or delivery only items) 339 var orderType = $('#type').val(); 340 if (orderType && orderType !== '') { 341 if (invalidBasketMenu(orderType)) { 342 // Scroll back to the top 343 $('html, body').animate({ 344 scrollTop: $("#orderSummary").offset().top 345 }, 500); 346 return false; 347 } 348 } 349 350 if (orderType === '') { 351 $('#validate_post_code').css('border', '4px solid #ED1C24'); 352 // Scroll back to the top 353 $('html, body').animate({ 354 scrollTop: $("#validate_post_code").offset().top 355 }, 500); 356 return false; 357 } 358 359 // Check that there is a order type selected. 360 if ($('#basket input[name="orderTypePicker"]').val() == '') { 361 alert('Please Select Order Type'); 362 return false; 363 } 364 365 var minOrderValue = parseFloat($('#min_delivery').val()); 366 var minOrderValueCollection = parseFloat($('#min_collection').val()); 367 var cartTotal = parseFloat($('#basket_total').val()); 368 369 // Validate if it is delivery 370 if (orderType === 'd') { 371 // If there is a min order value then we need to check that the cart total is higher and there is no minimum order 372 if (cartTotal < minOrderValue) { 373 alert('Your order subtotal does not meet the minimum value of £' + minOrderValue.toFixed(2) + ' for delivery.'); 374 return false; 375 } 376 } else { 377 // A new minimum collection order value. 378 if (cartTotal < minOrderValueCollection) { 379 alert('Your order subtotal does not meet the minimum value of £' + minOrderValueCollection.toFixed(2) + ' for collection.'); 380 return false; 381 } 382 } 383 384 // If success, we need to show the spinner 385 $('#submit-ajax-load').show(); 386 disableButtons(); 387 window.location.href = 'checkout/loginform'; 388 return false; 389 }); 390 391 $(document).on('click', '.editExtras', function (e) { 392 e.preventDefault(); 393 394 showOptionsAndExtras({ 395 'basket-item-id': $(e.target).data('basket-item-id') 396 }); 397 }); 398 399 /** 400 * Options and extras screen 401 */ 402 // Handle the adding of the options to a product 403 $(document).on('click', '#addProductWithOptions', function (e) { 404 e.preventDefault(); 405 406 // Now loop through the options getting selected text 407 var options = $('#selectOptionsAndExtras').find('select'); 408 var cont = true; // Used to make the form not submit. 409 410 // Check to see if the option value is not empty ie. they have chosen all options. 411 $.each(options, function (i, option) { 412 if ($(option).find("option:selected").val() === '') { 413 $('#optionsMissing').show(); 414 cont = false; 415 return false; 416 } 417 }); 418 419 if (cont) { 420 $('#selectOptionsAndExtras').submit(); 421 } 422 }); 423 424 // Handles the option form submit 425 $(document).on('submit', "#selectOptionsAndExtras", function (ev) { 426 ev.preventDefault(); 427 addToCart($(this).serialize()); 428 }); 429 430 // Click to handle the leaving of the options screen 431 $(document).on('click', '#leaveOptions', function () { 432 window.history.back(); 433 }); 434 435 $(document).on('click', '#options .quantity .minus', function () { 436 const quantityField = $('#quantity'); 437 const quantityHtml = $('#options .quantity .value'); 438 let currentValue = parseInt('0' + quantityField.val(), 10); 439 440 if (currentValue > 1) { 441 currentValue--; 442 quantityField.val(currentValue); 443 quantityHtml.html(currentValue); 444 } 445 }); 446 447 $(document).on('click', '#options .quantity .plus', function () { 448 const quantityField = $('#quantity'); 449 const quantityHtml = $('#options .quantity .value'); 450 let currentValue = parseInt('0' + quantityField.val(), 10); 451 452 if (currentValue < 21) { 453 currentValue++; 454 quantityField.val(currentValue); 455 quantityHtml.html(currentValue); 456 } 457 }); 458 459 460 // If a menu link is clicked hide options show the menu 461 $('.menuLink').click(function () { 462 $('#options').hide(); 463 $('#menu').show(); 464 }); 465 466 $('.menuAddToBasket').click(function () { 467 updateBasketPosition(); 468 469 // Get the data out from the product that add was clicked on 470 var productId = $(this).data("id"); 471 var productName = $(this).data("name"); 472 var parentId = $(this).data("parentid"); 473 var productPrice = $(this).data("price"); 474 var productCategory = $(this).data("category"); 475 var options = $(this).data("options"); 476 var extras = $(this).data("extras"); 477 478 if (!(parentId && parentId !== "")) { 479 parentId = "" 480 } 481 482 // If there are options show the options list 483 if (options === 1 || extras === 1) { 484 showOptionsAndExtras($(this).data()); 485 } else { 486 // Perform the ajax call to add the product to basket and then update the totals etc. 487 addToCart({ 488 "prd_id": productId, 489 "prd_cat": productCategory, 490 "prd_parent": parentId ? parentId : "" 491 }); 492 } 493 }); 494 495 function addToCart(data) { 496 $.ajax({ 497 type: 'POST', 498 url: 'add_to_cart?ts=' + (new Date().getTime()), 499 data: data, 500 beforeSend: function () { 501 $('#orderSummary .overlay').show(); 502 disableButtons(); 503 }, 504 success: function (response) { 505 updateBasket(response); 506 updateBasketPosition(); 507 508 if (window.location.hash !== '') { 509 window.history.back(); 510 } 511 }, 512 error: function () { 513 alert('Unable to add product please try again'); 514 }, 515 complete: function () { 516 $('#orderSummary .overlay').hide(); 517 enableButtons(); 518 } 519 }); 520 } 521 522 // Add to cart click 523 function showOptionsAndExtras(data) { 524 const basketItemId = data['basket-item-id'] || ''; 525 const productId = data.id || ''; 526 527 // Clear any previous options and extras 528 $('#optionsAndExtras').html(''); 529 530 // Hide the menu and show options screen 531 window.location.hash = 'options-and-extras'; 532 533 // Put user back at top of the screen 534 $('html, body').animate({
535 scrollTop: $('.shop-details-bottom').position().top 536 }, 400); 537 538 // Go get the extras screen 539 $.ajax({ 540 type: 'POST', 541 url: 'get_options_and_extras?ts=' + (new Date().getTime()), 542 data: { 543 "prd_id": productId, 544 "basket_item_id": basketItemId 545 }, 546 beforeSend: function () { 547 $('#optionsLoader').show(); 548 disableButtons(); 549 }, 550 success: function (response) { 551 if (response.error !== undefined) { 552 alert('Unable to load product details: ' + response.error); 553 return; 554 } 555 556 $('#optionsAndExtras').html(response.data); 557 }, 558 complete: function () { 559 $('#optionsLoader').hide(); 560 enableButtons(); 561 } 562 }) 563 } 564 565 // The search submit function 566 $('#post_code_search').submit(function (e) { 567 e.preventDefault(); 568 searchLocations(); // Call the search function. 569 }); 570 571 // Handle the click of the closed view shops 572 $('#viewClosedShopsDesktopContainer').click(function (e) { 573 e.preventDefault(); 574 $('#closedShopsDesktopContainer').toggle(); 575 }); 576 577 // Handle a review link click 578 $('.reviews').click(function (e) { 579 e.preventDefault(); 580 var shopId = $(this).data('wid'); 581 582 $.ajax({ 583 type: "POST", 584 url: '/takeaways/get_reviews?ts=' + (new Date().getTime()), 585 data: {shopId: shopId} 586 }) 587 .done(function (msg) { 588 if (msg === false) { 589 return false; 590 } else { 591 $('#reviewsHolder').html(''); 592 593 var reviews = $.parseJSON(msg); 594 595 for (var i = 0; i < reviews.length; i++) { 596 var average = 0; 597 598 // Average rating 599 average = (parseInt(reviews[i].review_food_quality) + parseInt(reviews[i].review_service_quality) + parseInt(reviews[i].review_delivery_quality)) / 3; 600 average = Math.ceil(average) + 1; // ceil and add 1 to make out of 5 601 602 // Split timestamp into [ Y, M, D, h, m, s ] 603 var t = reviews[i].review_date.split(/[- :]/); 604 var n = reviews[i].review_name.split(' '); 605 // Apply each element to the Date function 606 var d = new Date(t[0], t[1] - 1, t[2], t[3], t[4], t[5]); 607 var reviewDate = d.getDate() + '/' + (d.getMonth() + 1) + '/' + d.getFullYear(); 608 var reviewDiv = '<div class="reviewDiv"><p><strong>Placed: </strong>' + reviewDate + '</p><p><strong>Left By: </strong>' + n[0] + '</p>'; 609 610 // Work out the star rating of the shop 611 reviewDiv = reviewDiv + '<p><strong>Overall: </strong>'; 612 var count = 0; 613 614 while (count < average) { 615 reviewDiv = reviewDiv + '<img src="/imgs/star.png" alt="star" />'; 616 count++; 617 } 618 reviewDiv = reviewDiv + '</p>'; 619 620 // If a review description add that to the div 621 if (reviews[i].review_description.length > 0) { 622 reviewDiv = reviewDiv + '<p>' + reviews[i].review_description + '</p>'; 623 } 624 625 reviewDiv = reviewDiv + '<div class="divider_menu"><img src="/imgs/divider_large.png" /></div>'; 626 627 $('#reviewsHolder').append(reviewDiv); 628 629 // Hide the reviews 630 $("#reviewsDialog").dialog({ 631 autoOpen: true, 632 title: "Reviews", 633 maxHeight: 600, 634 modal: true, 635 buttons: [{ 636 text: "Ok", click: function () { 637 $(this).dialog("close"); 638 } 639 }] 640 }); 641 } 642 } 643 }); 644 }); 645 646 // Handle the click of a desktop filter 647 $('.sort_types').change(function (e) { 648 e.preventDefault(); 649 650 var sort_types = $(this).val(); 651 652 $('#shop-details-desktop').html($('.sort-this-desktop').sort(function (a, b) { 653 654 // if there is no filter return 655 var va; 656 var vb; 657 if (sort_types == '') { 658 return false;
659 } 660 661 // If filter by distance make sure that the data type is a float 662 if (sort_types == 'name') { 663 va = $(a).data(sort_types); 664 vb = $(b).data(sort_types); 665 666 } else { 667 va = parseFloat($(a).data(sort_types)); 668 vb = parseFloat($(b).data(sort_types)); 669 } 670 671 if (sort_types == 'name') { 672 // Sort By Name 673 // DESC 674 return va == vb ? 0 : va < vb ? -1 : 1; 675 } else if (sort_types == 'distance') { 676 // Sort By Distance 677 // DESC 678 return va == vb ? 0 : va < vb ? -1 : 1; 679 } else if (sort_types == 'discount') { 680 //va = va.substring(0, va.length - 1); 681 //vb = vb.substring(0, vb.length - 1); 682 return va == vb ? 0 : va > vb ? -1 : 1; 683 } else { 684 // Sort By Rating And 685 // ASC 686 var ratingTemp = va == vb ? 0 : va > vb ? -1 : 1; 687 return ratingTemp; 688 } 689 })); 690 }); 691 692 // The drop down change handle the sort 693 $('#sort_mobile').change(function () { 694 var sort_types = $('#sort_mobile').val(); 695 696 $('#shop-details-mobile').html($('.sort-this-mobile').sort(function (a, b) { 697 // if there is no filter return 698 var va; 699 var vb; 700 if (sort_types == '') { 701 return false; 702 } 703 704 // If filter by distance make sure that the data type is a float 705 if (sort_types == 'name') { 706 va = $(a).data(sort_types); 707 vb = $(b).data(sort_types); 708 } else { 709 va = parseFloat($(a).data(sort_types)); 710 vb = parseFloat($(b).data(sort_types)); 711 } 712 713 if (sort_types == 'name') { 714 // Sort By Name 715 // DESC 716 return va == vb ? 0 : va < vb ? -1 : 1; 717 } else if (sort_types == 'distance') { 718 // Sort By Distance 719 // DESC 720 return va == vb ? 0 : va < vb ? -1 : 1; 721 } else if (sort_types == 'discount') { 722 //va = va.substring(0, va.length - 1); 723 //vb = vb.substring(0, vb.length - 1); 724 return va == vb ? 0 : va > vb ? -1 : 1; 725 } else { 726 // Sort By Rating And 727 // ASC 728 return va == vb ? 0 : va > vb ? -1 : 1; 729 } 730 })); 731 }); 732 733 $("#slider-raitings").slider({ 734 range: "max", 735 min: 0, 736 max: 3, 737 value: 0, 738 slide: function (event, ui) { 739 var val; 740 if (ui.value == 0) { 741 val = 1; 742 } else if (ui.value == 1) { 743 val = 2; 744 } else if (ui.value == 2) { 745 val = 3; 746 } else { 747 val = 4; 748 } 749 750 $(".shop-details-wrapper").each(function (i) { 751 var rating = parseFloat($(this).data('rating')); 752 // If the value is 1 reset the display 753 if (val == 1) { 754 // To avoid mobile view been shown when shops reset 755 if (!$(this).hasClass('closed_shop_list')) { 756 $(this).css('display', ''); 757 } 758 } else { 759 // If the raiting is equel or less than the value of the filter 760 if (parseFloat(val) > rating) { 761 $(this).css('display', 'none'); 762 } else { 763 $(this).css('display', ''); 764 } 765 } 766 }); 767 } 768 }); 769 770 $("#slider-distance").slider({ 771 range: "max", 772 min: 0, 773 max: 2, 774 value: 0, 775 slide: function (event, ui) { 776 var val; 777 if (ui.value == 0) { 778 val = 1; 779 } else if (ui.value == 1) { 780 val = 3; 781 } else { 782 val = 6; 783 } 784 785 $(".shop-details-wrapper").each(function (i) { 786 var distance = $(this).data('distance'); 787 if (distance > val) { 788 $(this).css('display', 'none'); 789 } else { 790 $(this).css('display', ''); 791 } 792 }); 793 } 794 }); 795 796 // Show/hide the login/signup 797 $('#newCustomer').click(function (e) { 798 e.preventDefault(); 799 $('#loginForm').hide(); 800 $('#signUpForm').show(); 801 window.scrollTo(0, 0); 802 }); 803 804 $('#existingCustomer').click(function (e) { 805 e.preventDefault(); 806 $('#signUpForm').hide(); 807 $('#loginForm').show(); 808 window.scrollTo(0, 0); 809 }); 810 811 $('#newCustomerUserArea').click(function (e) { 812 e.preventDefault(); 813 $('#loginFormHolder').addClass('hidden-phone'); 814 $('#signUpFormHolder').removeClass('hidden-phone'); 815 window.scrollTo(0, 0); 816 }); 817 818 $('#existingCustomerUserArea').click(function (e) { 819 e.preventDefault(); 820 $('#signUpFormHolder').addClass('hidden-phone'); 821 $('#loginFormHolder').removeClass('hidden-phone'); 822 window.scrollTo(0, 0); 823 }); 824 825 // Check to see if there are registration errors if so show the signup form automatically. 826 if ($('#signUpErrors').length > 0) { 827 $('#loginForm').hide(); 828 $('#signUpForm').show(); 829 window.scrollTo(0, 0); 830 } 831 832 // CLOSES ALL BOXS ON PAGE LOAD 833 $('.category_content').hide(); 834 835 // Accordian Button For The Menu 836 $('.category_button').click(function (e) { 837 $('.category_button').removeClass('on'); 838 $('.category_content').slideUp('slow'); 839 840 if ($(this).next().is(':hidden') == true) { 841 $(this).addClass('on'); 842 $(this).next().slideDown('slow'); 843 } 844 }); 845 846 // GET THE DELIVERY PRICES FOR THIS POSTCODE 847 if ($('#checkout_page').length > 0) { 848 let lastOrderType = $('#checkout_page input[name="order-type"]:checked').val() 849 let lastPaymentType = $('#checkout_page input[name="payment-type"]:checked').val() 850 851 function updatePostcodeWarning() { 852 const payment_type = $('#checkout_page input[name="payment-type"]:checked').val(); 853 const ot = $('#checkout_page input[name="order-type"]:checked').val(); 854 855 let orderButtonDisplay = payment_type === 'cash' ? 'ORDER NOW' : 'CONTINUE'; 856 857 const updateButton = $('#update-button'); 858 const continueButton = $('#continue-button'); 859 const errorRow = $('#error_row'); 860 const validatePc = $('#validate_pc'); 861 862 // Post code variables 863 const postCode = $.trim(validatePc.val()).replace(/\s+/, "").toUpperCase(); 864 const searched_pc = $.trim($('#delivery_pc').val()).replace(/\s+/, "").toUpperCase(); 865 866 // If delivery is selected and the postcodes don't match, take user to the update postcode block 867 if (ot === 'd' && postCode !== searched_pc) { 868 errorRow.html(renderWarning(
869 'Postcode entered (' + 870 searched_pc + 871 ') does not match registered postcode (' + 872 postCode + 873 '). Please confirm your delivery address and postcode below.' 874 )).show(); 875 updateButton.show(); 876 continueButton.hide(); 877 validatePc.css('border', '2px solid #AB6503'); 878 } else { 879 errorRow.hide(); 880 updateButton.hide(); 881 continueButton.val(orderButtonDisplay).show(); 882 validatePc.css('border', ''); 883 } 884 } 885 886 // Handle change of order type at this stage 887 $('#checkout_page input[name="order-type"]').click(function (ev) { 888 ev.preventDefault(); 889 890 var orderType = $(this).val(); 891 const that = $(this); 892 893 const newCustomerDetailsSectionTitle = orderType === 'c' 894 ? '4. YOUR CUSTOMER COLLECTION DETAILS' 895 : '4. YOUR DELIVERY DETAILS'; 896 const newTitle = orderType === 'c' 897 ? 'BASKET FOR COLLECTION' 898 : 'BASKET FOR DELIVERY'; 899 const newPotLabel = orderType === 'c' 900 ? 'Collection Time' 901 : 'Delivery Time'; 902 903 // Validate 904 if (orderType === lastOrderType) { 905 return; 906 } 907
908 if (invalidBasketMenu(orderType)) { 909 return; 910 } 911 912 if(that.closest('.id_radio').hasClass('radio-disabled')) { 913 return; 914 } 915 916 // Update the session via ajax call 917 $.ajax({ 918 type: 'POST', 919 url: 'checkout/update_type?ts=' + (new Date().getTime()), 920 data: { 921 "orderType": orderType 922 }, 923 beforeSend: function () { 924 $('.information-display .overlay').show(); 925 $('#orderSummary .overlay').show(); 926 disableButtons(); 927 }, 928 success: function (response) { 929 if (response.error === undefined) { 930 that.prop('checked', true); 931 lastOrderType = orderType; 932 updateBasket(response); 933 updatePostcodeWarning(); 934 $('#type_header').html(newTitle); 935 $('#customerDetailsSectionTitle').html(newCustomerDetailsSectionTitle); 936 937 const canPreOrder = $('#checkout_page .preOrderTimePicker').length !== 0; 938 939 if (canPreOrder) { 940 $('#checkout_page .preOrderTimePicker .pot-label').html(newPotLabel); 941 942 const currentPaymentType = $('#checkout_page input[name="payment-type"]:checked'); 943 const isCard = (currentPaymentType.val() || 'card').toLowerCase() === 'card'; 944 const isCash = !isCard; 945 946 // if delivery or collection is not available now 947 const availableNow = that.data('availableNow'); 948 const availableTime = that.data('firstTime'); 949 950 // If available now, enable all payment options 951 if (availableNow) { 952 // Enable cash 953 $('#checkout_page input[name="payment-type"][value="cash"]') 954 .closest('.id_radio') 955 .removeClass('radio-disabled'); 956 957 // Hide warning banner 958 $('#payment-warning').hide(); 959 960 // Set default text to 'As soon as possible' 961 $('#checkout_page .preOrderTimePicker .pot-value') 962 .html('As soon as possible'); 963 964 // Set default value to '' 965 $('#checkout_page input[name="scheduled_at"]') 966 .val(''); 967 } else { 968 969 // Not available now, disable cash and force selection to card 970 // Disable cash 971 $('#checkout_page input[name="payment-type"][value="cash"]') 972 .closest('.id_radio') 973 .addClass('radio-disabled'); 974 975 // Force selection to card 976 if (isCash) { 977 $('#checkout_page input[name="payment-type"][value="card"]') 978 .prop('checked', true) 979 .trigger('click') 980 .trigger('change'); 981 982 // Show warning banner if payment method was not already card 983 $('#payment-warning') 984 .css('display', 'flex') 985 .find('.checkout_page__warn-text-title') 986 .show(); 987 } 988 989 // Set default text to hh:mm 990 $('#checkout_page .preOrderTimePicker .pot-value') 991 .html( 992 (new Date(availableTime)) 993 .toLocaleTimeString('en-GB', { 994 timeZone: 'Europe/London', 995 hour: '2-digit', 996 minute: '2-digit', 997 hour12: false, // Use 24-hour format 998 }) 999 ); 1000 1001 // Set default value to first available time 1002 $('#checkout_page input[name="scheduled_at"]') 1003 .val(availableTime); 1004 } 1005 1006 // Enable/disable the order time picker 1007 $('#checkout_page .preOrderTimePicker') 1008 .toggleClass('pot-disabled', availableTime === '') 1009 } 1010 } 1011 1012 if (response.error !== undefined) { 1013 $('#paymentdeliveryErrors').html(renderError(response.error)).show(); 1014 return; 1015 } 1016 $('#paymentdeliveryErrors').hide(); 1017 }, 1018 complete: function () { 1019 $('#orderSummary .overlay').hide(); 1020 $('.information-display .overlay').hide(); 1021 enableButtons(); 1022 } 1023 }); 1024 }); 1025 1026 $('#checkout_page .preOrderTimePicker').click(function () { 1027 const orderType = $('#checkout_page input[name="order-type"]:checked'); 1028 1029 if($(this).closest('.preOrderTimePicker').hasClass('pot-disabled')) { 1030 return; 1031 } 1032 1033 window.modals.PreOrderTimesModal.show({ 1034 availableNow: orderType.data('availableNow'), 1035 orderType: orderType.val(), 1036 value: $('#checkout_page input[name="scheduled_at"]').val(), 1037 onContinue: value => { 1038 const scheduledAt = $('#checkout_page input[name="scheduled_at"]'); 1039 const originalValue = scheduledAt.val(); 1040 1041 // Update the value 1042 scheduledAt.val(value); 1043 let displayText = 'As soon as possible'; 1044 if(value !== '') { 1045 const date = new Date(value); 1046 displayText = date.toLocaleTimeString('en-GB', { 1047 timeZone: 'Europe/London', 1048 hour: '2-digit', 1049 minute: '2-digit', 1050 hour12: false // Use 24-hour format 1051 }) 1052 } 1053 $('#checkout_page .preOrderTimePicker .pot-value') 1054 .html(displayText); 1055 1056 const paymentType = $('#checkout_page input[name="payment-type"]:checked'); 1057 const isCard = (paymentType.val() || 'card').toLowerCase() === 'card'; 1058 const isCash = !isCard; 1059 const isPreOrder = value !== ''; 1060 const wasPreOrder = originalValue !== ''; 1061 1062 // Switch payment type to card 1063 if (isCash && isPreOrder && !wasPreOrder) { 1064 $('#checkout_page input[name="payment-type"][value="card"]') 1065 .prop('checked', true) 1066 .trigger('click') 1067 .trigger('change'); 1068 1069 $('#payment-warning') 1070 .css('display', 'flex') 1071 .find('.checkout_page__warn-text-title') 1072 .show(); 1073 } else { 1074 $('#payment-warning').hide(); 1075 } 1076 1077 // Disable cash option as this is a pre-order 1078 $('#checkout_page input[name="payment-type"][value="cash"]') 1079 .closest('.id_radio') 1080 .toggleClass('radio-disabled', isPreOrder); 1081 } 1082 }); 1083 }); 1084 1085 $('#payment-warning .checkout_page__warn-close-icon').click(function (ev) { 1086 $('#payment-warning').hide(); 1087 }); 1088 1089 //Handle change of order type at this stage 1090 $('#checkout_page input[name="payment-type"]').click(function (ev) { 1091 ev.preventDefault(); 1092 1093 let paymentType = $(this).val(); 1094 const that = $(this); 1095 1096 // Validate 1097 if (paymentType === lastPaymentType) { 1098 return; 1099 } 1100 1101 const radio = that.closest('.id_radio'); 1102 1103 if(radio.hasClass('radio-disabled')) { 1104 if(!radio.hasClass('radio-card-only')) { 1105 $('#payment-warning') 1106 .css('display', 'flex') 1107 .find('.checkout_page__warn-text-title') 1108 .hide(); 1109 } 1110 return; 1111 } 1112 1113 // Update the session via ajax call 1114 $.ajax({ 1115 type: 'POST', 1116 url: 'checkout/update_payment_type?ts=' + (new Date().getTime()), 1117 data: { 1118 "paymentType": paymentType 1119 }, 1120 beforeSend: function () { 1121 $('.information-display .overlay').show(); 1122 disableButtons(); 1123 }, 1124 success: function (response) { 1125 if (response.error === undefined) { 1126 that.prop('checked', true); 1127 lastPaymentType = paymentType; 1128 updatePostcodeWarning(); 1129 } 1130 if (response.error !== undefined) { 1131 $('#paymentdeliveryErrors').html(renderError(response.error)).show(); 1132 return; 1133 } 1134 $('#paymentdeliveryErrors').hide(); 1135 }, 1136 complete: function () { 1137 $('.information-display .overlay').hide(); 1138 enableButtons(); 1139 } 1140 }); 1141 }); 1142 1143 $("[data-hide]").on("click", function () { 1144 $(this).closest("." + $(this).attr("data-hide")).hide(); 1145 }); 1146 1147 $('#checkout_page #continue-button, #checkout_page #update-button').click(function () { 1148 const mode = $(this).val().toLowerCase(); 1149 const postCode = $.trim($('#validate_pc').val()).replace(/\s+/g, '').toLowerCase(); 1150 1151 // Validate 1152 if (!validPostcode(postCode)) { 1153 alert('ALERT: Please Enter A Full Valid UK Post Code'); 1154 return; 1155 } 1156 1157 if (postCode === '' || postCode.length <= 4) { 1158 alert('ALERT: Please Enter A Valid Post Code'); 1159 return; 1160 } 1161 1162 switch (mode) { 1163 case 'update': 1164 updateDeliveryAddress(function () { 1165 updatePostcodeWarning() 1166 }) 1167 break; 1168 1169 case 'order now': 1170 case 'continue': 1171 1172 // Validate 1173 const cashCard = $('input:radio[name=payment-type]:checked').val(); 1174 const cashCardPresent = typeof cashCard !== 'undefined'; 1175 1176 if (!cashCardPresent) { 1177 $('#paymentOption').css('border', '3px solid #a94442'); 1178 $('#cashCardError').show(); 1179 $('html, body').animate({ 1180 scrollTop: $("#cashCardError").offset().top 1181 }, 500); 1182 return false;
1183 } else { 1184 $('#paymentOption').css('border', ''); 1185 } 1186 1187 // Place the order 1188 order_now(); 1189 break; 1190 } 1191 }); 1192 1193 $('#checkout_page #update-address-form input[name="postcode"]').keyup(function () { 1194 updatePostcodeWarning(); 1195 }); 1196 1197 updatePostcodeWarning(); 1198 } 1199 1200 // Show/hide the login/signup 1201 $('#show_closed').click(function (e) { 1202 if ($(".closed_shop_list").is(":hidden")) { 1203 $(".closed_shop_list").slideDown("slow"); 1204 $('html, body').animate({ 1205 scrollTop: $('#closed_shops').offset().top 1206 }, 500); 1207 } else { 1208 $(".closed_shop_list").slideToggle("slow"); 1209 } 1210 }); 1211 1212 // $('#takeaway-signup-captcha').click(function(e){ 1213 // e.preventDefault(); 1214 // grecaptcha.ready(function() { 1215 // grecaptcha.execute('6LfHujcnAAAAANoJ6M_LeOGXwQktW3XCmIIEP0Ha', {action: 'submit'}).then(function(token) { 1216 // $('form[action="/contact/takeawaySignup"]').submit(); 1217 // }); 1218 // }); 1219 // }); 1220 1221 // Finally initialise the screen 1222 renderPhoneCartFooter(); 1223 1224 // Search results dropdowns 1225 $('#sortDropdown').click(function () { 1226 $('#sortDropdown').children('img').toggleClass('results-filter__dropdown-closed'); 1227 $('#sortList').toggle(); 1228 }) 1229 $('#offerDropdown').click(function () { 1230 $('#offerDropdown').children('img').toggleClass('results-filter__dropdown-closed'); 1231 $('#offerList').toggle(); 1232 }) 1233 $('#cuisineDropdown').click(function () { 1234 $('#cuisineDropdown').children('img').toggleClass('results-filter__dropdown-closed'); 1235 $('#cuisineList').toggle(); 1236 }) 1237 $('#sortList').click(function () { 1238 $('#results-filter__list--start-closed').children('img').toggleClass('results-filter__dropdown-closed'); 1239 $('#results-filter__list--start-closed').toggle(); 1240 }) 1241 // sorting selected state 1242 $('.results-filter__option--sorting, .filter-overlay__option--sorting').click(function () { 1243 if ($(this).find('.filter-overlay__radio-button--active').length === 0) { 1244 $('.results-filter__option--sorting, .filter-overlay__option--sorting').children('.filter-overlay__radio-button').removeClass('filter-overlay__radio-button--active') 1245 $(this).children('.filter-overlay__radio-button').addClass('filter-overlay__radio-button--active') 1246 } 1247 1248 let sortType = $(this).find('span').text().trim(); 1249 currentSort = sortType; 1250 sortTakeaways(sortType); 1251 }) 1252 1253 // sorting hover state 1254 $('.results-filter__option--sorting, .filter-overlay__option--sorting').hover(function () { 1255 if ($(this).find('.filter-overlay__radio-button--active').length === 0) { 1256 $(this).children('.filter-overlay__radio-button').addClass('filter-overlay__radio-button--hover') 1257 } 1258 }, function () { 1259 if ($(this).find('.filter-overlay__radio-button--active').length === 0) { 1260 $(this).children('.filter-overlay__radio-button').removeClass('filter-overlay__radio-button--hover') 1261 } 1262 }) 1263 // filter option hover state 1264 $('.results-filter__option--filter').not('.results-filter__option--disabled').hover(function () { 1265 if ($(this).find('.results-filter__option-icon').attr("src") === "/img/checkbox.svg") { 1266 $(this).find('.results-filter__option-icon').attr("src", "/img/checkbox-hover.svg"); 1267 } 1268 }, function () { 1269 if ($(this).find('.results-filter__option-icon').attr("src") === "/img/checkbox-hover.svg") { 1270 $(this).find('.results-filter__option-icon').attr("src", "/img/checkbox.svg"); 1271 } 1272 }) 1273 1274 // sorting selected state 1275 var currentSort = 'Discount'; 1276 var searchTerm = ''; 1277 var filterCount = 0; 1278 const tempOffers = new Map(); 1279 const tempCuisines = new Map(); 1280 const selectedOffers = new Map(); 1281 const selectedCuisines = new Map(); 1282 1283 // filter option selected state 1284 $('.results-filter__option--filter, .filter-overlay__option--filter') 1285 .not('.results-filter__option--disabled, .filter-overlay__option--disabled') 1286 .click(function () { 1287 let offerType = $(this).find('span').data('offertype'); 1288 let foodType = $(this).find('span').data('foodtype'); 1289 let checkboxImg = $(this).find('.results-filter__option-icon'); 1290 1291 // Toggle checkbox image 1292 if (offerType) { 1293 if ($(this).find('.results-filter__option-icon').attr("src") === "/img/checkbox.svg" || $(this).find('.results-filter__option-icon').attr("src") === "/img/checkbox-hover.svg") { 1294 if (offerType === "All Offers") { 1295 // Clear all other offers and checkboxes 1296 selectedOffers.clear(); 1297 $('.results-filter__option--filter span[data-offertype], .filter-overlay__option--filter span[data-offertype]') 1298 .closest('.filter-overlay__option--filter, .results-filter__option--filter') 1299 .not('.filter-overlay__option--disabled, .results-filter__option--disabled') 1300 .find('.results-filter__option-icon') 1301 .attr("src", "/img/checkbox.svg"); 1302 } else { 1303 // Remove "All Offers" and clear checkbox 1304 selectedOffers.delete("All Offers"); 1305 $('.results-filter__option--filter span[data-offertype="All Offers"], .filter-overlay__option--filter span[data-offertype="All Offers"]') 1306 .closest('.filter-overlay__option--filter, .results-filter__option--filter') 1307 .find('.results-filter__option-icon') 1308 .attr("src", "/img/checkbox.svg"); 1309 } 1310 checkboxImg.attr("src", "/img/checkbox-ticked.svg"); 1311 selectedOffers.set(offerType, filterCount++); 1312 } else { 1313 checkboxImg.attr("src", "/img/checkbox.svg"); 1314 selectedOffers.delete(offerType); 1315 } 1316 } else { 1317 if ($(this).find('.results-filter__option-icon').attr("src") === "/img/checkbox.svg" || $(this).find('.results-filter__option-icon').attr("src") === "/img/checkbox-hover.svg") { 1318 checkboxImg.attr("src", "/img/checkbox-ticked.svg"); 1319 selectedCuisines.set(foodType, filterCount++); 1320 } else { 1321 checkboxImg.attr("src", "/img/checkbox.svg");
1322 selectedCuisines.delete(foodType); 1323 } 1324 } 1325 1326 // Update results and filter tags 1327 filterTakeaways(); 1328 updateFilterTags(); 1329 }); 1330 1331 // Add click event to remove tags 1332 $('.search-results__filter-tag-wrapper').on('click', '.search-results__filter-tag-icon', function () { 1333 1334 let offerToRemove = $(this).data('offer'); 1335 let cuisineToRemove = $(this).data('cuisine'); 1336 1337 if (offerToRemove) { 1338 // Remove from selected offers 1339 selectedOffers.delete(offerToRemove); 1340 1341 // Find the corresponding filter checkbox and update its state manually 1342 let checkboxWrapper = $('.filter-overlay__option--filter span[data-offertype="' + offerToRemove + '"], .results-filter__option--filter span[data-offertype="' + offerToRemove + '"]') 1343 .closest('.filter-overlay__option--filter, .results-filter__option--filter'); 1344 1345 if (checkboxWrapper.length) { 1346 let checkboxImg = checkboxWrapper.find('.results-filter__option-icon'); 1347 if (checkboxImg.length) { 1348 checkboxImg.attr("src", "/img/checkbox.svg"); 1349 } 1350 } 1351 } else { 1352 // Remove from selected cuisines 1353 selectedCuisines.delete(cuisineToRemove); 1354 1355 // Find the corresponding filter checkbox and update its state manually 1356 let checkboxWrapper = $('.filter-overlay__option--filter span[data-foodtype="' + cuisineToRemove + '"], .results-filter__option--filter span[data-foodtype="' + cuisineToRemove + '"]') 1357 .closest('.filter-overlay__option--filter, .results-filter__option--filter'); 1358 1359 if (checkboxWrapper.length) { 1360 let checkboxImg = checkboxWrapper.find('.results-filter__option-icon'); 1361 if (checkboxImg.length) { 1362 checkboxImg.attr("src", "/img/checkbox.svg"); 1363 } 1364 } 1365 } 1366 1367 // Update results and filter tags 1368 filterTakeaways(); 1369 updateFilterTags(); 1370 }); 1371 1372 function updateCheckboxes() { 1373 1374 // Clear checkboxes 1375 $('.results-filter__option--filter span[data-offertype], .filter-overlay__option--filter span[data-offertype]') 1376 .closest('.filter-overlay__option--filter, .results-filter__option--filter') 1377 .find('.results-filter__option-icon') 1378 .attr("src", "/img/checkbox.svg"); 1379 $('.results-filter__option--filter span[data-foodtype], .filter-overlay__option--filter span[data-foodtype]') 1380 .closest('.filter-overlay__option--filter, .results-filter__option--filter') 1381 .find('.results-filter__option-icon') 1382 .attr("src", "/img/checkbox.svg"); 1383 1384 // Add correct checkboxes 1385 selectedOffers.forEach(function (offer) { 1386 $('.results-filter__option--filter span[data-offertype="' + offer + '"], .filter-overlay__option--filter span[data-offertype="' + offer + '"]') 1387 .closest('.filter-overlay__option--filter, .results-filter__option--filter') 1388 .find('.results-filter__option-icon') 1389 .attr("src", "/img/checkbox-ticked.svg"); 1390 }); 1391 selectedCuisines.forEach(function (cuisine) { 1392 $('.results-filter__option--filter span[data-foodtype="' + cuisine + '"], .filter-overlay__option--filter span[data-foodtype="' + cuisine + '"]') 1393 .closest('.filter-overlay__option--filter, .results-filter__option--filter') 1394 .find('.results-filter__option-icon') 1395 .attr("src", "/img/checkbox-ticked.svg"); 1396 }); 1397 } 1398 1399 /** 1400 * Update the filter tags at the top of the page 1401 */ 1402 function updateFilterTags() { 1403 1404 let filterTags = []; 1405 1406 // Add selected offers 1407 selectedOffers.forEach((id, label) => { 1408 filterTags.push({ label: label, id: id, type: 'offer' }); 1409 }); 1410 1411 // Add selected cuisines 1412 selectedCuisines.forEach((id, label) => { 1413 filterTags.push({ label: label, id: id, type: 'cuisine' }); 1414 }); 1415 1416 // Sort filters by ID 1417 filterTags.sort((a, b) => a.id - b.id); 1418 1419 // Clear existing tags 1420 $('.search-results__filter-tag-wrapper').empty(); 1421 1422 // Set filter tags
1423 filterTags.forEach(function (filter) { 1424 let tagHtml = `<div class="search-results__filter-tag" data-id="${filter.id}"> 1425 <div>${filter.label}</div> 1426 <img src="/img/close-icon-white.svg" 1427 class="search-results__filter-tag-icon" 1428 data-${filter.type}="${filter.label}" /> 1429 </div>`; 1430 $('.search-results__filter-tag-wrapper').append(tagHtml); 1431 }); 1432 1433 // Update counters for mobile 1434 let totalFilters = filterTags.length; 1435 if (totalFilters > 0) { 1436 $('#filterIcon').hide(); 1437 $('.search-results__filter-counter').show(); 1438 $('.search-results__filter-counter').text(totalFilters); 1439 $('.filter-overlay__header-tag').text(totalFilters + ' Selected'); 1440 } else { 1441 $('#filterIcon').show(); 1442 $('.search-results__filter-counter').hide(); 1443 $('.filter-overlay__header-tag').text('0 Selected'); 1444 } 1445 1446 // Scroll to top of page 1447 window.scrollTo({ top: 0, behavior: "smooth" }); 1448 } 1449 1450 function resetSearch() { 1451 // Show/hide clear button 1452 if (searchTerm.length > 0) { 1453 if ($(window).width() < 768) { 1454 $('.empty-results__heading').text('Search Results for "' + searchTerm + '"'); 1455 } else { 1456 $('.search-results__title').text('Search Results for "' + searchTerm + '"'); 1457 } 1458 $('.results-filter__close-icon').removeClass('hidden'); 1459 } else { 1460 $('.search-results__title').text('Search Results'); 1461 $('.results-filter__close-icon').addClass('hidden'); 1462 } 1463 } 1464 1465 // Handle filtering of takeaway cards based on selected cuisines 1466 function filterTakeaways() { 1467 let totalTakeaways = 0; 1468 let postcode = $('.total-takeaways-count').data('postcode'); 1469 1470 $('.shop-card').each(function () { 1471 1472 // Match search filter 1473 let matchesSearch = searchTerm.length === 0 1474 || $(this).data('name').toLowerCase().includes(searchTerm.toLowerCase()); 1475 1476 // Match offer filter 1477 let offerTypesRaw = $(this).data('offertypes'); 1478 let offerTypes = offerTypesRaw ? offerTypesRaw.split(', ').map(type => type.trim()).filter(type => type !== "") : []; 1479 1480 let matchesOffer; 1481 if (selectedOffers.has("All Offers")) { 1482 matchesOffer = offerTypes.length > 0; 1483 } else { 1484 matchesOffer = selectedOffers.size === 0 || offerTypes.some(type => selectedOffers.has(type)); 1485 } 1486 1487 // Match cuisine filter 1488 let foodTypes = $(this).data('foodtypes').split(', ').map(type => type.trim()); 1489 let matchesCuisine = selectedCuisines.size === 0 || foodTypes.some(type => selectedCuisines.has(type)); 1490 1491 if (matchesSearch && matchesOffer && matchesCuisine) totalTakeaways++; 1492 1493 $(this).toggle(matchesSearch && matchesOffer && matchesCuisine); 1494 }); 1495 1496 // Sort shops 1497 sortTakeaways(currentSort); 1498 1499 // Update the total takeaway count 1500 $('.total-takeaways-count').text(totalTakeaways + " takeaway" + (totalTakeaways != 1 ? "s" : "") + " near " + postcode); 1501 1502 // Show empty results state 1503 if (totalTakeaways == 0) { 1504 $('.empty-results').css('display', 'flex'); 1505 $(window).width() < 768 && $('.search-results__title-wrapper').hide(); 1506 } else { 1507 $('.empty-results').css('display', 'none'); 1508 $(window).width() < 768 && $('.search-results__title-wrapper').show(); 1509 } 1510 } 1511 1512 $('.results-filter__search-input').on('keyup', function () { 1513 searchTerm = $(this).val().trim(); 1514 resetSearch(); 1515 1516 // Filter takeaways 1517 filterTakeaways(); 1518 }); 1519 1520 // Clear search input on no results 1521 $('.empty-results__button--reset-search').on('click', function() { 1522 $('.results-filter__search-input').val(''); 1523 clearAll(); 1524 resetSearch(); 1525 filterTakeaways(); 1526 }) 1527 1528 // Clear search input and reset list when clicking the "X" button 1529 $('.results-filter__close-icon').on('click', function () { 1530 $('.results-filter__search-input').val(''); 1531 searchTerm = $(this).val().trim(); 1532 $(this).addClass('hidden'); 1533 1534 // Reset header 1535 $('.search-results__title').text('Search Results'); 1536 1537 // Filter takeaways 1538 filterTakeaways(); 1539 }); 1540 1541 $('.filter-overlay__footer-button--apply-filters').click(function () { 1542 filterTakeaways(); 1543 $('.filter-overlay').toggle(); 1544 }) 1545 1546 $('.filter-overlay__footer-button--clear-filters').click(function () { 1547 clearAll(); 1548 $('.filter-overlay').toggle(); 1549 }) 1550 1551 function clearAll() { 1552 1553 // Clear search 1554 searchTerm = ''; 1555 1556 // Clear offer and reset checkboxes
1557 selectedOffers.forEach(function (id, offer) { 1558 let checkboxWrapper = $('.filter-overlay__option--filter span[data-offertype="' + offer + '"], .results-filter__option--filter span[data-offertype="' + offer + '"]') 1559 .closest('.filter-overlay__option--filter, .results-filter__option--filter'); 1560 1561 if (checkboxWrapper.length) { 1562 let checkboxImg = checkboxWrapper.find('.results-filter__option-icon'); 1563 if (checkboxImg.length) { 1564 checkboxImg.attr("src", "/img/checkbox.svg"); 1565 } 1566 } 1567 }); 1568 selectedOffers.clear(); 1569 1570 // Clear cuisines and reset checkboxes 1571 selectedCuisines.forEach(function (id, cuisine) { 1572 let checkboxWrapper = $('.filter-overlay__option--filter span[data-foodtype="' + cuisine + '"], .results-filter__option--filter span[data-foodtype="' + cuisine + '"]') 1573 .closest('.filter-overlay__option--filter, .results-filter__option--filter'); 1574 1575 if (checkboxWrapper.length) { 1576 let checkboxImg = checkboxWrapper.find('.results-filter__option-icon'); 1577 if (checkboxImg.length) { 1578 checkboxImg.attr("src", "/img/checkbox.svg"); 1579 } 1580 } 1581 }); 1582 selectedCuisines.clear(); 1583 1584 // Update results and filter tags 1585 filterTakeaways(); 1586 updateFilterTags(); 1587 } 1588 1589 // Open filter overlay 1590 $('.search-results__filter-button').click(function () { 1591 1592 // Set temp offers 1593 tempOffers.clear(); 1594 selectedOffers.forEach((id, offer) => tempOffers.set(offer, id)); 1595 1596 // Set temp cuisines 1597 tempCuisines.clear(); 1598 selectedCuisines.forEach((id, cuisine) => tempCuisines.set(cuisine, id)); 1599 1600 $('.filter-overlay').toggle(); 1601 }); 1602 1603 // Toggle search results filter overlay 1604 $('#overlayClose').click(function () { 1605 1606 // Set temp offers 1607 selectedOffers.clear(); 1608 tempOffers.forEach((id, offer) => selectedOffers.set(offer, id)); 1609 tempOffers.clear(); 1610 1611 // Set temp cuisines 1612 selectedCuisines.clear(); 1613 tempCuisines.forEach((id, cuisine) => selectedCuisines.set(cuisine, id)); 1614 tempCuisines.clear(); 1615 1616 // Update results, filter tags and filter checkboxes 1617 filterTakeaways(); 1618 updateFilterTags(); 1619 updateCheckboxes(); 1620 1621 $('.filter-overlay').toggle(); 1622 }); 1623 1624 // Apply filters and close overlay 1625 $('.apply-filters-btn').click(function () { 1626 filterTakeaways(); 1627 }); 1628}); 1629 1630function reduceQuantity(basketItemId) { 1631 $.ajax({ 1632 type: "POST", 1633 url: 'decrease_quantity_in_basket?ts=' + (new Date().getTime()), 1634 data: { 1635 "basket_item_id": basketItemId, 1636 }, 1637 beforeSend: function () { 1638 $('#orderSummary .overlay').show(); 1639 disableButtons(); 1640 }, 1641 success: function (response) { 1642 updateBasket(response); 1643 updateBasketPosition(); 1644 }, 1645 error: function () { 1646 console.log('Error in reduceQuantity() item id ' + basketItemId); 1647 }, 1648 complete: function () { 1649 $('#orderSummary .overlay').hide(); 1650 enableButtons(); 1651 } 1652 }); 1653} 1654 1655/** 1656 * Removes an item from the cart 1657 */ 1658function removeFromCart(basketItemId) { 1659 $.ajax({ 1660 type: "POST", 1661 url: 'delete_product_from_basket?ts=' + (new Date().getTime()), 1662 data: { 1663 "basket_item_id": basketItemId, 1664 }, 1665 beforeSend: function () { 1666 $('#orderSummary .overlay').show(); 1667 disableButtons(); 1668 }, 1669 success: function (response) { 1670 updateBasket(response); 1671 updateBasketPosition(); 1672 }, 1673 complete: function () { 1674 $('#orderSummary .overlay').hide(); 1675 enableButtons(); 1676 } 1677 }); 1678 return false; 1679} 1680 1681/** 1682 * Sort Takeaways 1683 * @param sortType 1684 */ 1685function sortTakeaways(sortType = 'discount') { 1686 let items = $('.shop-card').toArray(); 1687 1688 items.sort((a, b) => { 1689 let aValue, bValue; 1690 1691 switch (sortType) { 1692 case 'Delivery Cost': 1693 aValue = parseFloat($(a).data('deliveryCost') || 99999); 1694 bValue = parseFloat($(b).data('deliveryCost') || 99999); 1695 if (aValue === bValue) { 1696 return secondarySort(a, b); 1697 } 1698 return aValue - bValue; 1699 case 'Distance': 1700 aValue = parseFloat($(a).data('distance') || 0); 1701 bValue = parseFloat($(b).data('distance') || 0); 1702 if (aValue === bValue) { 1703 return secondarySort(a, b); 1704 } 1705 return aValue - bValue; 1706 case 'Name': 1707 aValue = $(a).data('name').toLowerCase(); 1708 bValue = $(b).data('name').toLowerCase(); 1709 return aValue.localeCompare(bValue); 1710 case 'Rating': 1711 aValue = parseFloat($(a).data('rating') || 0); 1712 bValue = parseFloat($(b).data('rating') || 0); 1713 if (aValue === bValue) { 1714 return secondarySort(a, b); 1715 } 1716 return bValue - aValue; 1717 case 'Total Reviews': 1718 aValue = parseInt($(a).data('totalReviews') || 0); 1719 bValue = parseInt($(b).data('totalReviews') || 0); 1720 if (aValue === bValue) { 1721 return secondarySort(a, b); 1722 } 1723 return bValue - aValue; 1724 case 'Discount': 1725 default: 1726 aValue = parseFloat($(a).data('discount') || 0); 1727 bValue = parseFloat($(b).data('discount') || 0); 1728 if (aValue === bValue) { 1729 return secondarySort(a, b); 1730 } 1731 return bValue - aValue; 1732 } 1733 }); 1734 1735 // Final Sort for Shops That Are Open 1736 items.sort((a, b) => { 1737 let aOpen = $(a).data('isOpen') ? 1 : 0; 1738 let bOpen = $(b).data('isOpen') ? 1 : 0; 1739 return bOpen - aOpen; 1740 }); 1741 1742 $('.shop-card-wrapper').empty().append(items); 1743} 1744 1745function secondarySort(a, b) { 1746 let aRandom = parseFloat($(a).data('randomSortOrder') || 0); 1747 let bRandom = parseFloat($(b).data('randomSortOrder') || 0); 1748 return aRandom - bRandom; 1749} 1750 1751function renderPhoneCartFooter() { 1752 // Get total product count (this doesn't exist for empty basket, so handle that)
1753 const productCount = parseInt($('#basket_product_count').val() || '0', 10); 1754 1755 // Update the phone footer 1756 const basketSubTotal = $('#basket_sub_total').val(); 1757 const basketTotal = $('#basket_total').val(); 1758 1759 $('#phoneCartFooterItemText').html(productCount === 1 ? 'item' : 'items'); 1760 $('#phoneCartFooterTotalProducts').html(productCount); 1761 $('#phoneCartFooterSubTotalPrice') 1762 .toggle(basketSubTotal !== basketTotal) 1763 .find('span') 1764 .html(basketSubTotal); 1765 $('#phoneCartFooterTotalPrice').html(basketTotal); 1766 $('#phoneCartFooter').toggleClass('hidden-phone', productCount === 0); 1767} 1768 1769function updateBasket(response) { 1770 1771 if (response.error !== undefined) { 1772 alert('A basket error has occurred: ' + response.error); 1773 return; 1774 } 1775 1776 // Update the basket html directly 1777 $('#basket').html(response.data.html); 1778 1779 // Update the basket errors section if available 1780 const basketErrorsField = $('#basket-errors'); 1781 if (basketErrorsField.length !== 0) { 1782 const errors = response.data.basketErrors; 1783 if (errors.length === 0) { 1784 basketErrorsField.hide(); 1785 $('#continue-button').removeAttr('disabled'); 1786 } else { 1787 basketErrorsField.html(renderError(errors[0], "Uh oh, we've found a basket error")).show(); 1788 $('#continue-button').attr('disabled', true); 1789 } 1790 } 1791 1792 // Reset counters 1793 $('[id^=product-count-]').html('0').addClass('hide'); 1794 1795 // Sync counters with basket 1796 $('#basket .cartItem').each(function (e) { 1797 const id = $(this).data('prd-id'); 1798 const quantity = $(this).data('qty'); 1799 const countField = $('#product-count-' + id); 1800 1801 countField 1802 .html(parseInt('0' + countField.text(), 10) + quantity) 1803 .removeClass('hide'); 1804 }); 1805 1806 // Update the phone footer 1807 renderPhoneCartFooter(); 1808} 1809 1810// enabling and disabling buttons to prevent button presses during loading times 1811function enableButtons() { 1812 $('#discount-code, #discount-code-apply-button, #basket .applied-codes-container, #order_button input[type=button], #checkout-img-right, .editExtras, #delColRadioHolder, #changeDeliveryPc, #updateFullPostcodeSubmit, #orderTypePickerCollection, #orderTypePickerDelivery, .menuAddToBasket.button-add, .cart_remove_item, #reduce_quantity_button, #addProductWithOptions, .checkout input').removeClass('disabled'); 1813} 1814 1815function disableButtons() { 1816 $('#discount-code, #discount-code-apply-button, #basket .applied-codes-container, #order_button input[type=button], #checkout-img-right, .editExtras, #delColRadioHolder, #changeDeliveryPc, #updateFullPostcodeSubmit, #orderTypePickerCollection, #orderTypePickerDelivery, .menuAddToBasket.button-add, .cart_remove_item, #reduce_quantity_button, #addProductWithOptions, .checkout input').addClass('disabled'); 1817} 1818 1819/** 1820 * Updates the position of the basket if needs be. Can be called after something has been added to cart or when window scrolls. 1821 */ 1822function updateBasketPosition() { 1823 1824 try { 1825 var y = $(this).scrollTop(); 1826 var top = $('#totalsSeperator').offset().top; 1827 1828 // Whether that's below the form 1829 if (y >= top) { 1830 1831 // If the window is not wide enough then dont do the scroll. 1832 if ($(window).width() < 768) { 1833 $('#stickyContainer').css({'margin': '', 'max-width': '', 'width': ''}); 1834 return false; 1835 } 1836 1837 // check we are past sidebar height so we only do this when we are far down the page 1838 var sidebar = $('#orderSummary'); 1839 var bottomOfSidebar = sidebar.position().top + sidebar.outerHeight(); 1840 1841 if (y < (bottomOfSidebar / 1.5)) { 1842 // if (y < (bottomOfSidebar)) { 1843 // otherwise remove it 1844 $('#stickyContainer') 1845 .removeClass('menu-box sticky hidden-phone') 1846 .css({'margin': '', 'max-width': '', 'width': ''}); 1847 $('#backToTopLink') 1848 .addClass('hide'); 1849 return false; 1850 } 1851 1852 // Correct the width 1853 var desiredWidth = $('#basket').outerWidth(); 1854 1855 // if so, ad the fixed class 1856 $('#stickyContainer') 1857 .addClass('menu-box sticky hidden-phone') 1858 .css({ 1859 'margin': '-2px', 1860 'max-width': desiredWidth + 'px', 1861 'width': desiredWidth + 'px' 1862 }); 1863 $('#backToTopLink') 1864 .removeClass('hide'); 1865 1866 } else { 1867 // otherwise remove it 1868 $('#stickyContainer') 1869 .removeClass('menu-box sticky hidden-phone') 1870 .css({'margin': '', 'max-width': '', 'width': ''}); 1871 1872 $('#backToTopLink') 1873 .addClass('hide'); 1874 } 1875 } catch (e) { 1876 } 1877} 1878 1879function renderError(text, title = '') { 1880 const punctuated = text.replace(/\.+$/, '') + '.'; 1881 const titleText = title === '' ? '' : '<div class="new-alert-title">' + title + '</div>'; 1882 return '<div class="new-alert new-alert-error"><div>' + titleText + punctuated + '</div></div>'; 1883} 1884 1885function renderWarning(text, title = '') { 1886 const punctuated = text.replace(/\.+$/, '') + '.'; 1887 const titleText = title === '' ? '' : '<div class="new-alert-title">' + title + '</div>'; 1888 return '<div class="new-alert new-alert-warning"><div>' + titleText + punctuated + '</div></div>'; 1889} 1890 1891function updateDeliveryPostcode(postcode, onComplete = null) { 1892 $.ajax({ 1893 type: "POST", 1894 url: 'update_delivery_postcode?ts=' + (new Date().getTime()), 1895 data: { 1896 "postcode": postcode 1897 }, 1898 beforeSend: function () { 1899 $('#orderSummary .overlay').show(); 1900 disableButtons(); 1901 }, 1902 success: function (response) { 1903 if (response.error !== undefined) { 1904 $('#missingPostcodeAlert').html(response.error).show(); 1905 $('#paymentdeliveryErrors').html(renderError(response.error)).show(); 1906 return; 1907 } 1908 $('#missingPostcodeAlert').hide(); 1909 $('#paymentdeliveryErrors').hide(); 1910 $('#delivery_pc').val(postcode); 1911 $('#deliveryPc').html(postcode); 1912 updateBasket(response); 1913 $('#deliveryPcHolder').show(); 1914 $('#updateFullPostcodeHolder').hide(); 1915 }, 1916 complete: function () { 1917 $('#orderSummary .overlay').hide(); 1918 enableButtons(); 1919 if (onComplete !== null) { 1920 onComplete(); 1921 } 1922 } 1923 }) 1924} 1925 1926function updateDeliveryAddress(onComplete = null) { 1927 const postcode = $.trim($('#validate_pc').val()).toUpperCase(); 1928 const payload = { 1929 "landline": $('#delivery_landline').val(), 1930 "mobile": $('#delivery_mobile').val(), 1931 "firstname": $('#delivery_firstname').val(), 1932 "lastname": $('#delivery_lastname').val(), 1933 "house_no": $('#delivery_house_number').val(), 1934 "address1": $('#delivery_address1').val(), 1935 "address2": $('#delivery_address2').val(), 1936 "town": $('#delivery_town').val(), 1937 "postcode": postcode, 1938 } 1939 1940 $.ajax({ 1941 type: "POST", 1942 url: 'checkout/update_delivery_address?ts=' + (new Date().getTime()), 1943 data: payload, 1944 beforeSend: function () { 1945 $('#orderSummary .overlay').show(); 1946 disableButtons(); 1947 }, 1948 success: function (response) { 1949 if (response.error !== undefined) { 1950 $('#paymentdeliveryErrors') 1951 .html(renderError(response.error)) 1952 .show(); 1953 return; 1954 } 1955 $('#paymentdeliveryErrors').hide(); 1956 $('#delivery_pc').val(postcode); 1957 $('#validate_pc').val(postcode); 1958 updateBasket(response, 'checkout'); 1959 }, 1960 complete: function () { 1961 $('#orderSummary .overlay').hide(); 1962 enableButtons(); 1963 if (onComplete !== null) { 1964 onComplete(); 1965 } 1966 } 1967 }) 1968} 1969
1970function invalidBasketMenu(orderType) { 1971 var toCheckAgainst = ''; 1972 var errorMessage = ''; 1973 var invalidBasket = false; 1974 if (orderType === 'c') { 1975 toCheckAgainst = "Delivery"; 1976 errorMessage = "You have chosen an order for Collection but your basket contains delivery-only items. Please check your basket."; 1977 } 1978 if (orderType === 'd') { 1979 toCheckAgainst = "Collection"; 1980 errorMessage = "You have chosen an order for Delivery but your basket contains collection-only items. Please check your basket."; 1981 } 1982 $('#myOrder .cartItem').each(function (e) { 1983 if ($(this).data('col-del') === toCheckAgainst) { 1984 invalidBasket = true; 1985 $(this).css('border', '4px solid #ED1C24'); 1986 } 1987 }); 1988 1989 if (invalidBasket) { 1990 alert(errorMessage); 1991 } 1992 1993 return invalidBasket; 1994} 1995 1996$("#alergyInfo").on('click', function () { 1997 $("#alergyWindow").fadeIn("fast"); 1998}); 1999 2000$("#alergyCross").on('click', function () { 2001 $("#alergyWindow").fadeOut("fast"); 2002}); 2003 2004function requestValidPostcode($formContainer, $input) { 2005 if ($formContainer.length) { 2006 var errorToShow = $formContainer.find('#search-form-pc-err'); 2007 errorToShow.css('visibility', 'visible'); 2008 $input.css({"border-color": "red", "border-style": "dashed"}); 2009 setTimeout(function () { 2010 errorToShow.css('visibility', 'hidden'); 2011 $input.css({"border-color": "#cccccc", "border-style": "solid"}); 2012 }, 1500); 2013 } 2014} 2015 2016function searchLocations() { 2017 var postcode = $("#post_code").val().trim(); 2018 2019 if (postcode.length > 4 && postcode.length < 9) { 2020 $("#post_code").val(postcode); 2021 var formattedPostcode = ''; 2022 try { 2023 formattedPostcode = postcode.replace(/\s/g, "").replace(/^(.*)(\d)/, "$1 $2").toUpperCase(); 2024 } catch (e) { 2025 var formattedPostcode = ''; 2026 } 2027 var url = 'https://prd-address-api.actionprompt.com/api/address/maps/' + encodeURIComponent(formattedPostcode); 2028 2029 $.ajax({ 2030 type: 'GET', 2031 url: url 2032 }) 2033 .done(function (results) { 2034 results = JSON.parse(results); 2035 2036 if (results.status !== 'OK') { 2037 alert("We have been unable to determine your location, please try again. (1)"); 2038 //callback(null); 2039 return; 2040 } 2041 window.location.href = "/search/" + 2042 postcode + "/" + 2043 results.results[0].geometry.location.lat + "/" + 2044 results.results[0].geometry.location.lng; 2045 }) 2046 .fail(function (results) { 2047 results = JSON.parse(results); 2048 alert("We have been unable to determine your location, please try again. (2)"); 2049 return false; 2050 }); 2051 } else { 2052 requestValidPostcode($('#search-wrapper'), $('#post_code')); 2053 } 2054} 2055 2056let commentUpdateTimer = null; 2057 2058function addToCommentsToSession() { 2059 clearTimeout(commentUpdateTimer); 2060 commentUpdateTimer = setTimeout(function () { 2061 $.ajax({ 2062 type: "POST", 2063 url: 'checkout/add_comments_to_session?ts=' + (new Date().getTime()), 2064 data: { 2065 "comments": $('#orderComments').val() 2066 }, 2067 }); 2068 }, 1000); 2069} 2070 2071function order_now() { 2072 let scheduled_at = $('input[name="scheduled_at"]').val() ?? null; 2073 var payment_type = $('#checkout_page input[name="payment-type"]:checked').val(); 2074 var order_comments = $('#orderComments').val(); 2075 var type = $('#checkout_page input[name="order-type"]:checked').val(); 2076 var validate = validateAddress(); 2077 2078 if (payment_type == '') { 2079 alert('ALERT: Please Select A Payment Method'); 2080 return false; 2081 } 2082 2083 if (type == '') { 2084 alert('ALERT: Please Return To the Menu And Select Collection Or Delivery'); 2085 return false; 2086 } 2087 2088 // Don't create an order if the address validation fails 2089 if (validate === false) { 2090 return false; 2091 } 2092 2093 $.ajax({ 2094 type: "POST", 2095 url: 'checkout/process_order?ts=' + (new Date().getTime()), 2096 data: { 2097 "scheduled_at": scheduled_at, 2098 "payment_type": payment_type, 2099 "type": type, 2100 "order_comments": order_comments, 2101 "customer_info": validate 2102 }, 2103 beforeSend: function () { 2104 $('#continue_button_loading').show(); 2105 $('.information-display .overlay').show(); 2106 disableButtons(); 2107 }, 2108 success: function (response) { 2109 const error = response.error; 2110 let data = response.data; 2111 2112 if (error !== undefined) { 2113 console.error('error:', error); 2114 data = 'error'; 2115 } 2116 2117 switch (data) { 2118 case 'blocked': 2119 alert('Your order has been blocked automatically, call for further details.'); 2120 break; 2121 2122 case 'cash': 2123 window.location = 'checkout/order_confirmation?ts=' + new Date().getTime(); 2124 break; 2125 2126 case 'card': 2127 window.location = 'checkout/payment?ts=' + new Date().getTime(); 2128 break; 2129 2130 case 'complete': 2131 alert('This order is pending, please wait until your order has been processed.
2131Click ok to continue.'); 2132 window.location = 'checkout/order_confirmation?ts=' + new Date().getTime(); 2133 break; 2134 2135 default: 2136 setTimeout(function () { 2137 alert(error + '\n\nPlease return to the menu and try again.'); 2138 }, 100); 2139 $('#continue_button_loading').hide(); 2140 $('.information-display .overlay').hide(); 2141 enableButtons(); 2142 break; 2143 } 2144 }, 2145 error: function (response) { 2146 console.log(response); 2147 }, 2148 complete: function () { 2149 } 2150 }); 2151} 2152 2153/** 2154 * Validates Postcode 2155 * @param string postCode The postcode to validate 2156 * @return boolean True if the postcode is valid and false on failure. 2157 */ 2158function validPostcode(postcode) { 2159 postcode = postcode.replace(/\s/g, ""); 2160 var regex = /^(((^[BEGLMNS][1-9]\d?)|(^W[2-9])|(^(A[BL]|B[ABDHLNRST]|C[ABFHMORTVW]|D[ADEGHLNTY]|E[HNX]|F[KY]|G[LUY]|H[ADGPRSUX]|I[GMPV]|JE|K[ATWY]|L[ADELNSU]|M[EKL]|N[EGNPRW]|O[LX]|P[AEHLOR]|R[GHM]|S[AEGKL-PRSTWY]|T[ADFNQRSW]|UB|W[ADFNRSV]|YO|ZE)\d\d?)|(^W1[A-HJKSTUW0-9])|(((^WC[1-2])|(^EC[1-4])|(^SW1))[ABEHMNPRVWXY]))(\s*)?([0-9][ABD-HJLNP-UW-Z]{2}))$|(^GIR\s?0AA$)/i; 2161 return regex.test(postcode); 2162} 2163 2164function checkOrder(id) { 2165 $.ajax({ 2166 type: "POST", 2167 url: 'checkout/order_status/' + id + '?ts=' + (new Date().getTime()), 2168 success: function (response) { 2169 const data = response.data; 2170 const status = data.status || 'unprocessed'; 2171 2172 if (status !== 'unprocessed') { 2173 $('#loaderContainer').html(data.html); 2174 clearInterval(timer); 2175 } 2176 } 2177 }); 2178} 2179 2180function validateAddress() { 2181 var errors = new Array(); // Stores any errors 2182 2183 // Get all values 2184 var last_name = $('input[name=lastname]').val(); 2185 var address2 = $('input[name=address2]').val(); 2186 var town = $('input[name=town]').val(); 2187 var landline = $('input[name=landline]').val(); 2188 var mobile = $('input[name=mobile]').val(); 2189 2190 // Check the validation for delivery address 2191 // If both are blank alert the user and return false 2192 if (landline == '' && mobile == '') { 2193 errors.push('You must have at least one contact number'); 2194 } 2195 2196 // Build an array of input fields you want to validate 2197 var i, 2198 validate_fields = ['delivery_firstname', 'delivery_house_number', 'delivery_address1', 'validate_pc'], // fields to validate 2199 invalid_fields = [], 2200 valid_array = []; // store of empty fields 2201 2202 // Loop through the fields 2203 for (i in validate_fields) { 2204 // check if field is empty 2205 var field = $('#' + validate_fields[i]).val(); 2206 field = field.replace(/\/\W/g, ''); 2207 2208 if (field.length < 1) { 2209 invalid_fields.push(validate_fields[i]); 2210 } else { 2211 if (validate_fields[i] === 'delivery_address1') { 2212 valid_array.push($('#' + validate_fields[i]).val()); 2213 } else { 2214 valid_array.push(field); 2215 } 2216 } 2217 } 2218 2219 // If the fields are blank alert the user which fields are required 2220 if (invalid_fields.length > 0) { 2221 var errorsTxt = 'The following fields are required: '; 2222 2223 for (i in invalid_fields) { 2224 var field = invalid_fields[i]; 2225 field = field.replace('delivery_', ''); 2226 field = field.replace('_', ' '); 2227 // Captitalise first letter of each word 2228 field = field.charAt(0).toUpperCase() + field.slice(1); 2229 errorsTxt = errorsTxt + ' ' + field + ','; 2230 } 2231 2232 // Remove the last , 2233 errorsTxt = errorsTxt.slice(0, errorsTxt.length - 1); 2234 errors.push(errorsTxt); 2235 } 2236 2237 if (errors.length > 0) { 2238 // Reset the error messages 2239 $('#paymentdeliveryErrors').html('').hide(); 2240 2241 // Loop through the error messages and display them on the form. 2242 for (var i = 0; i < errors.length; i++) { 2243 $('#paymentdeliveryErrors').append(renderError(errors[i])); 2244 } 2245 2246 $('#paymentdeliveryErrors').show(); 2247 2248 // Make the window scroll to the top 2249 window.scrollTo(0, 0); 2250 return false;
2251 } else { 2252 // Return all data back to the order now function 2253 valid = [valid_array, last_name, address2, town, landline, mobile] 2254 return valid; 2255 } 2256} 2257 2258$('.foodTypeFilter').click(function () { 2259 var foodType = $(this).data('foodtype'); 2260 var count_total_shops = 0; 2261 var count_total_hidden = 0; 2262 2263 $('.sort-this-desktop').each(function (e) { 2264 var array = $(this).data('foodtypes').split(","); 2265 var is_type = 0; 2266 count_total_shops++ 2267 2268 $.each(array, function (i) { 2269 var a = array[i].replace(/\s/g, ""); 2270 var b = foodType.replace(/\s/g, ""); 2271 2272 if (a == b) { 2273 is_type = 1; 2274 return false; 2275 } else { 2276 is_type = 0; 2277 } 2278 }); 2279 2280 if (foodType == 'all') { 2281 $(this).css('display', ''); 2282 } else { 2283 if (is_type == 1) { 2284 $(this).css('display', ''); 2285 } else { 2286 $(this).css('display', 'none'); 2287 count_total_hidden++; 2288 } 2289 } 2290 }); 2291 2292 if (count_total_shops == count_total_hidden) { 2293 $(".noFoodTypes").html('We\'re sorry, all ' + foodType + ' takeaways are currently closed').css("padding-top", "2rem"); 2294 } else { 2295 $(".noFoodTypes").html('').css("padding-top", "0"); 2296 } 2297}); 2298 2299$('#food_types').change(function () { 2300 var foodType = $(this).val(); 2301 var count_total_shops = 0; 2302 var count_total_hidden = 0; 2303 2304 $('.sort-this-desktop').each(function (e) { 2305 var array = $(this).data('foodtypes').split(","); 2306 var is_type = 0; 2307 count_total_shops++ 2308 2309 $.each(array, function (i) { 2310 var a = array[i].replace(/\s/g, ""); 2311 var b = foodType.replace(/\s/g, ""); 2312 2313 if (a == b) { 2314 is_type = 1; 2315 return false; 2316 } else { 2317 is_type = 0; 2318 } 2319 }); 2320 2321 if (foodType == 'Select All') { 2322 $(this).css('display', ''); 2323 } else { 2324 if (is_type == 1) { 2325 $(this).css('display', ''); 2326 } else { 2327 $(this).css('display', 'none'); 2328 count_total_hidden++; 2329 } 2330 } 2331 }); 2332 2333 if (count_total_shops == count_total_hidden) { 2334 $(".noFoodTypes").html('We\'re sorry, all ' + foodType + ' takeaways are currently closed').css("padding-top", "2rem"); 2335 } else { 2336 $(".noFoodTypes").html('').css("padding-top", "0"); 2337 } 2338}); 2339 2340// Loop all the faqs 2341$(".faq").each(function (e) { 2342 $(this).click(function () { 2343 // If the element clicked is open close it and perform no other action 2344 if ($(this).find('.faq-answer').is(":visible")) { 2345 $(this).find('.faq-answer').hide('fast'); 2346 return false; 2347 } 2348 2349 // If the above is not met loop all other elements and close every one apart from the one thats clicked 2350 $(".faq").each(function (e) { 2351 // when a faq is clicked make sure all the other answers are not displayed 2352 $('.faq-answer').not(this).hide(); 2353 }); 2354 2355 //show the question for the faq thats clicked if not already visible 2356 if (!$(this).find('.faq-answer').is(":visible")) { 2357 $(this).find('.faq-answer').show('fast'); 2358 } 2359 }); 2360}); 2361 2362// Gets a cookie set in JS 2363function getCookie(cname) { 2364 var name = cname + "="; 2365 var ca = document.cookie.split(';'); 2366 for (var i = 0; i < ca.length; i++) { 2367 var c = ca[i].trim(); 2368 if (c.indexOf(name) == 0) return c.substring(name.length, c.length); 2369 } 2370 return ""; 2371}
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.