From f7c1dc0a5d7a555450ddd3d6dc1d97932713ef07 Mon Sep 17 00:00:00 2001 From: Abhishek Kumar Date: Wed, 16 Aug 2023 13:25:07 +0530 Subject: [PATCH 01/53] Improve room search UX --- js/daterangepicker/qlodaterangepicker.js | 3 +- .../views/css/wk-global-search.css | 25 +++ .../views/js/wk-room-search-block.js | 187 ++++++++++++++++-- .../views/templates/hook/searchForm.tpl | 3 + .../css/daterangepicker.css | 3 + 5 files changed, 201 insertions(+), 20 deletions(-) diff --git a/js/daterangepicker/qlodaterangepicker.js b/js/daterangepicker/qlodaterangepicker.js index 369ea9325..7e4186a97 100644 --- a/js/daterangepicker/qlodaterangepicker.js +++ b/js/daterangepicker/qlodaterangepicker.js @@ -31,7 +31,8 @@ minDays: 2, startOfWeek: 'monday', hoveringTooltip: false, - container: '#page', + container: page_name == 'index' ? '#date-range-picker-container' : '#page', + inline: page_name == 'index', customArrowPrevSymbol: '', customArrowNextSymbol: '', getValue: function() diff --git a/modules/wkroomsearchblock/views/css/wk-global-search.css b/modules/wkroomsearchblock/views/css/wk-global-search.css index a9f773a21..1eeacfa62 100644 --- a/modules/wkroomsearchblock/views/css/wk-global-search.css +++ b/modules/wkroomsearchblock/views/css/wk-global-search.css @@ -63,6 +63,15 @@ column-gap: 5px; grid-template-columns: repeat(2, 1fr); } +#date-range-picker-container { + position: absolute; +} +#date-range-picker-container.top { + bottom: 82px; +} +#date-range-picker-container.bottom { + top: 85px; +} /* #search_hotel_block_form { display: grid; grid-template-columns: 0.8fr repeat(3, 1fr) 0.6fr; @@ -169,6 +178,17 @@ background-color: #379bf0; color: #FFFFFF;} +.header-rmsearch-wrapper .location_search_results_ul.top { + top: unset; + bottom: 55px; } +.header-rmsearch-wrapper .location_search_results_ul.bottom { + top: 100%; } +.header-rmsearch-wrapper .hotel_dropdown_ul.top { + top: unset; + bottom: 100%; } +.header-rmsearch-wrapper .hotel_dropdown_ul.bottom { + top: 100%; } + .header-rmsearch-wrapper .label-desc-txt { font-size: 12px; @@ -217,6 +237,11 @@ box-shadow: 0 8px 25px -4px rgba(0,0,0,0.39); left: 0px; padding: 20px;} + #search_occupancy_wrapper.top { + top: unset; + bottom: 100%; } + #search_occupancy_wrapper.bottom { + top: 100%; } #search_occupancy_wrapper .occupancy-info-separator { margin-bottom: 15px; margin-top: 15px; diff --git a/modules/wkroomsearchblock/views/js/wk-room-search-block.js b/modules/wkroomsearchblock/views/js/wk-room-search-block.js index bfb5f13bc..7dcb7b66f 100644 --- a/modules/wkroomsearchblock/views/js/wk-room-search-block.js +++ b/modules/wkroomsearchblock/views/js/wk-room-search-block.js @@ -17,6 +17,43 @@ * @license https://store.webkul.com/license.html */ +const BookingSearchManager = { + inputSteps: { + 'location': { + selector: '#hotel_location', + activate: function() { $('#hotel_location').focus(); }, + inputHasValue: function () { return ($('#hotel_location').val() != '') && ($('#location_category_id').val() != ''); }, + }, + 'hotel': { + selector: '#id_hotel_button', + activate: function() { $('#id_hotel_button').click(); }, + inputHasValue: function () { return ($('#id_hotel').val() != '') && ($('#hotel_cat_id').val() != ''); }, + }, + 'date_range': { + selector: '#daterange_value', + activate: function() { $('#daterange_value').data('dateRangePicker').open(); }, + inputHasValue: function () { return ($('#check_in_time').val() != '') && ($('#check_out_time').val() != ''); }, + }, + 'occupancy': { + selector: '#guest_occupancy', + activate: function() { if ($('#search_occupancy_wrapper').css('display') == 'none') { $('#guest_occupancy').click().focus(); } }, + inputHasValue: function () { return false; }, + }, + 'submit': { + selector: '#search_room_submit', + activate: function() { $('#search_room_submit').focus(); }, + inputHasValue: function () { return false; }, + }, + }, + activateStep: function (step, force = false) { + if (step in this.inputSteps) { + if (force || !this.inputSteps[step].inputHasValue()) { + this.inputSteps[step].activate(); + } + } + }, +} + $(document).ready(function() { // for screen size changes for room search var window_width = $(window).width(); @@ -123,6 +160,8 @@ $(document).ready(function() { }).on('datepicker-change', function(event,obj){ $('#check_in_time').val($.datepicker.formatDate('yy-mm-dd', obj.date1)); $('#check_out_time').val($.datepicker.formatDate('yy-mm-dd', obj.date2)); + }).on('datepicker-closed', function() { + BookingSearchManager.activateStep('occupancy'); }); } @@ -184,30 +223,43 @@ $(document).ready(function() { }); // set data on clicking the searched location on dropdown + var focusHotelSelection = true; $(document).on('click', '.location_search_results_ul li', function(e) { + let currentLocationName = $('#hotel_location').val(); + let currentLocationId = $('#location_category_id').val(); + + $('.location_search_results_ul').empty().hide(); $('#hotel_location').attr('value', $(this).html()); $('#location_category_id').val($(this).val()); - $('.location_search_results_ul').empty().hide(); + // check if current location as same as previous one + if (currentLocationName != $(this).html() && currentLocationId != $(this).val()) { + $.ajax({ + url: autocomplete_search_url, + data: { + location_category_id: $('#location_category_id').val(), + }, + method: 'POST', + dataType: 'json', + success: function(result) { + if (result.status == 'success') { + $('#hotel_cat_id').val(''); + $('#hotel_cat_name').html('Select Hotel'); + $('.hotel_dropdown_ul').empty(); + $('.hotel_dropdown_ul').html(result.data); - $.ajax({ - url: autocomplete_search_url, - data: { - location_category_id: $('#location_category_id').val(), - }, - method: 'POST', - dataType: 'json', - success: function(result) { - if (result.status == 'success') { - $('#hotel_cat_id').val(''); - $('#hotel_cat_name').html('Select Hotel'); - $('.hotel_dropdown_ul').empty(); - $('.hotel_dropdown_ul').html(result.data); - } else { - alert(no_results_found_cond); + if (focusHotelSelection) { + BookingSearchManager.activateStep('hotel'); + focusHotelSelection = false; + } + } else { + alert(no_results_found_cond); + } } - } - }); + }); + } else { + BookingSearchManager.activateStep('hotel'); + } }); // navigate to prev and next li in the location/hotel dropdown @@ -268,6 +320,7 @@ $(document).ready(function() { $('#id_hotel').val($(this).attr('data-id-hotel')); $('#hotel_cat_id').val($(this).attr('data-hotel-cat-id')); $('#hotel_cat_name').html($(this).html()); + BookingSearchManager.activateStep('date_range'); }); // If only one hotel then set max order date on date pickers @@ -539,6 +592,7 @@ $(document).ready(function() { if (hasErrors == 0) { $("#search_occupancy_wrapper").hide(); $("#search_hotel_block_form #guest_occupancy").removeClass('error_border'); + BookingSearchManager.activateStep('submit'); } else { $("#search_hotel_block_form #guest_occupancy").addClass('error_border'); return false; @@ -547,6 +601,53 @@ $(document).ready(function() { } } }); + + if (page_name == 'index') { + // set search dropdown position handlers + $('#hotel_location, #id_hotel_button, #guest_occupancy').focus(function () { + setBookingSearchDropdownPositions(); + setBookingSearchCalendarPositions(); + }); + + $('#daterange_value').click(function () { + setBookingSearchDropdownPositions(); + setBookingSearchCalendarPositions(); + }); + } + + // handle Tab/Enter keypresses on input fields - start + $(document).on('keydown', '.location_search_results_ul li', function (e) { + if (e.which == 9 || e.which == 13) { // Tab/Enter key + if (e.which == 9) { + $(this).click(); + } + if ($('#id_hotel_button').length) { + focusHotelSelection = true; + } + } + }); + + $(document).on('keydown', '.hotel_dropdown_ul li', function (e) { + if (e.which == 9 || e.which == 13) { // Tab/Enter key + if (e.which == 9) { + $(this).click(); + } + if ($('#daterange_value').length) { + $('#daterange_value').click(); + } + } + }); + + $(document).on('keydown', '#guest_occupancy', function (e) { + e.preventDefault(); + if (e.which == 9) { // Tab key + if ($('#search_occupancy_wrapper').css('display') != 'none') { + $('#guest_occupancy').click(); + } + BookingSearchManager.activateStep('submit'); + } + }); + // handle Tab keypresses on input fields - end }); // function to set occupancy infor in guest occupancy field(search form) function setGuestOccupancy() @@ -579,4 +680,52 @@ function setGuestOccupancy() guestButtonVal += ', ' + parseInt(rooms) + ' ' + room_txt; } $('#guest_occupancy > span').text(guestButtonVal); -} \ No newline at end of file +} + +function setBookingSearchDropdownPositions() { + let inputFieldsAndDropdowns = [ + { input: $('#hotel_location'), dropdown: $('.location_search_results_ul')}, + { input: $('#id_hotel_button'), dropdown: $('.dropdown-menu.hotel_dropdown_ul')}, + { input: $('#guest_occupancy'), dropdown: $('#search_occupancy_wrapper')}, + ]; + + $(inputFieldsAndDropdowns).each(function (i, inputFieldAndDropdown) { + // find available space + let inputFieldHeight = inputFieldAndDropdown.input.outerHeight(); + let spaceTop = inputFieldAndDropdown.input.offset().top - $(window).scrollTop(); + let spaceBottom = $(window).height() - inputFieldHeight - spaceTop; + let cssMaxHeight = inputFieldAndDropdown.dropdown.css('max-height') || '292px'; + let dropdownMaxHeight = parseInt(cssMaxHeight.replace('px', '')); + dropdownMaxHeight = Math.max(dropdownMaxHeight, 292); // 292 is height of the calendar + + let dropdownClass = 'bottom'; + if (spaceBottom < dropdownMaxHeight && spaceTop > spaceBottom) { + dropdownClass = 'top'; + } + + // position dropdown + inputFieldAndDropdown.dropdown.removeClass('top bottom').addClass(dropdownClass); + }); +} + +function setBookingSearchCalendarPositions() { + let calendarInputFields = [ + { input: $('#daterange_value'), calendarContainer: $('#date-range-picker-container')}, + ]; + + $(calendarInputFields).each(function (i, calendarInputField) { + // find available space + let inputFieldHeight = calendarInputField.input.outerHeight(); + let spaceTop = calendarInputField.input.offset().top - $(window).scrollTop(); + let spaceBottom = $(window).height() - inputFieldHeight - spaceTop; + let calendarHeight = 292; // 292 is height of the calendar + + let calendarContainerClass = 'bottom'; + if (spaceBottom < calendarHeight && spaceTop > spaceBottom) { + calendarContainerClass = 'top'; + } + + // position calendar + calendarInputField.calendarContainer.removeClass('top bottom').addClass(calendarContainerClass); + }); +} diff --git a/modules/wkroomsearchblock/views/templates/hook/searchForm.tpl b/modules/wkroomsearchblock/views/templates/hook/searchForm.tpl index 79e7bcf2f..a515da256 100644 --- a/modules/wkroomsearchblock/views/templates/hook/searchForm.tpl +++ b/modules/wkroomsearchblock/views/templates/hook/searchForm.tpl @@ -57,6 +57,9 @@
{l s='Check-in' mod='wkroomsearchblock'}    {l s='Check-out' mod='wkroomsearchblock'}
+ {if isset($is_index_page) && $is_index_page} +
+ {/if} {/if} diff --git a/themes/hotel-reservation-theme/css/daterangepicker.css b/themes/hotel-reservation-theme/css/daterangepicker.css index 5d07270cd..f1b6cbe07 100644 --- a/themes/hotel-reservation-theme/css/daterangepicker.css +++ b/themes/hotel-reservation-theme/css/daterangepicker.css @@ -29,6 +29,9 @@ margin-top: -4px; padding: 10px; } +#index .date-picker-wrapper.no-shortcuts { + margin-top: 0; +} .date-picker-wrapper .month-wrapper{ border: none; background-color: transparent; From 87ac2f128e29e59566debac0e129b18bb8d68a42 Mon Sep 17 00:00:00 2001 From: Abhishek Kumar Date: Tue, 17 Oct 2023 17:47:07 +0530 Subject: [PATCH 02/53] Improve search flow --- .../classes/HotelHelper.php | 1 + .../AdminHotelGeneralSettingsController.php | 17 + .../classes/WkRoomSearchHelper.php | 1 + .../controllers/front/autocompletesearch.php | 42 +- .../wkroomsearchblock/views/css/chosen.css | 483 ++++++++++++++++++ .../views/img/chosen-sprite.png | Bin 0 -> 646 bytes .../views/img/chosen-sprite@2x.png | Bin 0 -> 872 bytes .../views/js/wk-room-search-block.js | 120 +++-- .../views/templates/front/hotel-options.tpl | 27 + .../views/templates/front/index.php | 29 ++ .../templates/front/location-options.tpl | 24 + .../views/templates/hook/searchForm.tpl | 36 +- .../wkroomsearchblock/wkroomsearchblock.php | 5 + 13 files changed, 707 insertions(+), 78 deletions(-) create mode 100644 modules/wkroomsearchblock/views/css/chosen.css create mode 100644 modules/wkroomsearchblock/views/img/chosen-sprite.png create mode 100644 modules/wkroomsearchblock/views/img/chosen-sprite@2x.png create mode 100644 modules/wkroomsearchblock/views/templates/front/hotel-options.tpl create mode 100644 modules/wkroomsearchblock/views/templates/front/index.php create mode 100644 modules/wkroomsearchblock/views/templates/front/location-options.tpl diff --git a/modules/hotelreservationsystem/classes/HotelHelper.php b/modules/hotelreservationsystem/classes/HotelHelper.php index 447e95354..0cbce162e 100644 --- a/modules/hotelreservationsystem/classes/HotelHelper.php +++ b/modules/hotelreservationsystem/classes/HotelHelper.php @@ -199,6 +199,7 @@ class HotelHelper Configuration::updateValue('WK_HOTEL_LOCATION_ENABLE', 1); Configuration::updateValue('WK_HOTEL_NAME_ENABLE', 1); + Configuration::updateValue('WK_HOTEL_NAME_SEARCH_THRESHOLD', 5); Configuration::updateValue('WK_ROOM_LEFT_WARNING_NUMBER', 10); Configuration::updateValue('WK_HTL_ESTABLISHMENT_YEAR', 2010); diff --git a/modules/hotelreservationsystem/controllers/admin/AdminHotelGeneralSettingsController.php b/modules/hotelreservationsystem/controllers/admin/AdminHotelGeneralSettingsController.php index 74e120141..2a907425a 100644 --- a/modules/hotelreservationsystem/controllers/admin/AdminHotelGeneralSettingsController.php +++ b/modules/hotelreservationsystem/controllers/admin/AdminHotelGeneralSettingsController.php @@ -81,6 +81,15 @@ class AdminHotelGeneralSettingsController extends ModuleAdminController 'hint' => $this->l('This option can be disabled if only one active hotel in the website. In case of more than one active hotel, Hotel Name will always be shown in the search panel.'), ), + 'WK_HOTEL_NAME_SEARCH_THRESHOLD' => array( + 'title' => $this->l('Hotel name search threshold'), + 'type' => 'text', + 'required' => true, + 'validation' => 'isUnsignedInt', + 'hint' => $this->l('Enter the number of hotels after which user can search hotel by name.'), + 'desc' => $this->l('Set to 0 to always show the search box.'), + 'class' => 'fixed-width-xxl', + ), ), 'submit' => array( 'title' => $this->l('Save'), @@ -290,6 +299,8 @@ class AdminHotelGeneralSettingsController extends ModuleAdminController public function postProcess() { if (Tools::isSubmit('submitOptions'.$this->table)) { + $hotelNameSearchThreshold = Tools::getValue('WK_HOTEL_NAME_SEARCH_THRESHOLD'); + // check if field is atleast in default language. Not available in default prestashop $defaultLangId = Configuration::get('PS_LANG_DEFAULT'); $objDefaultLanguage = Language::getLanguage((int) $defaultLangId); @@ -302,6 +313,12 @@ class AdminHotelGeneralSettingsController extends ModuleAdminController // End occupancy fields validation + if (!$hotelNameSearchThreshold && $hotelNameSearchThreshold !== '0') { + $this->errors[] = $this->l('Hotel name search threshold field is required.'); + } elseif (!Validate::isUnsignedInt(Tools::getValue('WK_HOTEL_NAME_SEARCH_THRESHOLD'))) { + $this->errors[] = $this->l('Hotel name search threshold field is invalid.'); + } + if (!trim(Tools::getValue('WK_HTL_CHAIN_NAME_'.$defaultLangId))) { $this->errors[] = $this->l('Hotel chain name is required at least in ').$objDefaultLanguage['name']; } else { diff --git a/modules/wkroomsearchblock/classes/WkRoomSearchHelper.php b/modules/wkroomsearchblock/classes/WkRoomSearchHelper.php index 7ab3d7138..236dbeaae 100644 --- a/modules/wkroomsearchblock/classes/WkRoomSearchHelper.php +++ b/modules/wkroomsearchblock/classes/WkRoomSearchHelper.php @@ -226,6 +226,7 @@ class WkRoomSearchHelper $smartyVars['hotels_info'] = $hotelsInfo; $smartyVars['show_hotel_name'] = Configuration::get('WK_HOTEL_NAME_ENABLE'); $smartyVars['max_child_age'] = Configuration::get('WK_GLOBAL_CHILD_MAX_AGE'); + $smartyVars['hotel_name_search_threshold'] = (int) Configuration::get('WK_HOTEL_NAME_SEARCH_THRESHOLD'); $maxOrderDate = HotelOrderRestrictDate::getMaxOrderDate($idHotel); $smartyVars['max_order_date'] = date('Y-m-d', strtotime($maxOrderDate)); diff --git a/modules/wkroomsearchblock/controllers/front/autocompletesearch.php b/modules/wkroomsearchblock/controllers/front/autocompletesearch.php index 4a051c103..487e9c2d2 100644 --- a/modules/wkroomsearchblock/controllers/front/autocompletesearch.php +++ b/modules/wkroomsearchblock/controllers/front/autocompletesearch.php @@ -29,29 +29,39 @@ class WkRoomSearchBlockAutoCompleteSearchModuleFrontController extends ModuleFro $location_category_id = Tools::getValue('location_category_id'); $obj_htl_info = new HotelBranchInformation(); if (isset($search_data) && $search_data) { - $return_data = $obj_htl_info->getHotelCategoryTree($search_data); - if ($return_data) { - $html = ''; - foreach ($return_data as $value) { - $html .= '
  • '. - $value['name'].'
  • '; - } + $locationCategories = $obj_htl_info->getHotelCategoryTree($search_data); + if ($locationCategories) { + $this->context->smarty->assign(array('location_categories' => $locationCategories)); + $html = $this->context->smarty->fetch( + $this->module->getTemplatePath('location-options.tpl') + ); $result['status'] = 'success'; $result['data'] = $html; } } elseif (isset($location_category_id) && $location_category_id) { - $cat_ids = Category::getAllCategoriesName($location_category_id); - if ($cat_ids) { - $html = ''; - foreach ($cat_ids as $value) { - if ($hotel_info = $obj_htl_info->hotelBranchInfoByCategoryId($value['id_category'])) { - $maxOrderDate = HotelOrderRestrictDate::getMaxOrderDate($hotel_info['id']); + $locationCategories = Category::getAllCategoriesName($location_category_id); + if ($locationCategories) { + $hotelsInfo = array(); + foreach ($locationCategories as $category) { + if ($hotelInfo = $obj_htl_info->hotelBranchInfoByCategoryId($category['id_category'])) { + $maxOrderDate = HotelOrderRestrictDate::getMaxOrderDate($hotelInfo['id']); $maxOrderDate = date('Y-m-d', strtotime($maxOrderDate)); - $html .= '
  • '. - $hotel_info['hotel_name'].'
  • '; + + $hotelsInfo[] = array( + 'id_hotel' => $hotelInfo['id'], + 'id_category' => $hotelInfo['id_category'], + 'hotel_name' => $hotelInfo['hotel_name'], + 'max_order_date' => $maxOrderDate, + ); } } + + $this->context->smarty->assign(array('hotels_info' => $hotelsInfo)); + $html = $this->context->smarty->fetch( + $this->module->getTemplatePath('hotel-options.tpl') + ); + + $result['status'] = 'success'; $result['data'] = $html; } else { diff --git a/modules/wkroomsearchblock/views/css/chosen.css b/modules/wkroomsearchblock/views/css/chosen.css new file mode 100644 index 000000000..c53604007 --- /dev/null +++ b/modules/wkroomsearchblock/views/css/chosen.css @@ -0,0 +1,483 @@ +/** + * 2010-2023 Webkul. + * + * NOTICE OF LICENSE + * + * All right is reserved, + * Please go through LICENSE.txt file inside our module + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade this module to newer + * versions in the future. If you wish to customize this module for your + * needs please refer to CustomizationPolicy.txt file inside our module for more information. + * + * @author Webkul IN + * @copyright 2010-2023 Webkul IN + * @license LICENSE.txt + */ + +/* @group Base */ +.chosen-container { + position: relative; + vertical-align: middle; + font-size: 14px; + zoom: 1; + display: inline; + -moz-user-select: -moz-none; + -ms-user-select: none; + -webkit-user-select: none; + user-select: none; +} +.chosen-container .chosen-drop { + position: absolute; + top: 0; + left: -9999px; + z-index: 1010; + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; + box-sizing: border-box; + width: 100%; + border-top: 0; + box-shadow: 0 4px 5px rgba(0, 0, 0, 0.15); +} +.chosen-container.chosen-container-single-nosearch .chosen-drop { + top: 100%; +} +.chosen-container.chosen-with-drop .chosen-drop { + left: 0; +} +.chosen-container a { + cursor: pointer; +} + +/* @end */ +/* @group Single Chosen */ +.chosen-container-single .chosen-single { + position: relative; + display: block; + overflow: hidden; + padding-left: 35px; + height: 100%; + border: 1px solid #aaa; + border-radius: 4px; + background-clip: padding-box; + box-shadow: 0 0 3px #fff inset, 0 1px 1px rgba(0, 0, 0, 0.1); + color: #444; + text-decoration: none; + white-space: nowrap; + line-height: 24px; + background: #fff url('../img/icon-hotel.svg') no-repeat 10px 50%; +} +.chosen-container-single.error_border .chosen-single { + border: 2px solid red !important; +} + +.chosen-container-single .chosen-default { + color: #999; +} +.chosen-container-single .chosen-single span { + display: block; + overflow: hidden; + margin-right: 26px; + text-overflow: ellipsis; + white-space: nowrap; + position: relative; + top: 15px; + color: #333; +} +.chosen-container-single .chosen-single-with-deselect span { + margin-right: 38px; +} +.chosen-container-single .chosen-single abbr { + position: absolute; + top: 6px; + right: 26px; + display: block; + width: 12px; + height: 12px; + background: url('chosen-sprite.png') -42px 1px no-repeat; + font-size: 1px; +} +.chosen-container-single .chosen-single abbr:hover { + background-position: -42px -10px; +} +.chosen-container-single.chosen-disabled .chosen-single abbr:hover { + background-position: -42px -10px; +} +.chosen-container-single .chosen-single div { + position: absolute; + top: 0; + right: 0; + display: block; + width: 18px; + height: 100%; +} +.chosen-container-single .chosen-single div b { + display: block; + width: 100%; + height: 100%; + background: url('../../../../themes/hotel-reservation-theme/img/icon/icon-dropdown-arrow.svg') no-repeat calc(100% - 8px) 50%; +} +.chosen-container-single .chosen-search { + position: relative; + z-index: 1010; + margin: 0; + white-space: nowrap; + background: #fff; + border-radius: 4px; + height: 55px; +} +.chosen-container-single .chosen-search::after { + content: ''; + position: absolute; + top: 16px; + right: 1px; + height: 22px; + width: 19px; + background: url('../../../../themes/hotel-reservation-theme/img/icon/icon-dropdown-arrow.svg') no-repeat calc(100% - 8px) 50%; + /* background: url('../img/icon-hotel.svg') no-repeat 9px 50%; */ +} +.chosen-container-single .chosen-search input[type="text"] { + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; + box-sizing: border-box; + margin: 0; + padding: 0; + padding-left: 35px; + width: 100%; + height: 100%; + outline: 0; + border: none; + font-size: 1em; + line-height: normal; + border-radius: 4px; + background: url('../img/icon-hotel.svg') no-repeat 9px 50%; +} +.chosen-container-single.chosen-container-active .chosen-search input[type="text"] { + border: 2px solid #1292FF; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(102, 175, 233, 0.6); + transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s; +} +.chosen-container-single .chosen-drop { + margin-top: -1px; + border-radius: 0 0 4px 4px; + background-clip: padding-box; +} +.chosen-container-single.chosen-container-single-nosearch .chosen-search { + position: absolute; + left: -9999px; +} + +/* @end */ +/* @group Results */ +.chosen-container .chosen-results { + position: relative; + overflow-x: hidden; + overflow-y: auto; + max-height: 240px; + background: #fff; + margin-top: 2px; + margin-bottom: 0; +} +.chosen-container .chosen-results li { + display: none; + margin: 0; + padding: 15px; + list-style: none; + color: #333; +} +.chosen-container .chosen-results li.active-result { + display: list-item; + cursor: pointer; +} +.chosen-container .chosen-results li.disabled-result { + display: list-item; + color: #ccc; + cursor: default; +} +.chosen-container .chosen-results li.highlighted { + background-color: #379bf0; + color: #fff; +} +.chosen-container .chosen-results li.no-results { + display: list-item; + background: #f4f4f4; +} +.chosen-container .chosen-results li.group-result { + display: list-item; + font-weight: bold; + cursor: default; +} +.chosen-container .chosen-results li.group-option { + padding-left: 15px; +} +.chosen-container .chosen-results li em { + font-style: normal; + text-decoration: underline; +} + +/* @end */ +/* @group Multi Chosen */ +.chosen-container-multi .chosen-choices { + position: relative; + overflow: hidden; + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; + box-sizing: border-box; + margin: 0; + padding: 0; + width: 100%; + height: auto !important; + height: 1%; + border: 1px solid #aaa; + background-color: #fff; + background-image: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJvYmplY3RCb3VuZGluZ0JveCIgeDE9IjAuNSIgeTE9IjAuMCIgeDI9IjAuNSIgeTI9IjEuMCI+PHN0b3Agb2Zmc2V0PSIxJSIgc3RvcC1jb2xvcj0iI2VlZWVlZSIvPjxzdG9wIG9mZnNldD0iMTUlIiBzdG9wLWNvbG9yPSIjZmZmZmZmIi8+PC9saW5lYXJHcmFkaWVudD48L2RlZnM+PHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0idXJsKCNncmFkKSIgLz48L3N2Zz4g'); + background-size: 100%; + background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(1%, #eeeeee), color-stop(15%, #ffffff)); + background-image: -moz-linear-gradient(#eeeeee 1%, #ffffff 15%); + background-image: -webkit-linear-gradient(#eeeeee 1%, #ffffff 15%); + background-image: linear-gradient(#eeeeee 1%, #ffffff 15%); + cursor: text; +} +.chosen-container-multi .chosen-choices li { + float: left; + list-style: none; +} +.chosen-container-multi .chosen-choices li.search-field { + margin: 0; + padding: 0; + white-space: nowrap; +} +.chosen-container-multi .chosen-choices li.search-field input[type="text"] { + margin: 1px 0; + padding: 5px; + height: 15px; + outline: 0; + border: 0 !important; + background: transparent !important; + box-shadow: none; + color: #666; + font-size: 100%; + line-height: normal; + border-radius: 0; +} +.chosen-container-multi .chosen-choices li.search-field .default { + color: #999; +} +.chosen-container-multi .chosen-choices li.search-choice { + position: relative; + margin: 3px 0 3px 5px; + padding: 3px 20px 3px 5px; + border: 1px solid #aaa; + border-radius: 3px; + background-color: #e4e4e4; + background-image: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJvYmplY3RCb3VuZGluZ0JveCIgeDE9IjAuNSIgeTE9IjAuMCIgeDI9IjAuNSIgeTI9IjEuMCI+PHN0b3Agb2Zmc2V0PSIyMCUiIHN0b3AtY29sb3I9IiNmNGY0ZjQiLz48c3RvcCBvZmZzZXQ9IjUwJSIgc3RvcC1jb2xvcj0iI2YwZjBmMCIvPjxzdG9wIG9mZnNldD0iNTIlIiBzdG9wLWNvbG9yPSIjZThlOGU4Ii8+PHN0b3Agb2Zmc2V0PSIxMDAlIiBzdG9wLWNvbG9yPSIjZWVlZWVlIi8+PC9saW5lYXJHcmFkaWVudD48L2RlZnM+PHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0idXJsKCNncmFkKSIgLz48L3N2Zz4g'); + background-size: 100%; + background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(20%, #f4f4f4), color-stop(50%, #f0f0f0), color-stop(52%, #e8e8e8), color-stop(100%, #eeeeee)); + background-image: -moz-linear-gradient(#f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%); + background-image: -webkit-linear-gradient(#f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%); + background-image: linear-gradient(#f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%); + background-clip: padding-box; + box-shadow: 0 0 2px #fff inset, 0 1px 0 rgba(0, 0, 0, 0.05); + color: #333; + line-height: 13px; + cursor: default; +} +.chosen-container-multi .chosen-choices li.search-choice .search-choice-close { + position: absolute; + top: 4px; + right: 3px; + display: block; + width: 12px; + height: 12px; + background: url('chosen-sprite.png') -42px 1px no-repeat; + font-size: 1px; +} +.chosen-container-multi .chosen-choices li.search-choice .search-choice-close:hover { + background-position: -42px -10px; +} +.chosen-container-multi .chosen-choices li.search-choice-disabled { + padding-right: 5px; + border: 1px solid #ccc; + background-color: #e4e4e4; + background-image: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJvYmplY3RCb3VuZGluZ0JveCIgeDE9IjAuNSIgeTE9IjAuMCIgeDI9IjAuNSIgeTI9IjEuMCI+PHN0b3Agb2Zmc2V0PSIyMCUiIHN0b3AtY29sb3I9IiNmNGY0ZjQiLz48c3RvcCBvZmZzZXQ9IjUwJSIgc3RvcC1jb2xvcj0iI2YwZjBmMCIvPjxzdG9wIG9mZnNldD0iNTIlIiBzdG9wLWNvbG9yPSIjZThlOGU4Ii8+PHN0b3Agb2Zmc2V0PSIxMDAlIiBzdG9wLWNvbG9yPSIjZWVlZWVlIi8+PC9saW5lYXJHcmFkaWVudD48L2RlZnM+PHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0idXJsKCNncmFkKSIgLz48L3N2Zz4g'); + background-size: 100%; + background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(20%, #f4f4f4), color-stop(50%, #f0f0f0), color-stop(52%, #e8e8e8), color-stop(100%, #eeeeee)); + background-image: -moz-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%); + background-image: -webkit-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%); + background-image: linear-gradient(to bottom, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%); + color: #666; +} +.chosen-container-multi .chosen-choices li.search-choice-focus { + background: #d4d4d4; +} +.chosen-container-multi .chosen-choices li.search-choice-focus .search-choice-close { + background-position: -42px -10px; +} +.chosen-container-multi .chosen-results { + margin: 0; + padding: 0; +} +.chosen-container-multi .chosen-drop .result-selected { + display: list-item; + color: #ccc; + cursor: default; +} + +/* @end */ +/* @group Active */ +.chosen-container-active .chosen-single { + border: 2px solid #1292FF; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(102, 175, 233, 0.6); + transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s; +} +.chosen-container-active.chosen-with-drop .chosen-single div { + border-left: none; + background: transparent; +} +.chosen-container-active .chosen-choices { + border: 1px solid #5897fb; + box-shadow: 0 0 5px rgba(0, 0, 0, 0.3); +} +.chosen-container-active .chosen-choices li.search-field input[type="text"] { + color: #111 !important; +} + +/* @end */ +/* @group Disabled Support */ +.chosen-disabled { + opacity: 0.5 !important; + cursor: default; +} +.chosen-disabled .chosen-single { + cursor: default; +} +.chosen-disabled .chosen-choices .search-choice .search-choice-close { + cursor: default; +} + +/* chosen-drop top - start */ +.hotel-selector-wrap .chosen-container .chosen-drop.top .chosen-results { + position: absolute; + width: 100%; + bottom: calc(100% + 2px); +} +.hotel-selector-wrap .chosen-container.chosen-container-single-nosearch .chosen-drop.top .chosen-results { + position: absolute; + width: 100%; + bottom: calc(100% + 55px); +} +/* chosen-drop top - end */ + + +/* @end */ +/* @group Right to Left */ +.chosen-rtl { + text-align: right; +} +.chosen-rtl .chosen-single { + overflow: visible; + padding: 0 8px 0 0; +} +.chosen-rtl .chosen-single span { + margin-right: 0; + margin-left: 26px; + direction: rtl; +} +.chosen-rtl .chosen-single-with-deselect span { + margin-left: 38px; +} +.chosen-rtl .chosen-single div { + right: auto; + left: 3px; +} +.chosen-rtl .chosen-single abbr { + right: auto; + left: 26px; +} +.chosen-rtl .chosen-choices li { + float: right; +} +.chosen-rtl .chosen-choices li.search-field input[type="text"] { + direction: rtl; +} +.chosen-rtl .chosen-choices li.search-choice { + margin: 3px 5px 3px 0; + padding: 3px 5px 3px 19px; +} +.chosen-rtl .chosen-choices li.search-choice .search-choice-close { + right: auto; + left: 4px; +} +.chosen-rtl.chosen-container-single-nosearch .chosen-search, +.chosen-rtl .chosen-drop { + left: 9999px; +} +.chosen-rtl.chosen-container-single .chosen-results { + margin: 0 0 4px 4px; + padding: 0 4px 0 0; +} +.chosen-rtl .chosen-results li.group-option { + padding-right: 15px; + padding-left: 0; +} +.chosen-rtl.chosen-container-active.chosen-with-drop .chosen-single div { + border-right: none; +} +.chosen-rtl .chosen-search input[type="text"] { + padding: 4px 5px 4px 20px; + background: #fff url('chosen-sprite.png') no-repeat -30px -20px; + background: url('chosen-sprite.png') no-repeat -30px -20px, url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJvYmplY3RCb3VuZGluZ0JveCIgeDE9IjAuNSIgeTE9IjAuMCIgeDI9IjAuNSIgeTI9IjEuMCI+PHN0b3Agb2Zmc2V0PSIxJSIgc3RvcC1jb2xvcj0iI2VlZWVlZSIvPjxzdG9wIG9mZnNldD0iMTUlIiBzdG9wLWNvbG9yPSIjZmZmZmZmIi8+PC9saW5lYXJHcmFkaWVudD48L2RlZnM+PHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0idXJsKCNncmFkKSIgLz48L3N2Zz4g'); + background: url('chosen-sprite.png') no-repeat -30px -20px, -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(1%, #eeeeee), color-stop(15%, #ffffff)); + background: url('chosen-sprite.png') no-repeat -30px -20px, -moz-linear-gradient(#eeeeee 1%, #ffffff 15%); + background: url('chosen-sprite.png') no-repeat -30px -20px, -webkit-linear-gradient(#eeeeee 1%, #ffffff 15%); + background: url('chosen-sprite.png') no-repeat -30px -20px, linear-gradient(#eeeeee 1%, #ffffff 15%); + direction: rtl; +} +.chosen-rtl.chosen-container-single .chosen-single div b { + background-position: 6px 2px; +} +.chosen-rtl.chosen-container-single.chosen-with-drop .chosen-single div b { + background-position: -12px 2px; +} + +.chosen-container .chosen-drop.dropup { + border-bottom: 0; + border-top: 1px solid #aaa; + top: auto; + bottom: 40px; +} + +.chosen-container.chosen-with-drop .chosen-single.dropup { + background-image: none; +} + +.chosen-container.chosen-with-drop .chosen-drop.dropup { + box-shadow: none; + margin-bottom: -16px; +} + +/* @end */ +/* @group Retina compatibility */ +@media only screen and (-webkit-min-device-pixel-ratio: 2), only screen and (min-resolution: 144dpi) { + .chosen-rtl .chosen-search input[type="text"], + .chosen-container-single .chosen-single abbr, + .chosen-container-single .chosen-single div b, + .chosen-container-single .chosen-search input[type="text"], + .chosen-container-multi .chosen-choices .search-choice .search-choice-close, + .chosen-container .chosen-results-scroll-down span, + .chosen-container .chosen-results-scroll-up span { + background-image: url('chosen-sprite@2x.png') !important; + background-size: 52px 37px !important; + background-repeat: no-repeat !important; + } +} +/* @end */ + +/* search results page - start */ +#category .chosen-container-single .chosen-single span { + min-height: 45px; + top: 11px; +} +/* search results page - end */ \ No newline at end of file diff --git a/modules/wkroomsearchblock/views/img/chosen-sprite.png b/modules/wkroomsearchblock/views/img/chosen-sprite.png new file mode 100644 index 0000000000000000000000000000000000000000..3611ae4ace1c4b1cbeacd6145b5a79cbc72e0bdc GIT binary patch literal 646 zcmV;10(t$3P)0006_Nkl&pbAC0n?)s%2x5M$#UgGxI1~gymp~v; zh<`zGaTJP5BybQY4tlRo;SIcmE0t>ueW3>*u6N;@_u;;|BoL8PuhZ#FWY9$(flan1oVvxDBL8~}0Q5z;^2p>Ov z7}Q$E7=l>$BZLUt1*uKMCaQwKYf$lsJCyerWMd+%BeGH6f_f&Vpy%=$BN%uK%Ahxi zF+%Jj=Pc-WXF;djSiJw|m4>cN%^Fi|FBZ!E{_yJLS?RI<3U696XLkQSs z{{&kQJ$K(#5CgC1;GbA>mjm56zJZ^-Hg2_ASKI_K@CybPh7Rq}8ud``)NM~eZx}qT z)oK?Lf>t!B;%Uh}*P+)Ef?jbx#w|BNEVb(l{2LK}m#fw4xx>ddF;&j}!S{N-e!<&Q z?kvzyI_AT@H-u4tUz1h&GCh8>?TnA~?BZ7WGP<9`r gQ6DuZO!_~60ju@{TzXF%TmS$707*qoM6N<$g2#CqL;wH) literal 0 HcmV?d00001 diff --git a/modules/wkroomsearchblock/views/img/chosen-sprite@2x.png b/modules/wkroomsearchblock/views/img/chosen-sprite@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..ffe4d7d1121ca45cd35783696940050c690a8676 GIT binary patch literal 872 zcmeAS@N?(olHy`uVBq!ia0vp^89?mC!3-o5mOWetq|OBRgt-3y{~yTgfB`oc01C8& zL0el}Lqh|Q1oD8A5J8A6G6@lfkU;ftMr&&;+$f+RkloVK0wm!8C|FWb0x`e2xj8g6 z6i7l;BAWwL4-tfu5G@ccP!{MmqnYOy06pVW666=m!0_*bfx(A_gav;C1PU5HKT!C5 z;g7@l4POuZ{>hQBP{j4uqq`I2WP9&Sn{}I8xJi*&v*QL&+Dw-Bf-CQLyLk0Ht2-;T zynum$iPO`?F{C2y?bYjfj|~J`6Xz~`vM4Ef+U{Vpli%)D%kKSey_RG0Bi9Xw4jtOb z@!)?~_%DVelO793W#Pl3vjdNCDTnGGb(^YY+BbF2;mJK!nq}@nBGoHxCn#7X*gdxr z+~ZQF6rpL6;MDP)JzehcJBL53AM-QU?@65Plc4-}1EW@`H@EEGrnFmTubZ~5iUzVn zrZYyBIm|RmW$3F@+wkq2)c>|mGh5Rv3%(p~zjStyruBl(TP2_51LpTH2noN*e&}J; z1;$+4EpJ(Mb+^1}Fv>ms%b`r}+KYy~zf5x(4?8l28%eNnEHzx({;NGP)_hX&tEw9t zSKv=Qjt(d#~b;F7hbDdUu$OUK8iumkkl&-=~$APCd2zdqHg6@=Z#Pt*5RY_s@Hw*YS9+ z^u)7AmzM6Ux!dus_!gJY)Vtf?+t>a3wO2S)_Vct=T}#@RuG(h!d8WYZS9Tst+VfKv zt~zntPsvfyqLY`klZSPslCz_dlcSRJLa$Px)_+W2Y&u!?oJrIMCNTz2S3j3^P6 spaceBottom) { - dropdownClass = 'top'; - } + dropdownHeightMax = Math.max(dropdownHeightMax, dropdownHeight); + spaceTopMax = Math.max(spaceTopMax, spaceTop); + spaceBottomMax = Math.max(spaceBottomMax, spaceBottom); + }); - // position dropdown + let dropdownClass = 'bottom'; + if (spaceBottomMax < dropdownHeightMax && spaceTopMax > spaceBottomMax) { + dropdownClass = 'top'; + } + + $(inputFieldsAndDropdowns).each(function (i, inputFieldAndDropdown) { inputFieldAndDropdown.dropdown.removeClass('top bottom').addClass(dropdownClass); }); } diff --git a/modules/wkroomsearchblock/views/templates/front/hotel-options.tpl b/modules/wkroomsearchblock/views/templates/front/hotel-options.tpl new file mode 100644 index 000000000..8c4c9912a --- /dev/null +++ b/modules/wkroomsearchblock/views/templates/front/hotel-options.tpl @@ -0,0 +1,27 @@ +{** + * 2010-2023 Webkul. + * + * NOTICE OF LICENSE + * + * All right is reserved, + * Please go through LICENSE.txt file inside our module + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade this module to newer + * versions in the future. If you wish to customize this module for your + * needs please refer to CustomizationPolicy.txt file inside our module for more information. + * + * @author Webkul IN + * @copyright 2010-2023 Webkul IN + * @license LICENSE.txt + *} + + +{if isset($hotels_info) && is_array($hotels_info)} + {foreach from=$hotels_info item=hotel_info} + + {/foreach} +{/if} diff --git a/modules/wkroomsearchblock/views/templates/front/index.php b/modules/wkroomsearchblock/views/templates/front/index.php new file mode 100644 index 000000000..1ad696d30 --- /dev/null +++ b/modules/wkroomsearchblock/views/templates/front/index.php @@ -0,0 +1,29 @@ +{$category.name} + {/foreach} +{/if} diff --git a/modules/wkroomsearchblock/views/templates/hook/searchForm.tpl b/modules/wkroomsearchblock/views/templates/hook/searchForm.tpl index a515da256..ad5a675eb 100644 --- a/modules/wkroomsearchblock/views/templates/hook/searchForm.tpl +++ b/modules/wkroomsearchblock/views/templates/hook/searchForm.tpl @@ -1,7 +1,7 @@
    {if isset($location_enabled) && $location_enabled}
    - + {else}
    From 911055e5a5749e4868d1f43740d70b808054a3fb Mon Sep 17 00:00:00 2001 From: Abhishek Kumar Date: Thu, 28 Dec 2023 14:52:26 +0530 Subject: [PATCH 08/53] Fix hotel field issue --- modules/wkroomsearchblock/views/js/wk-room-search-block.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/modules/wkroomsearchblock/views/js/wk-room-search-block.js b/modules/wkroomsearchblock/views/js/wk-room-search-block.js index 66e647ada..6f6e13477 100644 --- a/modules/wkroomsearchblock/views/js/wk-room-search-block.js +++ b/modules/wkroomsearchblock/views/js/wk-room-search-block.js @@ -688,10 +688,12 @@ $(document).ready(function() { // handle Tab/Enter keypresses on input fields - start $(document).on('keydown', '#hotel_location', function (e) { if (e.which == 9) { // Tab key - if ($('.location_search_results_ul').is(':visible')) { - e.preventDefault(); + e.preventDefault(); + if ($('.location_search_results_ul').is(':visible')) { $('.location_search_results_ul li:first').focus().click(); + } else { + BookingSearchManager.activateStep('hotel'); } } }); From d938b6e10d57575145f6757578b83bba49a35d3b Mon Sep 17 00:00:00 2001 From: Abhishek Kumar Date: Thu, 28 Dec 2023 15:35:11 +0530 Subject: [PATCH 09/53] Fix calendar issue --- .../wkroomsearchblock/views/js/wk-room-search-block.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/modules/wkroomsearchblock/views/js/wk-room-search-block.js b/modules/wkroomsearchblock/views/js/wk-room-search-block.js index 6f6e13477..3c006972f 100644 --- a/modules/wkroomsearchblock/views/js/wk-room-search-block.js +++ b/modules/wkroomsearchblock/views/js/wk-room-search-block.js @@ -275,8 +275,14 @@ $(document).ready(function() { } }); + // fix for: if user pressed Tab after selecting only one date + $('body').on('keydown', function(e) { + if (e.which == 9 && $('#date-range-picker-container').is(':visible')) { + $('#daterange_value').data('dateRangePicker').close(); + } + }); + // set data on clicking the searched location on dropdown - var focusHotelSelection = true; $(document).on('click', '.location_search_results_ul li', function(e) { e.preventDefault(); From d8063e7e2762b168a719a986002c33177109aa97 Mon Sep 17 00:00:00 2001 From: Abhishek Kumar Date: Thu, 28 Dec 2023 19:36:26 +0530 Subject: [PATCH 10/53] Fix occupancy and calendar issues --- .../views/js/wk-room-search-block.js | 142 ++++++++++++------ 1 file changed, 94 insertions(+), 48 deletions(-) diff --git a/modules/wkroomsearchblock/views/js/wk-room-search-block.js b/modules/wkroomsearchblock/views/js/wk-room-search-block.js index 3c006972f..ad4c75220 100644 --- a/modules/wkroomsearchblock/views/js/wk-room-search-block.js +++ b/modules/wkroomsearchblock/views/js/wk-room-search-block.js @@ -155,10 +155,13 @@ $(document).ready(function() { } }, endDate: max_order_date, + }).on('datepicker-first-date-selected', function() { + calendarFirstDateSelected = true; }).on('datepicker-change', function(event,obj){ $('#check_in_time').val($.datepicker.formatDate('yy-mm-dd', obj.date1)); $('#check_out_time').val($.datepicker.formatDate('yy-mm-dd', obj.date2)); focusNextOnCalendarClose = true; + calendarFirstDateSelected = false; }).on('datepicker-open', function() { $('#daterange_value').addClass('focused').focus(); }).on('datepicker-close', function() { @@ -181,14 +184,18 @@ $(document).ready(function() { startDate: $.datepicker.formatDate('dd-mm-yy', new Date()), startDate: start_date, endDate: max_order_date, + }).on('datepicker-first-date-selected', function() { + calendarFirstDateSelected = true; }).on('datepicker-change', function(event,obj){ $('#check_in_time').val($.datepicker.formatDate('yy-mm-dd', obj.date1)); $('#check_out_time').val($.datepicker.formatDate('yy-mm-dd', obj.date2)); focusNextOnCalendarClose = true; + calendarFirstDateSelected = false; }).on('datepicker-open', function() { $('#daterange_value').addClass('focused').focus(); }).on('datepicker-close', function() { $('#daterange_value').removeClass('focused').blur(); + calendarFirstDateSelected = false; }).on('datepicker-closed', function() { if (search_auto_focus_next_field && focusNextOnCalendarClose) { if (is_occupancy_wise_search) { @@ -265,7 +272,7 @@ $(document).ready(function() { } }); - var focusNextOnCalendarClose = true; + var focusNextOnCalendarClose = true, calendarFirstDateSelected = false;; // check if user clicked outside calendar $('body').on('click', function(e) { if ($('#date-range-picker-container').is(':visible')) { @@ -275,10 +282,22 @@ $(document).ready(function() { } }); - // fix for: if user pressed Tab after selecting only one date + // fix for: if user pressed Tab after selecting only first date $('body').on('keydown', function(e) { - if (e.which == 9 && $('#date-range-picker-container').is(':visible')) { + if (e.which == 9 + && $('#date-range-picker-container').is(':visible') + && calendarFirstDateSelected + ) { + e.preventDefault(); $('#daterange_value').data('dateRangePicker').close(); + + setTimeout(function () { + if (is_occupancy_wise_search) { + BookingSearchManager.activateStep('occupancy'); + } else { + BookingSearchManager.activateStep('submit'); + } + }, 10); } }); @@ -378,9 +397,8 @@ $(document).ready(function() { if (search_auto_focus_next_field) { setTimeout(function () { $('#id_hotel_button').data('chosen').close_field(); + BookingSearchManager.activateStep('date_range'); }, 10); - - BookingSearchManager.activateStep('date_range'); } } @@ -619,6 +637,54 @@ $(document).ready(function() { $("#search_occupancy_wrapper").toggle(); }); + function validateOccupancies() { + let hasErrors = 0; + + let adults = $("#search_occupancy_wrapper").find(".num_adults").map(function(){return $(this).val();}).get(); + let children = $("#search_occupancy_wrapper").find(".num_children").map(function(){return $(this).val();}).get(); + let child_ages = $("#search_occupancy_wrapper").find(".guest_child_age").map(function(){return $(this).val();}).get(); + + // start validating above values + if (!adults.length || (adults.length != children.length)) { + hasErrors = 1; + showErrorMessage(invalid_occupancy_txt); + } else { + $("#search_occupancy_wrapper").find('.occupancy_count').removeClass('error_border'); + + // validate values of adults and children + adults.forEach(function (item, index) { + if (isNaN(item) || parseInt(item) < 1) { + hasErrors = 1; + $("#search_occupancy_wrapper .num_adults").eq(index).closest('.occupancy_count_block').find('.occupancy_count').addClass('error_border'); + } + if (isNaN(children[index])) { + hasErrors = 1; + $("#search_occupancy_wrapper .num_children").eq(index).closest('.occupancy_count_block').find('.occupancy_count').addClass('error_border'); + } + }); + + // validate values of selected child ages + $("#search_occupancy_wrapper").find('.guest_child_age').removeClass('error_border'); + child_ages.forEach(function (age, index) { + age = parseInt(age); + if (isNaN(age) || (age < 0) || (age >= parseInt(max_child_age))) { + hasErrors = 1; + $("#search_occupancy_wrapper .guest_child_age").eq(index).addClass('error_border'); + } + }); + } + + if (hasErrors == 0) { + $("#search_occupancy_wrapper").hide(); + $("#search_hotel_block_form #guest_occupancy").removeClass('error_border'); + } else { + $("#search_hotel_block_form #guest_occupancy").addClass('error_border'); + return false; + } + + return true; + } + // close the occupancy block when clink anywhere in the body outside occupancy block $('body').on('click', function(e) { // @TODO better approach to be found @@ -626,54 +692,21 @@ $(document).ready(function() { if ($('#search_occupancy_wrapper').css('display') !== 'none') { if (!($(e.target).closest("#search_occupancy_wrapper").length)) { // Before closing the occupancy block validate the vaules inside - let hasErrors = 0; - - let adults = $("#search_occupancy_wrapper").find(".num_adults").map(function(){return $(this).val();}).get(); - let children = $("#search_occupancy_wrapper").find(".num_children").map(function(){return $(this).val();}).get(); - let child_ages = $("#search_occupancy_wrapper").find(".guest_child_age").map(function(){return $(this).val();}).get(); - - // start validating above values - if (!adults.length || (adults.length != children.length)) { - hasErrors = 1; - showErrorMessage(invalid_occupancy_txt); - } else { - $("#search_occupancy_wrapper").find('.occupancy_count').removeClass('error_border'); - - // validate values of adults and children - adults.forEach(function (item, index) { - if (isNaN(item) || parseInt(item) < 1) { - hasErrors = 1; - $("#search_occupancy_wrapper .num_adults").eq(index).closest('.occupancy_count_block').find('.occupancy_count').addClass('error_border'); - } - if (isNaN(children[index])) { - hasErrors = 1; - $("#search_occupancy_wrapper .num_children").eq(index).closest('.occupancy_count_block').find('.occupancy_count').addClass('error_border'); - } - }); - - // validate values of selected child ages - $("#search_occupancy_wrapper").find('.guest_child_age').removeClass('error_border'); - child_ages.forEach(function (age, index) { - age = parseInt(age); - if (isNaN(age) || (age < 0) || (age >= parseInt(max_child_age))) { - hasErrors = 1; - $("#search_occupancy_wrapper .guest_child_age").eq(index).addClass('error_border'); - } - }); - } - - if (hasErrors == 0) { - $("#search_occupancy_wrapper").hide(); - $("#search_hotel_block_form #guest_occupancy").removeClass('error_border'); - } else { - $("#search_hotel_block_form #guest_occupancy").addClass('error_border'); - return false; - } + return validateOccupancies(); } } } }); + $('body').on('keydown', function(e) { + if (e.which == 9 && $('#search_occupancy_wrapper:visible').length) { + e.preventDefault(); + if (validateOccupancies()) { + BookingSearchManager.activateStep('submit'); + } + } + }); + if (page_name == 'index') { $('#hotel_location, #id_hotel_button, #guest_occupancy').focus(function () { setBookingSearchPositions(); @@ -732,6 +765,19 @@ $(document).ready(function() { } }); + $(document).on('keydown', '#id_hotel_button_chosen .chosen-search input', function (e) { + if (e.which == 9 && $('#date-range-picker-container').is(':visible')) { // Tab key + e.preventDefault(); + $('#daterange_value').data('dateRangePicker').close(); + + if (is_occupancy_wise_search) { + BookingSearchManager.activateStep('occupancy'); + } else { + BookingSearchManager.activateStep('submit'); + } + } + }); + $(document).on('keydown', '#daterange_value', function (e) { if (e.which == 9) { // Tab key e.preventDefault(); From 730841d8c4ac223d6aa28005e1c2e1a19d44e2df Mon Sep 17 00:00:00 2001 From: abhishek-webkul <84142535+abhishek-webkul@users.noreply.github.com> Date: Thu, 15 Feb 2024 20:25:33 +0530 Subject: [PATCH 11/53] 2023 -> 2024 --- modules/wkroomsearchblock/views/css/chosen.css | 4 ++-- .../views/templates/front/hotel-options-dropdown.tpl | 4 ++-- .../views/templates/front/hotel-options-select.tpl | 4 ++-- modules/wkroomsearchblock/views/templates/front/index.php | 4 ++-- .../views/templates/front/location-options.tpl | 4 ++-- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/modules/wkroomsearchblock/views/css/chosen.css b/modules/wkroomsearchblock/views/css/chosen.css index b5b31fd7a..779c5e4c7 100644 --- a/modules/wkroomsearchblock/views/css/chosen.css +++ b/modules/wkroomsearchblock/views/css/chosen.css @@ -1,5 +1,5 @@ /** - * 2010-2023 Webkul. + * 2010-2024 Webkul. * * NOTICE OF LICENSE * @@ -13,7 +13,7 @@ * needs please refer to CustomizationPolicy.txt file inside our module for more information. * * @author Webkul IN - * @copyright 2010-2023 Webkul IN + * @copyright 2010-2024 Webkul IN * @license LICENSE.txt */ diff --git a/modules/wkroomsearchblock/views/templates/front/hotel-options-dropdown.tpl b/modules/wkroomsearchblock/views/templates/front/hotel-options-dropdown.tpl index 9f6431809..8939516b2 100644 --- a/modules/wkroomsearchblock/views/templates/front/hotel-options-dropdown.tpl +++ b/modules/wkroomsearchblock/views/templates/front/hotel-options-dropdown.tpl @@ -1,5 +1,5 @@ {** - * 2010-2023 Webkul. + * 2010-2024 Webkul. * * NOTICE OF LICENSE * @@ -13,7 +13,7 @@ * needs please refer to CustomizationPolicy.txt file inside our module for more information. * * @author Webkul IN - * @copyright 2010-2023 Webkul IN + * @copyright 2010-2024 Webkul IN * @license LICENSE.txt *} diff --git a/modules/wkroomsearchblock/views/templates/front/hotel-options-select.tpl b/modules/wkroomsearchblock/views/templates/front/hotel-options-select.tpl index 8c4c9912a..b6dd9cd0d 100644 --- a/modules/wkroomsearchblock/views/templates/front/hotel-options-select.tpl +++ b/modules/wkroomsearchblock/views/templates/front/hotel-options-select.tpl @@ -1,5 +1,5 @@ {** - * 2010-2023 Webkul. + * 2010-2024 Webkul. * * NOTICE OF LICENSE * @@ -13,7 +13,7 @@ * needs please refer to CustomizationPolicy.txt file inside our module for more information. * * @author Webkul IN - * @copyright 2010-2023 Webkul IN + * @copyright 2010-2024 Webkul IN * @license LICENSE.txt *} diff --git a/modules/wkroomsearchblock/views/templates/front/index.php b/modules/wkroomsearchblock/views/templates/front/index.php index 1ad696d30..089d93577 100644 --- a/modules/wkroomsearchblock/views/templates/front/index.php +++ b/modules/wkroomsearchblock/views/templates/front/index.php @@ -1,6 +1,6 @@ Date: Thu, 29 Feb 2024 16:42:11 +0530 Subject: [PATCH 12/53] Fix placeholder issue --- modules/wkroomsearchblock/views/js/wk-room-search-block.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/wkroomsearchblock/views/js/wk-room-search-block.js b/modules/wkroomsearchblock/views/js/wk-room-search-block.js index ad4c75220..dc8226e9b 100644 --- a/modules/wkroomsearchblock/views/js/wk-room-search-block.js +++ b/modules/wkroomsearchblock/views/js/wk-room-search-block.js @@ -268,7 +268,7 @@ $(document).ready(function() { && e.target.id != 'hotel_location' ) { $('.location_search_results_ul').hide(); - $('#hotel_location').val(hotel_location_txt); + $('#hotel_location').attr('placeholder', hotel_location_txt); } }); From b5eef16554822c3c1801a9a120b4d283996d1e77 Mon Sep 17 00:00:00 2001 From: Abhishek Kumar Date: Wed, 3 Apr 2024 15:06:33 +0530 Subject: [PATCH 13/53] Code organization --- js/daterangepicker/qlodaterangepicker.js | 59 +- .../controllers/front/autocompletesearch.php | 25 +- .../views/css/wk-global-search.css | 33 +- .../views/js/wk-room-search-block.js | 724 ++++++++++-------- ...l-options-select.tpl => hotel-options.tpl} | 0 .../views/templates/hook/searchForm.tpl | 44 +- .../css/daterangepicker.css | 6 +- themes/hotel-reservation-theme/css/global.css | 4 +- 8 files changed, 461 insertions(+), 434 deletions(-) rename modules/wkroomsearchblock/views/templates/front/{hotel-options-select.tpl => hotel-options.tpl} (100%) diff --git a/js/daterangepicker/qlodaterangepicker.js b/js/daterangepicker/qlodaterangepicker.js index 7e4186a97..401d2b6bc 100644 --- a/js/daterangepicker/qlodaterangepicker.js +++ b/js/daterangepicker/qlodaterangepicker.js @@ -22,6 +22,9 @@ var dateRangePickerOrg = $.fn.dateRangePicker; $.fn.dateRangePicker = function(opt) { if(typeof opt === "object") { + let container = $(this).parent(); + container.css({ position: 'relative' }); + const custom_opt = { format: 'DD-MM-YYYY', showTopbar: false, @@ -31,15 +34,14 @@ minDays: 2, startOfWeek: 'monday', hoveringTooltip: false, - container: page_name == 'index' ? '#date-range-picker-container' : '#page', - inline: page_name == 'index', + container: container, + inline: true, customArrowPrevSymbol: '', customArrowNextSymbol: '', - getValue: function() - { + getValue: function() { return $(this).find('span').html(); }, - setValue: function(s, s1, s2) { + setValue: function(s) { if (s) { $(this).find('span').html(s.replace('to', '  ')); } else { @@ -49,15 +51,56 @@ } } } + $.each(opt, function(index) { delete custom_opt[index]; }); $.extend(true, opt, custom_opt); - } var args = Array.prototype.slice.call(arguments,0); - return dateRangePickerOrg.apply(this, args); + + const dateRangePickerInput = dateRangePickerOrg.apply(this, args); + const calendarDom = $(dateRangePickerInput).data('dateRangePicker').getDatePicker(); + + dateRangePickerInput.on('datepicker-open', function() { + const positionClass = getPositionClass(dateRangePickerInput, calendarDom); + $(calendarDom).removeClass('top bottom').addClass(positionClass); + setPosition(dateRangePickerInput, calendarDom, positionClass) + }); + + return dateRangePickerInput; + + // helper function definitions + function getPositionClass(dateRangePickerInput, calendarDom) { + const inputElementHeight = dateRangePickerInput.outerHeight(); + const spaceTop = dateRangePickerInput.offset().top - $(window).scrollTop(); + const spaceBottom = $(window).height() - inputElementHeight - spaceTop; + const maxHeightNeeded = $(calendarDom).get(0).scrollHeight; + + let positionClass = 'bottom'; + // determine position class + if (spaceBottom < maxHeightNeeded && spaceTop > spaceBottom) { + positionClass = 'top'; + } + + return positionClass; + } + + function setPosition(dateRangePickerInput, calendarDom, positionClass) { + const inputElementHeight = dateRangePickerInput.outerHeight(); + + const css = {}; + if (positionClass == 'top') { + css.top = 'unset'; + css.bottom = inputElementHeight; + } else { + css.bottom = 'unset'; + css.top = $(dateRangePickerInput).position().top + inputElementHeight; + } + + $(calendarDom).css(css); + } } -})(jQuery); \ No newline at end of file +})(jQuery); diff --git a/modules/wkroomsearchblock/controllers/front/autocompletesearch.php b/modules/wkroomsearchblock/controllers/front/autocompletesearch.php index 696179ef5..9dfa3bed5 100644 --- a/modules/wkroomsearchblock/controllers/front/autocompletesearch.php +++ b/modules/wkroomsearchblock/controllers/front/autocompletesearch.php @@ -22,9 +22,10 @@ class WkRoomSearchBlockAutoCompleteSearchModuleFrontController extends ModuleFro { public function initContent() { - $result = array(); $this->display_column_left = false; $this->display_column_right = false; + + $result = array('status' => false); $search_data = Tools::getValue('to_search_data'); $location_category_id = Tools::getValue('location_category_id'); $obj_htl_info = new HotelBranchInformation(); @@ -35,7 +36,7 @@ class WkRoomSearchBlockAutoCompleteSearchModuleFrontController extends ModuleFro $html = $this->context->smarty->fetch( $this->module->getTemplatePath('location-options.tpl') ); - $result['status'] = 'success'; + $result['status'] = true; $result['data'] = $html; } } elseif (isset($location_category_id) && $location_category_id) { @@ -57,23 +58,15 @@ class WkRoomSearchBlockAutoCompleteSearchModuleFrontController extends ModuleFro } $this->context->smarty->assign(array('hotels_info' => $hotelsInfo)); - $html_select = $this->context->smarty->fetch( - $this->module->getTemplatePath('hotel-options-select.tpl') + $html = $this->context->smarty->fetch( + $this->module->getTemplatePath('hotel-options.tpl') ); - $html_dropdown = $this->context->smarty->fetch( - $this->module->getTemplatePath('hotel-options-dropdown.tpl') - ); - - $result['status'] = 'success'; - $result['data_select'] = $html_select; - $result['data_dropdown'] = $html_dropdown; - } else { - $result['status'] = 'failed2'; + $result['status'] = true; + $result['html_hotel_options'] = $html; } - } else { - $result['status'] = 'failed3'; } - die(json_encode($result)); + + $this->ajaxDie(json_encode($result)); } } diff --git a/modules/wkroomsearchblock/views/css/wk-global-search.css b/modules/wkroomsearchblock/views/css/wk-global-search.css index 5196325af..89acdfa75 100644 --- a/modules/wkroomsearchblock/views/css/wk-global-search.css +++ b/modules/wkroomsearchblock/views/css/wk-global-search.css @@ -63,21 +63,9 @@ column-gap: 5px; grid-template-columns: repeat(2, 1fr); } -#date-range-picker-container { - position: absolute; -} -#date-range-picker-container.top { - bottom: 82px; -} -#date-range-picker-container.bottom { - top: 85px; -} .fancybox-wrap #search_hotel_block_form .form-group.xs-calendar { position: relative; } -.fancybox-wrap #search_hotel_block_form #date-range-picker-container { - top: 56px; -} /* #search_hotel_block_form { display: grid; grid-template-columns: 0.8fr repeat(3, 1fr) 0.6fr; @@ -115,6 +103,9 @@ #search_hotel_block_form .header-rmsearch-input:active, #search_hotel_block_form .header-rmsearch-input:focus { border: 2px solid #1292FF;} #search_hotel_block_form #id_hotel_button { + appearance: none; + width: 100%; + padding-left: 35px; background: url("../../views/img/icon-hotel.svg") no-repeat 10px 50%, url("../../views/img/icon-dropdown-arrow.svg") no-repeat calc(100% - 10px) 50%; background-color: #FFF;} #search_hotel_block_form #guest_occupancy { @@ -157,15 +148,6 @@ position: relative;} .header-rmsearch-wrapper .dropdown-menu { margin: 0px;} -.header-rmsearch-wrapper .hotel_dropdown_ul { - position: absolute; - font-size: 14px; - font-weight: 400; - padding: 0px; - width: 100%; - box-shadow: 0 8px 25px -4px rgba(0,0,0,0.39); - max-height: 145px; - overflow-y: auto;} .header-rmsearch-wrapper .location_search_results_ul { position: absolute; font-size: 14px; @@ -176,7 +158,7 @@ box-shadow: 0 8px 25px -4px rgba(0,0,0,0.39); max-height: 145px; overflow-y: auto;} - .header-rmsearch-wrapper .location_search_results_ul li, .header-rmsearch-wrapper .hotel_dropdown_ul li { + .header-rmsearch-wrapper .location_search_results_ul li { background-color: #fff; color: #333333; cursor: pointer; @@ -184,7 +166,7 @@ font-size: 14px; list-style: outside none none; padding: 15px;} - .header-rmsearch-wrapper .location_search_results_ul li:hover, .header-rmsearch-wrapper .location_search_results_ul li:focus, .header-rmsearch-wrapper .location_search_results_ul li:active, .header-rmsearch-wrapper .hotel_dropdown_ul li:hover, .header-rmsearch-wrapper .hotel_dropdown_ul li:focus, .header-rmsearch-wrapper .hotel_dropdown_ul li:active { + .header-rmsearch-wrapper .location_search_results_ul li:hover, .header-rmsearch-wrapper .location_search_results_ul li:focus, .header-rmsearch-wrapper .location_search_results_ul li:active { background-color: #379bf0; color: #FFFFFF;} @@ -193,11 +175,6 @@ bottom: 55px; } .header-rmsearch-wrapper .location_search_results_ul.bottom { top: 100%; } -.header-rmsearch-wrapper .hotel_dropdown_ul.top { - top: unset; - bottom: 100%; } -.header-rmsearch-wrapper .hotel_dropdown_ul.bottom { - top: 100%; } .header-rmsearch-wrapper .label-desc-txt { diff --git a/modules/wkroomsearchblock/views/js/wk-room-search-block.js b/modules/wkroomsearchblock/views/js/wk-room-search-block.js index 9e458db28..f0c1d2dba 100644 --- a/modules/wkroomsearchblock/views/js/wk-room-search-block.js +++ b/modules/wkroomsearchblock/views/js/wk-room-search-block.js @@ -20,31 +20,294 @@ const BookingSearchManager = { inputSteps: { 'location': { - selector: '#hotel_location', - activate: function() { $('#hotel_location').focus(); }, - inputHasValue: function () { return ($('#hotel_location').val() != '') && ($('#location_category_id').val() != ''); }, + init: function() { + $('.location_search_results_ul').hide(); + + // search location with users searched characters + $(document).on('keyup', '#hotel_location', function(e) { + BookingSearchManager.inputSteps['location'].onInput.call(this, e); + }); + + // set data on clicking the searched location on dropdown + $(document).on('click', '.location_search_results_ul li', function(e) { + e.preventDefault(); + + BookingSearchManager.inputSteps['location'].onInputComplete.call(this, e); + }); + + // handle Tab key press on hotel location field + $(document).on('keydown', '#hotel_location', function (e) { + if (e.which == 9) { // Tab key + e.preventDefault(); + + if ($('.location_search_results_ul').is(':visible')) { + $('.location_search_results_ul li:first').focus().click(); + } else { + BookingSearchManager.activateStep('hotel'); + } + } + }); + + // handle Tab key press on hotel location list + $(document).on('keydown', '.location_search_results_ul li', function (e) { + if (e.which == 9) { // Tab key + e.preventDefault(); + $(this).click(); + } + }); + + // navigate to prev and next li in the location dropdown + $('body').on('keydown', '.location_search_results_ul li', function(e) { + if (e.which == 40 || e.which == 38) { + var ulElement = $(this).closest('ul'); + var ulLength = ulElement.find('li').length; + $(this).blur(); + ulElement.scrollTop($(this).index() * $(this).outerHeight()); + if (e.which == 40) { + if ($(this).index() != (ulLength - 1)) { + $(this).next('li.search_result_li').focus(); + } else { + ulElement.find('li:first').focus(); + } + } else if (e.which == 38) { + if ($(this).index()) { + $(this).prev('li.search_result_li').focus(); + } else { + ulElement.find('li:last').focus(); + } + } + } + }); + }, + activate: function() { + $('#hotel_location').focus(); + }, + inputHasValue: function () { + return ($('#hotel_location').val() != '') && ($('#location_category_id').val() != ''); + }, + onInput: function (e) { + if (e.which == 13) { + return; + } + + if (($('.location_search_results_ul').is(':visible')) && (e.which == 40 || e.which == 38)) { + $(this).blur(); + if (e.which == 40) { + $('.location_search_results_ul li:first').focus(); + } else if (e.which == 38) { + $('.location_search_results_ul li:last').focus(); + } + } else { + $('.location_search_results_ul').empty().hide(); + if ($(this).val() != '') { + abortRunningAjax(); + ajax_check_var = $.ajax({ + url: autocomplete_search_url, + data: { + to_search_data: $(this).val(), + }, + method: 'POST', + dataType: 'json', + success: function(result) { + if (result.status) { + $('.location_search_results_ul').html(result.data); + $('.location_search_results_ul').show(); + } + } + }); + } + } + }, + onInputComplete: function (e) { + e.preventDefault(); + + $('.location_search_results_ul').empty().hide(); + $('#hotel_location').attr('value', $(this).html()); + $('#location_category_id').val($(this).val()); + + // fetch hotels for selected location + $.ajax({ + url: autocomplete_search_url, + data: { + location_category_id: $('#location_category_id').val(), + }, + method: 'POST', + dataType: 'json', + success: function(result) { + if (result.status) { + $('#hotel_cat_id').val(''); + $('#id_hotel_button').html(result.html_hotel_options); + $('#id_hotel_button').trigger('chosen:updated'); + + if (search_auto_focus_next_field) { + BookingSearchManager.activateStep('hotel'); + } + } else { + alert(no_results_found_cond); + } + } + }); + }, }, 'hotel': { - selector: '#id_hotel_button', - activate: function() { $('#id_hotel_button').trigger('chosen:open'); }, - inputHasValue: function () { return ($('#id_hotel').val() != '') && ($('#hotel_cat_id').val() != ''); }, + init: function() { + $('select#id_hotel_button').chosen({ + search_contains: true, + disable_search: !hotel_name_has_search, + width: '100%', + }); + + $(document).on('change', '#id_hotel_button', function() { + if ($(this).find('option:selected').val().trim() != '') { + $('#id_hotel_button_chosen .chosen-search input').blur(); + BookingSearchManager.inputSteps['hotel'].onInputComplete.call(this); + } + }); + + // prevents calendar from closing on hotel selection + $(document).on('click', '#id_hotel_button_chosen li', function(e) { + e.stopPropagation(); + }); + + $(document).on('keydown', '#id_hotel_button_chosen.chosen-container-active', function (e) { + if (e.which == 9) { // Tab key + e.preventDefault(); + if ($('#daterange_value').length) { + $('#daterange_value').focus(); + $('#daterange_value').click(); + } + } + }); + + $(document).on('keydown', '#id_hotel_button_chosen .chosen-search input', function (e) { + if (e.which == 9 && $('#daterange_value').siblings('.date-picker-wrapper').is(':visible')) { // Tab key + e.preventDefault(); + $('#daterange_value').data('dateRangePicker').close(); + + if (is_occupancy_wise_search) { + BookingSearchManager.activateStep('occupancy'); + } else { + BookingSearchManager.activateStep('submit'); + } + } + }); + + // if chosen will not be initialized add placeholder to hotel select element as first option + if (!BookingSearchManager.isBrowserSupported()) { + $('select#id_hotel_button option').first().html(select_htl_txt); + } + + if (hotel_name_has_search) { + $('select#id_hotel_button').on('chosen:showing_dropdown', function() { + $(this).siblings('.chosen-container').find('.chosen-single').addClass('invisible') + }); + + $('select#id_hotel_button').on('chosen:hiding_dropdown', function() { + $(this).siblings('.chosen-container').find('.chosen-single').removeClass('invisible') + }); + } + }, + activate: function() { + $('#id_hotel_button').trigger('chosen:open'); + }, + inputHasValue: function () { + return ($('#id_hotel').val() != '') && ($('#hotel_cat_id').val() != ''); + }, + onInputComplete: function () { + $('#id_hotel_button_chosen .chosen-search input').blur(); + const selectedHotel = $(this).find('option:selected'); + + if ($(selectedHotel).val().trim() != '') { + const maxOrderDate = $(selectedHotel).attr('data-max_order_date'); + const preparationTime = $(selectedHotel).attr('data-preparation_time') + + createDateRangePicker(maxOrderDate, preparationTime, $('#check_in_time').val(), $('#check_out_time').val()); + + $('#max_order_date').val(maxOrderDate); + $('#preparation_time').val(preparationTime); + $('#id_hotel').val($(selectedHotel).attr('data-id-hotel')); + $('#hotel_cat_id').val($(selectedHotel).attr('data-hotel-cat-id')); + + if (search_auto_focus_next_field) { + setTimeout(function () { + if ($('#id_hotel_button').data('chosen') != undefined) { + $('#id_hotel_button').data('chosen').close_field(); + } + + BookingSearchManager.activateStep('date_range'); + }, 10); + } + } else { + $('#id_hotel').val(''); + $('#hotel_cat_id').val(''); + } + }, }, 'date_range': { - selector: '#daterange_value', - activate: function() { $('#daterange_value').data('dateRangePicker').open(); }, - inputHasValue: function () { return ($('#check_in_time').val() != '') && ($('#check_out_time').val() != ''); }, + init: function() { + $(document).on('keydown', '#daterange_value', function (e) { + if (e.which == 9) { // Tab key + e.preventDefault(); + $('#daterange_value').removeClass('focused').blur(); + + if ($('#daterange_value').data('dateRangePicker') != undefined) { + $('#daterange_value').data('dateRangePicker').close(); + } + + if (is_occupancy_wise_search) { + BookingSearchManager.activateStep('occupancy'); + } else { + BookingSearchManager.activateStep('submit'); + } + } + }); + }, + activate: function() { + $('#daterange_value').data('dateRangePicker').open(); + }, + inputHasValue: function () { + return ($('#check_in_time').val() != '') && ($('#check_out_time').val() != ''); + }, }, 'occupancy': { - selector: '#guest_occupancy', - activate: function() { if ($('#search_occupancy_wrapper').css('display') == 'none') { $('#guest_occupancy').click().focus(); } }, - inputHasValue: function () { return false; }, + init: function() { + $(document).on('keydown', '#guest_occupancy', function (e) { + if (e.which == 9) { // Tab key + e.preventDefault(); + if ($('#search_occupancy_wrapper').css('display') != 'none') { + $('#guest_occupancy').click(); + } + + BookingSearchManager.activateStep('submit'); + } + }); + }, + activate: function() { + if ($('#search_occupancy_wrapper').css('display') == 'none') { + $('#guest_occupancy').click().focus(); + } + }, + inputHasValue: function () { + return false; + }, }, 'submit': { - selector: '#search_room_submit', - activate: function() { $('#search_room_submit').focus(); }, - inputHasValue: function () { return false; }, + activate: function() { + $('#search_room_submit').focus(); + }, + inputHasValue: function () { + return false; + }, }, }, + init: function () { + this.inputSteps['location'].init(); + this.inputSteps['hotel'].init(); + this.inputSteps['date_range'].init(); + if (is_occupancy_wise_search) { + this.inputSteps['occupancy'].init(); + } + }, activateStep: function (step) { if (step in this.inputSteps) { this.inputSteps[step].activate(); @@ -53,10 +316,28 @@ const BookingSearchManager = { allFieldsFilled: function () { return this.inputSteps['hotel'].inputHasValue() && this.inputSteps['date_range'].inputHasValue() - } + }, + isBrowserSupported: function() { // defined as it is from chosen to decide if chosen will be initialized + if (window.navigator.appName === "Microsoft Internet Explorer") { + return document.documentMode >= 8; + } + if (/iP(od|hone)/i.test(window.navigator.userAgent)) { + return false; + } + if (/Android/i.test(window.navigator.userAgent)) { + if (/Mobile/i.test(window.navigator.userAgent)) { + return false; + } + } + + return true; + }, } $(document).ready(function() { + // initialize booking search fields + BookingSearchManager.init(); + // for screen size changes for room search var window_width = $(window).width(); if (window_width > 767) { @@ -84,24 +365,17 @@ $(document).ready(function() { helpers: { overlay: { closeClick: false } //Disable click outside event }, - 'beforeShow': function() { - $('#date-range-picker-container').closest('.form-group').addClass('xs-calendar'); - }, 'afterClose': function() { $('.header-rmsearch-container').show(); $('#xs_room_search_form').show(); - - $('#date-range-picker-container').closest('.form-group').removeClass('xs-calendar'); }, }); }); /*END*/ var ajax_check_var = ''; - $('.location_search_results_ul').hide(); - function createDateRangePicker(max_order_date, preparation_time, dateFrom, dateTo) - { + createDateRangePicker = function (max_order_date, preparation_time, dateFrom, dateTo) { let start_date = new Date(); if (preparation_time) { start_date.setDate(start_date.getDate() + parseInt(preparation_time)); @@ -177,6 +451,8 @@ $(document).ready(function() { BookingSearchManager.activateStep('submit'); } } + + focusNextOnCalendarClose = false; } }); } else { @@ -207,6 +483,8 @@ $(document).ready(function() { BookingSearchManager.activateStep('submit'); } } + + focusNextOnCalendarClose = false; } }); } @@ -217,207 +495,21 @@ $(document).ready(function() { $.datepicker.formatDate('dd-mm-yy', $.datepicker.parseDate('yy-mm-dd', dateTo)) ); } - } - function abortRunningAjax() { + abortRunningAjax = function () { if (ajax_check_var) { ajax_check_var.abort(); } } - // search location with users searched characters - $(document).on('keyup', "#hotel_location", function(e) { - if (e.which == 13) { - return; - } - - if (($('.location_search_results_ul').is(':visible')) && (e.which == 40 || e.which == 38)) { - $(this).blur(); - if (e.which == 40) { - $(".location_search_results_ul li:first").focus(); - } else if (e.which == 38) { - $(".location_search_results_ul li:last").focus(); - } - } else { - $('.location_search_results_ul').empty().hide(); - if ($(this).val() != '') { - abortRunningAjax(); - ajax_check_var = $.ajax({ - url: autocomplete_search_url, - data: { - to_search_data: $(this).val(), - }, - method: 'POST', - dataType: 'json', - success: function(result) { - if (result.status == 'success') { - $('.location_search_results_ul').html(result.data); - $('.location_search_results_ul').show(); - } - } - }); - } - } - }); - - // if user clicks anywhere and location li is visible then close it - $('body').on('click', function(e) { - if ($('.location_search_results_ul').is(':visible') - && e.target.className != 'search_result_li' - && e.target.id != 'hotel_location' - ) { - $('.location_search_results_ul').hide(); - $('#hotel_location').attr('placeholder', hotel_location_txt); - } - }); - - var focusNextOnCalendarClose = true, calendarFirstDateSelected = false;; - // check if user clicked outside calendar - $('body').on('click', function(e) { - if ($('#date-range-picker-container').is(':visible')) { - if (!$(e.target).closest('.form-group').find('#date-range-picker-container').length) { - focusNextOnCalendarClose = false; - } - } - }); - - // fix for: if user pressed Tab after selecting only first date - $('body').on('keydown', function(e) { - if (e.which == 9 - && $('#date-range-picker-container').is(':visible') - && calendarFirstDateSelected - ) { - e.preventDefault(); - $('#daterange_value').data('dateRangePicker').close(); - - setTimeout(function () { - if (is_occupancy_wise_search) { - BookingSearchManager.activateStep('occupancy'); - } else { - BookingSearchManager.activateStep('submit'); - } - }, 10); - } - }); - - // set data on clicking the searched location on dropdown - $(document).on('click', '.location_search_results_ul li', function(e) { - e.preventDefault(); - - $('.location_search_results_ul').empty().hide(); - $('#hotel_location').attr('value', $(this).html()); - $('#location_category_id').val($(this).val()); - - // fetch hotels for selected location - $.ajax({ - url: autocomplete_search_url, - data: { - location_category_id: $('#location_category_id').val(), - }, - method: 'POST', - dataType: 'json', - success: function(result) { - if (result.status == 'success') { - $('#hotel_cat_id').val(''); - $('#id_hotel_button').html(result.data_select); - $('.hotel_dropdown_ul').empty(); - $('.hotel_dropdown_ul').html(result.data_dropdown); - $('#id_hotel_button').trigger('chosen:updated'); - - if (search_auto_focus_next_field) { - BookingSearchManager.activateStep('hotel'); - } - } else { - alert(no_results_found_cond); - } - } - }); - - $('#id_hotel_button_chosen .chosen-search input').blur(); - }); - - // prevents calendar from closing on hotel selection - $(document).on('click', '#id_hotel_button_chosen li', function(e) { - e.stopPropagation(); - }); - - // navigate to prev and next li in the location/hotel dropdown - $('body').on('keyup', 'li.search_result_li', function(e) { - if (e.which == 40 || e.which == 38) { - var ulElement = $(this).closest('ul'); - var ulLength = ulElement.find('li').length; - $(this).blur(); - ulElement.scrollTop($(this).index() * $(this).outerHeight()); - if (e.which == 40) { - if ($(this).index() != (ulLength - 1)) { - $(this).next('li.search_result_li').focus(); - } else { - ulElement.find("li:first").focus(); - } - } else if (e.which == 38) { - if ($(this).index()) { - $(this).prev('li.search_result_li').focus(); - } else { - ulElement.find("li:last").focus(); - } - } - } - }); - - // if user is selecting the location by keydown / up key - $(document).on('keydown', 'body', function(e) { - if ((e.which == 40 || e.which == 38) && ($('.location_search_results_ul li.search_result_li').is(':visible') || $('.hotel_dropdown_ul li.search_result_li').is(':visible'))) { - return false; - } else if (e.which == 13 && e.target.className == 'search_result_li') { - e.target.click(); - } else if (e.which == 9 && $('.location_search_results_ul').is(':visible')) { - if ($('.location_search_results_ul .search_result_li').length) { - $('.location_search_results_ul li.search_result_li:first').click(); - } - } else if (e.which == 9 && $('.hotel_dropdown_ul').is(':visible')) { - if ($('.hotel_dropdown_ul .search_result_li').length) { - $('.hotel_dropdown_ul li.search_result_li:first').click(); - } - } - }); - - function selectHotelFromList(selectedHotel) { - let max_order_date = $(selectedHotel).attr('data-max_order_date'); - let preparation_time = $(selectedHotel).attr('data-preparation_time') - - createDateRangePicker(max_order_date, preparation_time, $('#check_in_time').val(), $('#check_out_time').val()); - - $("#max_order_date").val(max_order_date); - $('#preparation_time').val(preparation_time); - $('#id_hotel').val($(selectedHotel).attr('data-id-hotel')); - $('#hotel_cat_id').val($(selectedHotel).attr('data-hotel-cat-id')); - $('#hotel_cat_name').html($(selectedHotel).html()); - - if (search_auto_focus_next_field) { - setTimeout(function () { - $('#id_hotel_button').data('chosen').close_field(); - BookingSearchManager.activateStep('date_range'); - }, 10); - } - } - - $(document).on('change', '#id_hotel_button', function() { - $('#id_hotel_button_chosen .chosen-search input').blur(); - selectHotelFromList($(this).find('option:selected')); - }); - - $(document).on('click', '.hotel_dropdown_ul li', function() { - selectHotelFromList($(this)); - }); - // If only one hotel then set max order date on date pickers var max_order_date = $('#max_order_date').val(); var preparation_time = $('#preparation_time').val(); createDateRangePicker(max_order_date, preparation_time, $('#check_in_time').val(), $('#check_out_time').val()); // validations on the submit of the search fields - $('#search_room_submit').on('click', function(e) { + $(document).on('click', '#search_room_submit', function() { var check_in_time = $("#check_in_time").val(); var check_out_time = $("#check_out_time").val(); var max_order_date = $("#max_order_date").val(); @@ -474,9 +566,10 @@ $(document).ready(function() { else return true; }); + // Occupancy field dropdown // add occupancy info block - $('#search_occupancy_wrapper .add_new_occupancy_btn').on('click', function(e) { + $(document).on('click', '#search_occupancy_wrapper .add_new_occupancy_btn', function(e) { e.preventDefault(); var occupancy_block = ''; @@ -653,7 +746,7 @@ $(document).ready(function() { // toggle occupancy block $('#guest_occupancy').on('click', function(e) { e.stopPropagation(); - if ($('#date-range-picker-container').is(':visible')) { + if ($('#daterange_value').siblings('.date-picker-wrapper').is(':visible')) { $('#daterange_value').data('dateRangePicker').close(); } $("#search_occupancy_wrapper").toggle(); @@ -707,28 +800,95 @@ $(document).ready(function() { return true; } - // close the occupancy block when clink anywhere in the body outside occupancy block + // Body Events - start + var focusNextOnCalendarClose = true; + var calendarFirstDateSelected = false; $('body').on('click', function(e) { - // @TODO better approach to be found + // if user clicks anywhere and location li is visible then close it + if ($('.location_search_results_ul').is(':visible') + && e.target.className != 'search_result_li' + && e.target.id != 'hotel_location' + ) { + $('.location_search_results_ul').hide(); + $('#hotel_location').attr('placeholder', hotel_location_txt); + } + + // check if user clicked outside calendar + if ($('#daterange_value').siblings('.date-picker-wrapper').is(':visible')) { + if (!$(e.target).closest('.form-group').find('.date-picker-wrapper').length) { + focusNextOnCalendarClose = false; + } + } + + // close the occupancy block when clink anywhere in the body outside occupancy block if ($('#search_occupancy_wrapper').length) { if ($('#search_occupancy_wrapper').css('display') !== 'none') { if (!($(e.target).closest("#search_occupancy_wrapper").length)) { - // Before closing the occupancy block validate the vaules inside + // Before closing the occupancy block validate the values inside return validateOccupancies(); } } } }); + var isEnterKeyHeldOnLocation = false; $('body').on('keydown', function(e) { + let preventDefault = false; + + // fix for: if user pressed Tab after selecting only first date + if (e.which == 9 + && $('#daterange_value').siblings('.date-picker-wrapper').is(':visible') + && calendarFirstDateSelected + ) { + preventDefault = true; + $('#daterange_value').data('dateRangePicker').close(); + + setTimeout(function () { + if (is_occupancy_wise_search) { + BookingSearchManager.activateStep('occupancy'); + } else { + BookingSearchManager.activateStep('submit'); + } + }, 10); + } + + // if user is selecting the location by Up, Down, Enter or Tab keys + if ((e.which == 40 || e.which == 38) && $('.location_search_results_ul li.search_result_li').is(':visible')) { + return false; + } else if (e.which == 13 && e.target.className == 'search_result_li') { + // select location only after held Enter key is unheld + preventDefault = true; + isEnterKeyHeldOnLocation = true; + } else if (e.which == 9 && $('.location_search_results_ul').is(':visible')) { + preventDefault = true; + $(e.target).click(); + } + + // check if submit button must be focused if (e.which == 9 && $('#search_occupancy_wrapper:visible').length) { - e.preventDefault(); + preventDefault = true; if (validateOccupancies()) { BookingSearchManager.activateStep('submit'); } } + + if (preventDefault) { + e.preventDefault(); + } }); + // select location only after held Enter key is unheld + $('body').on('keyup', function(e) { + if ($(e.target).is('.location_search_results_ul li') + && isEnterKeyHeldOnLocation + && e.which == 13 + ) { + $(e.target).click(); + } + }); + // Body Events - end + + // set positions of popups when required if (page_name == 'index') { $('#hotel_location, #id_hotel_button, #guest_occupancy').focus(function () { setBookingSearchPositions(); @@ -745,112 +905,8 @@ $(document).ready(function() { setBookingSearchPositions(); }); } - - // handle Tab/Enter keypresses on input fields - start - $(document).on('keydown', '#hotel_location', function (e) { - if (e.which == 9) { // Tab key - e.preventDefault(); - - if ($('.location_search_results_ul').is(':visible')) { - $('.location_search_results_ul li:first').focus().click(); - } else { - BookingSearchManager.activateStep('hotel'); - } - } - }); - - $(document).on('keydown', '.location_search_results_ul li', function (e) { - if (e.which == 9) { // Tab key - e.preventDefault(); - $(this).click(); - } - }); - - $(document).on('keydown', '.hotel_dropdown_ul li', function (e) { - if (e.which == 9 || e.which == 13) { // Tab/Enter key - if (e.which == 9) { - $(this).click(); - } - if ($('#daterange_value').length) { - $('#daterange_value').click(); - } - } - }); - - $(document).on('keydown', '#id_hotel_button_chosen.chosen-container-active', function (e) { - if (e.which == 9) { // Tab key - e.preventDefault(); - if ($('#daterange_value').length) { - $('#daterange_value').focus(); - $('#daterange_value').click(); - } - } - }); - - $(document).on('keydown', '#id_hotel_button_chosen .chosen-search input', function (e) { - if (e.which == 9 && $('#date-range-picker-container').is(':visible')) { // Tab key - e.preventDefault(); - $('#daterange_value').data('dateRangePicker').close(); - - if (is_occupancy_wise_search) { - BookingSearchManager.activateStep('occupancy'); - } else { - BookingSearchManager.activateStep('submit'); - } - } - }); - - $(document).on('keydown', '#daterange_value', function (e) { - if (e.which == 9) { // Tab key - e.preventDefault(); - $('#daterange_value').removeClass('focused').blur(); - - if ($('#daterange_value').data('dateRangePicker') != undefined) { - $('#daterange_value').data('dateRangePicker').close(); - } - - if (is_occupancy_wise_search) { - BookingSearchManager.activateStep('occupancy'); - } else { - BookingSearchManager.activateStep('submit'); - } - } - }); - - $(document).on('keydown', '#guest_occupancy', function (e) { - if (e.which == 9) { // Tab key - e.preventDefault(); - if ($('#search_occupancy_wrapper').css('display') != 'none') { - $('#guest_occupancy').click(); - } - - BookingSearchManager.activateStep('submit'); - } - }); - // handle Tab/Enter keypresses on input fields - end - - $('select#id_hotel_button').chosen({ - search_contains: true, - disable_search: !hotel_name_has_search, - width: '100%', - }); - - if (hotel_name_has_search) { - $('select#id_hotel_button').on('chosen:showing_dropdown', function() { - $(this).siblings('.chosen-container').find('.chosen-single').addClass('invisible') - }); - - $('select#id_hotel_button').on('chosen:hiding_dropdown', function() { - $(this).siblings('.chosen-container').find('.chosen-single').removeClass('invisible') - }); - } - - // if hotel chosen is not intialized use dropdown - if ($('select#id_hotel_button').data('chosen') === undefined) { - $('#search_hotel_block_form .hotel-select-wrap').addClass('hide'); - $('#search_hotel_block_form .hotel-dropdown-wrap').removeClass('hide'); - } }); + // function to set occupancy infor in guest occupancy field(search form) function setGuestOccupancy() { @@ -884,44 +940,35 @@ function setGuestOccupancy() $('#guest_occupancy > span').text(guestButtonVal); } -// position dropdowns and the calendar +// position dropdowns function setBookingSearchPositions() { // calculate available spaces let searchForm = $('#search_hotel_block_form'); let inputFieldsAndDropdowns = [ { input: $('#hotel_location'), dropdown: $('.location_search_results_ul')}, - { input: $('#id_hotel_button'), dropdown: $('.hotel_dropdown_ul')}, { input: $('.hotel-selector-wrap'), dropdown: $('#id_hotel_button_chosen .chosen-drop')}, { input: $('#guest_occupancy'), dropdown: $('#search_occupancy_wrapper')}, ]; - let calendarInputField = { input: $('#daterange_value'), calendarContainer: $('#date-range-picker-container')}; - let positionClass = 'bottom'; if (!searchForm.closest('.fancybox-wrap').length) { let searchFormHeight = searchForm.outerHeight(); let spaceTop = searchForm.offset().top - $(window).scrollTop(); let spaceBottom = $(window).height() - searchFormHeight - spaceTop; - let calendarHeight = 292; - // calculate max height for dropdowns let maxHeightNeeded = 0; $(inputFieldsAndDropdowns).each(function (i, inputFieldAndDropdown) { if (!inputFieldAndDropdown.input.length) return false; // find needed space height - let cssMaxHeight = inputFieldAndDropdown.dropdown.css('max-height') || calendarHeight + 'px'; - let dropdownHeight = parseInt(cssMaxHeight.replace('px', '')); - dropdownHeight = Math.max(dropdownHeight || 0, calendarHeight); - - maxHeightNeeded = Math.max(maxHeightNeeded, dropdownHeight); + let cssMaxHeight = parseInt(inputFieldAndDropdown.dropdown.css('max-height')); + if (Number.isInteger(cssMaxHeight)) { + maxHeightNeeded = Math.max(maxHeightNeeded, cssMaxHeight); + } }); - // manage calendar now - maxHeightNeeded = Math.max(maxHeightNeeded, calendarHeight); - // determine position class if (spaceBottom < maxHeightNeeded && spaceTop > spaceBottom) { positionClass = 'top'; @@ -932,7 +979,4 @@ function setBookingSearchPositions() { $(inputFieldsAndDropdowns).each(function (i, inputFieldAndDropdown) { inputFieldAndDropdown.dropdown.removeClass('top bottom').addClass(positionClass); }); - - // position calendar - calendarInputField.calendarContainer.removeClass('top bottom').addClass(positionClass); } diff --git a/modules/wkroomsearchblock/views/templates/front/hotel-options-select.tpl b/modules/wkroomsearchblock/views/templates/front/hotel-options.tpl similarity index 100% rename from modules/wkroomsearchblock/views/templates/front/hotel-options-select.tpl rename to modules/wkroomsearchblock/views/templates/front/hotel-options.tpl diff --git a/modules/wkroomsearchblock/views/templates/hook/searchForm.tpl b/modules/wkroomsearchblock/views/templates/hook/searchForm.tpl index 2dbe8961d..1703b29bf 100644 --- a/modules/wkroomsearchblock/views/templates/hook/searchForm.tpl +++ b/modules/wkroomsearchblock/views/templates/hook/searchForm.tpl @@ -21,37 +21,13 @@ -
    -
    - -
    -
    -
    - {if isset($hotels_info) && count($hotels_info)} - - {/if} +
    +
    {/if} @@ -65,18 +41,12 @@
    {l s='Check-out' mod='wkroomsearchblock'}
    - {if isset($is_index_page) && $is_index_page} -
    - {/if}
    {else}
    {l s='Check-in' mod='wkroomsearchblock'}    {l s='Check-out' mod='wkroomsearchblock'}
    - {if isset($is_index_page) && $is_index_page} -
    - {/if}
    {/if} diff --git a/themes/hotel-reservation-theme/css/daterangepicker.css b/themes/hotel-reservation-theme/css/daterangepicker.css index f1b6cbe07..a84b58ff0 100644 --- a/themes/hotel-reservation-theme/css/daterangepicker.css +++ b/themes/hotel-reservation-theme/css/daterangepicker.css @@ -26,11 +26,11 @@ box-shadow: 0 4px 10px 0 rgb(0 0 0 / 26%); } .date-picker-wrapper.no-shortcuts { - margin-top: -4px; padding: 10px; } -#index .date-picker-wrapper.no-shortcuts { - margin-top: 0; +.date-picker-wrapper.top, +.date-picker-wrapper.bottom { + position: absolute; } .date-picker-wrapper .month-wrapper{ border: none; diff --git a/themes/hotel-reservation-theme/css/global.css b/themes/hotel-reservation-theme/css/global.css index 50095cd66..6d8662914 100644 --- a/themes/hotel-reservation-theme/css/global.css +++ b/themes/hotel-reservation-theme/css/global.css @@ -6533,8 +6533,8 @@ table.table_block td { .input-date span i, .form-control .input-date span i { transform: scale(0.8, 0.6);} -.input-hotel, .form-control .input-hotel, .input-location, .form-control .input-location { - background: url("../img/icon/icon-location.svg") no-repeat 10px 50%; +.input-location, .form-control .input-location { + background: url("../img/icon/icon-location.svg") no-repeat 6px 50%; padding-left: 35px; background-color: #FFF; } From 43374957176ffec7416e35056c2d28ab71cad9d8 Mon Sep 17 00:00:00 2001 From: Abhishek Kumar Date: Wed, 3 Apr 2024 15:10:49 +0530 Subject: [PATCH 14/53] Remove unwanted file hotel-options-dropdown.tpl --- .../front/hotel-options-dropdown.tpl | 26 ------------------- 1 file changed, 26 deletions(-) delete mode 100644 modules/wkroomsearchblock/views/templates/front/hotel-options-dropdown.tpl diff --git a/modules/wkroomsearchblock/views/templates/front/hotel-options-dropdown.tpl b/modules/wkroomsearchblock/views/templates/front/hotel-options-dropdown.tpl deleted file mode 100644 index 8939516b2..000000000 --- a/modules/wkroomsearchblock/views/templates/front/hotel-options-dropdown.tpl +++ /dev/null @@ -1,26 +0,0 @@ -{** - * 2010-2024 Webkul. - * - * NOTICE OF LICENSE - * - * All right is reserved, - * Please go through LICENSE.txt file inside our module - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade this module to newer - * versions in the future. If you wish to customize this module for your - * needs please refer to CustomizationPolicy.txt file inside our module for more information. - * - * @author Webkul IN - * @copyright 2010-2024 Webkul IN - * @license LICENSE.txt - *} - -{if isset($hotels_info) && is_array($hotels_info)} - {foreach from=$hotels_info item=hotel_info} -
  • - {$hotel_info.hotel_name} -
  • - {/foreach} -{/if} From d0847d23e0cc2c95a9b604a886eaf5d22b88a7a2 Mon Sep 17 00:00:00 2001 From: Shreesh Arora Date: Wed, 17 Apr 2024 15:32:01 +0530 Subject: [PATCH 15/53] Fixed: design issue in new list header design when switching from mobile to desktop view --- admin/themes/default/template/helpers/list/list_header.tpl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/admin/themes/default/template/helpers/list/list_header.tpl b/admin/themes/default/template/helpers/list/list_header.tpl index bf7678e4f..ca8600b9a 100644 --- a/admin/themes/default/template/helpers/list/list_header.tpl +++ b/admin/themes/default/template/helpers/list/list_header.tpl @@ -167,7 +167,7 @@ $(form).find('table.table .field_optional').hide(); $(form).find('table.table .field_optional').each(function(i, val) { if (list_fields_visibility.includes($(this).data('key'))) { - $(this).show(); + $(this).css('display', ''); } }); updateListVisibility(list_fields_visibility) From bd3d7092bb3ffa1b5ccb86d3b059d6c8ee8546e5 Mon Sep 17 00:00:00 2001 From: Sumit Panwar Date: Mon, 22 Apr 2024 16:41:13 +0530 Subject: [PATCH 16/53] Fixed:Need to arrange the options in correct order at order list page in mobile view. --- admin/themes/default/template/helpers/list/list_header.tpl | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/admin/themes/default/template/helpers/list/list_header.tpl b/admin/themes/default/template/helpers/list/list_header.tpl index bf7678e4f..d8e313a11 100644 --- a/admin/themes/default/template/helpers/list/list_header.tpl +++ b/admin/themes/default/template/helpers/list/list_header.tpl @@ -553,10 +553,11 @@ From 4014f2db9e6c74d58bbb10b70b6c145c75a79359 Mon Sep 17 00:00:00 2001 From: Sumit Panwar Date: Mon, 22 Apr 2024 17:45:01 +0530 Subject: [PATCH 17/53] Fixed:Getting a fatal error when removing the product from the cart from a different tab before creating order. --- controllers/admin/AdminOrdersController.php | 3 +++ .../hotelreservationsystem/classes/HotelCartBookingData.php | 6 ++++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/controllers/admin/AdminOrdersController.php b/controllers/admin/AdminOrdersController.php index 9c6d1fe61..13ce8e303 100644 --- a/controllers/admin/AdminOrdersController.php +++ b/controllers/admin/AdminOrdersController.php @@ -1666,6 +1666,9 @@ class AdminOrdersControllerCore extends AdminController if ($this->tabAccess['edit'] === '1') { $objCart = new Cart($id_cart); if (Validate::isLoadedObject($objCart)) { + $this->context->cart = $objCart; + + $this->errors = HotelCartBookingData::validateCartBookings(); $orderTotal = $objCart->getOrderTotal(true, Cart::BOTH); if ($objCart->is_advance_payment) { $advancePaymentAmount = $objCart->getOrderTotal(true, Cart::ADVANCE_PAYMENT); diff --git a/modules/hotelreservationsystem/classes/HotelCartBookingData.php b/modules/hotelreservationsystem/classes/HotelCartBookingData.php index dc32346d2..9e9028b49 100644 --- a/modules/hotelreservationsystem/classes/HotelCartBookingData.php +++ b/modules/hotelreservationsystem/classes/HotelCartBookingData.php @@ -928,8 +928,8 @@ class HotelCartBookingData extends ObjectModel public static function validateCartBookings() { $context = Context::getContext(); - $errors = array(); + $objModule = Module::getInstanceByName('hotelreservationsystem'); // validate room types if bookable from front office if ($cartProducts = $context->cart->getProducts()) { @@ -939,6 +939,9 @@ class HotelCartBookingData extends ObjectModel $objHotelCartBookingData->deleteCartBookingData($context->cart->id, $product['id_product']); } } + } else { + $error = true; + $errors[] = $objModule->l('No booking found in the cart.', 'HotelOrderRestrictDate'); } // validate service products @@ -955,7 +958,6 @@ class HotelCartBookingData extends ObjectModel } // validate room types for restriction date - $objModule = Module::getInstanceByName('hotelreservationsystem'); if ($cartProducts = $context->cart->getProducts()) { $objHotelCartBookingData = new HotelCartBookingData(); $objHotelBookingDetail = new HotelBookingDetail(); From 60d003c3eda2983958d0d6e108bc521f5102949e Mon Sep 17 00:00:00 2001 From: Sumit Panwar Date: Sat, 27 Apr 2024 12:30:17 +0530 Subject: [PATCH 18/53] Fixxed:: Issues in the process of Bok now from back office --- .../template/controllers/orders/form.tpl | 1033 +++++++++-------- controllers/admin/AdminOrdersController.php | 112 +- controllers/front/OrderOpcController.php | 4 +- .../classes/HotelCartBookingData.php | 114 +- .../RoomTypeServiceProductCartDetail.php | 2 +- .../AdminHotelRoomsBookingController.php | 14 +- 6 files changed, 632 insertions(+), 647 deletions(-) diff --git a/admin/themes/default/template/controllers/orders/form.tpl b/admin/themes/default/template/controllers/orders/form.tpl index 933d0a6cc..dc225fd9a 100644 --- a/admin/themes/default/template/controllers/orders/form.tpl +++ b/admin/themes/default/template/controllers/orders/form.tpl @@ -1731,539 +1731,542 @@
    {block name="leadin"}{/block}
    {include file='controllers/orders/_current_cart_details_data.tpl'} -
    -
    - - {l s='Customer'} -
    -
    - -
    -
    -
    -
    - - - - -
    -
    - -
    -
    -
    -
    -
    -
    - {*
    - + {* If cart has errors the do not allow to proceed with this cart *} + {if !$hasCartErrors} +
    +
    + + {l s='Customer'} +
    +
    + +
    +
    +
    +
    + + + + +
    +
    + +
    +
    +
    +
    +
    +
    + {*
    + - -
    -
    - - - - - - - - - - - -
    {l s='ID'}{l s='Date'}{l s='Total'}
    -
    -
    - - - - - - - - - - - - - - -
    {l s='ID'}{l s='Date'}{l s='Products'}{l s='Total paid'}{l s='Payment'}{l s='Status'}
    -
    -
    -
    -->*} -
    + +
    +
    + + + + + + + + + + + +
    {l s='ID'}{l s='Date'}{l s='Total'}
    +
    +
    + + + + + + + + + + + + + + +
    {l s='ID'}{l s='Date'}{l s='Products'}{l s='Total paid'}{l s='Payment'}{l s='Status'}
    +
    +
    +
    -->*} +
    - - - + -
    -
    - - {l s='Addresses'} -
    - +
    +
    + + {l s='Addresses'} +
    + -
    -
    -

    - - {l s='Customer Address'} -

    -
    - -
    - -
    - -
    - -
    - + - +
    +
    +
    + +
    + +
    +
    + + {if isset($smarty.post.is_full_payment)} + {assign var=is_full_payment value=((bool) $smarty.post.is_full_payment)} + {else} + {assign var=is_full_payment value=true} + {/if} +
    + +
    + + + + + + + +

    {l s='Keep this option enabled for full payment and disable it to take partial payment of the booking.'}

    +
    +
    +
    + +
    +
    + {$currency->sign} + +
    +

    + {l s='Advance payment amount: '} + {displayPrice price=$advance_payment_amount_with_tax currency=$currency->id} +

    +
    +
    +
    + +
    + +
    +
    +
    + +
    + + + {foreach from=$payment_modules item=payment_module} + +

    {l s='Select or type the payment method using which payment for booking will be made.'}

    +
    +
    +
    + +
    + +
    +
    +
    +
    + +
    +
    +
    +
    +
    + + {/if} {strip} {addJsDef max_child_age=$max_child_age} {addJsDef max_child_in_room=$max_child_in_room} diff --git a/controllers/admin/AdminOrdersController.php b/controllers/admin/AdminOrdersController.php index 13ce8e303..c69117ec1 100644 --- a/controllers/admin/AdminOrdersController.php +++ b/controllers/admin/AdminOrdersController.php @@ -374,19 +374,7 @@ class AdminOrdersControllerCore extends AdminController $this->errors[] = $this->l('You have to select a shop before creating new orders.'); } - $id_cart = (int)Tools::getValue('id_cart'); - $cart = new Cart((int)$id_cart); - if ($id_cart && !Validate::isLoadedObject($cart)) { - $this->errors[] = $this->l('This cart does not exists'); - } - if ($id_cart && Validate::isLoadedObject($cart) && !$cart->id_customer) { - $this->errors[] = $this->l('The cart must have a customer'); - } - if (count($this->errors) && !Tools::getValue('submitAddorder')) { - return false; - } - - // check page is whether ad new order page or order detail page + // check page is new order creation page and cart id is set if ((Tools::isSubmit('addorder') && ($id_cart = Tools::getValue('cart_id'))) || (Tools::isSubmit('submitAddOrder') && ($id_cart = Tools::getValue('id_cart'))) ) { @@ -395,15 +383,10 @@ class AdminOrdersControllerCore extends AdminController $cart_order_exists = $cart->orderExists(); if (!$cart_order_exists) { $this->context->cart = $cart; - if ($this->context->employee->isSuperAdmin()) { - $backOrderConfigKey = 'PS_BACKDATE_ORDER_SUPERADMIN'; - } else { - $backOrderConfigKey = 'PS_BACKDATE_ORDER_EMPLOYEES'; - } - if (!Configuration::get($backOrderConfigKey)) { - $objHotelCartBookingData = new HotelCartBookingData(); - $objHotelCartBookingData->removeBackdateRoomsFromCart($this->context->cart->id); - } + + // validate cart for removing invalid data from cart before new order creation + $this->errors = array_merge($this->errors, HotelCartBookingData::validateCartBookings()); + $this->context->currency = new Currency((int)$cart->id_currency); $cart_detail_data = array(); $cart_detail_data_obj = new HotelCartBookingData(); @@ -420,61 +403,69 @@ class AdminOrdersControllerCore extends AdminController $this->context->smarty->assign('cart_normal_data', $normalCartProduct); } + if (empty($cart_detail_data) && empty($normalCartProduct)) { + // if no rooms added in the cart and user visits add order page then redirect to BOOK NOW page + Tools::redirectAdmin($this->context->link->getAdminLink('AdminHotelRoomsBooking')); + } + + $payment_modules = array(); + foreach (PaymentModule::getInstalledPaymentModules() as $p_module) { + $payment_modules[] = Module::getInstanceById((int)$p_module['id_module']); + } + + $paymentTypes = array(); + foreach ($this->getPaymentsTypes() as $paymentType) { + if ($paymentType['value'] != OrderPayment::PAYMENT_TYPE_REMOTE_PAYMENT) { + $paymentTypes[] = $paymentType; + } + } + + $occupancyRequiredForBooking = false; + if (Configuration::get('PS_BACKOFFICE_ROOM_BOOKING_TYPE') == HotelBookingDetail::PS_ROOM_UNIT_SELECTION_TYPE_OCCUPANCY) { + $occupancyRequiredForBooking = true; + } + $objHotelAdvancedPayment = new HotelAdvancedPayment(); $this->context->smarty->assign(array( 'order_total' => $cart->getOrderTotal(true), 'is_advance_payment_active' => $objHotelAdvancedPayment->isAdvancePaymentAvailableForCurrentCart(), 'advance_payment_amount_without_tax' => $cart->getOrderTotal(false, Cart::ADVANCE_PAYMENT), 'advance_payment_amount_with_tax' => $cart->getOrderTotal(true, Cart::ADVANCE_PAYMENT), + 'cart' => $cart, + 'currencies' => Currency::getCurrenciesByIdShop(Context::getContext()->shop->id), + 'langs' => Language::getLanguages(true, Context::getContext()->shop->id), + 'payment_modules' => $payment_modules, + 'payment_types' => $paymentTypes, + 'currency' => new Currency((int)$cart->id_currency), + 'max_child_in_room' => Configuration::get('WK_GLOBAL_MAX_CHILD_IN_ROOM'), + 'max_child_age' => Configuration::get('WK_GLOBAL_CHILD_MAX_AGE'), + 'occupancy_required_for_booking' => $occupancyRequiredForBooking, )); - if (empty($cart_detail_data) && empty($normalCartProduct)) { - // if no rooms added in the cart and user visits add order page then redirect to BOOK NOW page - Tools::redirectAdmin($this->context->link->getAdminLink('AdminHotelRoomsBooking')); - } + } else { + Tools::redirectAdmin($this->context->link->getAdminLink('AdminHotelRoomsBooking')); } $this->context->smarty->assign('is_order_created', $cart_order_exists); + } else { + Tools::redirectAdmin($this->context->link->getAdminLink('AdminHotelRoomsBooking')); } + //end parent::renderForm(); unset($this->toolbar_btn['save']); $this->addJqueryPlugin(array('autocomplete', 'fancybox', 'typewatch')); - $payment_modules = array(); - foreach (PaymentModule::getInstalledPaymentModules() as $p_module) { - $payment_modules[] = Module::getInstanceById((int)$p_module['id_module']); - } - - $paymentTypes = array(); - foreach ($this->getPaymentsTypes() as $paymentType) { - if ($paymentType['value'] != OrderPayment::PAYMENT_TYPE_REMOTE_PAYMENT) { - $paymentTypes[] = $paymentType; - } - } - - $occupancyRequiredForBooking = false; - if (Configuration::get('PS_BACKOFFICE_ROOM_BOOKING_TYPE') == HotelBookingDetail::PS_ROOM_UNIT_SELECTION_TYPE_OCCUPANCY) { - $occupancyRequiredForBooking = true; - } - $this->context->smarty->assign(array( + 'hasCartErrors' => count($this->errors) ? 1 : 0, 'recyclable_pack' => (int)Configuration::get('PS_RECYCLABLE_PACK'), 'gift_wrapping' => (int)Configuration::get('PS_GIFT_WRAPPING'), - 'cart' => $cart, - 'currencies' => Currency::getCurrenciesByIdShop(Context::getContext()->shop->id), - 'langs' => Language::getLanguages(true, Context::getContext()->shop->id), - 'payment_modules' => $payment_modules, - 'payment_types' => $paymentTypes, 'show_toolbar' => $this->show_toolbar, 'toolbar_btn' => $this->toolbar_btn, 'toolbar_scroll' => $this->toolbar_scroll, 'PS_CATALOG_MODE' => Configuration::get('PS_CATALOG_MODE'), 'title' => array($this->l('Orders'), $this->l('Create order')), - 'currency' => new Currency((int)$cart->id_currency), - 'max_child_in_room' => Configuration::get('WK_GLOBAL_MAX_CHILD_IN_ROOM'), - 'max_child_age' => Configuration::get('WK_GLOBAL_CHILD_MAX_AGE'), - 'occupancy_required_for_booking' => $occupancyRequiredForBooking, )); + $this->content .= $this->createTemplate('form.tpl')->fetch(); } @@ -1713,23 +1704,6 @@ class AdminOrdersControllerCore extends AdminController } } - // Validate if booking dates are allowed - if ($this->context->employee->isSuperAdmin()) { - $backOrderConfigKey = 'PS_BACKDATE_ORDER_SUPERADMIN'; - } else { - $backOrderConfigKey = 'PS_BACKDATE_ORDER_EMPLOYEES'; - } - if (!Configuration::get($backOrderConfigKey)) { - $objCartBookingData = new HotelCartBookingData(); - if ($cartBookingData = $objCartBookingData->getCartCurrentDataByCartId($cart->id)) { - foreach ($cartBookingData as $cartRoom) { - if (strtotime($cartRoom['date_from']) < strtotime(date('Y-m-d'))) { - $this->errors[] = Tools::displayError('You cannot book rooms before today date.'); - } - } - } - } - if (!count($this->errors)) { $this->context->currency = new Currency((int) $objCart->id_currency); $this->context->customer = new Customer((int) $objCart->id_customer); diff --git a/controllers/front/OrderOpcController.php b/controllers/front/OrderOpcController.php index 465c6a7ca..9de4e2b55 100644 --- a/controllers/front/OrderOpcController.php +++ b/controllers/front/OrderOpcController.php @@ -424,7 +424,7 @@ class OrderOpcControllerCore extends ParentOrderController public function initContent() { // validate room types before payment by customer - $orderRestrictErr = HotelCartBookingData::validateCartBookings(); + $this->errors = HotelCartBookingData::validateCartBookings(); parent::initContent(); @@ -492,7 +492,7 @@ class OrderOpcControllerCore extends ParentOrderController // $objCurrency = new Currency(Configuration::get('PS_CURRENCY_DEFAULT')); $this->context->smarty->assign( array( - 'orderRestrictErr' => $orderRestrictErr, + 'orderRestrictErr' => count($this->errors) ? 0 : 1, // 'allDemands' => $allDemands, // 'defaultcurrencySign' => $objCurrency->sign, 'THEME_DIR' => _THEME_DIR_, diff --git a/modules/hotelreservationsystem/classes/HotelCartBookingData.php b/modules/hotelreservationsystem/classes/HotelCartBookingData.php index 9e9028b49..59e2bdd9e 100644 --- a/modules/hotelreservationsystem/classes/HotelCartBookingData.php +++ b/modules/hotelreservationsystem/classes/HotelCartBookingData.php @@ -925,26 +925,34 @@ class HotelCartBookingData extends ObjectModel return true; } + // validate cart data if not available then remove from cart public static function validateCartBookings() { $context = Context::getContext(); $errors = array(); $objModule = Module::getInstanceByName('hotelreservationsystem'); + // For admin cart validations use this variable + $forAdminCart = 0; + if (isset($context->employee->id)) { + $forAdminCart = 1; + } + // validate room types if bookable from front office if ($cartProducts = $context->cart->getProducts()) { - $objHotelCartBookingData = new HotelCartBookingData(); - foreach ($cartProducts as $product) { - if ($product['booking_product'] && !$product['show_at_front']) { - $objHotelCartBookingData->deleteCartBookingData($context->cart->id, $product['id_product']); + if (!$forAdminCart) { + $objHotelCartBookingData = new HotelCartBookingData(); + foreach ($cartProducts as $product) { + if ($product['booking_product'] && !$product['show_at_front']) { + $objHotelCartBookingData->deleteCartBookingData($context->cart->id, $product['id_product']); + } } } } else { - $error = true; $errors[] = $objModule->l('No booking found in the cart.', 'HotelOrderRestrictDate'); } - // validate service products + // validate service products if not active not then remove from cart if ($cartProducts = $context->cart->getProducts()) { $objRoomTypeServiceProductCartDetail = new RoomTypeServiceProductCartDetail(); foreach ($cartProducts as $product) { @@ -957,6 +965,19 @@ class HotelCartBookingData extends ObjectModel } } + // for admin/employee remove bookings of the back dates from cart if not allowed + if ($forAdminCart) { + if ($context->employee->isSuperAdmin()) { + $backOrderConfigKey = 'PS_BACKDATE_ORDER_SUPERADMIN'; + } else { + $backOrderConfigKey = 'PS_BACKDATE_ORDER_EMPLOYEES'; + } + if (!Configuration::get($backOrderConfigKey)) { + $objHotelCartBookingData = new HotelCartBookingData(); + $objHotelCartBookingData->removeBackdateRoomsFromCart($context->cart->id); + } + } + // validate room types for restriction date if ($cartProducts = $context->cart->getProducts()) { $objHotelCartBookingData = new HotelCartBookingData(); @@ -979,43 +1000,43 @@ class HotelCartBookingData extends ObjectModel } foreach ($cartData as $roomData) { - if ($maxOrderDate = HotelOrderRestrictDate::getMaxOrderDate($roomData['id_hotel'])) { - if (strtotime('-1 day', strtotime($maxOrderDate)) < strtotime($roomData['date_from']) - || strtotime($maxOrderDate) < strtotime($roomData['date_to']) - ) { - $objHotelBranchInformation = new HotelBranchInformation( - $roomData['id_hotel'], - $context->language->id - ); - $errors[] = sprintf( - 'You can not book rooms for hotel \'%s\' after date %s. Please remove rooms from %s - %s to proceed.', - $objHotelBranchInformation->hotel_name, - Tools::displayDate($maxOrderDate), - Tools::displayDate($roomData['date_from']), - Tools::displayDate($roomData['date_to']) - ); - $error = true; + if (!$forAdminCart) { + if ($maxOrderDate = HotelOrderRestrictDate::getMaxOrderDate($roomData['id_hotel'])) { + if (strtotime('-1 day', strtotime($maxOrderDate)) < strtotime($roomData['date_from']) + || strtotime($maxOrderDate) < strtotime($roomData['date_to']) + ) { + $objHotelBranchInformation = new HotelBranchInformation( + $roomData['id_hotel'], + $context->language->id + ); + $errors[] = sprintf( + 'You can not book rooms for hotel \'%s\' after date %s. Please remove rooms from %s - %s to proceed.', + $objHotelBranchInformation->hotel_name, + Tools::displayDate($maxOrderDate), + Tools::displayDate($roomData['date_from']), + Tools::displayDate($roomData['date_to']) + ); + } } - } - $preparationTime = HotelOrderRestrictDate::getPreparationTime($roomData['id_hotel']); - if ($preparationTime !== false) { - $minOrderDate = date('Y-m-d', strtotime('+'. ($preparationTime) .' days')); - if (strtotime($minOrderDate) > strtotime($roomData['date_from']) - || strtotime($minOrderDate . ' +1 day')> strtotime($roomData['date_to']) - ) { - $objHotelBranchInformation = new HotelBranchInformation( - $roomData['id_hotel'], - $context->language->id - ); - $errors[] = sprintf( - 'You can not book rooms for hotel \'%s\' before date %s. Please remove rooms from %s - %s to proceed.', - $objHotelBranchInformation->hotel_name, - Tools::displayDate($minOrderDate), - Tools::displayDate($roomData['date_from']), - Tools::displayDate($roomData['date_to']) - ); - $error = true; + $preparationTime = HotelOrderRestrictDate::getPreparationTime($roomData['id_hotel']); + if ($preparationTime !== false) { + $minOrderDate = date('Y-m-d', strtotime('+'. ($preparationTime) .' days')); + if (strtotime($minOrderDate) > strtotime($roomData['date_from']) + || strtotime($minOrderDate . ' +1 day')> strtotime($roomData['date_to']) + ) { + $objHotelBranchInformation = new HotelBranchInformation( + $roomData['id_hotel'], + $context->language->id + ); + $errors[] = sprintf( + 'You can not book rooms for hotel \'%s\' before date %s. Please remove rooms from %s - %s to proceed.', + $objHotelBranchInformation->hotel_name, + Tools::displayDate($minOrderDate), + Tools::displayDate($roomData['date_from']), + Tools::displayDate($roomData['date_to']) + ); + } } } @@ -1027,32 +1048,27 @@ class HotelCartBookingData extends ObjectModel 'only_search_data' => 1, ); $bookingSearchData = $objHotelBookingDetail->dataForFrontSearch($bookingParams); - $isRmBooked = 0; + $isRoomBooked = 0; if (count($bookingSearchData['rm_data'][$product['id_product']]['data']['available']) < count($roomData['id_rms'])) { foreach ($roomData['id_rms'] as $searchRoomData) { - if($isRmBooked = $objHotelBookingDetail->chechRoomBooked($searchRoomData, $roomData['date_from'], $roomData['date_to'])){ + if($isRoomBooked = $objHotelBookingDetail->chechRoomBooked($searchRoomData, $roomData['date_from'], $roomData['date_to'])){ break; } } - if ($isRmBooked) { + if ($isRoomBooked) { $errors[] = sprintf($objModule->l('The Room \'%s\' has been booked by another customer from \'%s\' to \'%s\' Please remove rooms from cart to proceed', 'HotelOrderRestrictDate'), $product['name'], date('d-m-Y', strtotime($roomData['date_from'])), date('d-m-Y', strtotime($roomData['date_to']))); - $error = true; } else { $errors[] = sprintf($objModule->l('The Room \'%s\' is no longer avalable from \'%s\' to \'%s\' Please remove rooms from cart to proceed', 'HotelOrderRestrictDate'), $product['name'], date('d-m-Y', strtotime($roomData['date_from'])), date('d-m-Y', strtotime($roomData['date_to']))); - $error = true; } } } } } else { - $error = true; $errors[] = $objModule->l('You can not book rooms from "', 'HotelOrderRestrictDate'). $product['name'] .$objModule->l('". Please remove rooms from "', 'HotelOrderRestrictDate'). $product['name'] . $objModule->l('" from cart to proceed.', 'HotelOrderRestrictDate'); } } } - $context->controller->errors = array_merge($context->controller->errors, $errors); - return $errors; } diff --git a/modules/hotelreservationsystem/classes/RoomTypeServiceProductCartDetail.php b/modules/hotelreservationsystem/classes/RoomTypeServiceProductCartDetail.php index 5fad5a10b..e40082572 100644 --- a/modules/hotelreservationsystem/classes/RoomTypeServiceProductCartDetail.php +++ b/modules/hotelreservationsystem/classes/RoomTypeServiceProductCartDetail.php @@ -94,7 +94,7 @@ class RoomTypeServiceProductCartDetail extends ObjectModel )) { $updateQty = $product['quantity']; if (Product::getProductPriceCalculation($product['id_product']) == Product::PRICE_CALCULATION_METHOD_PER_DAY) { - $objHotelCartBookingData = new HotelCartBookingData($idHtlCartData); + $objHotelCartBookingData = new HotelCartBookingData($htlCartBookingId); $numdays = HotelHelper::getNumberOfDays($objHotelCartBookingData->date_from, $objHotelCartBookingData->date_to); $updateQty *= $numdays; } diff --git a/modules/hotelreservationsystem/controllers/admin/AdminHotelRoomsBookingController.php b/modules/hotelreservationsystem/controllers/admin/AdminHotelRoomsBookingController.php index 0edf2d641..58115fe8f 100644 --- a/modules/hotelreservationsystem/controllers/admin/AdminHotelRoomsBookingController.php +++ b/modules/hotelreservationsystem/controllers/admin/AdminHotelRoomsBookingController.php @@ -42,6 +42,9 @@ class AdminHotelRoomsBookingController extends ModuleAdminController $objCart = new Cart($this->context->cookie->id_cart); if (Validate::isLoadedObject($objCart) && !$objCart->orderExists()) { $this->context->cart = $objCart; + + // validate cart for removing invalid data from cart + HotelCartBookingData::validateCartBookings(); } else { $this->context->cookie->id_cart = 0; // remove invalid id_cart $this->context->cart = new Cart(); @@ -61,17 +64,6 @@ class AdminHotelRoomsBookingController extends ModuleAdminController $objCustomer->deleted = 0; $objCustomer->logged = 0; $objCustomer->id_guest = (int) $this->context->cookie->id_guest; - - $this->context->customer = $objCustomer; - if ($this->context->employee->isSuperAdmin()) { - $backOrderConfigKey = 'PS_BACKDATE_ORDER_SUPERADMIN'; - } else { - $backOrderConfigKey = 'PS_BACKDATE_ORDER_EMPLOYEES'; - } - if (!Configuration::get($backOrderConfigKey)) { - $htlCart = new HotelCartBookingData(); - $htlCart->removeBackdateRoomsFromCart($this->context->cart->id); - } } protected function createNewCart() From 15db13081bd2fd3f7e48bbae365d4a255c3ad57f Mon Sep 17 00:00:00 2001 From: Sumit Panwar Date: Sat, 27 Apr 2024 13:03:46 +0530 Subject: [PATCH 19/53] Fixxed:: Issues in the process of Book now from back office --- .../template/controllers/orders/form.tpl | 2293 +++++++++++++++++ .../template/controllers/orders/form.tpl | 986 ++++--- controllers/admin/AdminOrdersController.php | 11 +- 3 files changed, 2787 insertions(+), 503 deletions(-) create mode 100644 admin/adminhtl/themes/default/template/controllers/orders/form.tpl diff --git a/admin/adminhtl/themes/default/template/controllers/orders/form.tpl b/admin/adminhtl/themes/default/template/controllers/orders/form.tpl new file mode 100644 index 000000000..933d0a6cc --- /dev/null +++ b/admin/adminhtl/themes/default/template/controllers/orders/form.tpl @@ -0,0 +1,2293 @@ +{* +* 2007-2017 PrestaShop +* +* NOTICE OF LICENSE +* +* This source file is subject to the Academic Free License (AFL 3.0) +* that is bundled with this package in the file LICENSE.txt. +* It is also available through the world-wide-web at this URL: +* http://opensource.org/licenses/afl-3.0.php +* If you did not receive a copy of the license and are unable to +* obtain it through the world-wide-web, please send an email +* to license@prestashop.com so we can send you a copy immediately. +* +* DISCLAIMER +* +* Do not edit or add to this file if you wish to upgrade PrestaShop to newer +* versions in the future. If you wish to customize PrestaShop for your +* needs please refer to http://www.prestashop.com for more information. +* +* @author PrestaShop SA +* @copyright 2007-2017 PrestaShop SA +* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) +* International Registered Trademark & Property of PrestaShop SA +*} + + +
    {block name="leadin"}{/block}
    +{include file='controllers/orders/_current_cart_details_data.tpl'} +
    +
    + + {l s='Customer'} +
    +
    + +
    +
    +
    +
    + + + + +
    +
    + +
    +
    +
    +
    +
    +
    + {*
    + + + +
    +
    + + + + + + + + + + + +
    {l s='ID'}{l s='Date'}{l s='Total'}
    +
    +
    + + + + + + + + + + + + + + +
    {l s='ID'}{l s='Date'}{l s='Products'}{l s='Total paid'}{l s='Payment'}{l s='Status'}
    +
    +
    +
    -->*} +
    + + +{strip} + {addJsDef max_child_age=$max_child_age} + {addJsDef max_child_in_room=$max_child_in_room} + {addJsDefL name='select_age_txt'}{l s='Select age' js=1}{/addJsDefL} + {addJsDefL name='under_1_age'}{l s='Under 1' js=1}{/addJsDefL} + {addJsDefL name='room_txt'}{l s='Room' js=1}{/addJsDefL} + {addJsDefL name='rooms_txt'}{l s='Rooms' js=1}{/addJsDefL} + {addJsDefL name='remove_txt'}{l s='Remove' js=1}{/addJsDefL} + {addJsDefL name='adult_txt'}{l s='Adult' js=1}{/addJsDefL} + {addJsDefL name='adults_txt'}{l s='Adults' js=1}{/addJsDefL} + {addJsDefL name='child_txt'}{l s='Child' js=1}{/addJsDefL} + {addJsDefL name='children_txt'}{l s='Children' js=1}{/addJsDefL} + {addJsDefL name='below_txt'}{l s='Below' js=1}{/addJsDefL} + {addJsDefL name='years_txt'}{l s='years' js=1}{/addJsDefL} + {addJsDefL name='all_children_txt'}{l s='All Children' js=1}{/addJsDefL} + {addJsDefL name='max_occupancy_reached_txt'}{l s='Maximum room occupancy reached' js=1}{/addJsDefL} + {addJsDefL name='max_adults_txt'}{l s='Maximum adult occupancy reached' js=1}{/addJsDefL} + {addJsDefL name='max_children_txt'}{l s='Maximum children occupancy reached' js=1}{/addJsDefL} + {addJsDefL name='no_children_allowed_txt'}{l s='Only adults can be accommodated' js=1}{/addJsDefL} + {addJsDefL name='invalid_occupancy_txt'}{l s='Invalid occupancy(adults/children) found.' js=1}{/addJsDefL} + + +{/strip} + +
    +
    +
    diff --git a/admin/themes/default/template/controllers/orders/form.tpl b/admin/themes/default/template/controllers/orders/form.tpl index dc225fd9a..584276e38 100644 --- a/admin/themes/default/template/controllers/orders/form.tpl +++ b/admin/themes/default/template/controllers/orders/form.tpl @@ -1732,258 +1732,84 @@
    {block name="leadin"}{/block}
    {include file='controllers/orders/_current_cart_details_data.tpl'} {* If cart has errors the do not allow to proceed with this cart *} - {if !$hasCartErrors} -
    -
    - - {l s='Customer'} -
    -
    - -
    -
    -
    -
    - - - - -
    -
    - -
    -
    -
    -
    -
    -
    - {*
    - - - -
    -
    - - - - - - - - - - - -
    {l s='ID'}{l s='Date'}{l s='Total'}
    -
    -
    - - - - - - - - - - - - - - -
    {l s='ID'}{l s='Date'}{l s='Products'}{l s='Total paid'}{l s='Payment'}{l s='Status'}
    -
    -
    -
    -->*} +
    +
    + + {l s='Customer'}
    - -