mirror of
https://github.com/alextselegidis/easyappointments.git
synced 2024-11-10 10:02:33 +03:00
Refactor the booking related JS files so that they become standalone modules.
This commit is contained in:
parent
795eccb165
commit
43ad017d7a
5 changed files with 228 additions and 225 deletions
|
@ -176,6 +176,7 @@ class Booking extends EA_Controller {
|
||||||
}
|
}
|
||||||
|
|
||||||
script_vars([
|
script_vars([
|
||||||
|
'manage_mode' => $manage_mode,
|
||||||
'available_services' => $available_services,
|
'available_services' => $available_services,
|
||||||
'available_providers' => $available_providers,
|
'available_providers' => $available_providers,
|
||||||
'date_format' => $date_format,
|
'date_format' => $date_format,
|
||||||
|
@ -354,7 +355,7 @@ class Booking extends EA_Controller {
|
||||||
/**
|
/**
|
||||||
* Register the appointment to the database.
|
* Register the appointment to the database.
|
||||||
*/
|
*/
|
||||||
public function ajax_register_appointment()
|
public function register()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|
|
@ -107,7 +107,6 @@
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
$(function () {
|
$(function () {
|
||||||
FrontendBook.initialize(true, GlobalVariables.manageMode);
|
|
||||||
GeneralFunctions.enableLanguageSelection($('#select-language'));
|
GeneralFunctions.enableLanguageSelection($('#select-language'));
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -49,7 +49,11 @@
|
||||||
|
|
||||||
<?php section('scripts') ?>
|
<?php section('scripts') ?>
|
||||||
|
|
||||||
<script src="<?= asset_url('assets/js/pages/frontend_book_api.js') ?>"></script>
|
<script src="<?= asset_url('assets/js/utils/date.js') ?>"></script>
|
||||||
<script src="<?= asset_url('assets/js/pages/frontend_book.js') ?>"></script>
|
<script src="<?= asset_url('assets/js/utils/message.js') ?>"></script>
|
||||||
|
<script src="<?= asset_url('assets/js/utils/validation.js') ?>"></script>
|
||||||
|
<script src="<?= asset_url('assets/js/utils/url.js') ?>"></script>
|
||||||
|
<script src="<?= asset_url('assets/js/http/booking_http_client.js') ?>"></script>
|
||||||
|
<script src="<?= asset_url('assets/js/pages/booking.js') ?>"></script>
|
||||||
|
|
||||||
<?php section('scripts') ?>
|
<?php section('scripts') ?>
|
||||||
|
|
|
@ -9,21 +9,17 @@
|
||||||
* @since v1.0.0
|
* @since v1.0.0
|
||||||
* ---------------------------------------------------------------------------- */
|
* ---------------------------------------------------------------------------- */
|
||||||
|
|
||||||
window.FrontendBookApi = window.FrontendBookApi || {};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Frontend Book API
|
* Booking HTTP Client
|
||||||
*
|
*
|
||||||
* This module serves as the API consumer for the booking wizard of the app.
|
* This module serves as the API consumer for the booking wizard of the app.
|
||||||
*
|
*
|
||||||
* @module FrontendBookApi
|
* Old Name: FrontendBookApi
|
||||||
*/
|
*/
|
||||||
(function (exports) {
|
App.Http.Booking = (function () {
|
||||||
'use strict';
|
let unavailableDatesBackup;
|
||||||
|
let selectedDateStringBackup;
|
||||||
var unavailableDatesBackup;
|
let processingUnavailabilities = false;
|
||||||
var selectedDateStringBackup;
|
|
||||||
var processingUnavailabilities = false;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get Available Hours
|
* Get Available Hours
|
||||||
|
@ -33,47 +29,47 @@ window.FrontendBookApi = window.FrontendBookApi || {};
|
||||||
*
|
*
|
||||||
* @param {String} selectedDate The selected date of the available hours we need.
|
* @param {String} selectedDate The selected date of the available hours we need.
|
||||||
*/
|
*/
|
||||||
exports.getAvailableHours = function (selectedDate) {
|
function getAvailableHours(selectedDate) {
|
||||||
$('#available-hours').empty();
|
$('#available-hours').empty();
|
||||||
|
|
||||||
// Find the selected service duration (it is going to be send within the "data" object).
|
// Find the selected service duration (it is going to be send within the "data" object).
|
||||||
var serviceId = $('#select-service').val();
|
const serviceId = $('#select-service').val();
|
||||||
|
|
||||||
// Default value of duration (in minutes).
|
// Default value of duration (in minutes).
|
||||||
var serviceDuration = 15;
|
let serviceDuration = 15;
|
||||||
|
|
||||||
var service = GlobalVariables.availableServices.find(function (availableService) {
|
const service = App.Vars.available_services.find(
|
||||||
return Number(availableService.id) === Number(serviceId);
|
(availableService) => Number(availableService.id) === Number(serviceId)
|
||||||
});
|
);
|
||||||
|
|
||||||
if (service) {
|
if (service) {
|
||||||
serviceDuration = service.duration;
|
serviceDuration = service.duration;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the manage mode is true then the appointment's start date should return as available too.
|
// If the manage mode is true then the appointment's start date should return as available too.
|
||||||
var appointmentId = FrontendBook.manageMode ? GlobalVariables.appointmentData.id : null;
|
const appointmentId = App.Pages.Booking.manageMode ? App.Vars.appointment_data.id : null;
|
||||||
|
|
||||||
// Make ajax post request and get the available hours.
|
// Make ajax post request and get the available hours.
|
||||||
var url = GlobalVariables.baseUrl + '/index.php/booking/ajax_get_available_hours';
|
const url = App.Utils.Url.siteUrl('booking/ajax_get_available_hours');
|
||||||
|
|
||||||
var data = {
|
const data = {
|
||||||
csrf_token: GlobalVariables.csrfToken,
|
csrf_token: App.Vars.csrf_token,
|
||||||
service_id: $('#select-service').val(),
|
service_id: $('#select-service').val(),
|
||||||
provider_id: $('#select-provider').val(),
|
provider_id: $('#select-provider').val(),
|
||||||
selected_date: selectedDate,
|
selected_date: selectedDate,
|
||||||
service_duration: serviceDuration,
|
service_duration: serviceDuration,
|
||||||
manage_mode: FrontendBook.manageMode,
|
manage_mode: App.Pages.Booking.manageMode,
|
||||||
appointment_id: appointmentId
|
appointment_id: appointmentId
|
||||||
};
|
};
|
||||||
|
|
||||||
$.post(url, data).done(function (response) {
|
$.post(url, data).done((response) => {
|
||||||
// The response contains the available hours for the selected provider and service. Fill the available
|
// The response contains the available hours for the selected provider and service. Fill the available
|
||||||
// hours div with response data.
|
// hours div with response data.
|
||||||
if (response.length > 0) {
|
if (response.length > 0) {
|
||||||
var providerId = $('#select-provider').val();
|
let providerId = $('#select-provider').val();
|
||||||
|
|
||||||
if (providerId === 'any-provider') {
|
if (providerId === 'any-provider') {
|
||||||
for (var availableProvider of GlobalVariables.availableProviders) {
|
for (const availableProvider of App.Vars.available_providers) {
|
||||||
if (availableProvider.services.indexOf(Number(serviceId)) !== -1) {
|
if (availableProvider.services.indexOf(Number(serviceId)) !== -1) {
|
||||||
providerId = availableProvider.id; // Use first available provider.
|
providerId = availableProvider.id; // Use first available provider.
|
||||||
break;
|
break;
|
||||||
|
@ -81,20 +77,20 @@ window.FrontendBookApi = window.FrontendBookApi || {};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var provider = GlobalVariables.availableProviders.find(function (availableProvider) {
|
const provider = App.Vars.available_providers.find(
|
||||||
return Number(providerId) === Number(availableProvider.id);
|
(availableProvider) => Number(providerId) === Number(availableProvider.id)
|
||||||
});
|
);
|
||||||
|
|
||||||
if (!provider) {
|
if (!provider) {
|
||||||
throw new Error('Could not find provider.');
|
throw new Error('Could not find provider.');
|
||||||
}
|
}
|
||||||
|
|
||||||
var providerTimezone = provider.timezone;
|
const providerTimezone = provider.timezone;
|
||||||
var selectedTimezone = $('#select-timezone').val();
|
const selectedTimezone = $('#select-timezone').val();
|
||||||
var timeFormat = GlobalVariables.timeFormat === 'regular' ? 'h:mm a' : 'HH:mm';
|
const timeFormat = App.Vars.time_format === 'regular' ? 'h:mm a' : 'HH:mm';
|
||||||
|
|
||||||
response.forEach(function (availableHour) {
|
response.forEach((availableHour) => {
|
||||||
var availableHourMoment = moment
|
const availableHourMoment = moment
|
||||||
.tz(selectedDate + ' ' + availableHour + ':00', providerTimezone)
|
.tz(selectedDate + ' ' + availableHour + ':00', providerTimezone)
|
||||||
.tz(selectedTimezone);
|
.tz(selectedTimezone);
|
||||||
|
|
||||||
|
@ -113,30 +109,29 @@ window.FrontendBookApi = window.FrontendBookApi || {};
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
if (FrontendBook.manageMode) {
|
if (App.Pages.Booking.manageMode) {
|
||||||
// Set the appointment's start time as the default selection.
|
// Set the appointment's start time as the default selection.
|
||||||
$('.available-hour')
|
$('.available-hour')
|
||||||
.removeClass('selected-hour')
|
.removeClass('selected-hour')
|
||||||
.filter(function () {
|
.filter(
|
||||||
return (
|
(index, availableHourEl) =>
|
||||||
$(this).text() ===
|
$(availableHourEl).text() ===
|
||||||
moment(GlobalVariables.appointmentData.start_datetime).format(timeFormat)
|
moment(App.Vars.appointment_data.start_datetime).format(timeFormat)
|
||||||
);
|
)
|
||||||
})
|
|
||||||
.addClass('selected-hour');
|
.addClass('selected-hour');
|
||||||
} else {
|
} else {
|
||||||
// Set the first available hour as the default selection.
|
// Set the first available hour as the default selection.
|
||||||
$('.available-hour:eq(0)').addClass('selected-hour');
|
$('.available-hour:eq(0)').addClass('selected-hour');
|
||||||
}
|
}
|
||||||
|
|
||||||
FrontendBook.updateConfirmFrame();
|
App.Pages.Booking.updateConfirmFrame();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!$('.available-hour').length) {
|
if (!$('.available-hour').length) {
|
||||||
$('#available-hours').text(App.Lang.no_available_hours);
|
$('#available-hours').text(App.Lang.no_available_hours);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Register an appointment to the database.
|
* Register an appointment to the database.
|
||||||
|
@ -144,8 +139,8 @@ window.FrontendBookApi = window.FrontendBookApi || {};
|
||||||
* This method will make an ajax call to the appointments controller that will register
|
* This method will make an ajax call to the appointments controller that will register
|
||||||
* the appointment to the database.
|
* the appointment to the database.
|
||||||
*/
|
*/
|
||||||
exports.registerAppointment = function () {
|
function registerAppointment() {
|
||||||
var $captchaText = $('.captcha-text');
|
const $captchaText = $('.captcha-text');
|
||||||
|
|
||||||
if ($captchaText.length > 0) {
|
if ($captchaText.length > 0) {
|
||||||
$captchaText.removeClass('is-invalid');
|
$captchaText.removeClass('is-invalid');
|
||||||
|
@ -155,10 +150,10 @@ window.FrontendBookApi = window.FrontendBookApi || {};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var formData = JSON.parse($('input[name="post_data"]').val());
|
const formData = JSON.parse($('input[name="post_data"]').val());
|
||||||
|
|
||||||
var data = {
|
const data = {
|
||||||
csrf_token: GlobalVariables.csrfToken,
|
csrf_token: App.Vars.csrf_token,
|
||||||
post_data: formData
|
post_data: formData
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -166,20 +161,20 @@ window.FrontendBookApi = window.FrontendBookApi || {};
|
||||||
data.captcha = $captchaText.val();
|
data.captcha = $captchaText.val();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (GlobalVariables.manageMode) {
|
if (App.Vars.manage_mode) {
|
||||||
data.exclude_appointment_id = GlobalVariables.appointmentData.id;
|
data.exclude_appointment_id = App.Vars.appointment_data.id;
|
||||||
}
|
}
|
||||||
|
|
||||||
var url = GlobalVariables.baseUrl + '/index.php/booking/ajax_register_appointment';
|
const url = App.Utils.Url.siteUrl('booking/register');
|
||||||
|
|
||||||
var $layer = $('<div/>');
|
const $layer = $('<div/>');
|
||||||
|
|
||||||
$.ajax({
|
$.ajax({
|
||||||
url: url,
|
url: url,
|
||||||
method: 'post',
|
method: 'post',
|
||||||
data: data,
|
data: data,
|
||||||
dataType: 'json',
|
dataType: 'json',
|
||||||
beforeSend: function (jqxhr, settings) {
|
beforeSend: () => {
|
||||||
$layer.appendTo('body').css({
|
$layer.appendTo('body').css({
|
||||||
background: 'white',
|
background: 'white',
|
||||||
position: 'fixed',
|
position: 'fixed',
|
||||||
|
@ -191,11 +186,11 @@ window.FrontendBookApi = window.FrontendBookApi || {};
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.done(function (response) {
|
.done((response) => {
|
||||||
if (response.captcha_verification === false) {
|
if (response.captcha_verification === false) {
|
||||||
$('#captcha-hint').text(App.Lang.captcha_is_wrong).fadeTo(400, 1);
|
$('#captcha-hint').text(App.Lang.captcha_is_wrong).fadeTo(400, 1);
|
||||||
|
|
||||||
setTimeout(function () {
|
setTimeout(() => {
|
||||||
$('#captcha-hint').fadeTo(400, 0);
|
$('#captcha-hint').fadeTo(400, 0);
|
||||||
}, 3000);
|
}, 3000);
|
||||||
|
|
||||||
|
@ -206,16 +201,15 @@ window.FrontendBookApi = window.FrontendBookApi || {};
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
window.location.href =
|
window.location.href = App.Utils.Url.siteUrl('booking_confirmation/of/' + response.appointment_hash);
|
||||||
GlobalVariables.baseUrl + '/index.php/booking_confirmation/of/' + response.appointment_hash;
|
|
||||||
})
|
})
|
||||||
.fail(function (jqxhr, textStatus, errorThrown) {
|
.fail(() => {
|
||||||
$('.captcha-title button').trigger('click');
|
$('.captcha-title button').trigger('click');
|
||||||
})
|
})
|
||||||
.always(function () {
|
.always(() => {
|
||||||
$layer.remove();
|
$layer.remove();
|
||||||
});
|
});
|
||||||
};
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the unavailable dates of a provider.
|
* Get the unavailable dates of a provider.
|
||||||
|
@ -228,7 +222,7 @@ window.FrontendBookApi = window.FrontendBookApi || {};
|
||||||
* @param {Number} serviceId The selected service ID.
|
* @param {Number} serviceId The selected service ID.
|
||||||
* @param {String} selectedDateString Y-m-d value of the selected date.
|
* @param {String} selectedDateString Y-m-d value of the selected date.
|
||||||
*/
|
*/
|
||||||
exports.getUnavailableDates = function (providerId, serviceId, selectedDateString) {
|
function getUnavailableDates(providerId, serviceId, selectedDateString) {
|
||||||
if (processingUnavailabilities) {
|
if (processingUnavailabilities) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -237,16 +231,16 @@ window.FrontendBookApi = window.FrontendBookApi || {};
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var appointmentId = FrontendBook.manageMode ? GlobalVariables.appointmentData.id : null;
|
const appointmentId = App.Pages.Booking.manageMode ? App.Vars.appointment_data.id : null;
|
||||||
|
|
||||||
var url = GlobalVariables.baseUrl + '/index.php/booking/ajax_get_unavailable_dates';
|
const url = App.Utils.Url.siteUrl('booking/ajax_get_unavailable_dates');
|
||||||
|
|
||||||
var data = {
|
const data = {
|
||||||
provider_id: providerId,
|
provider_id: providerId,
|
||||||
service_id: serviceId,
|
service_id: serviceId,
|
||||||
selected_date: encodeURIComponent(selectedDateString),
|
selected_date: encodeURIComponent(selectedDateString),
|
||||||
csrf_token: GlobalVariables.csrfToken,
|
csrf_token: App.Vars.csrf_token,
|
||||||
manage_mode: FrontendBook.manageMode,
|
manage_mode: App.Pages.Booking.manageMode,
|
||||||
appointment_id: appointmentId
|
appointment_id: appointmentId
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -255,16 +249,16 @@ window.FrontendBookApi = window.FrontendBookApi || {};
|
||||||
type: 'GET',
|
type: 'GET',
|
||||||
data: data,
|
data: data,
|
||||||
dataType: 'json'
|
dataType: 'json'
|
||||||
}).done(function (response) {
|
}).done((response) => {
|
||||||
unavailableDatesBackup = response;
|
unavailableDatesBackup = response;
|
||||||
selectedDateStringBackup = selectedDateString;
|
selectedDateStringBackup = selectedDateString;
|
||||||
applyUnavailableDates(response, selectedDateString, true);
|
applyUnavailableDates(response, selectedDateString, true);
|
||||||
});
|
});
|
||||||
};
|
}
|
||||||
|
|
||||||
exports.applyPreviousUnavailableDates = function () {
|
function applyPreviousUnavailableDates() {
|
||||||
applyUnavailableDates(unavailableDatesBackup, selectedDateStringBackup);
|
applyUnavailableDates(unavailableDatesBackup, selectedDateStringBackup);
|
||||||
};
|
}
|
||||||
|
|
||||||
function applyUnavailableDates(unavailableDates, selectedDateString, setDate) {
|
function applyUnavailableDates(unavailableDates, selectedDateString, setDate) {
|
||||||
setDate = setDate || false;
|
setDate = setDate || false;
|
||||||
|
@ -272,16 +266,16 @@ window.FrontendBookApi = window.FrontendBookApi || {};
|
||||||
processingUnavailabilities = true;
|
processingUnavailabilities = true;
|
||||||
|
|
||||||
// Select first enabled date.
|
// Select first enabled date.
|
||||||
var selectedDateMoment = moment(selectedDateString);
|
const selectedDateMoment = moment(selectedDateString);
|
||||||
var selectedDate = selectedDateMoment.toDate();
|
const selectedDate = selectedDateMoment.toDate();
|
||||||
var numberOfDays = selectedDateMoment.daysInMonth();
|
const numberOfDays = selectedDateMoment.daysInMonth();
|
||||||
|
|
||||||
if (setDate && !GlobalVariables.manageMode) {
|
if (setDate && !App.Vars.manage_mode) {
|
||||||
for (var i = 1; i <= numberOfDays; i++) {
|
for (let i = 1; i <= numberOfDays; i++) {
|
||||||
var currentDate = new Date(selectedDate.getFullYear(), selectedDate.getMonth(), i);
|
const currentDate = new Date(selectedDate.getFullYear(), selectedDate.getMonth(), i);
|
||||||
if (unavailableDates.indexOf(moment(currentDate).format('YYYY-MM-DD')) === -1) {
|
if (unavailableDates.indexOf(moment(currentDate).format('YYYY-MM-DD')) === -1) {
|
||||||
$('#select-date').datepicker('setDate', currentDate);
|
$('#select-date').datepicker('setDate', currentDate);
|
||||||
FrontendBookApi.getAvailableHours(moment(currentDate).format('YYYY-MM-DD'));
|
getAvailableHours(moment(currentDate).format('YYYY-MM-DD'));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -293,7 +287,7 @@ window.FrontendBookApi = window.FrontendBookApi || {};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Grey out unavailable dates.
|
// Grey out unavailable dates.
|
||||||
$('#select-date .ui-datepicker-calendar td:not(.ui-datepicker-other-month)').each(function (index, td) {
|
$('#select-date .ui-datepicker-calendar td:not(.ui-datepicker-other-month)').each((index, td) => {
|
||||||
selectedDateMoment.set({day: index + 1});
|
selectedDateMoment.set({day: index + 1});
|
||||||
if (unavailableDates.indexOf(selectedDateMoment.format('YYYY-MM-DD')) !== -1) {
|
if (unavailableDates.indexOf(selectedDateMoment.format('YYYY-MM-DD')) !== -1) {
|
||||||
$(td).addClass('ui-datepicker-unselectable ui-state-disabled');
|
$(td).addClass('ui-datepicker-unselectable ui-state-disabled');
|
||||||
|
@ -308,32 +302,41 @@ window.FrontendBookApi = window.FrontendBookApi || {};
|
||||||
*
|
*
|
||||||
* @param {Object} consent Contains user's consents.
|
* @param {Object} consent Contains user's consents.
|
||||||
*/
|
*/
|
||||||
exports.saveConsent = function (consent) {
|
function saveConsent(consent) {
|
||||||
var url = GlobalVariables.baseUrl + '/index.php/consents/ajax_save_consent';
|
const url = App.Utils.Url.siteUrl('consents/ajax_save_consent');
|
||||||
|
|
||||||
var data = {
|
const data = {
|
||||||
csrf_token: GlobalVariables.csrfToken,
|
csrf_token: App.Vars.csrf_token,
|
||||||
consent: consent
|
consent: consent
|
||||||
};
|
};
|
||||||
|
|
||||||
$.post(url, data);
|
$.post(url, data);
|
||||||
};
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Delete personal information.
|
* Delete personal information.
|
||||||
*
|
*
|
||||||
* @param {Number} customerToken Customer unique token.
|
* @param {Number} customerToken Customer unique token.
|
||||||
*/
|
*/
|
||||||
exports.deletePersonalInformation = function (customerToken) {
|
function deletePersonalInformation(customerToken) {
|
||||||
var url = GlobalVariables.baseUrl + '/index.php/privacy/ajax_delete_personal_information';
|
const url = App.Utils.Url.siteUrl('privacy/ajax_delete_personal_information');
|
||||||
|
|
||||||
var data = {
|
const data = {
|
||||||
csrf_token: GlobalVariables.csrfToken,
|
csrf_token: App.Vars.csrf_token,
|
||||||
customer_token: customerToken
|
customer_token: customerToken
|
||||||
};
|
};
|
||||||
|
|
||||||
$.post(url, data).done(function () {
|
$.post(url, data).done(() => {
|
||||||
window.location.href = GlobalVariables.baseUrl;
|
window.location.href = App.Vars.base_url;
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
registerAppointment,
|
||||||
|
getAvailableHours,
|
||||||
|
getUnavailableDates,
|
||||||
|
applyPreviousUnavailableDates,
|
||||||
|
saveConsent,
|
||||||
|
deletePersonalInformation
|
||||||
};
|
};
|
||||||
})(window.FrontendBookApi);
|
})();
|
|
@ -9,53 +9,41 @@
|
||||||
* @since v1.0.0
|
* @since v1.0.0
|
||||||
* ---------------------------------------------------------------------------- */
|
* ---------------------------------------------------------------------------- */
|
||||||
|
|
||||||
window.FrontendBook = window.FrontendBook || {};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Frontend Book
|
* Booking Page
|
||||||
*
|
*
|
||||||
* This module contains functions that implement the book appointment page functionality. Once the "initialize" method
|
* This module contains functions that implement the book appointment page functionality. Once the "initialize" method
|
||||||
* is called the page is fully functional and can serve the appointment booking process.
|
* is called the page is fully functional and can serve the appointment booking process.
|
||||||
*
|
*
|
||||||
* @module FrontendBook
|
* Old Name: FrontendBook
|
||||||
*/
|
*/
|
||||||
(function (exports) {
|
App.Pages.Booking = (function () {
|
||||||
'use strict';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Contains terms and conditions consent.
|
* Contains terms and conditions consent.
|
||||||
*
|
*
|
||||||
* @type {Object}
|
* @type {Object}
|
||||||
*/
|
*/
|
||||||
var termsAndConditionsConsent;
|
let termsAndConditionsConsent;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Contains privacy policy consent.
|
* Contains privacy policy consent.
|
||||||
*
|
*
|
||||||
* @type {Object}
|
* @type {Object}
|
||||||
*/
|
*/
|
||||||
var privacyPolicyConsent;
|
let privacyPolicyConsent;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determines the functionality of the page.
|
* Determines the functionality of the page.
|
||||||
*
|
*
|
||||||
* @type {Boolean}
|
* @type {Boolean}
|
||||||
*/
|
*/
|
||||||
exports.manageMode = false;
|
let manageMode = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method initializes the book appointment page.
|
* This method initializes the book appointment page.
|
||||||
*
|
|
||||||
* @param {Boolean} defaultEventHandlers (OPTIONAL) Determines whether the default
|
|
||||||
* event handlers will be bound to the dom elements.
|
|
||||||
* @param {Boolean} manageMode (OPTIONAL) Determines whether the customer is going
|
|
||||||
* to make changes to an existing appointment rather than booking a new one.
|
|
||||||
*/
|
*/
|
||||||
exports.initialize = function (defaultEventHandlers, manageMode) {
|
function initialize() {
|
||||||
defaultEventHandlers = defaultEventHandlers || true;
|
if (App.Vars.display_cookie_notice) {
|
||||||
manageMode = manageMode || false;
|
|
||||||
|
|
||||||
if (GlobalVariables.displayCookieNotice) {
|
|
||||||
cookieconsent.initialise({
|
cookieconsent.initialise({
|
||||||
palette: {
|
palette: {
|
||||||
popup: {
|
popup: {
|
||||||
|
@ -84,12 +72,12 @@ window.FrontendBook = window.FrontendBook || {};
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
FrontendBook.manageMode = manageMode;
|
manageMode = App.Vars.manage_mode;
|
||||||
|
|
||||||
// Initialize page's components (tooltips, datepickers etc).
|
// Initialize page's components (tooltips, datepickers etc).
|
||||||
tippy('[data-tippy-content]');
|
tippy('[data-tippy-content]');
|
||||||
|
|
||||||
var weekDayId = GeneralFunctions.getWeekDayId(GlobalVariables.firstWeekday);
|
const weekDayId = GeneralFunctions.getWeekDayId(GlobalVariables.firstWeekday);
|
||||||
|
|
||||||
$('#select-date').datepicker({
|
$('#select-date').datepicker({
|
||||||
dateFormat: 'dd-mm-yy',
|
dateFormat: 'dd-mm-yy',
|
||||||
|
@ -144,14 +132,14 @@ window.FrontendBook = window.FrontendBook || {};
|
||||||
closeText: App.Lang.close,
|
closeText: App.Lang.close,
|
||||||
|
|
||||||
onSelect: function (dateText, instance) {
|
onSelect: function (dateText, instance) {
|
||||||
FrontendBookApi.getAvailableHours(moment($(this).datepicker('getDate')).format('YYYY-MM-DD'));
|
App.Http.Booking.getAvailableHours(moment($(this).datepicker('getDate')).format('YYYY-MM-DD'));
|
||||||
FrontendBook.updateConfirmFrame();
|
updateConfirmFrame();
|
||||||
},
|
},
|
||||||
|
|
||||||
onChangeMonthYear: function (year, month, instance) {
|
onChangeMonthYear: (year, month) => {
|
||||||
var currentDate = new Date(year, month - 1, 1);
|
const currentDate = new Date(year, month - 1, 1);
|
||||||
|
|
||||||
FrontendBookApi.getUnavailableDates(
|
App.Http.Booking.getUnavailableDates(
|
||||||
$('#select-provider').val(),
|
$('#select-provider').val(),
|
||||||
$('#select-service').val(),
|
$('#select-service').val(),
|
||||||
moment(currentDate).format('YYYY-MM-DD')
|
moment(currentDate).format('YYYY-MM-DD')
|
||||||
|
@ -162,23 +150,21 @@ window.FrontendBook = window.FrontendBook || {};
|
||||||
$('#select-timezone').val(Intl.DateTimeFormat().resolvedOptions().timeZone);
|
$('#select-timezone').val(Intl.DateTimeFormat().resolvedOptions().timeZone);
|
||||||
|
|
||||||
// Bind the event handlers (might not be necessary every time we use this class).
|
// Bind the event handlers (might not be necessary every time we use this class).
|
||||||
if (defaultEventHandlers) {
|
bindEventHandlers();
|
||||||
bindEventHandlers();
|
|
||||||
}
|
|
||||||
|
|
||||||
// If the manage mode is true, the appointments data should be loaded by default.
|
// If the manage mode is true, the appointments data should be loaded by default.
|
||||||
if (FrontendBook.manageMode) {
|
if (manageMode) {
|
||||||
applyAppointmentData(
|
applyAppointmentData(
|
||||||
GlobalVariables.appointmentData,
|
GlobalVariables.appointmentData,
|
||||||
GlobalVariables.providerData,
|
GlobalVariables.providerData,
|
||||||
GlobalVariables.customerData
|
GlobalVariables.customerData
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
var $selectProvider = $('#select-provider');
|
const $selectProvider = $('#select-provider');
|
||||||
var $selectService = $('#select-service');
|
const $selectService = $('#select-service');
|
||||||
|
|
||||||
// Check if a specific service was selected (via URL parameter).
|
// Check if a specific service was selected (via URL parameter).
|
||||||
var selectedServiceId = GeneralFunctions.getUrlParameter(location.href, 'service');
|
const selectedServiceId = GeneralFunctions.getUrlParameter(location.href, 'service');
|
||||||
|
|
||||||
if (selectedServiceId && $selectService.find('option[value="' + selectedServiceId + '"]').length > 0) {
|
if (selectedServiceId && $selectService.find('option[value="' + selectedServiceId + '"]').length > 0) {
|
||||||
$selectService.val(selectedServiceId);
|
$selectService.val(selectedServiceId);
|
||||||
|
@ -187,12 +173,12 @@ window.FrontendBook = window.FrontendBook || {};
|
||||||
$selectService.trigger('change'); // Load the available hours.
|
$selectService.trigger('change'); // Load the available hours.
|
||||||
|
|
||||||
// Check if a specific provider was selected.
|
// Check if a specific provider was selected.
|
||||||
var selectedProviderId = GeneralFunctions.getUrlParameter(location.href, 'provider');
|
const selectedProviderId = GeneralFunctions.getUrlParameter(location.href, 'provider');
|
||||||
|
|
||||||
if (selectedProviderId && $selectProvider.find('option[value="' + selectedProviderId + '"]').length === 0) {
|
if (selectedProviderId && $selectProvider.find('option[value="' + selectedProviderId + '"]').length === 0) {
|
||||||
// Select a service of this provider in order to make the provider available in the select box.
|
// Select a service of this provider in order to make the provider available in the select box.
|
||||||
for (var index in GlobalVariables.availableProviders) {
|
for (const index in GlobalVariables.availableProviders) {
|
||||||
var provider = GlobalVariables.availableProviders[index];
|
const provider = GlobalVariables.availableProviders[index];
|
||||||
|
|
||||||
if (provider.id === selectedProviderId && provider.services.length > 0) {
|
if (provider.id === selectedProviderId && provider.services.length > 0) {
|
||||||
$selectService.val(provider.services[0]).trigger('change');
|
$selectService.val(provider.services[0]).trigger('change');
|
||||||
|
@ -204,7 +190,7 @@ window.FrontendBook = window.FrontendBook || {};
|
||||||
$selectProvider.val(selectedProviderId).trigger('change');
|
$selectProvider.val(selectedProviderId).trigger('change');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method binds the necessary event handlers for the book appointments page.
|
* This method binds the necessary event handlers for the book appointments page.
|
||||||
|
@ -213,16 +199,16 @@ window.FrontendBook = window.FrontendBook || {};
|
||||||
/**
|
/**
|
||||||
* Event: Timezone "Changed"
|
* Event: Timezone "Changed"
|
||||||
*/
|
*/
|
||||||
$('#select-timezone').on('change', function () {
|
$('#select-timezone').on('change', () => {
|
||||||
var date = $('#select-date').datepicker('getDate');
|
const date = $('#select-date').datepicker('getDate');
|
||||||
|
|
||||||
if (!date) {
|
if (!date) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
FrontendBookApi.getAvailableHours(moment(date).format('YYYY-MM-DD'));
|
App.Http.Booking.getAvailableHours(moment(date).format('YYYY-MM-DD'));
|
||||||
|
|
||||||
FrontendBook.updateConfirmFrame();
|
updateConfirmFrame();
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -230,13 +216,13 @@ window.FrontendBook = window.FrontendBook || {};
|
||||||
*
|
*
|
||||||
* Whenever the provider changes the available appointment date - time periods must be updated.
|
* Whenever the provider changes the available appointment date - time periods must be updated.
|
||||||
*/
|
*/
|
||||||
$('#select-provider').on('change', function () {
|
$('#select-provider').on('change', (event) => {
|
||||||
FrontendBookApi.getUnavailableDates(
|
App.Http.Booking.getUnavailableDates(
|
||||||
$(this).val(),
|
$(event.target).val(),
|
||||||
$('#select-service').val(),
|
$('#select-service').val(),
|
||||||
moment($('#select-date').datepicker('getDate')).format('YYYY-MM-DD')
|
moment($('#select-date').datepicker('getDate')).format('YYYY-MM-DD')
|
||||||
);
|
);
|
||||||
FrontendBook.updateConfirmFrame();
|
updateConfirmFrame();
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -245,17 +231,16 @@ window.FrontendBook = window.FrontendBook || {};
|
||||||
* When the user clicks on a service, its available providers should
|
* When the user clicks on a service, its available providers should
|
||||||
* become visible.
|
* become visible.
|
||||||
*/
|
*/
|
||||||
$('#select-service').on('change', function () {
|
$('#select-service').on('change', (event) => {
|
||||||
var serviceId = $('#select-service').val();
|
const serviceId = $('#select-service').val();
|
||||||
|
|
||||||
$('#select-provider').empty();
|
$('#select-provider').empty();
|
||||||
|
|
||||||
GlobalVariables.availableProviders.forEach(function (provider) {
|
GlobalVariables.availableProviders.forEach((provider) => {
|
||||||
// If the current provider is able to provide the selected service, add him to the list box.
|
// If the current provider is able to provide the selected service, add him to the list box.
|
||||||
var canServeService =
|
const canServeService =
|
||||||
provider.services.filter(function (providerServiceId) {
|
provider.services.filter((providerServiceId) => Number(providerServiceId) === Number(serviceId))
|
||||||
return Number(providerServiceId) === Number(serviceId);
|
.length > 0;
|
||||||
}).length > 0;
|
|
||||||
|
|
||||||
if (canServeService) {
|
if (canServeService) {
|
||||||
$('#select-provider').append(
|
$('#select-provider').append(
|
||||||
|
@ -271,12 +256,14 @@ window.FrontendBook = window.FrontendBook || {};
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
FrontendBookApi.getUnavailableDates(
|
App.Http.Booking.getUnavailableDates(
|
||||||
$('#select-provider').val(),
|
$('#select-provider').val(),
|
||||||
$(this).val(),
|
$(event.target).val(),
|
||||||
moment($('#select-date').datepicker('getDate')).format('YYYY-MM-DD')
|
moment($('#select-date').datepicker('getDate')).format('YYYY-MM-DD')
|
||||||
);
|
);
|
||||||
FrontendBook.updateConfirmFrame();
|
|
||||||
|
updateConfirmFrame();
|
||||||
|
|
||||||
updateServiceDescription(serviceId);
|
updateServiceDescription(serviceId);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -284,16 +271,16 @@ window.FrontendBook = window.FrontendBook || {};
|
||||||
* Event: Next Step Button "Clicked"
|
* Event: Next Step Button "Clicked"
|
||||||
*
|
*
|
||||||
* This handler is triggered every time the user pressed the "next" button on the book wizard.
|
* This handler is triggered every time the user pressed the "next" button on the book wizard.
|
||||||
* Some special tasks might be performed, depending the current wizard step.
|
* Some special tasks might be performed, depending on the current wizard step.
|
||||||
*/
|
*/
|
||||||
$('.button-next').on('click', function () {
|
$('.button-next').on('click', (event) => {
|
||||||
// If we are on the first step and there is not provider selected do not continue with the next step.
|
// If we are on the first step and there is not provider selected do not continue with the next step.
|
||||||
if ($(this).attr('data-step_index') === '1' && !$('#select-provider').val()) {
|
if ($(event.target).attr('data-step_index') === '1' && !$('#select-provider').val()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we are on the 2nd tab then the user should have an appointment hour selected.
|
// If we are on the 2nd tab then the user should have an appointment hour selected.
|
||||||
if ($(this).attr('data-step_index') === '2') {
|
if ($(event.target).attr('data-step_index') === '2') {
|
||||||
if (!$('.selected-hour').length) {
|
if (!$('.selected-hour').length) {
|
||||||
if (!$('#select-hour-prompt').length) {
|
if (!$('#select-hour-prompt').length) {
|
||||||
$('<div/>', {
|
$('<div/>', {
|
||||||
|
@ -308,15 +295,15 @@ window.FrontendBook = window.FrontendBook || {};
|
||||||
|
|
||||||
// If we are on the 3rd tab then we will need to validate the user's input before proceeding to the next
|
// If we are on the 3rd tab then we will need to validate the user's input before proceeding to the next
|
||||||
// step.
|
// step.
|
||||||
if ($(this).attr('data-step_index') === '3') {
|
if ($(event.target).attr('data-step_index') === '3') {
|
||||||
if (!validateCustomerForm()) {
|
if (!validateCustomerForm()) {
|
||||||
return; // Validation failed, do not continue.
|
return; // Validation failed, do not continue.
|
||||||
} else {
|
} else {
|
||||||
FrontendBook.updateConfirmFrame();
|
updateConfirmFrame();
|
||||||
|
|
||||||
var $acceptToTermsAndConditions = $('#accept-to-terms-and-conditions');
|
const $acceptToTermsAndConditions = $('#accept-to-terms-and-conditions');
|
||||||
if ($acceptToTermsAndConditions.length && $acceptToTermsAndConditions.prop('checked') === true) {
|
if ($acceptToTermsAndConditions.length && $acceptToTermsAndConditions.prop('checked') === true) {
|
||||||
var newTermsAndConditionsConsent = {
|
const newTermsAndConditionsConsent = {
|
||||||
first_name: $('#first-name').val(),
|
first_name: $('#first-name').val(),
|
||||||
last_name: $('#last-name').val(),
|
last_name: $('#last-name').val(),
|
||||||
email: $('#email').val(),
|
email: $('#email').val(),
|
||||||
|
@ -327,13 +314,13 @@ window.FrontendBook = window.FrontendBook || {};
|
||||||
JSON.stringify(newTermsAndConditionsConsent) !== JSON.stringify(termsAndConditionsConsent)
|
JSON.stringify(newTermsAndConditionsConsent) !== JSON.stringify(termsAndConditionsConsent)
|
||||||
) {
|
) {
|
||||||
termsAndConditionsConsent = newTermsAndConditionsConsent;
|
termsAndConditionsConsent = newTermsAndConditionsConsent;
|
||||||
FrontendBookApi.saveConsent(termsAndConditionsConsent);
|
App.Http.Booking.saveConsent(termsAndConditionsConsent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var $acceptToPrivacyPolicy = $('#accept-to-privacy-policy');
|
const $acceptToPrivacyPolicy = $('#accept-to-privacy-policy');
|
||||||
if ($acceptToPrivacyPolicy.length && $acceptToPrivacyPolicy.prop('checked') === true) {
|
if ($acceptToPrivacyPolicy.length && $acceptToPrivacyPolicy.prop('checked') === true) {
|
||||||
var newPrivacyPolicyConsent = {
|
const newPrivacyPolicyConsent = {
|
||||||
first_name: $('#first-name').val(),
|
first_name: $('#first-name').val(),
|
||||||
last_name: $('#last-name').val(),
|
last_name: $('#last-name').val(),
|
||||||
email: $('#email').val(),
|
email: $('#email').val(),
|
||||||
|
@ -342,19 +329,19 @@ window.FrontendBook = window.FrontendBook || {};
|
||||||
|
|
||||||
if (JSON.stringify(newPrivacyPolicyConsent) !== JSON.stringify(privacyPolicyConsent)) {
|
if (JSON.stringify(newPrivacyPolicyConsent) !== JSON.stringify(privacyPolicyConsent)) {
|
||||||
privacyPolicyConsent = newPrivacyPolicyConsent;
|
privacyPolicyConsent = newPrivacyPolicyConsent;
|
||||||
FrontendBookApi.saveConsent(privacyPolicyConsent);
|
App.Http.Booking.saveConsent(privacyPolicyConsent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Display the next step tab (uses jquery animation effect).
|
// Display the next step tab (uses jquery animation effect).
|
||||||
var nextTabIndex = parseInt($(this).attr('data-step_index')) + 1;
|
const nextTabIndex = parseInt($(event.target).attr('data-step_index')) + 1;
|
||||||
|
|
||||||
$(this)
|
$(event.target)
|
||||||
.parents()
|
.parents()
|
||||||
.eq(1)
|
.eq(1)
|
||||||
.hide('fade', function () {
|
.hide('fade', () => {
|
||||||
$('.active-step').removeClass('active-step');
|
$('.active-step').removeClass('active-step');
|
||||||
$('#step-' + nextTabIndex).addClass('active-step');
|
$('#step-' + nextTabIndex).addClass('active-step');
|
||||||
$('#wizard-frame-' + nextTabIndex).show('fade');
|
$('#wizard-frame-' + nextTabIndex).show('fade');
|
||||||
|
@ -367,13 +354,13 @@ window.FrontendBook = window.FrontendBook || {};
|
||||||
* This handler is triggered every time the user pressed the "back" button on the
|
* This handler is triggered every time the user pressed the "back" button on the
|
||||||
* book wizard.
|
* book wizard.
|
||||||
*/
|
*/
|
||||||
$('.button-back').on('click', function () {
|
$('.button-back').on('click', (event) => {
|
||||||
var prevTabIndex = parseInt($(this).attr('data-step_index')) - 1;
|
const prevTabIndex = parseInt($(event.target).attr('data-step_index')) - 1;
|
||||||
|
|
||||||
$(this)
|
$(event.target)
|
||||||
.parents()
|
.parents()
|
||||||
.eq(1)
|
.eq(1)
|
||||||
.hide('fade', function () {
|
.hide('fade', () => {
|
||||||
$('.active-step').removeClass('active-step');
|
$('.active-step').removeClass('active-step');
|
||||||
$('#step-' + prevTabIndex).addClass('active-step');
|
$('#step-' + prevTabIndex).addClass('active-step');
|
||||||
$('#wizard-frame-' + prevTabIndex).show('fade');
|
$('#wizard-frame-' + prevTabIndex).show('fade');
|
||||||
|
@ -386,13 +373,13 @@ window.FrontendBook = window.FrontendBook || {};
|
||||||
* Triggered whenever the user clicks on an available hour
|
* Triggered whenever the user clicks on an available hour
|
||||||
* for his appointment.
|
* for his appointment.
|
||||||
*/
|
*/
|
||||||
$('#available-hours').on('click', '.available-hour', function () {
|
$('#available-hours').on('click', '.available-hour', (event) => {
|
||||||
$('.selected-hour').removeClass('selected-hour');
|
$('.selected-hour').removeClass('selected-hour');
|
||||||
$(this).addClass('selected-hour');
|
$(event.target).addClass('selected-hour');
|
||||||
FrontendBook.updateConfirmFrame();
|
updateConfirmFrame();
|
||||||
});
|
});
|
||||||
|
|
||||||
if (FrontendBook.manageMode) {
|
if (manageMode) {
|
||||||
/**
|
/**
|
||||||
* Event: Cancel Appointment Button "Click"
|
* Event: Cancel Appointment Button "Click"
|
||||||
*
|
*
|
||||||
|
@ -402,8 +389,8 @@ window.FrontendBook = window.FrontendBook || {};
|
||||||
*
|
*
|
||||||
* @param {jQuery.Event} event
|
* @param {jQuery.Event} event
|
||||||
*/
|
*/
|
||||||
$('#cancel-appointment').on('click', function (event) {
|
$('#cancel-appointment').on('click', () => {
|
||||||
var buttons = [
|
const buttons = [
|
||||||
{
|
{
|
||||||
text: App.Lang.cancel,
|
text: App.Lang.cancel,
|
||||||
click: function () {
|
click: function () {
|
||||||
|
@ -441,18 +428,18 @@ window.FrontendBook = window.FrontendBook || {};
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
|
|
||||||
$('#delete-personal-information').on('click', function () {
|
$('#delete-personal-information').on('click', () => {
|
||||||
var buttons = [
|
const buttons = [
|
||||||
{
|
{
|
||||||
text: App.Lang.cancel,
|
text: App.Lang.cancel,
|
||||||
click: function () {
|
click: () => {
|
||||||
$('#message-box').dialog('close');
|
$('#message-box').dialog('close');
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
text: App.Lang.delete,
|
text: App.Lang.delete,
|
||||||
click: function () {
|
click: () => {
|
||||||
FrontendBookApi.deletePersonalInformation(GlobalVariables.customerToken);
|
App.Http.Booking.deletePersonalInformation(GlobalVariables.customerToken);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
@ -474,22 +461,20 @@ window.FrontendBook = window.FrontendBook || {};
|
||||||
*
|
*
|
||||||
* @param {jQuery.Event} event
|
* @param {jQuery.Event} event
|
||||||
*/
|
*/
|
||||||
$('#book-appointment-submit').on('click', function () {
|
$('#book-appointment-submit').on('click', () => {
|
||||||
FrontendBookApi.registerAppointment();
|
App.Http.Booking.registerAppointment();
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Event: Refresh captcha image.
|
* Event: Refresh captcha image.
|
||||||
*
|
|
||||||
* @param {jQuery.Event} event
|
|
||||||
*/
|
*/
|
||||||
$('.captcha-title button').on('click', function (event) {
|
$('.captcha-title button').on('click', () => {
|
||||||
$('.captcha-image').attr('src', GlobalVariables.baseUrl + '/index.php/captcha?' + Date.now());
|
$('.captcha-image').attr('src', GlobalVariables.baseUrl + '/index.php/captcha?' + Date.now());
|
||||||
});
|
});
|
||||||
|
|
||||||
$('#select-date').on('mousedown', '.ui-datepicker-calendar td', function (event) {
|
$('#select-date').on('mousedown', '.ui-datepicker-calendar td', () => {
|
||||||
setTimeout(function () {
|
setTimeout(() => {
|
||||||
FrontendBookApi.applyPreviousUnavailableDates(); // New jQuery UI version will replace the td elements.
|
App.Http.Booking.applyPreviousUnavailableDates(); // New jQuery UI version will replace the td elements.
|
||||||
}, 300); // There is no draw event unfortunately.
|
}, 300); // There is no draw event unfortunately.
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -506,24 +491,26 @@ window.FrontendBook = window.FrontendBook || {};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Validate required fields.
|
// Validate required fields.
|
||||||
var missingRequiredField = false;
|
let missingRequiredField = false;
|
||||||
$('.required').each(function (index, requiredField) {
|
|
||||||
|
$('.required').each((index, requiredField) => {
|
||||||
if (!$(requiredField).val()) {
|
if (!$(requiredField).val()) {
|
||||||
$(requiredField).parents('.form-group').addClass('is-invalid');
|
$(requiredField).parents('.form-group').addClass('is-invalid');
|
||||||
missingRequiredField = true;
|
missingRequiredField = true;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if (missingRequiredField) {
|
if (missingRequiredField) {
|
||||||
throw new Error(App.Lang.fields_are_required);
|
throw new Error(App.Lang.fields_are_required);
|
||||||
}
|
}
|
||||||
|
|
||||||
var $acceptToTermsAndConditions = $('#accept-to-terms-and-conditions');
|
const $acceptToTermsAndConditions = $('#accept-to-terms-and-conditions');
|
||||||
if ($acceptToTermsAndConditions.length && !$acceptToTermsAndConditions.prop('checked')) {
|
if ($acceptToTermsAndConditions.length && !$acceptToTermsAndConditions.prop('checked')) {
|
||||||
$acceptToTermsAndConditions.parents('.form-check').addClass('text-danger');
|
$acceptToTermsAndConditions.parents('.form-check').addClass('text-danger');
|
||||||
throw new Error(App.Lang.fields_are_required);
|
throw new Error(App.Lang.fields_are_required);
|
||||||
}
|
}
|
||||||
|
|
||||||
var $acceptToPrivacyPolicy = $('#accept-to-privacy-policy');
|
const $acceptToPrivacyPolicy = $('#accept-to-privacy-policy');
|
||||||
if ($acceptToPrivacyPolicy.length && !$acceptToPrivacyPolicy.prop('checked')) {
|
if ($acceptToPrivacyPolicy.length && !$acceptToPrivacyPolicy.prop('checked')) {
|
||||||
$acceptToPrivacyPolicy.parents('.form-check').addClass('text-danger');
|
$acceptToPrivacyPolicy.parents('.form-check').addClass('text-danger');
|
||||||
throw new Error(App.Lang.fields_are_required);
|
throw new Error(App.Lang.fields_are_required);
|
||||||
|
@ -546,27 +533,27 @@ window.FrontendBook = window.FrontendBook || {};
|
||||||
* Every time this function is executed, it updates the confirmation page with the latest
|
* Every time this function is executed, it updates the confirmation page with the latest
|
||||||
* customer settings and input for the appointment booking.
|
* customer settings and input for the appointment booking.
|
||||||
*/
|
*/
|
||||||
exports.updateConfirmFrame = function () {
|
function updateConfirmFrame() {
|
||||||
if ($('.selected-hour').text() === '') {
|
if ($('.selected-hour').text() === '') {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Appointment Details
|
// Appointment Details
|
||||||
var selectedDate = $('#select-date').datepicker('getDate');
|
let selectedDate = $('#select-date').datepicker('getDate');
|
||||||
|
|
||||||
if (selectedDate !== null) {
|
if (selectedDate !== null) {
|
||||||
selectedDate = GeneralFunctions.formatDate(selectedDate, GlobalVariables.dateFormat);
|
selectedDate = App.Utils.Date.format(selectedDate, App.Vars.date_format, App.Vars.time_format);
|
||||||
}
|
}
|
||||||
|
|
||||||
var serviceId = $('#select-service').val();
|
const serviceId = $('#select-service').val();
|
||||||
var servicePrice = '';
|
let servicePrice = '';
|
||||||
var serviceCurrency = '';
|
let serviceCurrency = '';
|
||||||
|
|
||||||
GlobalVariables.availableServices.forEach(function (service, index) {
|
App.Vars.available_services.forEach((service) => {
|
||||||
if (Number(service.id) === Number(serviceId) && Number(service.price) > 0) {
|
if (Number(service.id) === Number(serviceId) && Number(service.price) > 0) {
|
||||||
servicePrice = service.price;
|
servicePrice = service.price;
|
||||||
serviceCurrency = service.currency;
|
serviceCurrency = service.currency;
|
||||||
return false; // break loop
|
return false; // Break loop
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -607,13 +594,13 @@ window.FrontendBook = window.FrontendBook || {};
|
||||||
}).appendTo('#appointment-details');
|
}).appendTo('#appointment-details');
|
||||||
|
|
||||||
// Customer Details
|
// Customer Details
|
||||||
var firstName = GeneralFunctions.escapeHtml($('#first-name').val());
|
const firstName = GeneralFunctions.escapeHtml($('#first-name').val());
|
||||||
var lastName = GeneralFunctions.escapeHtml($('#last-name').val());
|
const lastName = GeneralFunctions.escapeHtml($('#last-name').val());
|
||||||
var phoneNumber = GeneralFunctions.escapeHtml($('#phone-number').val());
|
const phoneNumber = GeneralFunctions.escapeHtml($('#phone-number').val());
|
||||||
var email = GeneralFunctions.escapeHtml($('#email').val());
|
const email = GeneralFunctions.escapeHtml($('#email').val());
|
||||||
var address = GeneralFunctions.escapeHtml($('#address').val());
|
const address = GeneralFunctions.escapeHtml($('#address').val());
|
||||||
var city = GeneralFunctions.escapeHtml($('#city').val());
|
const city = GeneralFunctions.escapeHtml($('#city').val());
|
||||||
var zipCode = GeneralFunctions.escapeHtml($('#zip-code').val());
|
const zipCode = GeneralFunctions.escapeHtml($('#zip-code').val());
|
||||||
|
|
||||||
$('#customer-details').empty();
|
$('#customer-details').empty();
|
||||||
|
|
||||||
|
@ -654,7 +641,7 @@ window.FrontendBook = window.FrontendBook || {};
|
||||||
}).appendTo('#customer-details');
|
}).appendTo('#customer-details');
|
||||||
|
|
||||||
// Update appointment form data for submission to server when the user confirms the appointment.
|
// Update appointment form data for submission to server when the user confirms the appointment.
|
||||||
var data = {};
|
const data = {};
|
||||||
|
|
||||||
data.customer = {
|
data.customer = {
|
||||||
last_name: $('#last-name').val(),
|
last_name: $('#last-name').val(),
|
||||||
|
@ -680,38 +667,39 @@ window.FrontendBook = window.FrontendBook || {};
|
||||||
id_services: $('#select-service').val()
|
id_services: $('#select-service').val()
|
||||||
};
|
};
|
||||||
|
|
||||||
data.manage_mode = FrontendBook.manageMode;
|
data.manage_mode = manageMode;
|
||||||
|
|
||||||
if (FrontendBook.manageMode) {
|
if (manageMode) {
|
||||||
data.appointment.id = GlobalVariables.appointmentData.id;
|
data.appointment.id = GlobalVariables.appointmentData.id;
|
||||||
data.customer.id = GlobalVariables.customerData.id;
|
data.customer.id = GlobalVariables.customerData.id;
|
||||||
}
|
}
|
||||||
$('input[name="csrfToken"]').val(GlobalVariables.csrfToken);
|
$('input[name="csrfToken"]').val(GlobalVariables.csrfToken);
|
||||||
$('input[name="post_data"]').val(JSON.stringify(data));
|
$('input[name="post_data"]').val(JSON.stringify(data));
|
||||||
};
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method calculates the end datetime of the current appointment.
|
* This method calculates the end datetime of the current appointment.
|
||||||
|
*
|
||||||
* End datetime is depending on the service and start datetime fields.
|
* End datetime is depending on the service and start datetime fields.
|
||||||
*
|
*
|
||||||
* @return {String} Returns the end datetime in string format.
|
* @return {String} Returns the end datetime in string format.
|
||||||
*/
|
*/
|
||||||
function calculateEndDatetime() {
|
function calculateEndDatetime() {
|
||||||
// Find selected service duration.
|
// Find selected service duration.
|
||||||
var serviceId = $('#select-service').val();
|
const serviceId = $('#select-service').val();
|
||||||
|
|
||||||
var service = GlobalVariables.availableServices.find(function (availableService) {
|
const service = App.Vars.available_services.find(
|
||||||
return Number(availableService.id) === Number(serviceId);
|
(availableService) => Number(availableService.id) === Number(serviceId)
|
||||||
});
|
);
|
||||||
|
|
||||||
// Add the duration to the start datetime.
|
// Add the duration to the start datetime.
|
||||||
var selectedDate = moment($('#select-date').datepicker('getDate')).format('YYYY-MM-DD');
|
const selectedDate = moment($('#select-date').datepicker('getDate')).format('YYYY-MM-DD');
|
||||||
|
|
||||||
var selectedHour = $('.selected-hour').data('value'); // HH:mm
|
const selectedHour = $('.selected-hour').data('value'); // HH:mm
|
||||||
|
|
||||||
var startMoment = moment(selectedDate + ' ' + selectedHour);
|
const startMoment = moment(selectedDate + ' ' + selectedHour);
|
||||||
|
|
||||||
var endMoment;
|
let endMoment;
|
||||||
|
|
||||||
if (service.duration && startMoment) {
|
if (service.duration && startMoment) {
|
||||||
endMoment = startMoment.clone().add({'minutes': parseInt(service.duration)});
|
endMoment = startMoment.clone().add({'minutes': parseInt(service.duration)});
|
||||||
|
@ -739,9 +727,9 @@ window.FrontendBook = window.FrontendBook || {};
|
||||||
$('#select-provider').val(appointment.id_users_provider);
|
$('#select-provider').val(appointment.id_users_provider);
|
||||||
|
|
||||||
// Set Appointment Date
|
// Set Appointment Date
|
||||||
var startMoment = moment(appointment.start_datetime);
|
const startMoment = moment(appointment.start_datetime);
|
||||||
$('#select-date').datepicker('setDate', startMoment.toDate());
|
$('#select-date').datepicker('setDate', startMoment.toDate());
|
||||||
FrontendBookApi.getAvailableHours(startMoment.format('YYYY-MM-DD'));
|
App.Http.Booking.getAvailableHours(startMoment.format('YYYY-MM-DD'));
|
||||||
|
|
||||||
// Apply Customer's Data
|
// Apply Customer's Data
|
||||||
$('#last-name').val(customer.last_name);
|
$('#last-name').val(customer.last_name);
|
||||||
|
@ -754,10 +742,10 @@ window.FrontendBook = window.FrontendBook || {};
|
||||||
if (customer.timezone) {
|
if (customer.timezone) {
|
||||||
$('#select-timezone').val(customer.timezone);
|
$('#select-timezone').val(customer.timezone);
|
||||||
}
|
}
|
||||||
var appointmentNotes = appointment.notes !== null ? appointment.notes : '';
|
const appointmentNotes = appointment.notes !== null ? appointment.notes : '';
|
||||||
$('#notes').val(appointmentNotes);
|
$('#notes').val(appointmentNotes);
|
||||||
|
|
||||||
FrontendBook.updateConfirmFrame();
|
updateConfirmFrame();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
} catch (exc) {
|
} catch (exc) {
|
||||||
|
@ -766,18 +754,18 @@ window.FrontendBook = window.FrontendBook || {};
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method updates a div's html content with a brief description of the
|
* This method updates a div's HTML content with a brief description of the
|
||||||
* user selected service (only if available in db). This is useful for the
|
* user selected service (only if available in db). This is useful for the
|
||||||
* customers upon selecting the correct service.
|
* customers upon selecting the correct service.
|
||||||
*
|
*
|
||||||
* @param {Number} serviceId The selected service record id.
|
* @param {Number} serviceId The selected service record id.
|
||||||
*/
|
*/
|
||||||
function updateServiceDescription(serviceId) {
|
function updateServiceDescription(serviceId) {
|
||||||
var $serviceDescription = $('#service-description');
|
const $serviceDescription = $('#service-description');
|
||||||
|
|
||||||
$serviceDescription.empty();
|
$serviceDescription.empty();
|
||||||
|
|
||||||
var service = GlobalVariables.availableServices.find(function (availableService) {
|
const service = App.Vars.available_services.find(function (availableService) {
|
||||||
return Number(availableService.id) === Number(serviceId);
|
return Number(availableService.id) === Number(serviceId);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -819,4 +807,12 @@ window.FrontendBook = window.FrontendBook || {};
|
||||||
}).appendTo($serviceDescription);
|
}).appendTo($serviceDescription);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})(window.FrontendBook);
|
|
||||||
|
document.addEventListener('DOMContentLoaded', initialize);
|
||||||
|
|
||||||
|
return {
|
||||||
|
manageMode,
|
||||||
|
initialize,
|
||||||
|
updateConfirmFrame
|
||||||
|
};
|
||||||
|
})();
|
Loading…
Reference in a new issue