{"version":3,"file":"AE.ui.min.js","sources":["AE.ui.min.js"],"sourcesContent":["var AE = AE || {}; /* Add to Base object or create it if it doesn't exist. */\n/*\nThe AE.ui object will be the returned result of a self-invoked function. This allows us to expose methods\nfor use by other modules while protecting some variables in a closure. If the AE.ui object is already\ndefined then it's not altered. This prevents us from running the entire function each time one of its\ninternal methods are called.\n*/\nAE.ui = AE.ui || (function () {\n\t/*\n\tDEPENDENCIES: AE\n\t*/\n\n\tvar UI = {\n\t\t// Like resizeTasks in AE.js, these arrays are to be filled with functions to be executed...\n\t\tbodyClickTasks: [], // Delegated Tasks Triggered On Body Click\n\t\tbodyChangeTasks: [], // Delegated Tasks Triggered On Body Change\n\t\tinit: function () {\n\t\t\tvar prepMenusearch = prepMenusearch || false;\n\t\t\t/* Establish the props object only upon init. No need to do the work if the module isn't being called. */\n\t\t\tUI.props = {\n\t\t\t\tbodyEvent: '',\n\t\t\t\tclicksDisabled: false, // If set to true, then clicks will not be registered for matrix and results elements.\n\t\t\t\t// This property will be defined as the result of an IFFE (Individually Invoked Function Expression)\n\t\t\t\tappendTarget: (function () {\n\t\t\t\t\t// Used for the main search form. Most jQuery UI widgets have a property called \"appendTo\" which controls where widgets will\n\t\t\t\t\t// exist in the DOM. If the value is null then widgets will be attached to the body. Otherwise, the widget will be attached\n\t\t\t\t\t// to whatever selector or jQuery object is defined. This is important because we've put our content on a different branch of\n\t\t\t\t\t// the DOM than dialogs occupy, so we could have dropdowns or autocomplete widgets which don't scroll when they should.\n\t\t\t\t\t//\n\t\t\t\t\t// We have three possibilities for where the main search form may appear. The main page, modify or in a dialog. The value is\n\t\t\t\t\t// initially set to null, which means that the widgets will be appended to the body.\n\t\t\t\t\t// 1. MODIFY:\t\tThis is an inline form, but it doesn't have the same parent structure as the main page. The page is checked\n\t\t\t\t\t// \t\t\t\t\tto see if the user is on the modify page and sets the variable accordingly.\n\t\t\t\t\t// 2. HOME PAGE:\tSame as above, but due to the different structure the variable is set to a different ID.\n\t\t\t\t\t// 3. IN A DIALOG:\tDialogs are not on the same branch of the DOM, to prevent them from scrolling along with site content. For\n\t\t\t\t\t// \t\t\t\t\tthis case, the variable needs to be set to null so that widgets will be appended to the body.\n\n\t\t\t\t\tvar appendTo = null; // Default, mainly used for dialogs.\n\t\t\t\t\tif ($('body').hasClass('my-booking')) {\n\t\t\t\t\t\t// Modify page\n\t\t\t\t\t\tappendTo = '#search-form';\n\t\t\t\t\t} else if (!$('#ae-search').closest('.ui-dialog')[0]) {\n\t\t\t\t\t\t// Home page\n\t\t\t\t\t\tappendTo = '#top_search_form';\n\t\t\t\t\t}\n\t\t\t\t\treturn appendTo; //( $('#ae-search').closest('.ui-dialog')[0] ) ? null : '#top_search_form'\n\t\t\t\t})(),\n\n\t\t\t\tscrollContainer: $('#scroll-content'),\n\t\t\t\t$mainFooterTogglers: $('.main-footer__header'),\n\t\t\t\t$mainFooterTogglees: $('.main-footer__links'),\n\t\t\t\t$aeSearch: $(\"#ae-search\"),\n\t\t\t\t$menusearchEnabled: prepMenusearch,\n\t\t\t\t$tabContainers: $(\".tab_container\"),\n\t\t\t\t$accordionContainers: $(\".accordion_container\"),\n\t\t\t\t$accordionCollapsedContainers: $(\".accordion_container--collapsed\"),\n\t\t\t\t$dateInputs: $('input[class=\"datePickerInput\"]'),\n\t\t\t\t$autoPostForms: $('#trg-autoPostForm'),\n\t\t\t\t$currentDatePicker: null\n\t\t\t};\n\n\t\t\tUI.searchProps = {\n\t\t\t\troundTrip: true,\n\t\t\t\tcity: null, // City name for pickup\n\t\t\t\tcityr: null, // City name for dropoff\n\t\t\t\tpuloclist: null, // List of pickup locations\n\t\t\t\tdoloclist: null, // List of dropoff locations\n\t\t\t\tpucode: null, // country ISO code for pickup.\n\t\t\t\tdocode: null, // country ISO code for dropoff.\n\t\t\t\tpuCal: null, // Pickup date\n\t\t\t\tdoCal: null, // Dropoff date\n\t\t\t\tputime: null, // Pickup hour, must be 24 hour time, 0 - 23\n\t\t\t\tdotime: null, // dropoff hour, must be 24 hour time, 0 - 23\n\t\t\t\tsearchAge: 40, // checkbox for if the driver's age is between 25 and 70\n\t\t\t\tbookingstep: 'searchwait' // Set and done. Required for back-end.\n\t\t\t\t/* Conditional Properties\n\t\t\t\t\tmodUUID: Included when search form posts from Modify Page, ColdFusion UUID\n\t\t\t\t*/\n\t\t\t};\n\n\t\t\tUI.addBodyClickTask({\n\t\t\t\tfunc: UI.onBodyClick\n\t\t\t});\n\n\t\t\t//var bodyEvent = (AE.getSiteViewType() === 'palm' && $('html').hasClass('ua-ios')) ? 'click, touchend' : 'click';\n\t\t\t$('body').on('click', function (event) {\n\t\t\t\tUI.manageBodyClick(event);\n\t\t\t});\n\t\t\t//$('body').on('touchend', function(event){UI.manageBodyClick(event)});\n\n\t\t\t$('body').on('change', function (event) {\n\t\t\t\tUI.manageBodyChange(event)\n\t\t\t});\n\t\t\tUI.applyJQUI();\n\n\t\t\t// iOS patch for related links,\n\t\t\t// real solution would be to move\n\t\t\t// bodyevent from manage resize to props\n\t\t\tif ($('html').hasClass('ua-ios')) {\n\t\t\t\t$('body').on('touchend', function (event) {\n\t\t\t\t\tif ($(event.target).parent().hasClass('related__links')) {\n\t\t\t\t\t\tUI.manageBodyClick(event);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\n\t\t\t/* Set padding-top to <5px to workaround WEBAE3-4259\n\t\t\t* This will cause jquery-ui _hasScroll() to return false to jquery-ui _scrollIntoView()\n\t\t\t* avoiding an uncaught exception inside the latter where the passed element is empty. \n\t\t\t\n\t\t\tWEBAE3-5178 - changed padding below from 4px to 2px and it seems to fix sporadic\n\t\t\tissue that breaks text inputs\n\t\t\t\n\t\t\t*/\n\t\t\tvar fractionalScrollHeightStyle = document.createElement('style');\n\t\t\tif (AE.props.siteCode == 'FCR') {\n\t\t\t\tfractionalScrollHeightStyle.appendChild( document.createTextNode('#ui-id-147,#ui-id-150{padding-top:2px!important}') );\n\t\t\t}\n\t\t\telse {\n\t\t\t\tfractionalScrollHeightStyle.appendChild( document.createTextNode('#ui-id-99,#ui-id-102{padding-top:2px!important}') );\n\t\t\t}\n\t\t\tdocument.head.appendChild(fractionalScrollHeightStyle);\n\n\t\t\n\t\t\t$('a').filter(function () {\n\t\t\t\t// Checking for external links and adding rel=\"noopener\" - Because we can't train marketing how to SEO good\n\t\t\t\tvar $a = $(this);\n\t\t\t\tvar _href = $a.attr('href') || false;\n\t\t\t\tvar _host = this.hostname || false;\n\t\t\t\n\t\t\t\t// test script to remove the no opener rel tag\n\t\t\t\tvar _langTag = $a.attr('hreflang');\n\t\t\t\tvar _href = $a.attr('href') || false;\n\t\t\t\n\t\t\t\tif (_langTag === 'zh-CN' || _langTag === 'tr-TR') {\n\t\t\t\t\t_href = false;\n\t\t\t\t}\n\n\t\t\t\tvar _location = (typeof (location) != 'undefined') ? location.hostname : false;\n\t\t\t\tvar _hrefStr = _href ? $a.attr('href').substring(0, 4) : _href;\n\t\t\t\n\t\t\t\tif (_host && _location && (_host === _location)) {\n\t\t\t\t\t_hrefStr = false;\n\t\t\t\t}\n\t\t\t\tif (_host && _location && (_host.substring(0, 3) === _location.substring(0, 3))) {\n\t\t\t\t\t_hrefStr = false;\n\t\t\t\t}\n\t\t\t\treturn (_hrefStr === 'http') ? this.hostname && this.hostname !== location.hostname : false;\n\t\t\t}).addClass(\"external\").attr({\n\t\t\t\trel: 'noopener'\n\t\t\t});\n\t\t\n\t\t\t// Manage resize\n\t\t\tAE.addResizeTask({\n\t\t\t\tfunc: function () {\n\t\t\t\t\tUI.manageResize();\n\t\t\t\t},\n\t\t\t\targs: []\n\t\t\t});\n\n\t\t\t// scroll task-Back to top-WEBAE3-3319\n\t\t\tAE.addScrollTask({\n \t\t\t\tfunc: function () {\t \t\t\t\t\t\n \t\t\t\t\tvar elm = document.getElementById(\"scroll_target\");\n \t\t\t\t\tvar distanceFromTop = elm.getBoundingClientRect().top; \n \t\t\t\t\tvar targetDistance = -1200; \n \t\t\t\t\tvar $b2t = $('#back2top'); \t\t\t\t\n\t\t\t\t\tif(distanceFromTop < targetDistance){\n \t\t\t\t\t$b2t.removeClass('visuallyhidden');\n \t\t\t\t}else{\n \t\t\t\t\t$b2t.addClass('visuallyhidden');\n \t\t\t\t} \t\t\t\t\n \t\t\t\t}\n \t\t\t});\n\t\t\n\t\t\t// Initiate UI modules, if they exist\n\t\t\tif (AE.ui.search && $(\"#ae-search\")[0]) {\n\t\t\t\tAE.ui.search.init();\n\t\t\t} else {\n\t\t\t\t$.each($('select.time--select'), function () {\n\t\t\t\t\t$(this).parent('.styled--select').removeClass('ui-searchform--custom-form-el ui-timeselect-rev ui-ready-waiting');\n\t\t\t\t});\n\t\t\t}\n\t\t\tif (AE.ui.searchType && $(\"#ae-search\")[0]) {\n\t\t\t\tAE.ui.searchType.init();\n\t\t\t}\n\t\t\tif (AE.ui.dialog) {\n\t\t\t\tAE.ui.dialog.init();\n\t\t\t}\n\t\t\t/*\n\t\t\t * Timeselect and datepicker inits are now in AE.ui.searchType's init function\n\t\t\t *\n\t\t\t * if (AE.ui.timeselectmenu) { AE.ui.timeselectmenu.init(); }\n\t\t\t * if (AE.ui.datepicker) { AE.ui.datepicker.init(); }\n\t\t\t */\n\t\t\tif (AE.ui.modify && $('#aemodify')[0]) {\n\t\t\t\tAE.ui.modify.init();\n\t\t\t}\n\t\t\tif (AE.ui.tabcordion) {\n\t\t\t\tAE.ui.tabcordion.init();\n\t\t\t}\n\t\t\tif (AE.ui.carousel) {\n\t\t\t\tAE.ui.carousel.init();\n\t\t\t}\n\t\t\tif (AE.ui.selectmenu) {\n\t\t\t\tAE.ui.selectmenu.init();\n\t\t\t}\n\t\t\tif (AE.affiliate) {\n\t\t\t\tAE.affiliate.init();\n\t\t\t}\n\t\t\tif (AE.affiliate.terms) {\n\t\t\t\tAE.affiliate.terms.init();\n\t\t\t}\n\n\t\t\t// CAROUSEL FOR RAU/RNZ HERO CARDS\n\t\t\tvar slide = document.getElementsByClassName(\"hero_-slide\");// WEBAE3-3645 - disable test\n\n\t\t\tif(slide.length !== 0) {\n\t\t\t\tvar heroCardIndex = 0;\n\t\t\t\tfunction carousel() {\n\t\t\t\t\tvar i;\n\t\t\t\t\tslide[0].style.display = \"block\";\n\t\t\t\t\tfor (i = 0; i < slide.length; i++) {\n\t\t\t\t\t\tslide[i].style.display = \"none\";\n\t\t\t\t\t}\n\t\t\t\t\theroCardIndex++;\n\t\t\t\t\tif (heroCardIndex > slide.length) {heroCardIndex = 1}\n\t\t\t\t\t$(slide[heroCardIndex-1]).css('opacity', 1)\n\t\t\t\t\t\t\t\t.show('slide', {direction: 'right'}, 1500)\n\t\t\t\t\t\t\t\t.animate(\n\t\t\t\t\t\t\t\t\t{ opacity: 1 },\n\t\t\t\t\t\t\t\t\t{ queue: false, duration: 2000 }\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\tsetTimeout(carousel, 7000); // Change hero card every 7 seconds\n\t\t\t\t}\n\t\t\t\tcarousel();\n\t\t\t}\n\t\t},\n\t\tdisableClicks: function () {\n\t\t\tUI.props.clicksDisabled = true;\n\t\t},\n\t\tenableClicks: function () {\n\t\t\tUI.props.clicksDisabled = false;\n\t\t},\n\t\tmanageResize: function () {\n\t\t\tvar siteViewType = AE.getSiteViewType();\n\n\t\t\t// Changing the target event for body clicks, changing to touchend when using a mobile device.\n\t\t\tUI.props.bodyEvent = ($('html').hasClass('ua-mobile')) ? 'touchend' : 'click';\n\n\t\t\t/*\n\t\t\tNOTE: The $mainFooterTogglees start with the \"visuallyhidden\" class so they don't flash into view upon palm-sized page load. This is\n\t\t\tsorted out by the initial run of manageResize() so they will be properly visible on a desk-sized page load.\n\n\t\t\t* Added check if toggle was already open on resize to leave it at it's current state.\n\t\t\t*/\n\t\t\t$('.hasDatepicker')\n\t\t\t\t.datepicker('hide')\n\t\t\t\t.on('click', function () {\n\t\t\t\t\t$(this).datepicker('show')\n\t\t\t\t});\n\n\t\t\t/* Mobile toggles only work at lap and down sizes. */\n\t\t\t$('.toggler.toggler--portable')\n\t\t\t\t.each(function (index) {\n\t\t\t\t\tvar $togglee = $(this)\n\t\t\t\t\t\t.closest('.toggle')\n\t\t\t\t\t\t.find('.togglee');\n\n\t\t\t\t\tif (siteViewType === 'desk' || siteViewType === 'desk-wide') {\n\t\t\t\t\t\t$(this).addClass('open');\n\t\t\t\t\t\tUI.show($togglee);\n\t\t\t\t\t} else {\n\t\t\t\t\t\t$(this).removeClass('open');\n\t\t\t\t\t\tUI.hide($togglee);\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\t\t/* Palm-only toggles only work at palm size, so they need to be closed initially. */\n\t\t\t$('.toggler.toggler--palm')\n\t\t\t\t.each(function (index) {\n\t\t\t\t\tvar $togglee = $('' + $(this).data('togglee') + '');\n\n\t\t\t\t\t// Insurance options Shenanigans with Plus and Minus state, different than other toggles\n\t\t\t\t\tvar insurance = ($(this).closest('#insuranceUI').length) ? true : false;\n\t\t\t\t\tvar pmOptionsStop = ($(this).hasClass('open') && !$togglee.hasClass('visuallyhidden')) ? false : true;\n\n\t\t\t\t\tif (siteViewType === 'palm') {\n\t\t\t\t\t\tif (insurance) {\n\t\t\t\t\t\t\tif (pmOptionsStop) {\n\t\t\t\t\t\t\t\thideToggle($(this), $togglee);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\thideToggle($(this), $togglee);\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tif (!pmOptionsStop) {\n\t\t\t\t\t\t\t$(this).addClass('open');\n\t\t\t\t\t\t\tUI.show($togglee);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (insurance) {\n\t\t\t\t\t\t\tif (!pmOptionsStop) {\n\t\t\t\t\t\t\t\tshowToggle($(this), $togglee);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tshowToggle($(this), $togglee);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tfunction hideToggle($toggler, $togglee) {\n\t\t\t\t\t\t$toggler.removeClass('open');\n\t\t\t\t\t\tUI.hide($togglee);\n\t\t\t\t\t}\n\n\t\t\t\t\tfunction showToggle($toggler, $togglee) {\n\t\t\t\t\t\t$toggler.addClass('open');\n\t\t\t\t\t\tUI.show($togglee);\n\t\t\t\t\t}\n\n\t\t\t\t});\n\n\t\t\t/* Toggles for larger sizes don't work at this size, so they need to be opened. */\n\t\t\t$('.toggler.toggler--lap-and-up').each(function (index) {\n\t\t\t\tvar $togglee = $(this).closest('.toggle').find('.togglee');\n\n\t\t\t\t/* Open non-palm toggles upon resize in palm view. */\n\t\t\t\tif (siteViewType === 'palm') {\n\t\t\t\t\t$(this).addClass('open');\n\t\t\t\t\tUI.show($togglee);\n\t\t\t\t} else {\n\t\t\t\t\t$(this).removeClass('open');\n\t\t\t\t\tUI.hide($togglee);\n\t\t\t\t}\n\t\t\t});\n\n\t\t\t/*\n\t\t\t\tTogglees that need to be open and delay befor then closing.\n\t\t\t\tNOTE: Need to add data size on togglee to target delay by type or all\n\t\t\t*/\n\t\t\t$('.togglee--delay-close').each(function (index) {\n\t\t\t\tvar $togglee = $(this);\n\t\t\t\tvar deviceSize = ($togglee.data('size') !== undefined) ? $togglee.data('size') : '';\n\t\t\t\tvar palm = ($togglee.hasClass('delay--palm')) ? 'palm' : '';\n\t\t\t\tvar lap = ($togglee.hasClass('delay--lap')) ? 'lap' : '';\n\t\t\t\tvar desk = ($togglee.hasClass('delay--desk')) ? 'desk' : '';\n\n\t\t\t\tsetTimeout(function () {\n\t\t\t\t\t_.each([palm, lap, desk], function (device) {\n\t\t\t\t\t\tif (AE.getSiteViewType() === device) {\n\t\t\t\t\t\t\tvar passSize = (deviceSize !== '') ? '--' + device : '';\n\t\t\t\t\t\t\tUI.hide($togglee, passSize);\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t}, 2000);\n\t\t\t});\n\t\t},\n\t\tonBodyClick: function (event, $target) {\n\n\t\t\t// Add scroll to top of this id selector\n\t\t\tif($target.hasClass('btn--back2top') || $($target.parent()).hasClass('btn--back2top')){\t\t\t\t\t\n \t\t\t\tdocument.getElementById('sticky-wrapper').scrollIntoView();\t\t\n \t\t\t}\n\n\t\t\t/* HANDLE TOGGLES:\n\t\t\t\tA container with a class of \".toggle\" contains a \".toggler\" and a \"togglee\". They don't have\n\t\t\t\tto be siblings. They can be in grids and other containers, so long as they can track upward to the same parent.\n\t\t\t\t\n\t\t\t\tFor manual toggles, use both classes: \"toggler\" and \"toggler--manual\". The toggler class will apply the proper\n\t\t\t\tCSS to the element, and the toggler--manual class will prevent it from functioning automatically.\n\t\t\t\t\n\t\t\t\tManual toggles require specific code to run the handleToggle() function, but they can add a callback function.\n\t\t\t\tSend in a jQuery collection of your toggler, the name of your function and an array of arguments.\n\t\t\t\t\n\t\t\t\tExample: AE.ui.handleToggle( $myToggler, myFunctionName, [arg1, arg2, arg3] );\n\t\t\t*/\n\t\t\tif ($target.hasClass('toggler') && !$target.hasClass('toggler--manual')) {\n\t\t\t\tUI.handleToggle($target);\n\t\t\t}else if($target.prop('tagName') !== 'INPUT' && !$target.hasClass('grid__item-ta-modifier')){// WEBAE3-3866 - don't run closeToggle when user clicks an input to start entering values - LJW\n\t\t\t\tvar $target = $(event.target);// now it's a jQuery object\n\t\t\t\tvar $toggleeContainer = $target.closest('.matrix_filter');\n\t\t\t\tvar $taModChildren = $target.find('.grid__item-ta-modifier');\n var checkout_process = $('body#options').length || $('body#upgrade').length|| $('body#checkout').length == 0;\n\t\t\t\tif($toggleeContainer.length == 0 && $taModChildren.length == 0 && !checkout_process) {\n\t\t\t\t\tUI.closeToggle();\n\t\t\t\t}\n\t\t\t}\n\t\t\t\n\t\t\t// Test environment for staging and production - QA1, QA2, QA3, QA4, and PTEST\n\t\t\tif ($target.hasClass('test_environment')) {\n\t\t\t\tAECookie.update('PTEST', 'no', 0); //remove the ptest cookie\n\t\t\t\tvar qaCookie = (AECookie.read('QA')) ? '?QA=false' : '';\n\t\t\t\twindow.location.href = '/'+qaCookie; //reset the stage/test environment back to the base\n\t\t\t}\n\t\t\t\n\t\t\t// ENABLER ELEMENT - toggle disabled property of a selected element\n\t\t\tif ($target.hasClass('trg__enabler') && $target.data('enablee')) {\n\t\t\t\tif ($target.hasClass('enabler--on')) {\n\t\t\t\t\t$($target.data('enablee')).prop('disabled', true);\n\t\t\t\t\t$target.removeClass('enabler--on');\n\t\t\t\t} else {\n\t\t\t\t\t$($target.data('enablee')).prop('disabled', false);\n\t\t\t\t\t$target.addClass('enabler--on');\n\t\t\t\t}\n\t\t\t}\n\t\t\t\n\t\t\t// Matrix Results, Utility bar, Modify & Optional Eq - More Info Tips\n\t\t\tif ($target.hasClass('more-info-tip')) {\n\t\t\t\t//WEBAE-4574 catch cancel modal triggers\n\t\t\t\tif ($target.attr('data-modalname')==\"cancelModal\"){\n\t\t\t\t\tAE.booking.cancelModal();\n\t\t\t\t\n\t\t\t\t}else{\n\t\t\t\tAE.ui.dialog.launch({\n\t\t\t\t\ttype: 'infoTip',\n\t\t\t\t\tpos: {\n\t\t\t\t\t\tmy: 'left top',\n\t\t\t\t\t\tat: 'left bottom+5',\n\t\t\t\t\t\tof: $target\n\t\t\t\t\t},\n\t\t\t\t\tselector: $target.children('.more-info-text')\n\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\n\t\t\t}\n\n\t\t\t// For pages which aren't part of the buyback or luxury portions of the booking system, we're going to have a special\n\t\t\t// link for \"iCommunicator Voice Over IP\". This is only shown on desktop, and opens a pop-up window.\n\t\t\tif ($target.hasClass('voip-link')) {\n\t\t\t\tAE.ga.gaArrayProcess([{\n\t\t\t\t\tGACATEGORY: 'VOIP',\n\t\t\t\t\tGAACTION: 'click'\n\t\t\t\t}]);\n\t\t\t\tvar clientID = $target.data('voipcode');\n\t\t\t\t\n\t\t\t\tif ($target.hasClass('icomm_direct') || (clientID == '8fb2338n0n5w2bj7' || clientID == 'ecz610fox8q57dgn' || clientID == 'o3lwm3e04730w06o')) {\n\t\t\t\t\twindow.open(\"http://client.icommconnect.com/Home/DirectCall?contactGuid=\" + clientID + \"\", \"\", \"scrollbars=yes,width=360, height=640\");\n\t\t\t\t} else {\n\t\t\t\t\t// hasClass 'icomm_directory'\n\t\t\t\t\twindow.open(\"http://client.icommconnect.com/Home/Call?clientSubscriptionGUId=\" + clientID + \"\", \"\", \"scrollbars=yes,width=360, height=640\");\n\t\t\t\t}\n\t\t\t}\n\t\t\t\n\t\t\t// 8x8 co-browsing\n\t\t\tif ($target.hasClass('co_browse_site')) {\n\t\t\t\treturn UI.call8x8CoBrowsing(event);\n\t\t\t}\n\t\t},\n\t\tmanageBodyClick: function (event) {\n\t\t\t/* Cycle through Body Click tasks */\n\t\t\tif (UI.props.clicksDisabled) {\n\t\t\t\treturn\n\t\t\t};\n\t\t\t// This module listens to 'click' and 'touchend' events to run this function. To prevent it from firing\n\t\t\t// twice, we keep a string in the props object to indicate which one to use. The event.type string in\n\t\t\t// the event object must match this module prop string in order to go forward. For example, if a tablet\n\t\t\t// registers both events, then the 'click' will cause this function to return, while the 'touchent' call\n\t\t\t// will run this function normally.\n\t\t\t//\n\t\t\t// This is important in case some brand of tablets decides to abandon click in favor of touchend. Since\n\t\t\t// the bodyEvent property initializes as an empty string, this line will also prevent toggles from working\n\t\t\t// until the property is populated by the name of the appropriate event.\n\t\t\t//if(event.type !== UI.props.bodyEvent) { return; }\n\n\t\t\tvar $target = $(event.target);\n\n\t\t\t// Run through all of the registered body click tasks in our codebase.\n\t\t\tfor (var i = 0; i < UI.bodyClickTasks.length; i++) {\n\t\t\t\t// Even if no arguments were passed in, the args array was still established as an empty array when\n\t\t\t\t// the task is added to the array. The first two arguments will be the event and target, with other\n\t\t\t\t// arguments following after. A new array is made with each loop iteration so that previous arguments\n\t\t\t\t// cannot carry over into subsequent iterations.\n\t\t\t\tvar arrArgs = [event, $target].concat(UI.bodyClickTasks[i].args);\n\n\t\t\t\t// Using the apply method, we'll pass in \"this\" from the perspective of this function, using the\n\t\t\t\t// arguments from the task object. So if you were to establish some sort of property like \"this.thing\"\n\t\t\t\t// then every bodyClick function in every module would have access to this.thing. We don't really do\n\t\t\t\t// that, however. Most of these functions simply require the event object and the first thing they\n\t\t\t\t// want to do is establish a jQuery collection of the event target. To save lines, we do this here\n\t\t\t\t// and pass it in.\n\t\t\t\tUI.bodyClickTasks[i].func.apply(this, arrArgs);\n\t\t\t};\n\t\t},\n\t\taddBodyClickTask: function (task) {\n\t\t\t/*\n\t\t\tAdds an object with a func property that is function taking the\n\t\t\tevent object as its ONLY argument to an array of functions.\n\t\t\tOn a body change event, these functions will be executed using\n\t\t\tthe apply() method in manageBodyClick() to pass in the correct target on each event.\n\n\t\t\tEach 'task' should start by performing logic on the event target to determine whether it should run.\n\n\t\t\tAE.ui.addBodyClickTask(\n\t\t\t\t{\n\t\t\t\tfunc:function(event){\n\t\t\t\t\tif(event meets criteria){\n\t\t\t\t\tdo stuff\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t}\n\t\t\t);\n\t\t\t*/\n\n\t\t\t// Make sure that the args array is an array if it wasn't defined.\n\t\t\ttask.args = task.args || [];\n\t\t\tUI.bodyClickTasks.push(task);\n\t\t},\n\t\tmanageBodyChange: function (event) {\n\t\t\t/* Cycle through Body Change tasks */\n\t\t\t// Explanations for this code are documented above in body click management\n\t\t\tvar $target = $(event.target);\n\t\t\tfor (var i = 0; i < UI.bodyChangeTasks.length; i++) {\n\t\t\t\tvar arrArgs = [event, $target].concat(UI.bodyChangeTasks[i].args);\n\t\t\t\tUI.bodyChangeTasks[i].func.apply(this, arrArgs);\n\t\t\t};\n\t\t},\n\t\taddBodyChangeTask: function (task) {\n\t\t\t/*\n\t\t\tAdds an object with a func property that is function taking the\n\t\t\tevent object as its ONLY argument to an array of functions.\n\t\t\tOn a body change event, these functions will be executed using\n\t\t\tthe apply() method in manageBodyChange() to pass in the correct target on each event.\n\n\t\t\tEach 'task' should start by performing logic on the event target to determine whether it should run.\n\n\t\t\tAE.ui.addBodyChangeTask(\n\t\t\t\t{\n\t\t\t\tfunc:function(event){\n\t\t\t\t\tif(event meets criteria){\n\t\t\t\t\tdo stuff\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t}\n\t\t\t);\n\t\t\t*/\n\t\t\ttask.args = task.args || [];\n\t\t\tUI.bodyChangeTasks.push(task);\n\t\t},\n\t\taddSpinner: function (selector, settings) {\n\t\t\t/*\n\t\t\tTurns an element into a relatively-positioned container for a spinner element, then adds the spinner. FontAwesome\n\t\t\tis used for the spinner itself, and it's rotated with CSS.\n\n\t\t\tExample call: AE.ui.addSpinner('.my-selector', { size:'5x', color: 'white' });\n\t\t\tThe size can be any size provided by FontAwesome. A value of '5x' results in a class of \"fa-5x\". The color can be\n\t\t\tthe default gray, white or black. Hex values may not be passed in because we don't want every developer to use a\n\t\t\tdifferent color every time. Three colors is plenty.\n\t\t\t*/\n\t\t\tvar $target = $(selector);\n\t\t\tsettings = settings || {};\n\t\t\tvar sizeClass = settings.size ? ' fa-ae-' + settings.size : '';\n\n\t\t\t/* If a color setting is passed in, white or black is used instead of relying upon the default gray in the CSS. */\n\n\t\t\t$target\n\t\t\t\t.addClass('spinner__container')\n\t\t\t\t.find('.spinner__div').parent()\n\t\t\t\t.remove()\n\t\t\t\t.end();\n\n\n\t\t\tif(AE.props.siteCode !== 'FCR') {\n\t\t\t\t$target.append('
');\n\t\t\t} else {\n\t\t\t\tfunction isIE() {\n\t\t\t\t\tvar ua = window.navigator.userAgent; //Check the userAgent property of the window.navigator object\n\t\t\t\t\tvar msie = ua.indexOf('MSIE '); // IE 10 or older\n\t\t\t\t\tvar trident = ua.indexOf('Trident/'); //IE 11\n\t\t\t\t\n\t\t\t\t\treturn (msie > 0 || trident > 0);\n\t\t\t\t}\n\t\t\t\tif(isIE()) {\n\t\t\t\t\t$target.append('
');\n\t\t\t\t} else {\n\t\t\t\t\t$target.append('
');\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (settings.color) {\n\t\t\t\tif ((settings.color.indexOf('#') != -1)) {\n\t\t\t\t\t$target.find('.spinner').css({\n\t\t\t\t\t\t'color': settings.color\n\t\t\t\t\t});\n\t\t\t\t} else {\n\t\t\t\t\tvar colorClass = (settings.color === 'white') ? 'spinner--white' : 'spinner--black';\n\t\t\t\t\t$target.find('.spinner').addClass(colorClass);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t$target.find('.spinner__div').parent().css('min-height', ($target.find('.spinner__div').outerHeight(true)) + 'px');\n\n\t\t\tif (settings.noWobble) {\n\t\t\t\tvar noWobbleClass = 'no-wobble';\n\t\t\t\t$target.find('.spinner').addClass(noWobbleClass);\n\t\t\t}\n\n\t\t},\n\t\tremoveSpinner: function (selector) {\n\t\t\t$(selector).removeClass('spinner__container').find('.spinner__div').parent().remove();\n\t\t},\n\t\tapplyJQUI: function (selector) { // Applies Common jQueryUI widget behaviors to elements with trigger classes in selected container\n\t\t\t// Get the jQuery selector for the CONTAINER element\n\t\t\tselector = selector || 'body';\n\t\t\t\n\t\t\t// This applies the jQueryUI datepicker method to all input elements with the datePickerInput class\n $(selector + ' input.datePickerInput').datepicker();\n\t\t\t\n\t\t\t// Set an \"onSelect\" event globally to all datePicker form fields on the page\n\t\t\t$(selector + ' input.datePickerInput')\n\t\t\t\t.datepicker(\"option\", \"onSelect\", function (dateText, inst) {\n\t\t\t\t\tif (this.dataset && this.dataset.endDatePicker && this.dataset.endDatePicker.length) {\n\t\t\t\t\t\tvar startDate = new Date(dateText);\n\t\t\t\t\t\tvar duration = this.dataset.minDuration || 0;\n\t\t\t\t\t\tif ($.isNumeric(duration) && duration >= 0) {\n\t\t\t\t\t\t\tstartDate.setDate(startDate.getDate() + duration);\n\t\t\t\t\t\t}\n\t\t\t\t\t\t$($.trim(this.dataset.endDatePicker)).datepicker(\"option\", \"minDate\", startDate);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\n\t\t\t$(selector + ' input.datePickerInput').prop(\"readonly\", true);\n\t\t\t\n\t\t\t/* Additional DatePicker calendar parameters */\n\t\t\t// Loop through all of the DatePickers on the page\n\t\t\tfor (var i = 0; i < $(selector + ' input.datePickerInput').length; i++) {\n\t\t\t\t// Get a pointer to the current DatePicker\n\t\t\t\tvar currentDatePicker = $(selector + ' input.datePickerInput')[i];\n\n\t\t\t\t// Read the data attribute about what kind of DatePicker this is\n\t\t\t\tvar pickerType = $(currentDatePicker).attr('data-pickertype');\n\n\t\t\t\t// If there is a date already chosen, get it\n\t\t\t\tvar pickerValue = $(currentDatePicker).val();\n\t\t\t\t\n\t\t\t\t// Call a function to configure this specific DatePicker\n\t\t\t\tconfigureCurrentDatePicker($(currentDatePicker), pickerType, pickerValue);\n\t\t\t}\n\n\t\t\t/* Function to configure specific DatePicker parameters */\n\t\t\tfunction configureCurrentDatePicker(currentDatePicker, pickerType, pickerValue) {\n\t\t\t\tvar yearUpperRange, yearLowerRange, dp_options = {};\n\t\t\t\tswitch (pickerType) {\n\t\t\t\t\tcase \"birthdate\":\n\t\t\t\t\tcase \"birthdateNotReq\":\n\t\t\t\t\t\n\t\t\t\t\t\t// DatePicker used for \"date of birth\"\n\t\t\t\t\t\tyearUpperRange = $.datepicker.formatDate(\"yy\", new Date()) - 18;\n\t\t\t\t\t\tif (pickerValue == \"\") {\n\t\t\t\t\t\t\tpickerValue = (pickerType == \"birthdateNotReq\") ? pickerValue : \"-18y\";\n\t\t\t\t\t\t}\n\t\t\t\t\t\tvar setminDate = \"-18y\";\n\t\t\t\t\t\thiddenDob = $(\"input#hidden-dob-date\").val();\n\n\t\t\t\t\t\tif(hiddenDob.length){\t\t\t\t\t\t\t\n\t\t\t\t\t\t\thiddenDob = $.datepicker.parseDate('yy-mm-dd', hiddenDob);\n\t\t\t\t\t\t\t//pickerValue = hiddenDob;\n\t\t\t\t\t\t\tpickerValue = new Date(hiddenDob);\n\t\t\t\t\t } \n\t\t\t\t\t\tdp_options = {\n\t\t\t\t\t\t\thideIfNoPrevNext: true,\n\t\t\t\t\t\t\tchangeMonth: true,\n\t\t\t\t\t\t\tchangeYear: true,\n\t\t\t\t\t\t\tyearRange: \"1900:\" + yearUpperRange,\n\t\t\t\t\t\t\tminDate: new Date(\"01/01/1900\"),\n\t\t\t\t\t\t\tdefaultDate: setminDate,\n\t\t\t\t\t\t\tsetDate: pickerValue,\n\t\t\t\t\t\t\taltField: '#hidden-dob-date',\n\t\t\t\t\t\t\taltFormat: 'mm-dd-yy'\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif(hiddenDob.length !=0){currentDatePicker.datepicker(\"setDate\", pickerValue);} \n\t\t\t\t\t\t// Should we show or hide the \"clear datepicker input form field\" option\n\t\t\t\t\t\tif (pickerValue == \"\") {\n\t\t\t\t\t\t\t$('span.ui-datepicker-target-input').hide();\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t$('span.ui-datepicker-target-input').show();\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\t\t\t\t\n\t\t\t\t\tcase \"expires\":\n\t\t\t\t\t\t// Datepicker used for things that expire in the future\n\t\t\t\t\t\tyearUpperRange = parseInt($.datepicker.formatDate(\"yy\", new Date())) + 20;\n\t\t\t\t\t\tyearLowerRange = parseInt($.datepicker.formatDate(\"yy\", new Date()));\n\t\t\t\t\t\tdp_options = {\n\t\t\t\t\t\t\thideIfNoPrevNext: true,\n\t\t\t\t\t\t\tchangeMonth: true,\n\t\t\t\t\t\t\tchangeYear: true,\n\t\t\t\t\t\t\tyearRange: yearLowerRange + \":\" + yearUpperRange,\n\t\t\t\t\t\t\tminDate: new Date(),\n\t\t\t\t\t\t\tsetDate: \"\"\n\t\t\t\t\t\t};\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"report\":\n\t\t\t\t\t\n\t\t\t\t\t\t// DatePicker used for \"date of birth\"\n\t\t\t\t\t\t//yearUpperRange = $.datepicker.formatDate(\"yy\", new Date()) - 18;\n\t\t\t\t\t\tif (pickerValue == \"\") {\n\t\t\t\t\t\t\tpickerValue = (pickerType == \"birthdateNotReq\") ? pickerValue : \"-18y\";\n\t\t\t\t\t\t}\n\t\t\t\t\t\t//var setminDate = \"-18y\";\n\t\t\t\t\t\thiddenReport = $(\"input#hiddenreportdate\").val();\n\n\t\t\t\t\t\tif(hiddenReport.length){\t\t\t\t\t\t\t\n\t\t\t\t\t\t\thiddenReport = $.datepicker.parseDate('yy-mm-dd', hiddenReport);\n\t\t\t\t\t\t\tpickerValue = new Date(hiddenReport);\n\t\t\t\t\t } \n\t\t\t\t\t\tdp_options = {\n\t\t\t\t\t\t\thideIfNoPrevNext: true,\n\t\t\t\t\t\t\tchangeMonth: true,\n\t\t\t\t\t\t\tchangeYear: true,\n\t\t\t\t\t\t\t//yearRange: \"1900:\" + yearUpperRange,\n\t\t\t\t\t\t\tminDate: new Date(\"01/01/1900\"),\n\t\t\t\t\t\t\t//defaultDate: setminDate,\n\t\t\t\t\t\t\tmaxDate: new Date(),\n\t\t\t\t\t\t\tsetDate: pickerValue,\n\t\t\t\t\t\t\taltField: '#hiddenreportdate',\n\t\t\t\t\t\t\taltFormat: 'mm-dd-yy'\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif(hiddenReport.length !=0){currentDatePicker.datepicker(\"setDate\", pickerValue);} \n\t\t\t\t\t\t// Should we show or hide the \"clear datepicker input form field\" option\n\t\t\t\t\t\tif (pickerValue == \"\") {\n\t\t\t\t\t\t\t$('span.ui-datepicker-target-input').hide();\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t$('span.ui-datepicker-target-input').show();\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\t\n\t\t\t\t\tcase \"report2\":\n\t\t\t\t\t\n\t\t\t\t\t\t// DatePicker used for \"date of birth\"\n\t\t\t\t\t\t//yearUpperRange = $.datepicker.formatDate(\"yy\", new Date()) - 18;\n\t\t\t\t\t\tif (pickerValue == \"\") {\n\t\t\t\t\t\t\tpickerValue = (pickerType == \"birthdateNotReq\") ? pickerValue : \"-18y\";\n\t\t\t\t\t\t}\n\t\t\t\t\t\t//var setminDate = \"-18y\";\n\t\t\t\t\t\thiddenReport = $(\"input#hiddenreportdate2\").val();\n\n\t\t\t\t\t\tif(hiddenReport.length){\t\t\t\t\t\t\t\n\t\t\t\t\t\t\thiddenReport = $.datepicker.parseDate('yy-mm-dd', hiddenReport);\n\t\t\t\t\t\t\tpickerValue = new Date(hiddenReport);\n\t\t\t\t\t } \n\t\t\t\t\t\tdp_options = {\n\t\t\t\t\t\t\thideIfNoPrevNext: true,\n\t\t\t\t\t\t\tchangeMonth: true,\n\t\t\t\t\t\t\tchangeYear: true,\n\t\t\t\t\t\t\t//yearRange: \"1900:\" + yearUpperRange,\n\t\t\t\t\t\t\tminDate: new Date(\"01/01/1900\"),\n\t\t\t\t\t\t\t//defaultDate: setminDate,\n\t\t\t\t\t\t\tmaxDate: new Date(),\n\t\t\t\t\t\t\tsetDate: pickerValue,\n\t\t\t\t\t\t\taltField: '#hiddenreportdate2',\n\t\t\t\t\t\t\taltFormat: 'mm-dd-yy'\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif(hiddenReport.length !=0){currentDatePicker.datepicker(\"setDate\", pickerValue);} \n\t\t\t\t\t\t// Should we show or hide the \"clear datepicker input form field\" option\n\t\t\t\t\t\tif (pickerValue == \"\") {\n\t\t\t\t\t\t\t$('span.ui-datepicker-target-input').hide();\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t$('span.ui-datepicker-target-input').show();\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\t\n\t\t\t\t\tcase \"issued\":\n if(AE.props.siteCode == 'DAU' || AE.props.siteCode == 'DNZ' || AE.props.siteCode == 'DAP') {\n dp_options = {\n\t\t\t\t\t\t\t\tbeforeShow: function (input, inst) {\n setTimeout(function() {\n var dpoffset = currentDatePicker.offset();\n var dpheight = currentDatePicker.outerHeight();\n var top = dpoffset.top + dpheight;\n \n inst.dpDiv.css({\n top: top,\n left: dpoffset.left\n });\n }, 0);\n }\n };\n break;\n }\n\t\t\t\t\tcase \"issuedExt\":\n\t\t\t\t\t\t// DatePicker used for things in the past like a \"date of issue\"\n\t\t\t\t\t\tyearUpperRange = parseInt($.datepicker.formatDate(\"yy\", new Date()));\n\t\t\t\t\t\tyearRangeSize = (pickerType === 'issuedExt' && AE.props.chaosSystem === 'EU')? 100 : 20;\n\t\t\t\t\t\tyearLowerRange = parseInt($.datepicker.formatDate(\"yy\", new Date())) - yearRangeSize;\n\t\t\t\t\t\tdp_options = {\n\t\t\t\t\t\t\thideIfNoPrevNext: true,\n\t\t\t\t\t\t\tchangeMonth: true,\n\t\t\t\t\t\t\tchangeYear: true,\n\t\t\t\t\t\t\tyearRange: yearLowerRange + \":\" + yearUpperRange,\n\t\t\t\t\t\t\tminDate: new Date(\"01/01/\" + yearLowerRange),\n\t\t\t\t\t\t\tmaxDate: new Date(),\n\t\t\t\t\t\t\tsetDate: \"\"\n\t\t\t\t\t\t};\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"lookup\":\n\t\t\t\t\t\t// DatePicker used to lookup a voucher\n\t\t\t\t\t\tdp_options = {\n\t\t\t\t\t\t\taltFormat: \"mm-dd-yy\",\n\t\t\t\t\t\t\taltField: \"#dateToPassAlong\"\n\t\t\t\t\t\t};\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"gps_pu\":\n\t\t\t\t\t\t// DatePicker used on the GPS form\n\t\t\t\t\t\tdp_options = {\n\t\t\t\t\t\t\t// dateFormat: \"mm/dd/yy\",\n\t\t\t\t\t\t\taltFormat: \"mm-dd-yy\",\n\t\t\t\t\t\t\tminDate: new Date(),\n\t\t\t\t\t\t\tsetDate: \"\"\n\t\t\t\t\t\t};\n\t\t\t\t\t\t// Removed for WEBAE3-1652\n\t\t\t\t\t\t// currentDatePicker.attr(\"placeholder\", $.datepicker.formatDate(currentDatePicker.datepicker(\"option\", \"dateFormat\"), new Date()));\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"gps_do\":\n\t\t\t\t\t\t// DatePicker used on the GPS form\n\t\t\t\t\t\tdp_options = {\n\t\t\t\t\t\t\t// dateFormat: \"mm/dd/yy\",\n\t\t\t\t\t\t\taltFormat: \"mm-dd-yy\",\n\t\t\t\t\t\t\tminDate: new Date(),\n\t\t\t\t\t\t\tsetDate: \"\"\n\t\t\t\t\t\t};\n\t\t\t\t\t\t// Removed for WEBAE3-1652\n\t\t\t\t\t\t// currentDatePicker.attr(\"placeholder\", $.datepicker.formatDate(currentDatePicker.datepicker(\"option\", \"dateFormat\"), new Date()));\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"datepaid\":\n\t\t\t\t\t\t// DatePicker used on the DAP advise electronic payment form\n\t\t\t\t\t\t// This is specifically written for Sydney, AU time. dapDatePaidMax and dapDatePaidMin are created in CF and sent to JS in mod_ds_actions.cfm.\n\t\t\t\t\t\t\n\t\t\t\t\t\t/*console.log(dapDatePaidMax);\n\t\t\t\t\t\tconsole.log(dapDatePaidMin);*/\n\t\t\t\t\t\t\n\t\t\t\t\t\tdp_options = {\n\t\t\t\t\t\t\t// dateFormat: \"mm/dd/yy\",\n\t\t\t\t\t\t\taltFormat: \"mm-dd-yy\",\n\t\t\t\t\t\t\tminDate: dapDatePaidMin,\n\t\t\t\t\t\t\tmaxDate: dapDatePaidMax,\n\t\t\t\t\t\t\tsetDate: dapDatePaidMax\n\t\t\t\t\t\t};\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\t// All other DatePickers\n\t\t\t\t\t\tdp_options = {\n\t\t\t\t\t\t\tminDate: new Date(),\n\t\t\t\t\t\t\tsetDate: new Date()\n\t\t\t\t\t\t};\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\tdp_options.onSelect = function (dateText) {\n\t\t\t\t\tif ($(this).attr('required') && dateText != '') {\n\t\t\t\t\t\t$(this).parent()\n\t\t\t\t\t\t\t.removeClass(\"ui-state-invalid\")\n\t\t\t\t\t\t\t.addClass(\"ui-state-valid\");\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t$(this).next('span.ui-error-message').remove();\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t\t\t\n\t\t\t\tdp_options.onClose = function (dateText) {\n\t\t\t\t\tif ($(this).is('[dpStartDate]')) {\n\t\t\t\t\t\tvar startDate = new Date(dateText);\n\t\t\t\t\t\tvar endDateElement = document.querySelector('input.datePickerInput[dpEndDate]');\n\t\t\t\t\t\tif (endDateElement) {\n\t\t\t\t\t\t\t$(endDateElement).datepicker(\"option\", \"minDate\", startDate);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t\t\t\n\t\t\t\t// Apply the above datepicker options\n\t\t\t\tcurrentDatePicker.datepicker(\"hide\").datepicker(\"destroy\").blur();\n\t\t\t\tcurrentDatePicker.datepicker(dp_options);\n\t\t\t\t\n\t\t\t\t$(AE.ui.props.scrollContainer)[0].addEventListener('scroll', function (e) {\n\t\t\t\t\tcurrentDatePicker.datepicker('hide').on('click', function () {\n\t\t\t\t\t\tcurrentDatePicker.datepicker('show');\n\t\t\t\t\t});\n\t\t\t\t}, {\n\t\t\t\t\tpassive: true\n\t\t\t\t});\n\t\t}\n\n\t\t\t// Keep the datepicker field empty on the forms found on these pages\n\t\t\tvar pagesWithEmptyDatepickerFields = [\"/driver-profile/\", \"/beatrate/\"];\n\t\t\tif (pagesWithEmptyDatepickerFields.includes(AE.url.props.path)) {\n\t\t\t\t//$(selector+' input.datePickerInput').datepicker('setDate','')\n\t\t\t}\n\t\t\t\n\t\t\t// Pick Up Date field in voucher lookup form must be excluded from these rules per Karen 2017-01-26 NW\n\t\t\tif ($('#vouchpudate')[0]) {\n\t\t\t\t$.datepicker._clearDate($('#vouchpudate').datepicker('option', 'minDate', null));\n\t\t\t}\n\t\t\t\n\t\t\t// Pickup and Dropoff defaults for different services. Put correct class on given input\n\t\t\t$(selector + ' .tab_container').tabs();\n\t\t\t\n\t\t\t/* This code anticipates an element with the tab_container class to have a child UL\n\t\t\t\twith LIs of anchored links to subsequent children\n\t\t\t\tExample:\n\t\t\t\t
\n\t\t\t\t\n\t\t\t\t
First
\n\t\t\t\t
Second
\n\t\t\t\t
\n\t\t\t*/\n\t\t\t$(selector + ' .accordion_container').accordion({\n\t\t\t\theightStyle: 'content'\n\t\t\t});\n\t\t\t\n\t\t\t/* This code anticipates an element with the accordion_container class to have a\n\t\t\t\tseries of child header and div pairs\n\t\t\t\tExample:\n\t\t\t\t
\n\t\t\t\t
First
\n\t\t\t\t
Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet.
\n\t\t\t\t
Second
\n\t\t\t\t
Phasellus mattis tincidunt nibh.
\n\t\t\t\t
Third
\n\t\t\t\t
Nam dui erat, auctor a, dignissim quis.
\n\t\t\t\t
\n\t\t\t*/\n\t\t\t$(selector + ' .accordion_container--collapsed').accordion({\n\t\t\t\tcollapsible: true,\n\t\t\t\tactive: false,\n\t\t\t\theightStyle: \"content\"\n\t\t\t}); // This accordion variant \"starts closed\" and sections will \"close\" if clicked after being \"opened\"\n\t\t},\n\t\tdecodeHtml: function (htmlStr) {\n\t\t\tvar txt = document.createElement(\"textarea\");\n\t\t\ttxt.innerHTML = htmlStr;\n\t\t\treturn txt.value;\n\t\t},\n\t\n\t\t/*\n\t\tWe have our own functions for some common jQuery methods to help with accessibility. The 'visuallyhidden' class moves an element\n\t\toff-screen but leaves it visible so that screen readers can still read it. The 'size' argument allows us to specifically target\n\t\tcertain sizes. For example, you could hide something only from the palm size. Leaving out the 'size' argument results in the\n\t\tregular 'visuallyhidden' class.\n\n\t\tThe code looks weird, so here are the steps:\n\n\t\tshow()\n\t\t1. Check the size, and set to an empty string if it isn't defined.\n\t\t2. Do a normal jQuery slideUp(). The element now has an inline style of \"display:none\".\n\t\t3. When finished, remove the 'visuallyhidden' class.\n\t\t4. Do a normal jQuery slideDown, but with a zero duration. The element is now displayed, but off-screen.\n\n\t\thide()\n\t\t1. Check the size, and set to an empty string if it isn't defined.\n\t\t2. Add the appropriate \"visuallyhidden\" class.\n\t\t4. Do a jQuery slideDown with a zero duration just to make sure that the element doesn't have \"display:none\" attached to it.\n\n\t\tslideUp()\n\t\t1. Check the size, and set to an empty string if it isn't defined.\n\t\t2. Do a jQuery slideUp() with a duration of 'fast'.The element now has an inline style of \"display:none\".\n\t\t3. When finished, add the appropriate \"visuallyhidden\" class.\n\t\t4. Do a normal jQuery slideDown, but with a zero duration. The element is now displayed, but off-screen.\n\n\t\tslideDown()\n\t\t1. Do a normal jQuery slideUp() to put \"display:none\" on the elements. This prevents it from becoming momentarily visible in the next step.\n\t\t2. When finished, remove all \"visuallyhidden\" classes. This eliminates the need for a size argument.\n\t\t3. Do a normal jQuery slideDown. The element is now displayed and on-screen.\n\t\t*/\n\t\tshow: function ($target, size) {\n\t\t\tsize = size || '';\n\t\t\t$target.slideUp(0, function () {\n\t\t\t\t$target.removeClass('visuallyhidden' + size).slideDown(0);\n\t\t\t});\n\t\t},\n\t\thide: function ($target, size) {\n\t\t\tsize = size || '';\n\t\t\t$target.addClass('visuallyhidden' + size).slideDown(0);\n\t\t},\n\t\tslideUp: function ($target, size) {\n\t\t\t/*\n\t\t\tIf the size has been passed in and if it's not an empty string, then prepend with dashes to build visibility class.\n\t\t\tOtherwise, leave it as an empty string so that we will wind up with just \"visuallyhidden\".\n\t\t\t*/\n\t\t\tsize = size || '';\n\t\t\t$target.slideUp('fast', function () {\n\t\t\t\t$target.addClass('visuallyhidden' + size).slideDown(0);\n\t\t\t});\n\t\t},\n\t\tslideDown: function ($target) {\n\t\t\t$target.slideUp(0, function () {\n\t\t\t\t$target\n\t\t\t\t\t.removeClass('visuallyhidden visuallyhidden--palm visuallyhidden--lap visuallyhidden--portable visuallyhidden--lap-and-up visuallyhidden--desk visuallyhidden--desk-wide')\n\t\t\t\t\t.slideDown('fast', function()\n {\n $target.removeClass('opening');\n });\n\t\t\t});\n\t\t},\n\t\tisVisuallyHidden: function ($target, size) {\n\t\t\t/* Returns true if the target is visually hidden at the given size. If no size is given, current size is used. */\n\t\t\tsize = size || AE.getSiteViewType();\n\t\t\treturn ($target.hasClass('visuallyhidden') || $target.hasClass('visuallyhidden' + size));\n\t\t},\n\t\thandleToggle: function ($toggler, objCallback, args) {\n\t\t\t// $toggler: jQuery object representing your toggler.\n\t\t\t// callback: The name of a function that you want to run along with the toggle. Not invoked, so no parentheses.\n\t\t\t// args: An array of arguments to be applied to the function.\n\t\t\t//\n\t\t\t// Example: AE.ui.handleToggle( $myToggler, myFunctionName, [arg1, arg2, arg3] );\n\n\t\t\tvar $togglee = null,\n\t\t\t\t$toggleo = null,\n\t\t\t\tsize = $toggler.data('size');\n\n\t\t\t// If there's a data attribute for the togglee, then use that as a jQuery selector string. If not, then find the\n\t\t\t// parent \"toggle\" class and then drill down within that parent container to the element with the \"togglee\" class.\n\n\t\t\tif ($toggler.data('togglee')) {\n\t\t\t\t$togglee = $($toggler.data('togglee'));\n\n\t\t\t\t// Since there's a date attribute, look for any other elements with the same data attribute. This covers the\n\t\t\t\t// rare case when there are two different togglers which act upon the same target. A $toggler is just a jQuery\n\t\t\t\t// collection, so jQuery methods will be run on all elements within that collection. Chevrons will stay in sync.\n\t\t\t\t$toggler = $('[data-togglee=\"' + $toggler.data('togglee') + '\"]');\n\n\t\t\t} else {\n\t\t\t\t$togglee = $toggler.closest('.toggle').find('.togglee');\n\t\t\t}\n\n\t\t\tif ($toggler.data('toggleo')) {\n\t\t\t\t$toggleo = $($toggler.data('toggleo'));\n\t\t\t} else {\n\t\t\t\t$toggleo = $togglee;\n\t\t\t}\n\n\t\t\tif (!(\n\t\t\t\t\tsize === 'palm' ||\n\t\t\t\t\tsize === 'portable' ||\n\t\t\t\t\tsize === 'lap' ||\n\t\t\t\t\tsize === 'lap-and-up' ||\n\t\t\t\t\tsize === 'desk' ||\n\t\t\t\t\tsize === 'desk-wide'\n\t\t\t\t)) {\n\t\t\t\tsize = '';\n\t\t\t}\n\t\t\n\t\t\t// This is an on/off toggle using a slide animation. We use our own slideUp and slideDown functions.\n\n\t\t\t// If the subset has been passed in and if it's not an empty string, then prepend with dashes to build visibility class.\n\t\t\t// Otherwise, leave it as an empty string so that we will wind up with just \"visuallyhidden\".\n\t\t\tsize = (size !== '') ? ('--' + size) : '';\n\n\t\t\tif ($togglee.hasClass('visuallyhidden' + size)) {\n\t\t\t// Close any open filters first\n var checkout_process = $('body#options').length || $('body#upgrade').length|| $('body#checkout').length == 0;\n\t\t\t\tif ($('.toggler').hasClass('open') && !$('.toggler').closest('#insuranceUI').length && !checkout_process) {\n $('.toggler').removeClass('open');\n\t\t\t\t\t$('.toggler').addClass('closed');\n\t\t\t\t\tUI.slideUp($('.styled--select .togglee'));\n \n // WEBAE3-4854 Handle closing of opened accordion FAQ questions\n UI.slideUp($('.US_Accordion .togglee'));\n\t\t\t\t}\n\t\t\t\t// Now open the the togglee\n $toggler.removeClass('closed')\n $toggler.addClass('open')\n $togglee.addClass('opening'); // Opening the toggle target, so add the 'open' class.\n UI.slideDown($togglee)\n } else if(!$togglee.hasClass('opening')) {\n $toggler.removeClass('open'); // Closing the toggle target, so remove the 'open' class.\n $toggler.addClass('closed'); // Closing the toggle target, so remove the 'open' class.\n UI.slideUp($togglee, size);\n }\n\n // Target an non nested header with an open class Modify Optional Eq has a cancel button that is an alternate toggler\n if ($toggleo.hasClass('open')) {\n $toggleo.removeClass('open');\n }\n\n // $('body').on('click', function () {\n // \t$('.toggler').removeClass('open')\n // \t$('.toggler').addClass('closed')\n // \tUI.slideUp($('.togglee'));\n // });\n\n // After the slide up or down is activated, the optional callback object is handled, if it was passed in.\n if (objCallback) {\n objCallback.func.apply(this, objCallback.args);\n }\n\t\t\t// }\n\t\t},\n\t\tcloseToggle: function () {\n // WEABE3-3864 & 5526 - Plus Minus Headers shouldn't be part of the togglers auto-closed when something besides them gets clicked.\n\t\t\t$('.toggler:not(.toggle_pm_header):not(.package-header)').removeClass('open')\n\t\t\t$('.toggler:not(.toggle_pm_header):not(.package-header)').addClass('closed')\n\t\t\tUI.slideUp($('.styled--select .togglee'));\n\n\t\t\t// var $toggleParent = ([event.target][0].parentElement)\n\t\t\t// // console.log(\"&*&*&*&*&*&*&*&*&*&\")\n\t\t\t// // console.log($toggleParent)\n\t\t\t// if ($toggleParent !== $('.matrix_filter')[0]) {\n\t\t\t// \t$('.toggler').removeClass('open')\n\t\t\t// \t$('.toggler').addClass('closed')\n\t\t\t// \tUI.slideUp($('.togglee'));\n\t\t\t// }\n\t\t},\n\t\tcontentGroup: function ($controllers, $contentEls, settings) {\n\t\t\t/*\n\t\t\tSimilar to tabs, but not limited by markup. The $controllers argument is a jQuery collection of links which will show or hide\n\t\t\tcontent. The $contentEls argument is a jQuery selector which targets the various content areas. For example, a set of navigation\n\t\t\tlinks could have a class called 'controllers' and the content areas could have a class called 'content'.\n\n\t\t\tThe controller links each need to have a data attribute which will identify it's content area. This DOES NOT need to be an id.\n\t\t\tContent areas will be limited to the $contentEls collection, so the data attribute just needs to be unique in that context.\n\n\t\t\tNOTE: The settings object is optional, and is used to determine what kind of show/hide method will be used.\n\n\t\t\t1.\tSetting the \"willSlide\" boolean property to true will cause items to slide up or down instead of the default show/hide.\n\t\t\t2.\tThe \"visual\" property determins whether our own show/hide methods will be used instead of the standard jQuery versions.\n\t\t\t\tOur methods show, hide and slide up or down using the \"visuallyhidden\" class within the inuitcss framework. Since these\n\t\t\t\tare technically visible (although off-screen) we can't just use is(\":visible\") to see if an element is shown on-screen.\n\t\t\t\tThis function DOES NOT support the other forms of the \"visuallyhidden\" class used for media queries. It just uses the\n\t\t\t\tregular class.\n\n\t\t\tHere's an example of the markup:\n\n\t\t\t\n\t\t\t
This is some stuff.
\n\t\t\t
Here are some things.
\n\t\t\t
Look at these doodads.
\n\t\t\t
Here is a dinglehopper.
\n\n\t\t\tYou would either add \"visuallyhidden\" or style=\"display:none\" to elements which will start out hidden.\n\n\t\t\tAnd then in your JavaScript:\n\t\t\tAE.ui.contentGroup( $('.myController'), $('.myContent') );\n\t\t\t*/\n\t\t\tvar options = $.extend({\n\t\t\t\t\twillSlide: false, // slide up/down or just show/hide\n\t\t\t\t\tvisual: false // display block/none or use \"visuallyhidden\" class\n\t\t\t\t},\n\t\t\t\tsettings // Object passed in will override default.\n\t\t\t);\n\n\t\t\tvar showHideFunc = (options.visual === true) ? visuallyToggle : showHide;\n\n\t\t\t$controllers.on(\"click\", function (event) {\n\t\t\t\tevent.preventDefault();\n\t\t\t\t$controllers.not($(this)).removeClass('current');\n\t\t\t\t$(this).addClass('current');\n\n\t\t\t\t// Saving \"$(this)\" to variable for when we go into a different scope.\n\t\t\t\tvar $content = $contentEls.filter(\"[data-content='\" + $(this).data('content') + \"']\");\n\t\t\t\tshowHideFunc($contentEls, $content, options.willSlide);\n\t\t\t});\n\n\n\t\t\tfunction showHide($contentEls, $content, willSlide) {\n\n\t\t\t\tvar $otherEls = $([]),\n\t\t\t\t\t$targetEl = $([]);\n\n\t\t\t\t$contentEls.not($content).each(function (index) {\n\t\t\t\t\tvar $item = $(this);\n\t\t\t\t\tif ($item.is(':visible')) {\n\t\t\t\t\t\t$otherEls = $otherEls.add($item);\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\t\t\tif (!$content.is(':visible')) {\n\t\t\t\t\t$targetEl = $targetEl.add($content);\n\t\t\t\t}\n\n\t\t\t\tif (willSlide) {\n\t\t\t\t\t// Using jQuery selectors to decide which ones to show or hide.\n\t\t\t\t\t$otherEls.slideUp();\n\t\t\t\t\t$targetEl.slideDown();\n\t\t\t\t} else {\n\t\t\t\t\t// Using jQuery selectors to decide which ones to show or hide.\n\t\t\t\t\t$otherEls.hide();\n\t\t\t\t\t$targetEl.show();\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfunction visuallyToggle($contentEls, $content, willSlide) {\n\n\t\t\t\t// Empty at first, fill it up in a sec.\n\t\t\t\tvar $otherEls = $([]),\n\t\t\t\t\t$targetEl = $([]);\n\n\t\t\t\t$contentEls.not($content).each(function (index) {\n\t\t\t\t\tvar $item = $(this);\n\t\t\t\t\tif (!$item.hasClass('visuallyhidden')) {\n\t\t\t\t\t\t$otherEls = $otherEls.add($item);\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\t\t\tif ($content.hasClass('visuallyhidden')) {\n\t\t\t\t\t$targetEl = $targetEl.add($content);\n\t\t\t\t}\n\n\n\t\t\t\tif (willSlide) {\n\t\t\t\t\t// Using jQuery selectors to decide which ones to show or hide.\n\t\t\t\t\tAE.ui.slideUp($otherEls);\n\t\t\t\t\tAE.ui.slideDown($targetEl);\n\t\t\t\t} else {\n\t\t\t\t\t// Using jQuery selectors to decide which ones to show or hide.\n\t\t\t\t\tAE.ui.hide($otherEls);\n\t\t\t\t\tAE.ui.show($targetEl);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t\n\n\t\t\n\n\t}\n\treturn UI;\n})();\n\n;\r\nvar AE = AE || {}; /* Add to Base object or create it if it doesn't exist. */\r\n\r\n/*\r\n This object will be the returned result of a self-invoked function. This allows us to expose methods\r\n for use by other modules while protecting some variables in a closure. If the object is already\r\n defined then it's not altered. This prevents us from running the entire function each time one of its\r\n internal methods are called.\r\n*/\r\nAE.ui.search = AE.ui.search || (function () {\r\n 'use strict';\r\n /* DEPENDENCIES: Any other modules that this one will call */\r\n\r\n var oSubmit = {},\r\n oStoredSearch = {},\r\n props = {},\r\n searchPuDate,\r\n searchDoDate,\r\n searchPuTime,\r\n searchDoTime,\r\n isMenuSearch = false;\r\n\r\n var UI = {\r\n init: function () {\r\n // Options for the datepicker, adding to props because they need to be reset (after widget.Destroy) in order to change the number of displayed months\r\n props = {\r\n $form: $(\"#ae-search\"),\r\n memberage: \"\",\r\n ageDefault: (AEdata && AEdata.defaultAgeOverride) ? AEdata.defaultAgeOverride : 40, // The generic default age can be overridden by member age bewteen 25-69 in search_form.cfm - WEBAE3-1686\r\n ageMin: 25, // The minimum age to rent without additional restrictions or fees\r\n ageMax: 69, // The maximum age to rent without additional restrictions or fees\r\n direction: \"\",\r\n useStoredSearch: (typeof useStoredSearch != \"undefined\") ? useStoredSearch : false, // useStoredSearch: (\"localStorage\" in window),\r\n $viewSize: AE.getSiteViewType(), // As of now, only changing the number of months displayed on the calendar for handhelds\r\n searchFormErrorHandler: {},\r\n displayMenusearch: AE.ui.props.$menusearchEnabled,\r\n oStoredSearch: AE.ui.search.getStoredSearch(),\r\n menusearch: {},\r\n menusearchOptions: {\r\n searchtype: 'menusearch',\r\n query: window.location.search.substring(1),\r\n timeout: 0\r\n },\r\n $searchFormErrorHandler: {\r\n msgTitle: null,\r\n msgDesc: null,\r\n pos: {\r\n top: -5,\r\n left: 0\r\n }\r\n },\r\n hasAgeChkbx:true,\r\n };\r\n\r\n if(oSite.bIsDapTpDomain){ //WEBAE3-6038\r\n if (oSite.path_info === \"\"){ \r\n AE.ui.search.cleanStoredSearch();\r\n }\r\n }\r\n\r\n if (!window.jsloginStatus) {\r\n if (UI.readCookie('MEMBERAGE')) { $.removeCookie('MEMBERAGE', { path: '/' }); }\r\n if (UI.readCookie('MEMBERFIRST')) { $.removeCookie('MEMBERFIRST', { path: '/' }); }\r\n props.showFillAgeCheckout = true;\r\n }\r\n\r\n // The appendTarget considers this module when setting its value\r\n props.$topSearch = AE.ui.props.appendTarget;\r\n props.$bottomSearch = '#bottom_search_form';\r\n props.$searchContainer = $('#search-form')[0];\r\n props.$searchSlideBtn = $('#targetSearch');\r\n\r\n props.$locationsWrapper = $('#locations-wrapper');\r\n props.$chkDiff = props.$form.find($(\"input[name='chk-diff']\")); // Pointer to the \"Different Dropoff Location\" checkbox form field\r\n props.$chkAge = props.$form.find($(\"input[name='chk-age']\")); // Pointer to the \"Age\" checkbox form field\r\n props.$txtAge = props.$form.find($(\"input[name='txt-age']\")); // Pointer to the \"Age\" text imput form field\r\n\r\n props.$jsonPost = props.$form.find($(\"input[name='jsonPost']\")); // A stringified version of the other values in the \"form\" object\r\n props.$btnSubmit = props.$form.find($(\"button[name='btn-submit']\")); // Button used to submit the hidden form\r\n\r\n props.$puLoc = props.$form.find($(\"div[name='pickup-loc']\"));\r\n props.$doLoc = props.$form.find($(\"div[name='dropoff-loc']\"));\r\n\r\n // MENU search: pointers to the PU & DO form fields\r\n props.$menu_puCountry = props.$form.find($(\"select[name='PU-country']\"));\r\n props.$menu_puCity = props.$form.find($(\"select[name='PU-city']\"));\r\n props.$menu_puLocation = props.$form.find($(\"select[name='PU-loc']\"));\r\n props.$menu_doCountry = props.$form.find($(\"select[name='DO-country']\"));\r\n props.$menu_doCity = props.$form.find($(\"select[name='DO-city']\"));\r\n props.$menu_doLocation = props.$form.find($(\"select[name='DO-loc']\"));\r\n\r\n // Pointers to the \"Pickup Date\" & \"Dropoff Date\" form fields\r\n props.$puDate = props.$form.find($(\"input[name='pickup-date']\"));\r\n props.$doDate = props.$form.find($(\"input[name='dropoff-date']\"));\r\n props.$doDateOneway = props.$form.find($(\"input[id='dropoff-date_oneway']\"));\r\n\r\n // Pointers to the hidden \"Pickup Date\" & \"Dropoff Date\" form fields - used when the past search criteria is found\r\n props.$hiddenPuDate = props.$form.find($(\"input[name='hidden-pickup-date']\"));\r\n props.$hiddenDoDate = props.$form.find($(\"input[name='hidden-dropoff-date']\"));\r\n \r\n\r\n // Pointers to the \"Pickup Time\" & \"Dropoff Time\" form fields\r\n props.$puTime = props.$form.find($(\"select[name='pickup-time']\"));\r\n props.$doTime = props.$form.find($(\"select[name='dropoff-time']\"));\r\n props.$doTimeOneway = props.$form.find($(\"select[id='dropoff-time_oneway']\"));\r\n\r\n // Pointers to the hidden \"Pickup Time\" & \"Dropoff Time\" form fields - used when the past search criteria is found\r\n props.$hiddenPuTime = props.$form.find($(\"input[name='hidden-pickup-time']\"));\r\n props.$hiddenDoTime = props.$form.find($(\"input[name='hidden-dropoff-time']\"));\r\n \r\n props.memberage = UI.readCookie('MEMBERAGE');\r\n\r\n props.$fcrOnewayChk = props.$form.find($(\"input[name='fcr-oneway_chk']\"))\r\n \r\n\r\n if (props.memberage == null) {\r\n props.memberage = (AEdata && AEdata.defaultAgeOverride) ? AEdata.defaultAgeOverride : props.memberage;\r\n }\r\n \r\n props.useStoredSearch = (!AE.privateBrowsing._checkLocalStorageAvailability()) ? true : false;\r\n\r\n if (!props.useStoredSearch) {\r\n props.ageDefault = (props.memberage) ? props.memberage: props.ageDefault; \r\n }\r\n\r\n isMenuSearch = prepMenusearch;//WEBAE3-4074 prepMenusearch will always be a boolean from CF now\r\n\r\n if(AE.props.siteCode){props.hasAgeChkbx = (AE.props.siteCode === 'PEU' || AE.props.siteCode === 'RNZ'|| AE.props.siteCode === 'RAU')? false : true;}\r\n\r\n oSubmit = {\r\n viewSize: AE.getSiteViewType(),\r\n display_label: null, // display value for search input\r\n display_labelr: null, // display value for search input\r\n city: null, // city name for pickup\r\n cityr: null, // city name for dropoff\r\n puloclist: null, // list of pickup locations\r\n doloclist: null, // list of dropoff locations\r\n pucode: null, // country ISO code for pickup\r\n docode: null, // country ISO code for dropoff\r\n puloctype: null, // category type for pickup\r\n doloctype: null, // category type for dropoff\r\n puCal: null, // pickup date sent from form (different from what the user sees)\r\n doCal: null, // dropoff date sent from form (different from what the user sees)\r\n putime: null, // pickup hour, must be 24 hour time, 0 - 23\r\n dotime: null, // dropoff hour, must be 24 hour time, 0 - 23\r\n puchaos_hub_id: null, // chaos_hub_id to increment click count server side\r\n dochaos_hub_id: null, // chaos_hub_id to increment click count server side\r\n searchAge: props.ageDefault, // checkbox for when the driver's age is less than 25 or over 69\r\n searchAgeCheckbox: true,\r\n showFillAgeCheckout:true,\r\n bookingstep: 'searchwait', // Set and done - required for back-end\r\n bookingUUID: '', // Filled with Car Search UUID or Booking Lookup UUID when posting from the Booking Process or Lookup Page respectively\r\n excl_ltr: false, // Flag for Long-Term Rental/Peugeot Lease exclusive search\r\n excl_cats: '' // Optional comma-delimited list of category codes (e.g. C6,C10 for luxury/convertible) for category exclusive search\r\n };\r\n\r\n props.searchAgeCheckbox = props.hasAgeChkbx;\r\n\r\n // Set the age checkbox as checked, setting the text input to the default age - moved above stored search check WEBAE3-1695\r\n if(props.hasAgeChkbx){\r\n if (props.ageDefault >= props.ageMax || props.ageDefault <= props.ageMin) {\r\n props.$chkAge.prop('checked', false);\r\n props.$txtAge.val(props.ageDefault.toString()).show();\r\n } else {\r\n props.$chkAge.prop('checked', true); \r\n props.$txtAge.val(props.ageDefault.toString()).hide();\r\n }\r\n }\r\n //WEBAE3-5460 if WL site, make sure aff and sys haven't changed\r\n //and if they have, clear stored search (again) only on white labels\r\n if(localStorage.getItem('aeSearchAff') !== null && localStorage.getItem('aeSearchSys') !== null && oSite.mSiteCode == 'WL'){\r\n if(localStorage.getItem('aeSearchAff') !== oSite.affiliate || localStorage.getItem('aeSearchSys') !== oSite.chaosSystem){\r\n localStorage.removeItem('aeSearch');\r\n localStorage.removeItem('aeSearchAff');\r\n localStorage.removeItem('aeSearchSys');\r\n }\r\n }\r\n\r\n if(AE.ui.search.useStoredSearch() && localStorage.getItem('aeSearch') === null && AECookie.read('aeSearch')){\r\n var cookieSearch = AECookie.read('aeSearch');\r\n if(_.isString(cookieSearch) && cookieSearch !== ''){\r\n localStorage.setItem('aeSearch',cookieSearch);\r\n }\r\n }\r\n\r\n if (AE.ui.search.useStoredSearch() && localStorage.getItem('aeSearch') && \r\n _.isString(localStorage.getItem('aeSearch')) && \r\n localStorage.getItem('aeSearch') != '') {\r\n props.oStoredSearch = JSON.parse(localStorage.getItem('aeSearch'));\r\n\r\n if (props.oStoredSearch.putime && _.isString(props.oStoredSearch.putime) && props.oStoredSearch.putime != '') {\r\n searchPuTime = props.oStoredSearch.putime;\r\n props.$hiddenPuTime.val(searchPuTime);\r\n props.$puTime.val(searchPuTime);\r\n } else {\r\n searchPuTime = '10:00';\r\n props.$hiddenPuTime.val(searchPuTime);\r\n props.$puTime.val(searchPuTime);\r\n }\r\n \r\n if (props.oStoredSearch.dotime && _.isString(props.oStoredSearch.dotime) && props.oStoredSearch.dotime != '') {\r\n searchDoTime = props.oStoredSearch.dotime;\r\n props.$hiddenDoTime.val(searchDoTime);\r\n props.$doTime.val(searchDoTime);\r\n } else {\r\n searchDoTime = '10:00';\r\n props.$hiddenDoTime.val(searchDoTime);\r\n props.$doTime.val(searchDoTime);\r\n }\r\n \r\n if (props.oStoredSearch.puCal && _.isString(props.oStoredSearch.puCal) && props.oStoredSearch.puCal != '') {\r\n searchPuDate = props.oStoredSearch.puCal;\r\n props.$hiddenPuDate.val(searchPuDate);\r\n }\r\n \r\n if (props.oStoredSearch.doCal && _.isString(props.oStoredSearch.doCal) && props.oStoredSearch.doCal != '') {\r\n searchDoDate = props.oStoredSearch.doCal;\r\n props.$hiddenDoDate.val(searchDoDate);\r\n isMenuSearch = prepMenusearch;//WEBAE3-4074 prepMenusearch will always be a boolean from CF now\r\n }\r\n \r\n //WEBAE3-1695 - use age from stored search if avail\r\n\r\n if (props.oStoredSearch.searchAge && props.oStoredSearch.search != '' && !isLTRSearch) {\r\n searchAge = props.oStoredSearch.searchAge;\r\n AE.ui.search.setAge(searchAge);//setAge function handles box checking for age range\r\n\r\n //if previous search had box unchecked, make sure this one does, too - WEBAE3-1686\r\n if (props.oStoredSearch.searchAgeCheckbox === false) {\r\n AE.ui.search.forceSearchAgeCheckBox();\r\n }\r\n }\r\n } else {\r\n //WEBAE3-1686 if not using local storage so analyze search age set in search_form.cfm for possible member age or oBK age\r\n if (props.ageDefault && props.ageDefault != '' && props.hasAgeChkbx) {\r\n AE.ui.search.setAge(props.ageDefault);\r\n } else if (searchAge && searchAge != '') {\r\n AE.ui.search.setAge(searchAge);\r\n\r\n //if previous search had box unchecked, make sure this one does, too - WEBAE3-1686\r\n if (props.oStoredSearch.searchAgeCheckbox === false) {\r\n AE.ui.search.forceSearchAgeCheckBox();\r\n }\r\n }\r\n }\r\n\r\n if(isBMRSearch){\r\n if(localStorage.getItem('aeBMRsearch')){ \r\n var bmr_age = JSON.parse(localStorage.getItem('aeBMRsearch')).driverAge;\r\n props.$txtAge.val(bmr_age);\r\n } \r\n }\r\n\r\n if(!props.hasAgeChkbx){\r\n props.$chkAge.hide();\r\n $('label[for=\"chk-age\"]').hide();\r\n\r\n props.$txtAge.addClass('flush').prop('required',true).attr('max',1000);\r\n $('input[name=\"txt-age\"]').show();\r\n props.$txtAge.show();\r\n \r\n if(props.memberage && props.memberage != '' && !AE.ui.search.useStoredSearch()){\r\n props.$txtAge.val( props.memberage);\r\n } \r\n }\r\n\r\n //search age handlers\r\n props.$chkAge.on(\"change\", function (event) {\r\n UI.chkAgeHandler(event.target.checked);\r\n var _checked = $(this).is(':checked');\r\n if (!_checked) {\r\n props.$txtAge.attr({ 'required': true });\r\n if (AE.props.siteCode == 'FCR') {\r\n $('#txt-age-error').show();\r\n }\r\n } else {\r\n props.$txtAge.attr({ 'required': false });\r\n if (AE.props.siteCode == 'FCR') {\r\n $('#txt-age-error').hide();\r\n }\r\n }\r\n if(!AE.account.props){AE.account.init();}\r\n\r\n if (props.memberage && AE.account.props.$isLoggedIn && !isBMRSearch) {\r\n if (_checked) {\r\n if (props.$txtAge.val() > props.ageMax || props.$txtAge.val()< props.ageMin || props.$txtAge.val() == \"\") {\r\n UI.setAge(40);// WEABE3-2963 - Changing this value to props.ageDefault in WEBAE3-2936 causes the checkbox to break\r\n // Returning this value to 40 restores checkbox functionality WITHOUT messing up the age input filling from the voucher OR member data\r\n } else { \r\n UI.setAge(props.$txtAge.val());\r\n }\r\n }\r\n }\r\n //WEBAE3-3047\r\n if (isBMRSearch) {\r\n if (bmr_age) {\r\n props.$txtAge.val(bmr_age);\r\n } else if ( props.memberage) {\r\n props.$txtAge.val(props.memberage);\r\n }\r\n }\r\n });\r\n //search age handlers\r\n props.$txtAge.on(\"blur\", function (event) {\r\n var runThis = true;\r\n if (AE.props.isAUNZ) { runThis = false; }\r\n if (runThis) {\r\n if (props.$txtAge.val() != '') {\r\n props.ageDefault = props.$txtAge.val();\r\n searchAge = props.oStoredSearch.searchAge;\r\n } else {\r\n props.$txtAge.attr({'required': true });\r\n oSubmit.searchAge = '';\r\n UI.chkAgeHandler(props.$chkAge.prop('checked'));\r\n }\r\n } else {\r\n props.$txtAge.attr({'required': true });\r\n }\r\n });\r\n props.$chkDiff.on(\"change\", function (event) {\r\n var _checked = $(this).is(':checked');\r\n if (_checked) {\r\n props.$locationsWrapper.addClass('both');\r\n } else {\r\n props.$locationsWrapper.removeClass('both');\r\n\r\n // clear the drop off input and check for LTR\r\n if (isLTRSearch) {\r\n AE.ui.searchType.leasesearch.props.$ltrdo.val(AE.ui.searchType.leasesearch.props.$ltrpu.val());\r\n AE.ui.searchType._forceInputBlur(AE.ui.searchType.text.props.$ltrdo);\r\n } else if (isBMRSearch) {\r\n // AE.ui.searchType.bmr.props.$ltrdo.val(AE.ui.searchType.bmr.props.$ltrpu.val());\r\n } else {\r\n AE.ui.searchType.text.props.$doLoc.next('.ui-textsearch-clear-input').trigger('click');\r\n AE.ui.searchType._forceInputBlur(AE.ui.searchType.text.props.$doLoc);\r\n }\r\n }\r\n });\r\n\r\n // // keep oneway search open without registering change event\r\n // if ($(\"input[name='chk-diff']\").is(\":checked\")) {\r\n // alert(\"checked\")\r\n // props.$locationsWrapper.addClass('both');\r\n // } else {\r\n // props.$locationsWrapper.removeClass('both');\r\n // alert(\"NOT checked\")\r\n\r\n // }\r\n\r\n // Set the bookingUUID\r\n if (AEdata) {\r\n if (AEdata.booking && AEdata.booking.props && AEdata.booking.props.uuid) {\r\n oSubmit.bookingUUID = AEdata.booking.props.uuid;\r\n } else if (AEdata.modify && AEdata.modify.uuid) {\r\n oSubmit.bookingUUID = AEdata.modify.uuid;\r\n }\r\n // Set the Commission Junction Event ID //WEBAE3-5634 : commission junction - believe this to possibly still be in use\r\n if(AEdata.URL && AEdata.URL.cjevent){\r\n oSubmit.cjEvent = AEdata.URL.cjevent;\r\n } else if(AEdata.URL && AEdata.URL.CJEVENT) {\r\n oSubmit.cjEvent = AEdata.URL.CJEVENT;\r\n } else if(AECookie.read('cje')) { //WEBAE3-5053\r\n if(_.isString(AECookie.read('cje')) && AECookie.read('cje') !== ''){\r\n oSubmit.cjEvent = AECookie.read('cje');\r\n }\r\n }\r\n }\r\n // Set exclusive search parameters\r\n if ($('.search-type--lease')[0]) {\r\n oSubmit.excl_ltr = true;\r\n } // Long Term Rental/Short Term Lease/Buyback only search\r\n \r\n if ($('.search-type--luxury')[0]) {\r\n oSubmit.excl_cats = 'C6,C10';\r\n } // Luxury ONLY Search - will include Standards to ensure results come back\r\n \r\n if ($('.search-type--van')[0]) {\r\n oSubmit.excl_cats = 'C8,C9';\r\n } // Vans ONLY Search\r\n\r\n // Submit button behaviors\r\n props.$btnSubmit.on(\"click\", function (event) {\r\n event.preventDefault();\r\n UI.formSubmit();\r\n });\r\n\r\n // Slide down to the form\r\n props.$searchSlideBtn.on(\"click\", function (event) {\r\n $('#scroll-content').stop().animate({\r\n scrollTop: parseInt($(props.$bottomSearch).offset().top)\r\n },\r\n 'fast',\r\n 'swing'\r\n );\r\n });\r\n\r\n // (WEBAE3-1095)\r\n props.$txtAge.on('keydown', function (e) {\r\n if (e.keyCode == 13) {\r\n e.preventDefault();\r\n }\r\n });\r\n\r\n // Submit the search form when the user presses the submit button\r\n // Ignore \"Return\" by defaulting to click submit button\r\n props.$form.on('keydown', function (e) {\r\n if (e.keyCode == 13) {\r\n // props.$btnSubmit.click();\r\n e.preventDefault();// WEBAE3-3383\r\n }\r\n });\r\n\r\n // ONLY RUN IF THE BOTTOM FORM CONTAINER EXISTS\r\n if (props.$bottomSearch != 'undefined') {\r\n // If open site in mobile view append search to bottom container\r\n if (AE.getSiteViewType() == 'palm') {\r\n AE.ui.props.appendTarget = props.$bottomSearch; // set target\r\n // wait for the page to load everything then append\r\n $(window).on('load', function () {\r\n $(props.$bottomSearch).append(props.$searchContainer)\r\n .ready(function () {\r\n // try and catch any mis loads and set page at top\r\n $('#scroll-content').scrollTop(0);\r\n });\r\n });\r\n } else {\r\n AE.ui.props.appendTarget = ($('#ae-search').closest('.ui-dialog')[0]) ? null : props.$topSearch;\r\n }\r\n\r\n // Transition between lap and palm append search\r\n AE.addTransitionTask({\r\n func: function () {\r\n /* HANDLES CONTENT MOVED BY APPEND:\r\n ARGUMENTS: 'Palm View', 'Desk Container', 'Mobile Container', 'Content Appended' */\r\n UI.palmTransition(arguments[0], props.$topSearch, props.$bottomSearch, '#search-form'); // Search Form\r\n }\r\n });\r\n };\r\n\r\n \r\n\r\n props.$fcrOnewayChk.on(\"change\", function(event) {\r\n var _checked = $(this).is(':checked');\r\n if (_checked) {\r\n UI.fcrToggleOnewayOpen();\r\n } else {\r\n UI.fcrToggleOnewayClose();\r\n }\r\n });\r\n\r\n if (AE.props.siteCode == 'FCR') {\r\n $(document).ready(function(event) {\r\n if(props.$fcrOnewayChk.is(':checked')){\r\n UI.fcrToggleOnewayOpen();\r\n } else {\r\n //see if different dropoff box should be checked on page load based on previous search\r\n var oStoredSearch = JSON.parse(localStorage.getItem('aeSearch'));\r\n try {\r\n if (oStoredSearch.puloclist !== oStoredSearch.doloclist && oStoredSearch.doloclist !== null && typeof AEdata.booking === 'undefined') {\r\n $(\"input[name='fcr-oneway_chk']\").prop( \"checked\", true );\r\n UI.fcrToggleOnewayOpen();\r\n } \r\n }\r\n catch (e) {\r\n }\r\n }\r\n });\r\n }\r\n\r\n if (AE.props.siteCode == 'FCR' && typeof(AEdata.booking) !== 'undefined') {\r\n //console.log(\"this ran AEbooking ==\", AEdata.booking )\r\n $(document).ready(function(event) {\r\n //console.log(\"this ran too\")\r\n UI.fcrOneWayToggle();\r\n });\r\n }\r\n },\r\n\r\n fcrToggleOnewayOpen: function(){\r\n //make sure it isn't already open\r\n if(!props.$locationsWrapper.hasClass('both')) {\r\n props.$locationsWrapper.addClass('both');\r\n $(\".fcr-dropoff_toggle\").slideDown();\r\n $(\".fcr-input_text_over\").addClass('fcr-full_width');\r\n $(\".fcr-pu_do_toggle\").toggle();\r\n }\r\n },\r\n fcrToggleOnewayClose: function(){\r\n props.$locationsWrapper.removeClass('both');\r\n $(\".fcr-dropoff_toggle\").slideUp();\r\n $(\".fcr-pu_do_toggle\").toggle();\r\n $(\".fcr-input_text_over\").removeClass('fcr-full_width');\r\n $(\"[name='dropoff-loc']\").next('.ui-textsearch-target-input').trigger('click');\r\n },\r\n palmTransition: function () {\r\n var palmContent = $('' + arguments[3] + '')[0];\r\n var container = (arguments[0]) ? arguments[2] : arguments[1];\r\n\r\n if (AE.getSiteViewType() == 'palm') {\r\n AE.ui.props.appendTarget = props.$bottomSearch;\r\n } else {\r\n AE.ui.props.appendTarget = ($('#ae-search').closest('.ui-dialog')[0]) ? null : props.$topSearch;\r\n }\r\n\r\n $('' + container + '').append(palmContent);\r\n },\r\n getValue: function (property) {\r\n /*\r\n Gets the current value from the JSON object which will be submitted to the server. This\r\n isn't the same as getting the value of the\r\n */\r\n var value = 'No property given';\r\n var _obj = Object.keys(oSubmit);\r\n\r\n for (var i in _obj) {\r\n var _key = _obj[i];\r\n if (_key.toString() == property) {\r\n value = oSubmit[_key];\r\n }\r\n }\r\n return value;\r\n },\r\n getSubmitValues: function () {\r\n // Returns the JSON object which will be submitted to the server\r\n return oSubmit;\r\n },\r\n getStoredSearch: function () {\r\n // Returns the JSON object which will was submitted to the server and saved in local storage\r\n if (props.oStoredSearch) {\r\n return props.oStoredSearch; // WEBAE3-2049 added 'props.' so menu search doesn't get empty default object\r\n } else {\r\n return oStoredSearch; // return empty default struct\r\n }; \r\n },\r\n getMaxAge: function () {\r\n return props.$ageMax;\r\n },\r\n getMinAge: function () {\r\n return props.$ageMin;\r\n },\r\n setValue: function (settings) {\r\n var options = {\r\n name: null,\r\n value: null,\r\n item: null,\r\n jsonOnly: false\r\n };\r\n $.extend(options, settings);\r\n\r\n // Without a name, we can't go forward\r\n if (!options.name) {\r\n throw \"ERR: AE.ui.search.setValue() - No input or value given.\";\r\n }\r\n\r\n if (options.resetAge) {\r\n oSubmit.searchAge = '';\r\n }\r\n\r\n if (options.item) {\r\n // Only the autocomplete needs entire jQuery UI item. For now, we'll just\r\n // assume that we're dealing with those two fields only.\r\n if (options.name == 'pickup-loc') {\r\n UI.autocomplete.setValue(options.item);\r\n } else if (options.name == 'dropoff-loc') {\r\n UI.autocomplete.setValue(options.item);\r\n } else {\r\n throw 'ERR search.setValue(): Valid jQuery UI item required.';\r\n }\r\n }\r\n if (options.value) {\r\n // If there's a value, then we're going to directly set the input\r\n switch (options.name) {\r\n case \"pickup-time\":\r\n if (!options.jsonOnly) {\r\n props.$puTime.val(options.value);\r\n }\r\n oSubmit.putime = options.value;\r\n props.$hiddenPuTime.val(options.value);\r\n break;\r\n case \"dropoff-time\":\r\n if (!options.jsonOnly) {\r\n props.$doTime.val(options.value);\r\n }\r\n oSubmit.dotime = options.value;\r\n props.$hiddenDoTime.val(options.value);\r\n break;\r\n case \"pickup-date\":\r\n if (!options.jsonOnly) {\r\n props.$puDate.val(options.value);\r\n }\r\n\r\n var _puDate = UI.isValidDate(options.value) ? options.value : AE.ui.datepicker.convertDate(props.$puDate);\r\n\r\n oSubmit.puCal = _puDate;\r\n props.$hiddenPuDate.val(_puDate);\r\n\r\n break;\r\n case \"dropoff-date\":\r\n if (!options.jsonOnly) {\r\n props.$doDate.val(options.value);\r\n }\r\n\r\n var _doDate = UI.isValidDate(options.value) ? options.value : AE.ui.datepicker.convertDate(props.$doDate);\r\n\r\n oSubmit.doCal = _doDate;\r\n props.$hiddenDoDate.val(_doDate);\r\n\r\n break;\r\n //case 'chk-diff':\r\n // break;\r\n //case 'chk-age':\r\n // break;\r\n //VM\r\n case \"txt-age\":\r\n if (!options.jsonOnly) {\r\n props.$txtAge.val(options.value);\r\n }\r\n oSubmit.searchAge = options.value;\r\n break;\r\n case \"chk-age\":\r\n if (!options.jsonOnly) {\r\n props.$chkAge.prop('checked');\r\n }\r\n oSubmit.searchAgeCheckbox = options.value;\r\n break;\r\n case \"display_label\":\r\n oSubmit.display_label = options.value;\r\n break;\r\n case \"display_labelr\":\r\n oSubmit.display_labelr = options.value;\r\n break;\r\n default:\r\n throw \"ERR search.setValue(): Valid value required.\";\r\n }\r\n }\r\n\r\n return oSubmit;\r\n },\r\n getmemberage : function() {\r\n return props.memberage;\r\n },\r\n isValidDate : function(d) {\r\n return d instanceof Date && !isNaN(d);\r\n },\r\n formSubmit: function (loginOverride) {\r\n\t\t\tloginOverride = loginOverride || false;\r\n\r\n /*\r\n oSubmit.city = set upon select in the ui.autocomplete module\r\n oSubmit.cityr = set upon select in the ui.autocomplete module\r\n oSubmit.puloclist = set upon select in the ui.autocomplete module\r\n oSubmit.doloclist = set upon select in the ui.autocomplete module\r\n oSubmit.pucode = set upon select in the ui.autocomplete module\r\n oSubmit.docode = set upon select in the ui.autocomplete module\r\n oSubmit.puCal = set upon init and select in the ui.datepicker module\r\n oSubmit.doCal = set upon init and select in the ui.datepicker module\r\n oSubmit.searchAge = Set in the behaviors listed above\r\n oSubmit.searchAgeCheckbox\r\n */\r\n\r\n var $ui_chkDiff = props.$chkDiff;\r\n\r\n // Text search\r\n var $ui_puInput = props.$puLoc;\r\n var $ui_doInput = props.$doLoc;\r\n\r\n // Menu search\r\n var $ui_menu_puInput_country = props.$menu_puCountry;\r\n var $ui_menu_puInput_city = props.$menu_puCity;\r\n var $ui_menu_puInput_location = props.$menu_puLocation;\r\n var $ui_menu_doInput_country = props.$menu_doCountry;\r\n var $ui_menu_doInput_city = props.$menu_doCity;\r\n var $ui_menu_doInput_location = props.$menu_doLocation;\r\n\r\n var $ui_puDate = props.$puDate;\r\n var $ui_doDate = props.$doDate;\r\n\r\n var $ui_puTime = props.$puTime;\r\n var $ui_doTime = props.$doTime;\r\n\r\n var $ui_chkAge = props.$chkAge;\r\n var $ui_txtAge = props.$txtAge;\r\n var $_subBtn = props.$btnSubmit;\r\n\r\n var _flagTitle;\r\n var _flagMsg;\r\n var _posDiff = {\r\n top: -5,\r\n left: 0\r\n };\r\n\r\n var $ui_elObj = {}\r\n\r\n if (isMenuSearch && !loginOverride && !isLTRSearch) { \r\n $ui_elObj.menusearchpucountry = ($ui_menu_puInput_country.val() === '' || $ui_menu_puInput_country.val() === '--') ? $fn_checkMenuSearchLocationInput : false;\r\n $ui_elObj.menusearchpucity = ($ui_menu_puInput_city.val() === '' || $ui_menu_puInput_city.val() === '--') ? $fn_checkMenuSearchLocationInput : false;\r\n $ui_elObj.menusearchpulocation = ($ui_menu_puInput_location.val() === '' || $ui_menu_puInput_location.val() === '--') ? $fn_checkMenuSearchLocationInput : false;\r\n if ($ui_chkDiff.is(':checked')) {\r\n $ui_elObj.menusearchdocountry = ($ui_menu_doInput_country.val() === '' || $ui_menu_doInput_country.val() === '--') ? $fn_checkMenuSearchLocationInput : false;\r\n $ui_elObj.menusearchdocity = ($ui_menu_doInput_city.val() === '' || $ui_menu_doInput_city.val() === '--') ? $fn_checkMenuSearchLocationInput : false;\r\n $ui_elObj.menusearchdolocation = ($ui_menu_doInput_location.val() === '' || $ui_menu_doInput_location.val() === '--') ? $fn_checkMenuSearchLocationInput : false;\r\n }\r\n } else if (isBMRSearch) { \r\n // Let remote BMR API call to check results handle incomplete input\r\n $ui_menu_puInput_country = $('select#bmr__country');\r\n $ui_menu_puInput_city = $('select#bmr__city');\r\n $ui_menu_doInput_country = $('select#bmr__countryr');\r\n $ui_menu_doInput_city = $('select#bmr__cityr');\r\n $ui_elObj.menusearchpucountry = ($ui_menu_puInput_country.val() === '' || $ui_menu_puInput_country.val() === '--') ? $fn_checkMenuSearchLocationInput : false;\r\n $ui_elObj.menusearchpucity = ($ui_menu_puInput_city.val() === '' || $ui_menu_puInput_city.val() === '--') ? $fn_checkMenuSearchLocationInput : false;\r\n if ($ui_chkDiff.is(':checked')) {\r\n $ui_elObj.menusearchdocountry = ($ui_menu_doInput_country.val() === '' || $ui_menu_doInput_country.val() === '--') ? $fn_checkMenuSearchLocationInput : false;\r\n $ui_elObj.menusearchdocity = ($ui_menu_doInput_city.val() === '' || $ui_menu_doInput_city.val() === '--') ? $fn_checkMenuSearchLocationInput : false;\r\n }\r\n } else {\r\n if (isLTRSearch ) {\r\n $ui_puInput = AE.ui.searchType.leasesearch.props.$ltrpu;\r\n $ui_doInput = AE.ui.searchType.leasesearch.props.$ltrdo;\r\n\r\n if($ui_puInput.val() === ''){\r\n $ui_elObj.textsearchlocation = $fn_flagLocationInput;\r\n }else if ($ui_doInput.val() === ''){\r\n $ui_elObj.textsearchlocation = $fn_flagLocationInput;\r\n }else{\r\n $ui_elObj.textsearchlocation = false;\r\n } \r\n } else {\r\n $ui_elObj.textsearchlocation = (UI.getValue(\"city\") == null) ? $fn_flagLocationInput : false; \r\n } \r\n }\r\n\r\n if (isBMRSearch && AE.ui.searchType.bmr) {\r\n if(AE.props.isAUNZ && AE.account.props.$isLoggedIn && props.$txtAge.val() == \"\"){\r\n /* WEBAE3-3034 - AUS and NZL display changes lead to mix ups when\r\n user is logged in, but deletes their age from the BMR search form\r\n this forces stricter validation and the appropriate alerts to display\r\n */\r\n oSubmit.searchAgeCheckbox = false;\r\n oSubmit.searchAge = '';\r\n }\r\n } \r\n \r\n if(props.hasAgeChkbx){\r\n $ui_elObj.age = (!UI.getValue(\"searchAgeCheckbox\") && props.$txtAge.val() === \"\" ) ? $fn_flagChkAgeInput : false; \r\n //$ui_elObj.age = (!UI.getValue(\"searchAgeCheckbox\") && UI.getValue(\"searchAge\") == \"\" ) ? $fn_flagChkAgeInput : false;\r\n }\r\n else{\r\n $ui_elObj.age = (UI.getValue(\"searchAge\") == \"\" || $ui_txtAge.val() == '') ? $fn_flagChkAgeInput : false;\r\n }\r\n\r\n //WEBAE3-4473 - make sure DO is later than PU\r\n var pickupDate = new Date($.datepicker.formatDate('yy-mm-dd',$ui_puDate.datepicker(\"getDate\")) + 'T' + $ui_puTime.val());\r\n var dropoffDate = new Date($.datepicker.formatDate('yy-mm-dd', $ui_doDate.datepicker(\"getDate\")) + 'T' + $ui_doTime.val());\r\n $ui_elObj.badDates = (dropoffDate.getTime() <= pickupDate.getTime()) ? $fn_flagDates : false;\r\n\r\n\r\n AE.forms.addSpinGear($_subBtn.attr('disabled', true));\r\n for (var i = 0; i < Object.keys($ui_elObj).length; i++) {\r\n var _el = Object.keys($ui_elObj)[i]; \r\n\r\n if ($ui_elObj[_el] != false) {\r\n return $ui_elObj[_el]();\r\n }\r\n }\r\n function $fn_flagDates() {\r\n $ui_doTime.addClass('ui--invalid-input');\r\n var _posDiff = {\r\n top: -5,\r\n left: -8\r\n };\r\n\r\n _flagTitle = AE.ui.decodeHtml(AE.props.oSearch.LABEL_DROPOFF_TIME); \r\n _flagMsg = '';\r\n\r\n return AE.ui.search.searchFormErrorHandler.init(_flagTitle, _flagMsg, _posDiff);\r\n }\r\n function $fn_flagLocationInput() {\r\n\r\n var _posDiff = {\r\n top: -5,\r\n left: -8\r\n };\r\n\r\n if(isLTRSearch ){ \r\n if($ui_puInput.val() === ''){\r\n $ui_puInput.addClass('ui--invalid-input');\r\n _flagTitle = AE.ui.decodeHtml(AE.props.oSearch.ERRORMSG_INPUTEMPTY); \r\n _flagMsg = '';\r\n $ui_puInput.attr({\r\n placeholder: _flagTitle\r\n });\r\n }else{\r\n $ui_doInput.addClass('ui--invalid-input');\r\n _flagTitle = AE.ui.decodeHtml(AE.props.oSearch.ERRORMSG_INPUTEMPTY); \r\n _flagMsg = '';\r\n $ui_doInput.attr({\r\n placeholder: _flagTitle\r\n });\r\n }\r\n }else{\r\n $ui_puInput.addClass('ui--invalid-input');\r\n _flagTitle = AE.ui.decodeHtml(AE.props.oSearch.ERRORMSG_PULOCEMPTY); \r\n _flagMsg = AE.ui.decodeHtml(AE.props.oSearch.ERRORMSG_INPUTEMPTY);\r\n $ui_puInput.attr({\r\n placeholder: _flagTitle\r\n });\r\n } \r\n\r\n return AE.ui.search.searchFormErrorHandler.init(_flagTitle, _flagMsg, _posDiff);\r\n } \r\n\r\n function $fn_flagChkAgeInput() {\r\n var $ui_ageInput = $ui_txtAge;\r\n var _val = $ui_ageInput.val();\r\n var _chars = _val.length;\r\n var _min = $ui_ageInput.attr('min');\r\n var _max = $ui_ageInput.attr('max');\r\n\r\n _posDiff = {\r\n top: -5,\r\n left: AE.legacy.grief.isIE ? 180 : 165\r\n };\r\n\r\n if((isBMRSearch && AE.props.isAUNZ) || !props.hasAgeChkbx) {\r\n _posDiff = { top: -5 };\r\n }\r\n\r\n $ui_txtAge.addClass('ui--invalid-input').parent().css({\r\n position: 'relative'\r\n });\r\n\r\n if (_val == '') { //} || _val <= 17) {\r\n _flagTitle = AE.props.oSearch.ERRORMSG_DRIVERAGETITLE; //'DRIVER AGE'\r\n _flagMsg = AE.props.oSearch.ERRORMSG_DRIVERAGEMESSAGE; //'ENTER A THE DRIVER'S AGE'\r\n return AE.ui.search.searchFormErrorHandler.init(_flagTitle, _flagMsg, _posDiff);\r\n// } else if ( (_val < parseInt(_min)) || (_chars == 2 && (parseInt(_val) < parseInt(_min))) ) {\r\n } else if ( (parseInt(_val) < parseInt(_min)) || (parseInt(_val) > parseInt(_max)) ) {\r\n _flagTitle = AE.props.oSearch.ERRORMSG_INVALIDAGETITLE; //'INVALID AGE SELECTION'\r\n _flagMsg = AE.props.oSearch.ERRORMSG_INVALIDAGEMESSAGE.replace('[AGE]', '' + _min + '');\r\n return AE.ui.search.searchFormErrorHandler.init(_flagTitle, _flagMsg, _posDiff);\r\n }\r\n\r\n UI.setValue({\r\n name: 'txt-age',\r\n value: props.$txtAge.val(),\r\n jsonOnly: true\r\n });\r\n \r\n props.$btnSubmit.removeClass('ui--btn-submit-wait').attr({\r\n 'disabled': false\r\n }).find('.ui--loading-results').remove();\r\n // return props.$btnSubmit.trigger('click');\r\n return false;\r\n }\r\n\r\n function $fn_checkMenuSearchLocationInput() {\r\n var menuSearchError = false;\r\n\r\n // Only show one error in this particular order\r\n if ($ui_menu_puInput_country.val() === '' || $ui_menu_puInput_country.val() === '--') {\r\n menuSearchError = true;\r\n $ui_menu_puInput_country.addClass('ui--invalid-input');\r\n _posDiff = { top: -19, left: -2 };\r\n } else if ($ui_menu_puInput_city.val() === '' || $ui_menu_puInput_city.val() === '--') {\r\n menuSearchError = true;\r\n $ui_menu_puInput_city.addClass('ui--invalid-input');\r\n _posDiff = { top: -19, left: -2 };\r\n } else if ($ui_menu_puInput_location.val() === '' || $ui_menu_puInput_location.val() === '--') {\r\n menuSearchError = true;\r\n $ui_menu_puInput_location.addClass('ui--invalid-input');\r\n _posDiff = { top: -19, left: -15 };\r\n } else if ($ui_chkDiff.is(':checked')) {\r\n if ($ui_menu_doInput_country.val() === '' || $ui_menu_doInput_country.val() === '--') {\r\n menuSearchError = true;\r\n $ui_menu_doInput_country.addClass('ui--invalid-input');\r\n _posDiff = { top: -19, left: -2 };\r\n } else if ($ui_menu_doInput_city.val() === '' || $ui_menu_doInput_city.val() === '--') {\r\n menuSearchError = true;\r\n $ui_menu_doInput_city.addClass('ui--invalid-input');\r\n _posDiff = { top: -19, left: -2 };\r\n } else if ($ui_menu_doInput_location.val() === '' || $ui_menu_doInput_location.val() === '--') {\r\n menuSearchError = true;\r\n $ui_menu_doInput_location.addClass('ui--invalid-input');\r\n _posDiff = { top: -19, left: -15 };\r\n }\r\n }\r\n\r\n if (menuSearchError) {\r\n _flagTitle = AE.ui.decodeHtml(AE.props.oSearch.ERRORMSG_INPUTEMPTY); //'INPUT CANNOT BE EMPTY'\r\n _flagMsg = '';\r\n $ui_puInput.attr({ placeholder: _flagTitle });\r\n return AE.ui.search.searchFormErrorHandler.init(_flagTitle, _flagMsg, _posDiff);\r\n }\r\n }\r\n\r\n if(!loginOverride){\r\n UI.setValue({\r\n name: \"txt-age\",\r\n value: props.$txtAge.val(),\r\n jsonOnly: true\r\n });\r\n\r\n UI.setValue({\r\n name: \"chk-age\",\r\n value: props.$chkAge.prop('checked'),\r\n jsonOnly: true\r\n });\r\n }\r\n\r\n UI.setValue({\r\n name: 'pickup-date',\r\n value: props.$puDate.val(),\r\n jsonOnly: true\r\n });\r\n\r\n //gbr test\r\n//if( AE.props.siteCode == 'GBR' ) {console.log(\"GBR\")}else{console.log(\"not GBR\")}\r\n \r\n // check for FCR one way dropoff date before setting value\r\n\r\n\r\n\r\n if (AE.props.siteCode == 'FCR') {\r\n if(props.$fcrOnewayChk.is(':checked')){\r\n props.$doDate = props.$doDateOneway;\r\n }\r\n }\r\n\r\n UI.setValue({\r\n name: 'dropoff-date',\r\n value: props.$doDate.val(),\r\n jsonOnly: true\r\n });\r\n \r\n /*if (AE.props.siteCode == 'FCR') {\r\n if(props.$fcrOnewayChk.is(':checked')){\r\n UI.setValue({\r\n name: 'dropoff-date',\r\n value: props.$doDateOneway.val(),\r\n jsonOnly: true\r\n });\r\n }\r\n }*/\r\n \r\n UI.setValue({\r\n name: 'pickup-time',\r\n value: props.$puTime.val(),\r\n jsonOnly: true\r\n });\r\n\r\n UI.setValue({\r\n name: 'dropoff-time',\r\n value: props.$doTime.val(),\r\n jsonOnly: true\r\n });\r\n\r\n // check for FCR one way and override dropoff time if present\r\n if (AE.props.siteCode == 'FCR') {\r\n if(props.$fcrOnewayChk.is(':checked')){\r\n UI.setValue({\r\n name: 'dropoff-time',\r\n value: props.$doTimeOneway.val(),\r\n jsonOnly: true\r\n });\r\n }\r\n }\r\n\r\n var _obj = JSON.stringify(oSubmit);\r\n var _path = $(props.$form).attr(\"action\");\r\n\r\n AECookie.create('aeSearch', _obj);\r\n //WEBAE3-5460 save aff and sys at time of search in case of change\r\n localStorage.setItem('aeSearchAff',oSite.affiliate);\r\n localStorage.setItem('aeSearchSys',oSite.chaosSystem);\r\n props.useStoredSearch = (AE.ui.search.useStoredSearch() && localStorage.setItem('aeSearch', _obj) == null) ? true : false;\r\n\r\n if (isBMRSearch && AE.ui.searchType.bmr) {\r\n AE.ui.searchType.bmr.handleSubmit(oSubmit);\r\n } else {\r\n return AE.ui.search.postToForm(_path, oSubmit, 'post');\r\n }\r\n\r\n },\r\n postToForm: function (path, params, method) {\r\n method = method || \"post\";\r\n \r\n //Sanitize JSON from POST URL\r\n var _tempForm = document.createElement(\"form\");\r\n _tempForm.setAttribute(\"method\", method);\r\n _tempForm.setAttribute(\"action\", path);\r\n \r\n //respect window targeting\r\n var killBtnSpinner = false;\r\n if (tgt !== undefined && tgt !== 0 && (isBMRSearch || self !== top)) {\r\n switch (tgt) {\r\n case \"1\":\r\n _tempForm.setAttribute(\"target\", '_blank');\r\n killBtnSpinner = true; //if targeting a new window, don't leave form in endless waiting\r\n break;\r\n case \"2\":\r\n _tempForm.setAttribute(\"target\", '_parent');\r\n break;\r\n }\r\n }\r\n\r\n // Check to see if the search is coming from within an iFrame and cookies have been disabled\r\n if (window.location !== window.parent.location) {\r\n // The form submit is coming from inside an iframe\r\n if (!AECookie.props.cookiesEnabled()) {\r\n // Cookies have been turned off, pop out of the iFrame to show results in a new tab\r\n _tempForm.setAttribute(\"target\", '_parent');\r\n \r\n // Since cookies have been disables, set a hidden form field with the session id so that\r\n // the search results in a new tab in the AE.com domain can continue\r\n // WEBAE3-5723 changed sessid to affiliate because we only get sessid from the cookie \r\n var _tempHiddenField_aff = document.createElement(\"input\");\r\n _tempHiddenField_aff.setAttribute(\"type\", \"hidden\");\r\n _tempHiddenField_aff.setAttribute(\"name\", \"aff\");\r\n _tempHiddenField_aff.setAttribute(\"value\", AE.props.affiliate);\r\n _tempForm.appendChild(_tempHiddenField_aff);\r\n \r\n // We now want to just send the customer's search request to the domain associated with the affiliate\r\n //_tempForm.setAttribute(\"action\", 'https://'+actualURL+'/'+searchFormAction+'/');//We dont need to do this so it is now commented out, form should know already WEBAE3-6611\r\n } else if ((navigator.userAgent.search(\"Safari\") >= 0 && navigator.userAgent.search(\"Chrome\") < 0) ||navigator.userAgent.search(\"Firefox\") >= 0) {\r\n // 3rd party cookies are no longer allowed by Safari without user interaction with domain\r\n // set critical values in DOM but change no other behavior\r\n // WEBAE3-5723 added check for Firefox and changed sessid to affiliate because we only get sessid from the cookie \r\n var _tempHiddenField_aff = document.createElement(\"input\");\r\n _tempHiddenField_aff.setAttribute(\"type\", \"hidden\");\r\n _tempHiddenField_aff.setAttribute(\"name\", \"aff\");\r\n _tempHiddenField_aff.setAttribute(\"value\", AE.props.affiliate);\r\n _tempForm.appendChild(_tempHiddenField_aff);\r\n }\r\n }\r\n\r\n for (var key in params) {\r\n if (params.hasOwnProperty(key)) {\r\n var _tempHiddenField = document.createElement(\"input\");\r\n _tempHiddenField.setAttribute(\"type\", \"hidden\");\r\n _tempHiddenField.setAttribute(\"name\", key);\r\n _tempHiddenField.setAttribute(\"value\", params[key]);\r\n _tempForm.appendChild(_tempHiddenField);\r\n }\r\n }\r\n\r\n document.body.appendChild(_tempForm);\r\n _tempForm.submit();\r\n if (killBtnSpinner) props.$btnSubmit.removeClass('ui--btn-submit-wait').attr({\r\n 'disabled': false\r\n }).find('.ui--loading-results').remove();\r\n },\r\n chkAgeHandler: function (isChecked) {\r\n /* This is called on the checkbox's change event, and also handles the text input. */\r\n var _checked = isChecked || false;\r\n\r\n //4646 console.log(_checked)\r\n \r\n\r\n if (_checked == true) {\r\n props.$txtAge.val(props.ageDefault.toString()).hide();\r\n props.$chkAge.prop(\"checked\", true);\r\n oSubmit.searchAgeCheckbox = true;\r\n $('.ui-warn-flag').hide();\r\n \r\n //fix issue with driver age error still showing when checked \r\n // what should happen is the last error message should not show if unchecked and pick-up location is set to default\r\n props.$txtAge.removeClass('ui--invalid-input');//WEBAE3-4632\r\n\r\n \r\n\r\n } else {\r\n props.$txtAge.val(\"\").show();\r\n props.$chkAge.prop(\"checked\", false);\r\n oSubmit.searchAgeCheckbox = false;\r\n \r\n }\r\n oSubmit.searchAge = props.$txtAge.val();\r\n \r\n return oSubmit;\r\n },\r\n setDefaultAgeOverride: function (age) {\r\n // This is called from outside of this module. It starts with the text input and updates the checkbox\r\n AEdata.defaultAgeOverride = age;\r\n },\r\n setAge: function (age) {\r\n // This is called from outside of this module. It starts with the text input and updates the checkbox\r\n\r\n // First we update the text input\r\n props.$txtAge.val(age.toString());\r\n // And now we update the JSON object\r\n oSubmit.searchAge = age.toString();\r\n\r\n if(!AEdata.modify){// Then we update the checkbox and show/hide the text input according to the age\r\n if(!props.hasAgeChkbx){\r\n props.$chkAge.hide()\r\n oSubmit.searchAgeCheckbox = false;\r\n props.$txtAge.show();\r\n }\r\n else if (age < props.ageMin || age > props.ageMax) {\r\n props.$chkAge.prop('checked', false);\r\n oSubmit.searchAgeCheckbox = false;\r\n props.$txtAge.show();\r\n } else {\r\n props.$chkAge.prop('checked', true);\r\n oSubmit.searchAgeCheckbox = true;\r\n props.$txtAge.hide();\r\n }\r\n }\r\n return oSubmit;\r\n },\r\n forceSearchAgeCheckBox: function () {\r\n //will uncheck search age box even if age is within range so user sees whatever was input - WEBAE3-1686\r\n props.$chkAge.prop('checked', false); \r\n props.$txtAge.show();\r\n oSubmit.searchAgeCheckbox = false;\r\n\r\n return true;\r\n },\r\n useStoredSearch: function () {\r\n return props.useStoredSearch;\r\n },\r\n\r\n hasAgeChkbx: function () {\r\n return props.hasAgeChkbx;\r\n },\r\n cleanStoredSearch: function () {\r\n if (AE.ui.search.useStoredSearch()) {\r\n return (localStorage.aeSearch = \"\");\r\n } else {\r\n return \"\";\r\n }\r\n },\r\n searchFormErrorHandler: {\r\n init: function (title, msg, posDiff, newClass) {\r\n var _elems = $('[tag*=\\'--ae-custom\\']');\r\n\r\n props.$searchFormErrorHandler = {\r\n msgTitle: title,\r\n msgDesc: msg,\r\n pos: posDiff || {\r\n top: -5,\r\n left: 0\r\n },\r\n newClass: newClass || 'arrow-down'\r\n };\r\n\r\n if (AE.getSiteViewType() == 'palm') { \r\n props.$puLoc.blur();\r\n props.$doLoc.blur();\r\n }\r\n\r\n props.$btnSubmit.removeClass('ui--btn-submit-wait').attr({\r\n 'disabled': false\r\n }).find('.ui--loading-results').remove();\r\n\r\n return UI.searchFormErrorHandler._checkValidity(_elems);\r\n },\r\n _checkValidity: function (elems) {\r\n var _elems = elems;\r\n\r\n for (var i = 0; i < _elems.length; i++) {\r\n var _el = _elems[i];\r\n var _isInvalid = $(_el).hasClass('ui--invalid-input');\r\n\r\n if (_isInvalid) {\r\n UI.searchFormErrorHandler._toggleFlag(_el);\r\n }\r\n }\r\n\r\n return false;\r\n },\r\n _renderFlag: function (el) {\r\n\r\n var _el = el;\r\n var _flag = $('
', {\r\n 'class': 'ui-warn-flag ui-invalid-input',\r\n role: 'tooltip',\r\n tag: 'warn--ae-custom',\r\n 'for': $(_el).attr('name'),\r\n visible: false\r\n }).uniqueId();\r\n var $ui_closeBtn = $('