PageSourceSearch

https://www.grubsouth.com/assets/templates/default/js/orderflow.js?v=126

js grubsouth.com collected 2026-10-01 16:02:40 UTC 36,388 bytes, 1,013 lines download raw bytes

1var DLCore = DLCore || {};
2
3DLCore.orderflow = (function($) {
4	'use strict';
5
6	// TODO: move this cookie to global function
7	var _cookie_logged_in = getCookie('logged_in');
8
9	// needed variables
10	var _addDrinkFromModal = false;
11	var _editFromCartModal = false;
12
13	// initialize this module
14	var _init = function() {
15		//console.info('DLCore.orderflow init');
16		_modal_delivery_settings.setup();
17		_modal_menu_item.setup();
18		_modal_estore.setup();
19		_modal_login.setup();
20
21		// see if we need to load specific item
22		_modal_delivery_settings.load_item();
23
24		// see if we need to redirect to checkout
25		var continue_to_checkout = sessionStorage.getItem('continue_to_checkout');
26		if (continue_to_checkout === 'Y') {
27			if (_cookie_logged_in && _cookie_logged_in === '1') {
28				sessionStorage.removeItem('continue_to_checkout');
29				if ((window.location.href.indexOf('order/checkout') == -1) && (window.location.href.indexOf('order/information') == -1)) {
30					window.location.href = base_url + 'order/checkout';
31				}
32			}
33		}
34	}
35
36	// functions specific to login modal
37	var _modal_login = {
38		setup: function() {
39			_modal_login.events();
40		},
41
42		// setup/bind all events
43		events: function() {
44			$('body').on('click', 'a[href*="/order/checkout"], a[href*="/account"], a[href*="/login"], #open-login-modal, #add_gap_fee_btn, #add_order_gap_btn, #estore-modal a[href*="/checkout"]', function(e) {
45				//if (this.href.indexOf('order/checkout?customer=guest') < 0 && this.href.indexOf('login/reset') < 0 && this.href.indexOf('register/account') < 0) {
46				if (this.href.indexOf('order/checkout?customer=guest') < 0 && this.href.indexOf('login/reset') < 0 && this.href.indexOf('mobile.php') < 0) {
47					if (!_cookie_logged_in || _cookie_logged_in === '0') {
48						e.preventDefault();
49						remove_page_loader();
50						$('.modal').modal('hide');
51						$("#estore-modal").modal('hide');
52						$('#login-modal').modal('show');
53					}
54				}
55
56				// temp fix for /login if mobile since we're not showing modal
57				if (this.href.indexOf('mobile.php') > 0) {
58					if (e.target.id === 'open-login-modal' || e.target.id === 'add_gap_fee_btn' || e.target.id === 'add_order_gap_btn') {
59						e.preventDefault();
60						sessionStorage.removeItem('log_from_delsettings');
61						window.location.href = '/mobile.php/login';
62					}
63				}
64			});
65
66			$('#login-modal').on('focus', 'input, textarea', function(event) {
67				event.preventDefault();
68				if($(window).width() < 768){
69					var offsetTop = $('#login-modal .modal-header').height();
70					$('.modal-body').animate({
71						scrollTop: $(this).closest('.form-group').position().top
72					}, 500);
73				}
74			});
75		}
76	}
77
78	// functions specific to estore modal
79	var _modal_estore = {
80		setup: function() {
81			_modal_estore.events();
82		},
83
84		events: function() {
85			// Sets addDrinkFromModal flag to true if the drink item is added from Drink modal
86			$('body').on('click', '#estore-modal .order_restaurant--menu_item', function(event) {
87				_addDrinkFromModal = true;
88				$("#estore-modal").modal('hide');
89			});
90		}
91	}
92
93	// functions specific to menu item modal
94	var _modal_menu_item = {
95		// initialize any plugins or variables
96		setup: function() {
97			$('textarea').autogrow({ onInitialize: true });
98			_modal_menu_item.qty_buttons();
99			_modal_menu_item.events();
100		},
101
102		// setup/bind all events
103		events: function() {
104			//Logic for 'show more'/'show less' buttons.
105			$("body").on('click', '#restaurant_item_form .show-more, #restaurant_edit_item_form .show-more', function(event) {
106
107				$(this).siblings('.form-group').css('max-height','none');
108				$(this).siblings('.form-group').css('height', 'auto');
109				$(this).html('<i class="icon ion-minus-round" style="font-size: 10px;">&nbsp;</i> ' + localization.common_showLess);
110				$(this).removeClass('show-more').addClass('show-less');
111			});
112
113			$("body").on('click', '#restaurant_item_form .show-less', function(event) {
114
115				$(this).siblings('.form-group').css("max-height", $(this).siblings('.form-group').data('heightAttr'));
116				$(this).html('<i class="icon ion-plus-round" style="font-size: 10px;">&nbsp;</i> ' + localization.common_showMore);
117				$(this).removeClass('show-less').addClass('show-more');
118			});
119
120			// Sets editFromCartModal flag to true if the edit item trigered form the cart modal
121			$('body').on('click', '.modal-body-content .cart_content--cart_items td', function(event) {
122				if($(this).attr('onclick')){
123					_editFromCartModal = true;
124					$("#cart-modal").modal('hide');
125				}
126			});
127
128			// Update total price in menu item modal
129			$("#menu-modal").on("change", ":input", function(event){
130
131				setTimeout(function() {
132
133					var total_price = _modal_menu_item.total_item_price();
134					$("#menu-modal #add_item_button").html(localization.action_addItem + ": <span>" + format_money(total_price) + "</span>");
135					$("#menu-modal #save_item_button").html(localization.action_saveItem + ": <span>" + format_money(total_price) + "</span>");
136					_modal_menu_item.enable_add_button();
137				}, 1);
138			});
139
140			// when menu item modal is closed
141			$("#menu-modal").on('hidden.bs.modal', function(event){
142				event.preventDefault();
143
144				sessionStorage.removeItem('view_restaurant_item');
145
146				// Opens the cart modal after editing an item if the flag editFromCartModal is set to true
147				if (_editFromCartModal) {
148					$('.show-cart-modal').trigger('click');
149					_editFromCartModal = false;
150				}
151
152				// Opens the Drink modal after editing a drink if the flag addDrinkFromModal is set to true
153				if (_addDrinkFromModal) {
154					$("#estore-modal").modal('show');
155					_addDrinkFromModal = false;
156				}
157
158			});
159
160			$('#menu-modal').on('focus', 'input, textarea', function(event) {
161				event.preventDefault();
162				if($(window).width() < 768){
163					$('.modal-body').animate({
164						scrollTop: $(this).closest('.row').position().top
165					}, 500);
166				}
167			});
168
169			//Logic for adding a 'show more' button in case the amount of items is too large for browsing comfort.
170			$(document).ajaxComplete(function(event, xhr, settings) {
171
172				var show_more_enabled = false;
173
174				if (show_more_enabled && (settings.url.indexOf('order/item/') > 0 || settings.url.indexOf('order/edit_item/') > 0)) {
175					var modalHeight = $('#menu-modal').outerHeight() / 3;
176					var $containers = $("#menu-modal form .form-group:has(.checkbox)");
177
178					$containers.each(function(index, el) {
179						if ($(this).outerHeight() >= modalHeight) {
180							var a = 0;
181							var label = $(this).find("> label").outerHeight(true);
182							var childHeight = 0;
183							var currentHeight = 0;
184							$(this).children(".checkbox").each(function(index, el) {
185								if ($(window).width() > 767) {
186									if (index % 2 == 0 || index == 0) {
187										a = $(this).outerHeight(true);
188										return true;
189									} else {
190										currentHeight = a >= $(this).outerHeight(true) ? a : $(this).outerHeight(true);
191									}
192								} else {
193									currentHeight = $(this).outerHeight(true);
194								}
195								if ((childHeight + currentHeight) <= (modalHeight - label)) {
196									childHeight += currentHeight;
197								}
198							});
199							$(this).height(label + childHeight);
200							$(this).data('heightAttr', label + childHeight + "px");
201							$(this).after('<span class="show-more text-primary"><i class="icon ion-plus-round" style="font-size: 10px;">&nbsp;</i> ' + localization.common_showMore + '</span>');
202						};
203					});
204				}
205				_modal_menu_item.scroll_to_error();
206
207				// Add data-price attribute to all suboptions
208				if (settings.url.indexOf('order/item/') >= 0 || settings.url.indexOf('order/edit_item/') >= 0) {
209					var action;
210					if (settings.url.indexOf('order/item/') >= 0) {
211						action = 'ADD';
212					} else {
213						action = 'EDIT';
214					}
215
216					var form = $('#menu-modal .modal-body form').attr('id');
217					var RID = $('#menu-modal').find('input[name="' + action + '_ITEM[RID]"]').val();
218					var MIID = $('#menu-modal').find('input[name="' + action + '_ITEM[MIID]"]').val();
219					$.getJSON(base_url + "order/get_option_prices/" + RID + "/" + MIID, function(data) {
220
221						$.each(data.options, function( key, val) { process_option_prices(val); });
222					}, 'json');
223
224					function process_option_prices(val) {
225						$.each(val.suboptions, function( subkey, val){
226							$('#' + form + ' select > option').each(function() {
227								if ($(this).val() === subkey) {
228									//console.log("this: "+$(this).val()+" key: "+subkey+" ; value: "+val.price);
229									$(this).attr("data-price", val.price);
230								}
231							});
232
233							$('#' + form + ' input').each(function() {
234								if($(this).val() === subkey) {
235									//console.log("this: "+$(this).val()+" key: "+subkey+" ; value: "+val.price);
236									$(this).attr("data-price", val.price);
237								}
238							});
239
240							// linked options
241							$.each(val.options, function(subkey, val) { process_option_prices(val); });
242						});
243					}
244				}
245
246				var total_price = _modal_menu_item.total_item_price();
247				$("#menu-modal #add_item_button").html(localization.action_addItem + ": <span>" + format_money(total_price) + "</span>");
248				$("#menu-modal #save_item_button").html(localization.action_saveItem + ": <span>" + format_money(total_price) + "</span>");
249				_modal_menu_item.enable_add_button();
250			});
251		},
252
253		qty_buttons: function() {
254			$('body').on('click', '.qty-buttons span', function(event) {
255				event.preventDefault();
256				var valOffset;
257				var currentVal =  parseInt($('.item_qty').val());
258
259				if ($(this).hasClass('qtyplus')) {
260					valOffset = 1;
261				} else {
262					valOffset = -1;
263				}
264
265				if (!isNaN(currentVal)) {
266					$('.item_qty').val(currentVal + valOffset);
267				} else {
268					$('.item_qty').val(1);
269				}
270
271				$('.item_qty').trigger( "change" );
272			});
273
274			function enterManually(event) {
275				if (parseInt($(event.target).val()) <= 0) {
276					$('.item_qty').val(1);
277				} else {
278					$('.item_qty').val($(event.target).val()|0);
279				}
280			}
281			
282			$('body').on('change', '.qty-buttons .item_qty', enterManually);
283			$('body').on('input', '.qty-buttons .item_qty', enterManually);
284		},
285
286		scroll_to_error: function() {
287			if ($('label.error').length >= 1 || $('select.error').length >= 1 ) {
288
289				var row = $("label.error").closest('.row');
290				var top = row.position().top;
291
292				// Check to see if this is a nested option, need the non-relative top of the parent.
293				var chk = $(row[0]).parent().parent().parent();
294				if((chk.length == 1) && $(chk).position().top > top) top = $(chk).position().top;
295
296//console.log(row);console.log($(row[0]).position().top);console.log(chk);console.log($(chk).position().top);
297
298				$('.modal-body').animate({ scrollTop: top }, 200);
299			}
300		},
301
302		total_item_price: function() {
303			var form = $('#menu-modal .modal-body form').attr('id');
304			var menu_price = parseFloat($('form#' + form).attr('data-itemPrice'));
305			var total_price, options_total = 0;
306			var selected_price;
307			var quantity = parseFloat($(".item_qty").last().val());
308			
309			$(".item_qty").val(quantity);
310
311			// loop through all of the select boxes and checked options for this particular menu item
312			$('#' + form + ' input:checked, #' + form + ' select, #' + form + ' input[type="number"]').each(function(index) {
313
314				if ( $(this).attr('type') == 'number' )
315				{
316					options_total += parseFloat( $(this).data('price') ) * this.value;
317				}
318				// if it's a select drop down, get the value of the selected option
319				else if ($(this).is('select')) {
320
321					// If the item is not visible it must be a linked option no longer referenced so don't count it.
322					if(!$(this).is(':visible')) return;
323
324					// only add the price if there is a data attribute with price
325					if (selected_price = $(this).find(':selected').data('price')) {
326						options_total += parseFloat(selected_price);
327					}
328				} else {
329
330					// If the item's paired span is not visible it must be a linked option no longer referenced so don't count it.
331					if(!$(this).next().is(':visible')) return;
332
333//console.log($(this).data('option-id') + '/' + $(this).is(':visible') + '/' + parseFloat($(this).data('price')));
334
335					options_total += parseFloat($(this).data('price'));
336				}
337			});
338
339			// add options total to base price to get final price
340			total_price = (menu_price + options_total) * quantity;
341			return (isNaN(total_price)) ? 0 : total_price;
342		},
343
344		enable_add_button: function() {
345			var req_incomp = 0;
346			$('#menu-modal .modal-body .form-group').each(function(index, el) {
347				if ($(this).parents('.linked-options.hidden').length == 0) {
348					if ($(this).is("[class*=required]")) {
349						var selected = 0;
350						var number_class = $(this).attr('class').indexOf('required');
351						var number = $(this).attr('class').slice(number_class).replace('required','');
352						number = parseInt(number);
353
354						$(this).find('input[type="number"]').each(function(index, el) {
355							if ( $(this).val() != '' ) selected += parseInt( $(this).val() );
356						});
357						
358						$(this).find('input[type="checkbox"]').each(function(index, el) {
359							if ($(this).prop('checked') === true) selected++;
360						});
361
362						$(this).find('select').each(function(index, el) {
363							if ($(this).val() != '') selected++;
364						});
365
366						if (selected < number) req_incomp++;
367					}
368				}
369
370				if (req_incomp > 0) {
371					$('#menu-modal #add_item_button').addClass('btn-inactive');
372				} else {
373					$('#menu-modal #add_item_button').removeClass('btn-inactive');
374				}
375			});
376		}
377	}
378
379	// functions specific to delivery setting modal
380	var _modal_delivery_settings = {
381		// initialize any plugins or variables
382		setup: function() {
383			// bind the address autocomplete to the modal address input field and have it run check_flow on submission
384			$('#time-modal input.address').address_autocomplete({ auto_submit: false, cache_address: false }, DLCore.orderflow.check_flow);
385			//_modal_delivery_settings.toggle_save_button('disabled');
386			_modal_delivery_settings.events();
387		},
388
389		// setup/bind all events
390		events: function() {
391			// get variables needed for delivery settings modal
392			var cached_address  = JSON.parse(localStorage.getItem('cached_customer_address'));
393			var cached_datetime = JSON.parse(sessionStorage.getItem('cached_delivery_datetime'));
394
395			if (sessionStorage.getItem('log_from_delsettings') === 'Y' && !cached_address) {
396				if (!_cookie_logged_in || _cookie_logged_in === '0') {
397					$('.show_user_address').hide();
398				} else {
399					$('#open-login-modal').hide();
400					$('#submit-delivery-settings, #delivery-settings-restaurants').css("width", "100%");
401				}
402
403				$('#time-modal').modal('show');
404				sessionStorage.removeItem('log_from_delsettings');
405			}
406
407			$('body').on('click', '#time_and_location_panel', function() { $('#t
407ime-modal').modal() });
408			$('body').on('click', '#time-modal #open-login-modal', function() {
409				try{
410					sessionStorage.setItem('log_from_delsettings','Y');
411			}
412				catch(e){}
413					
414			});
415
416			// $('#find-me-button').on('click', function(e) {
417			// 	// Dont geolocate on mobile
418			// 	if (window.location.href.indexOf('mobile.php') < 0) {
419			// 		$(this).html('<div class="spin_loader"></div>');
420			// 		_modal_delivery_settings.get_location();
421			// 	}
422			// });
423
424			$('#submit-delivery-settings').on('click', function(e) {
425				e.preventDefault();
426				$('#partial-address-warning').addClass('hide');
427				if($('#order_time_modal').val() !== "" || country_code =='mm') {
428					add_page_loader();
429					_modal_delivery_settings.check_flow(true);
430				} else {
431					$('#when-time-error').show();
432					$("#when_panel_form").show();
433					$('#time-modal .modal-body').addClass('when-error');
434				}
435			});
436
437			$('#time-modal').on('keypress', 'form', function(e) {
438				return e.keyCode != 13;
439			});
440
441			$('#time-modal').on('show.bs.modal', function(e) {
442				// hide any previous errors
443				$('.delivery-settings-errors').hide();
444				$('#time-modal').addClass('loading');
445
446				if (!_cookie_logged_in || _cookie_logged_in === '0') {
447					$('.show_user_address').hide();
448				} else {
449					$('#open-login-modal').hide();
450					$('#submit-delivery-settings, #delivery-settings-restaurants').css("width", "100%");
451				}
452			});
453
454			$('#time-modal').on('shown.bs.modal', function(e) {
455				if (cached_address) {
456					$('#time-modal input[name="address"]').val(cached_address.full_address);
457					$('#time-modal input[name="zip_code"]').val(cached_address.zip_code);
458				}
459
460				// on load, run check_flow
461				_modal_delivery_settings.check_flow();
462			});
463
464			$('#time-modal .order_date').on('change', function(e) {
465				_modal_delivery_settings.check_flow();
466			});
467
468			$('#time-modal .order_time').on('change', function(e) {
469				//console.log($(this).val());
470				if ($('#delivery-settings-restaurants').css('display') !== 'none' || $('#delivery-settings-restaurants').is(':hidden')) {
471					$('#time-modal .modal-footer').removeClass('show-list');
472					//$('#delivery-settings-restaurants').hide();
473					//$('#submit-delivery-settings').show();
474					_modal_delivery_settings.toggle_save_button('enabled');
475				}
476			});
477		},
478
479		// function to get users location when they click on the find-me button
480		get_location: function() {
481			if (navigator.geolocation) {
482				//console.log('getting location....');
483				
484			  	navigator.geolocation.getCurrentPosition(
485					function(position) {
486						//console.log(position);
487
488						var lat = position.coords.latitude;
489						var lon = position.coords.longitude;
490
491						// grab address via Google API using your position
492						var apiurl = 'https://maps.googleapis.com/maps/api/geocode/json?latlng='+lat+','+lon+'&sensor=true&key='+google_browser_api_key;
493
494						// Google does not allow Cross Domain Access so let's use a Proxy: http://benalman.com/projects/php-simple-proxy/
495						var endpoint = base_url + 'order/find_my_address?url='+encodeURIComponent(apiurl);
496
497						// make the Ajax request
498						$.ajax({
499							url: endpoint,
500							type: 'get',
501							//data: data,
502							dataType: 'json',
503							success: function(data) {
504								// console.log('get location success');
505								// console.log(data);
506								  //if we make a successfl request and it returns an address
507								  if (data.status.http_code == 200 && data.contents.results.length > 0) {
508									//get formatted address from https://developers.google.com/maps/documentation/geocoding/#ReverseGeocoding
509									var result = data.contents.results[0].formatted_address;
510									$('#find-me-button').html('<i class="fa fa-location-arrow"></i>');
511									var selector = ["address", "city", "state", "zip_code"];
512
513									if (selector.length == 1) {
514										//one field for address
515										var field = document.getElementById(selector[0]);
516										field.value = result;
517									} else {
518										//multiple fields
519										var street = document.getElementById(selector[0]);
520										var city = document.getElementById(selector[1]);
521										var state = document.getElementById(selector[2]);
522										var zip = document.getElementById(selector[3]);
523
524										var a = result.split(",");
525										street.value = a[0].trim();
526										city.value = a[1].trim();
527										state.value = a[2].trim().split(" ")[0];
528										zip.value = a[2].trim().split(" ")[1];
529									}
530									_modal_delivery_settings.check_flow();
531									//clear array
532									selector = [];
533
534								  } else {
535									$('#find-me-button').html('<i class="fa fa-location-arrow"></i>');
536									//send some general error
537									$('.error_container').innerHTML = "<i class='icon ion-alert'></i> Could not find your location. Please re-enter your address.";
538								}
539							},
540							error: function(xhr, textStatus, errorThrown) {
541								$('#find-me-button').html('<i class="fa fa-location-arrow"></i>');
542								//send some general error
543								$('.error_container').innerHTML = "<i class='icon ion-alert'></i> Could not find your location. Please re-enter your address.";
544
545							},
546							complete: function (jqXHR, XMLHttpRequest, textStatus, errorThrown) {
547								$('#find-me-button').html('<i class="fa fa-location-arrow"></i>');
548								//send some general error
549								$('.error_container').innerHTML = "<i class='icon ion-alert'></i> Could not find your location. Please re-enter your address.";
550							}
551						});
552					})
553			} else{
554				$('#find-me-button').html('<i class="fa fa-location-arrow"></i>');
555				$('.error_container').innerHTML="Geolocation is not supported by this browser.";
556			}
557		},
558
559		// cache user address so it can be reused
560		cache_location: function(address, zipcode) {
561			var cached_address = {};
562			cached_address.full_address = address;
563			cached_address.zip_code = zipcode;
564			try{
565				localStorage.setItem('cached_customer_address', JSON.stringify(cached_address));
566			}
567			catch(e){}
568		},
569
570		// cache time/date for current session
571		cache_delivery: function(date, time) {
572			var cached_delivery = {};
573			cached_delivery.date = date;
574			cached_delivery.time = time;
575
576			try{
577				sessionStorage.setItem('cached_delivery_datetime', JSON.stringify(cached_delivery));
578		}
579			catch(e){}
580		},
581
582		// function to enable/disable save button
583		toggle_save_button: function(state) {
584			if (state == 'disabled') {
585				$('#submit-delivery-settings').addClass('disabled');
586				$('#submit-delivery-settings').addClass('btn-inactive');
587			} else {
588				$('#submit-delivery-settings').removeClass('disabled');
589				$('#submit-delivery-settings').removeClass('btn-inactive');
590			}
591		},
592
593		// check if we need to load a menu item after delivery settings modal is set
594		load_item: function() {
595			var menu_item = JSON.parse(sessionStorage.getItem('view_restaurant_item'));
596			var cached_address  = JSON.parse(localStorage.getItem('cached_customer_address'));
597			var cached_datetime = JSON.parse(sessionStorage.getItem('cached_delivery_datetime'));
598
599			if (menu_item && cached_address && cached_datetime) {
600				if (cached_datetime.time !== null) {
601					// open menu section and click on item
602					$('.restaurant_items--item_' + menu_item.id).closest('.restaurant_heading').find('a.menu-heading-toggle').trigger('click');
603					$('.restaurant_items--item_' + menu_item.id).trigger('click');
604				}
605			}
606		},
607
608		// function to check the order flow for errors
609		check_flow: function(reload) {
610			//_modal_delivery_settings.toggle_save_button('disabled');
611			//add_page_loader();
612			
613			var errors   = false;
614			var endpoint = '';
615			var change_url = null;
616			
617			if(window.location.href.indexOf("/order") == -1) {
618			   change_url = true;
619			   endpoint = '/order';
620			}
621
622			var address  = $('#time-modal input[name="address"]').val();
623			var zip_code = $('#time-modal input[name="zip_code"]').val();
624			var date     = $('#time-modal input[name="ORDER_WHEN[date]"]').val();
625			var time     = $('#time-modal select[name="ORDER_WHEN[time]"]').val();
626			var type     = $('#order_type').val();
627			
628			var checkout = (window.location.href.indexOf('order/checkout') > 0) ? true : false;
629			var data     = {
630						'address'             : address,
631						'zip_code'            : zip_code,
632						'ORDER_WHEN[date]'    : date,
633						'ORDER_WHEN[time]'    : time,
634						'ORDER_WHEN[type]'    : type,
635						'on_checkout_page'    : checkout,
636						'update_order_params' : true
637					};
638
639			if (!address && country_code !='mm') {
640				$("#when_panel_form").hide();
641				$("#no-restaurant-error").hide();
642				if(zip_code != '')
643					$("#enter-your-address-error").hide();
644				else
645					$("#enter-your-address-error").show();
646				$('#zero-restaurant-error').hide();
647				remove_page_loader();
648				return;
649			}
650			if (time != '' && time != 'UNAVAILABLE') _modal_delivery_settings.cache_delivery(date, time);
651			$('#time-modal .modal-footer').removeClass('show-list');
652
653			$.ajax({
654				url: endpoint,
655				type: 'post',
656				data: data,
657				dataType: 'json',
658				success: function(data) {
659					//console.log('check flow success:');
660					//console.log(data);
661					
662					$('#time-modal .modal-body').removeClass('where-error');
663					$('#time-modal .modal-body').removeClass('when-error');
664					$('#where-restaurant-error, #where-rds-error, #where-nonexisting-error').hide();
665
666					if (data.set_address != null) {
667						// Address does not exists or is out of service area
668						if (data.set_address === 'verify_address') {
669							if(data.restaurant != null){
670								window.location.href = base_url + 'order/verify_address/none/' + data.restaurant;
671							}else{
672								window.location.href = base_url + 'order/verify_address';
673							}
674						} else if(data.set_address === 'out_of_rds_area') {
675							$("#when_panel_form").hide();
676							$('#where-rds-error').show();
677							$('#time-modal .modal-body').addClass('where-error');
678							//$('#time-modal .modal-footer').addClass('show-list');
679							errors = true;
680						
681						} else if(data.set_address === 'out_of_area') {
682							$("#when_panel_form").hide();
683							//$('#where-rds-error').show();
684							$('#where-restaurant-error').show();
685							$('#time-modal .modal-body').addClass('where-error');
686							$('#time-modal .modal-footer').addClass('show-list');
687							errors = true;
688
689						// User is not on a restaurant menu page
690						} else if(data.set_address === 'no_RID'){
691							initialize_when(true);
692							$("#when_panel_form").show();
693							
694							if(data.order_time == '') {
695								$('#when-time-error').show();
696								$('#time-modal .modal-body').addClass('when-error');
697							}
698
699							_modal_delivery_settings.cache_location(address, zip_code);
700							_modal_delivery_settings.toggle_save_button('enabled');
701
702						// The RDS is closed for the given date/time
703						//} else if (data.restaurant_status !== 'closed' && data.restaurants === 0){
704						} else if (data.restaurant_status === 'open' && data.restaurants === 0){
705							initialize_when(true);
706							$("#when_panel_form").show();
707
708							if (time) {
709								$('#when-rds-error').show();
710								$('#time-modal .modal-body').addClass('when-error');
711							} else {
712								$('#when_panel_fields select').css('borderColor', 'red');
713							}
714							errors = true;
715
716						} else {
717							// Address is outside of restaurant area
718							if (data.restaurant_status === 'unavailable' || data.restaurant_status === 'unavailable_geo') {
719								$("#when_panel_form").hide();
720								$('#where-restaurant-error').show();
721								$('#time-modal .modal-body').addClass('where-error');
722								$('#time-modal .modal-footer').addClass('show-list');
723								errors = true;
724
725							// The restaurant is closed for the given date/time
726							} else if (data.restaurant_status === 'closed') {
727								initialize_when(true);
728								$("#when_panel_form").show();
729
730								$('#when-restaurant-error').show();
731								$('#time-modal .modal-body').addClass('when-error');
732
733								//Show available restaurants for this address and time/date
734								//$('#time-modal #delivery-settings-restaurants').show();
735								$('#time-modal .modal-footer').addClass('show-list');
736								errors = true;
737							} else {
738								// The RDS is closed
739								if (status === 'closed'){
740									initialize_when(true);
741									$("#when_panel_form").show();
742
743									$('#when-restaurant-error-maychange').show();
744									$('#time-modal .modal-body').addClass('when-error');
745									errors = true;
746
747								} else {
748									//There are no errors so cache address
749									initialize_when(true);
750									$("#when_panel_form").show();
751
752									_modal_delivery_settings.cache_location(address, zip_code);
753									_modal_delivery_settings.toggle_save_button('enabled');
754								}
755							}
756						}
757					// We're in a pending address mode (non-full address).
758					} else if (data.restaurant_status === 'pending') {
759
760						errors = false;
761					// The address does not exist
762					} else {
763						$("#when_panel_form").hide();
764						$('#where-nonexisting-error').show();
765						$('#time-modal .modal-body').addClass('where-error');
766						errors = true;
767					}
768
769				},
770
771				complete: function (jqXHR, XMLHttpRequest, textStatus, errorThrown) {
772					//console.log('check flow complete');
773
774					$('#time-modal').removeClass('loading');
775					remove_page_loader();
776					var data = jqXHR.responseJSON;
777					if (reload && !errors) {
778						$('#time-modal').modal('hide');
779						if(change_url && data.set_address == 'no_RID' && data.restaurant == null) {
780							window.location.href = base_url + 'order/restaurants';
781						}
782						else {
783							window.location.reload();
784						}
785					}
786				}
787			});
788
789			return true;
790		}
791	}
792
793	// expose certain functions publically
794	return {
795		init: _init,
796		check_flow: _modal_delivery_settings.check_flow,
797		enable_add_menu_item_button: _modal_menu_item.enable_add_button
798	};
799})(jQuery);
800
801jQuery(document).ready(function($) {
802	// initialize this module and check if we need to load menu item
803	DLCore.orderflow.init();
804
805	$('body').on('click', '.cart_content--checkout_btn', function() {
806		try{
807			sessionStorage.setItem('continue_to_checkout','Y'); //Flag indicating the user has clicked the checkout button
808	}
809		catch(e){}
810	});
811
812	/**
813	 *  Add the name of the technology in the body tag
814	 */
815	var OSName="unknown";
816	if (navigator.appVersion.indexOf("Win")!=-1) OSName="windows";
817	if (navigator.appVersion.indexOf("Mac")!=-1) OSName="apple";
818	if (navigator.appVersion.indexOf("X11")!=-1) OSName="unix";
819	if (navigator.appVersion.indexOf("Linux")!=-1) OSName="android";
820
821	$('body, html').addClass( OSName );
822
823	if( navigator.userAgent.match( /iPad/i ) || navigator.userAgent.match( /iPhone/i ) || navigator.userAgent.match( /iPod/i ) ){
824	  $('body, html').addClass( 'ios' );
825	}
826
827	if( navigator.userAgent.match('CriOS') || navigator.userAgent.match('Chrome') ) {
828		// it is a chrome browser
829		$('body').addClass( 'chrome' );
830	}else if( navigator.userAgent.match('Safari') ){
831		// it is a Safari browser
832		$('body').addClass( 'safari' );
833	}else if( navigator.userAgent.match('MSIE') || navigator.userAgent.match('Edge') || navigator.userAgent.match('Trident')){
834		// it is a explorer browser
835		$('body').addClass( 'explorer' );
836	}
837
838	$('.modal').on('show.bs.modal', function(e) {
839		$('.modal').not($(this)).modal('hide');
840	});
841
842	//HACK FOR ANDROID
843	$('.android .modal').on('focus', 'input, textarea', function(event) {
844		event.preventDefault();
845		if($(window).width() < 768){
846			//$($(this).closest('.modal-content')).find('.modal-footer').addClass('hidden');
847		}
848	});
849
850	//HACK FOR ANDROID
851	$('.android .modal').on('blur', 'input, textarea', function(event) {
852		event.preventDefault();
853		if($(window).width() < 768){
854			$($(this).closest('.modal-content')).find('.modal-footer').removeClass('hidden');
855		}
856	});
857	
858	if(address_required == 'Y') {
859		
860		var el = $('#main_address_form').length ? '#main_address_form' : '#address_form';
861		
862		//console.log(el)
863		
864		var pathname = window.location.pathname.toLowerCase();
865		var cached_customer_address = localStorage.getItem('cached_customer_address');
866
867		if (pathname == '/' || pathname == '/main') {
868
869			// Hide zip code input if visable
870			if($(el + ' input[name="zip_code"]').attr('type') != 'hidden') {
871				$(el + ' input[name="zip_code"]').closest('.row').addClass('hidden')
872			}
873
874			// Auto fill address form with cached customer address
875			if (cached_customer_address !== null) {
876				var cached_customer_address = JSON.parse(cached_customer_address);
877				var fullAddress = cached_customer_address.full_address;
878
879				try {
880					$(el + ' input[name="address"]').val(fullAddress);
881					$(el + ' input[name="zip_code"]').val(cached_customer_address.zip_code);
882				}
883				catch(err) {
884					console.log("Issue parsing the stored address");   
885				}
886			}
887
888		}
889
890		if (pathname == '/mobile.php') {
891
892			// Auto fill mobile address form with cached customer address
893			if (cached_customer_address !== null) {
894				var cached_customer_address = JSON.parse(cached_customer_address);
895				var fullAddress = cached_customer_address.full_address;
896
897				try {
898					$(el + ' input[name="address"]').val(fullAddress);
899					$(el + ' input[name="zip_code"]').val(cached_customer_address.zip_code);
900				}
901				catch(err) {
902					console.log("Issue parsing the stored address");   
903				}
904			}
905		}
906	
907		$(el + ' input[name="address"]').focus(function() {
908			$('[data-toggle="address_popover"]').popover('hide');
909			//$(el + ' input[name="address"]').removeAttr('data-toggle').removeAttr('data-content').removeAttr('data-placement').removeAttr('data-animation');
910			$('[data-toggle="address_popover"]').popover('disable');
911		});
912	
913		$(el).on('submit', function(e){
914			e.preventDefault(e);
915			e.returnValue = false;
916			
917			if($(el + ' input[name="address"]').val().length === 0 && $(el + ' input[name="address"]').val() == '') {
918				$(el + ' input[name="address"]').attr('data-toggle', 'address_popover').attr('data-content', 'Please enter your address.').attr('data-placement','bottom').attr('data-animation','true');
919				$('[data-toggle="address_popover"]').popover('enable');
920				$('[data-toggle="address_popover"]').popover('show');
921				//return false;
922			}
923			else if($(el + ' input[name="address"]').val().length > 0 && $(el + ' input[name="zip_code"]').val().length === 0) {
924				$(el + ' input[name="address"]').attr('data-toggle', 'address_popover').attr('data-content', 'Please select a valid address from the dropdown list.').attr('data-placement','bottom').attr('data-animation','true');
925				$('[data-toggle="address_popover"]').popover('enable');
926				$('[data-toggle="address_popover"]').popover('show');
927			}
928			else {
929				add_page_loader();
930				is_in_area(true);
931			}
932		});
933	
934		function is_in_area(page_loader) {
935			var result = '';
936			var formData = { address_required_ajax: true };
937			$(el).find("input[name]").each(function (index, node) {
938				formData[node.name] = node.value;
939			});
940			$.ajax({
941				type: 'POST',
942				url: base_url + 'order',
943				dataType: 'json',
944				async: false,
945				data: formData,
946				success: function(data) {
947					if(data.out_of_area === 1){
948						remove_page_loader();
949						result = 'out_of_area';
950						localStorage.removeItem('cached_customer_address');
951						$(el + ' input[name="zip_code"]').val('');
952						$(el + ' input[name="address"]').attr('data-toggle', 'address_popover').attr('data-content', 'We’re sorry, but the address you entered is outside of our service area.').attr('data-placement','bottom').attr('data-animation','true');
953						$('[data-toggle="address_popover"]').popover('enable');
954						$('[data-toggle="address_popover"]').popover('show');
955					}
956					else if(data.in_area === 1){
957						result = 'in_area';
958					}
959					else {
960						result = 'unknown_error';
961					}
962				},
963				error: function(data) { 
964					result = 'out_of_area';
965					$(el + ' input[name="zip_code"]').val('');
966					$(el + ' input[name="address"]').attr('data-toggle', 'address_popover').attr('data-content', 'Please select a valid address from the dropdown list.').attr('data-placement','bottom').attr('data-animation','true');
967					$('[data-toggle="address_popover"]').popover('enable');
968					$('[data-toggle="address_popover"]').popover('show');
969					remove_page_loader();
970					localStorage.removeItem('cached_customer_address');
971				},
972				complete: function() {
973					if(result === 'in_area'){
974						if(!page_loader) {
975							add_page_loader();
976						}
977						// make sure that we are no longer handling the submit event; clear handler
978						$(el).off('submit');
979						// actually submit the form
980						if (pathname == '/mobile.php') {
981							$(el).attr('action', '/mobile.php/order');
982						}
983						else {
984							$(el).attr('action', '/order');
985						}
986						
987						// cache user address so it can be reused
988						var address = $(el + ' input[name="address"]').val()
989						var zipcode = $(el + ' input[name="zip_code"]').val()
990						var cached_address = {};
991						cached_address.full_address = address;
992						cached_address.zip_code = zipcode;
993
994						localStorage.setItem('cached_customer_address', JSON.stringify(cached_address));
995						
996						$(el).submit();
997					}
998					else if(result === 'unknown_error'){
999
1000						$(el + ' input[name="zip_code"]').val('');
1001						$(el + ' input[name="address"]').attr('data-toggle', 'address_popover').attr('data-content', 'We’re sorry, but the address you entered could not be found or is outside of our service area.').attr('data-placement','bottom').attr('data-animation','true');
1002						$('[data-toggle="address_popover"]').popover('enable');
1003						$('[data-toggle="address_popover"]').popover('show');
1004						remove_page_loader();
1005						localStorage.removeItem('cached_customer_address');
1006					}
1007				}
1008			});
1009			return true;
1010		}
1011	}
1012});
1013

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.