$(function() {
$('#vapempsel').select2({
allowClear: false,
width: 300,
});
$('#vapmonthsel, #vapserpeopleselect').select2({
minimumResultsForSearch: -1,
allowClear: false,
width: 150,
});
$('#vapempsel, #vapmonthsel, .vap-empsearch-locval').on('change', () => {
document.sersearchform.submit();
});
jQuery(function($) {
$('.vaptdday[data-day]').on('click', function() {
// remove selection from any other cell
$('.vaptdday').removeClass('vaptdselected');
// auto-select clicked cell
$(this).addClass('vaptdselected');
jQuery(function($) {
// auto-load timeline in case a date was selected
vapGetTimeline();
});
function vapGetTimeline(date) {
if (TIMELINE_XHR !== null) {
// abort previous request
TIMELINE_XHR.abort();
}
if (typeof date === 'undefined') {
// recover stored date
date = jQuery('#vapdayselected').val();
// auto-select clicked cell
jQuery('.vaptdday[data-day="' + date + '"]').addClass('vaptdselected');
} else {
// register selected date
jQuery('#vapdayselected').val(date);
}
/**
* @see views/employeesearch/tmpl/default.php
*/
LAST_TIMESTAMP_USED = date;
// prepare timeline data
let data = {
day: date,
id_emp: 0,
id_ser: 1,
people: jQuery('#vapserpeopleselect').val(),
admin: 0,
id_res: 0,
locations: [],
};
// unset hours and minutes as the checkin day has changed
jQuery('#vapconfhourselected').val('');
jQuery('#vapconfminselected').val('');
// update input hidden holding the selected number of participants
jQuery('#vappeopleselected').val(data.people);
jQuery('.vap-empsearch-locval').each(function() {
if (jQuery(this).is(':checked')) {
data.locations.push(jQuery(this).val());
} else {
// at least one not selected
all = false;
}
});
if (all) {
// all locations are selected, so we can ignore this filter
delete data.locations;
}
new Promise((resolve, reject) => {
TIMELINE_XHR = UIAjax.do(
'https://syselicat.com/wp-admin/admin-ajax.php?task=employeesearch.timelineajax&action=vikappointments&vik_ajax_client=site',
data,
(resp) => {
resolve(resp);
},
(err) => {
reject(err);
}
);
}).then((resp) => {
if (!resp.error) {
// render timeline through the helper function
vapRenderTimeline(resp.timeline, resp.html, resp.rate, data);
} else {
// register availability error
error = resp.error;
}
}).catch((err) => {
if (err.statusText === 'abort') {
aborted = false;
} else if (typeof err.responseText !== 'undefined') {
// register response HTTP error message
error = err.responseText || Joomla.JText._('VAPWAITLISTADDED0');
} else {
error = true;
// we are probably handling an exception
console.error(err);
}
}).finally(() => {
TIMELINE_XHR = null;
// do not go ahead in case we aborted the request
if (aborted === true) {
return;
}
if (error !== false) {
if (typeof error === 'string') {
// Fill timeline box with fetched error message.
// Wrap error in a
for individual styling.
jQuery('#vaptimeline').html(
jQuery('
').html(error)
);
}
// unset selected date on error
jQuery('#vapdayselected').val('');
// hide wait list button
jQuery('#vapwaitlistbox').hide();
// hide add cart button
jQuery('#vapadditembutton').hide();
}
// animate only in case the timeline is not visible
var px_to_scroll = isBoxOutOfMonitor(jQuery('#vaptimeline'), 60);
if (px_to_scroll !== false) {
jQuery('html,body').animate({scrollTop: "+=" + px_to_scroll}, {duration:'normal'});
}
});
}
var HOUR_MIN_SELECTED = false;
function vapRenderTimeline(timeline, html, newRate, request) {
let eventArgs = {
timeline: timeline,
html: html,
newRate: newRate,
request: request,
};
// inject received parameters within the event to dispatch
var event = jQuery.Event('timeline.beforerender');
event.params = eventArgs;
// trigger event before rendering the timeline
jQuery(window).trigger(event);
// fill timeline with fetched HTML
jQuery('#vaptimeline').html(html);
// update base cost
if (newRate && typeof vapUpdateServiceRate !== 'undefined') {
/**
* @see views/employeesearch/tmpl/default_filterbar.php
*/
vapUpdateServiceRate(newRate);
}
var at_least_one_open = false;
var at_least_one_closed = false;
// iterate timeline levels
timeline.forEach((level) => {
// iterate level times
level.forEach((time) => {
at_least_one_open = at_least_one_open || (time.status == 1);
at_least_one_closed = at_least_one_closed || (time.status == 0);
});
});
// display "add to cart" button only if the timeline
// reports at least an available slot
if (at_least_one_open) {
jQuery('#vapadditembutton').show();
} else {
jQuery('#vapadditembutton').hide();
}
// display "add to waiting list" button only if the
// timeline reports at least an occupied slot
if (at_least_one_closed) {
jQuery('#vapwaitlistbox').show();
} else {
jQuery('#vapwaitlistbox').hide();
}
// inject received parameters within the event to dispatch
var event = jQuery.Event('timeline.afterrender');
event.params = eventArgs;
// trigger event after rendering the timeline
jQuery(window).trigger(event);
}
function vapTimeClicked(hour, min, slot)
{
let eventArgs = {
hour: hour,
min: min,
};
// inject received parameters within the event to dispatch
var event = jQuery.Event('timeline.beforepicktime');
event.params = eventArgs;
// trigger event before picking a time slot
jQuery(slot).trigger(event);
// get new rate as string
var newRate = '' + jQuery(slot).find('.vaptlblock1').data('rate');
if (newRate.length && typeof vapUpdateServiceRate !== 'undefined') {
/**
* Dispatch rate update only if the data is set.
*
* @see views/employeesearch/tmpl/default_filterbar.php
*/
vapUpdateServiceRate(parseFloat(newRate));
}
jQuery('#vapconfempselected').val(0);
jQuery('#vapconfserselected').val(1);
jQuery('#vapconfdayselected').val(jQuery('#vapdayselected').val());
jQuery('#vapconfhourselected').val(hour);
jQuery('#vapconfminselected').val(min);
jQuery('#vapconfpeopleselected').val(jQuery('#vappeopleselected').val());
jQuery('.vaptlblock1').removeClass('vaptimeselected');
jQuery(slot).find('.vaptlblock1').addClass('vaptimeselected');
var opt_div = jQuery('.vapseroptionscont');
if (opt_div.length > 0) {
opt_div.slideDown();
}
var rec_div = jQuery('.vaprecurrencediv');
if (rec_div.length > 0) {
rec_div.slideDown();
}
isTimeChoosen = true;
// inject received parameters within the event to dispatch
var event = jQuery.Event('timeline.afterpicktime');
event.params = eventArgs;
// trigger event after picking a time slot
jQuery(slot).trigger(event);
}
var isTimeChoosen = false;
var vapCheckoutProceed = 0;
jQuery(function($) {
$('#vaprepeatbyrecsel, #vapfornextrecsel').select2({
minimumResultsForSearch: -1,
allowClear: false,
width: 150,
});
$('#vapamountrecsel').select2({
minimumResultsForSearch: -1,
allowClear: false,
width: 70,
});
});
/**
* Used to register the selected options within the DOM
* or to return them as array.
*/
function vapRegisterOptions(what) {
try
{
var options = vapGetSelectedOptions();
}
catch (error)
{
if (error == 'MissingRequiredOptionException')
{
// do not proceed as the customer forgot to fill
// one or more required fields
return false;
}
// Proceed because the service doesn't own any option
// and the function vapGetSelectedOptions() hasn't been declared.
// Define an empty options array to avoid breaking the flow.
var options = [];
}
if (what === 'ajax') {
// return options array
return options;
}
options.forEach((opt) => {
jQuery('#vapempconfirmapp').append(
' '+
' '+
' '
);
});
return true;
}
/**
* Used to book the selected details by submitting the form.
*/
function vapBookNow() {
if (isTimeChoosen) {
// register options only in case the time has been selected
if (vapRegisterOptions('submit') === false) {
// missing some required options
return false;
}
// register recurrence only in case the time has been selected
var recurrence = vapGetSelectedRecurrence();
if (recurrence) {
jQuery('#vapempconfirmapp').append(' ');
}
}
if (isTimeChoosen || vapCheckoutProceed) {
document.confirmapp.submit();
} else {
vapDisplayWrongMessage(2500, Joomla.JText._('VAPBOOKNOTIMESELECTED'));
}
}
var _items_add_count = 0;
var _items_timeout = null;
var _items_bad_timeout = null;
/**
* Used to book one or more services via AJAX.
*/
function vapAddItemToCart() {
if (!isTimeChoosen) {
return false;
}
var id_ser = jQuery("#vapconfserselected").val();
var id_emp = jQuery("#vapconfempselected").val();
var day = jQuery("#vapconfdayselected").val();
var hour = jQuery("#vapconfhourselected").val();
var min = jQuery("#vapconfminselected").val();
var people = jQuery("#vapconfpeopleselected").val();
// get selected options
var options = vapRegisterOptions('ajax');
if (options === false) {
// missing some required options
return false;
}
// It doesn't matter if the checkout select exists
// as the controller won't use this value (because the
// checkout selection is disabled for this service).
var factor = jQuery('#vap-checkout-sel').val();
var recurrence = vapGetSelectedRecurrence();
// use default URL
var _url = 'https://syselicat.com/wp-admin/admin-ajax.php?task=cart.additem&Itemid=2589&action=vikappointments&vik_ajax_client=site';
if (recurrence) {
// user recurrence URL
_url = 'https://syselicat.com/wp-admin/admin-ajax.php?task=cart.addrecuritem&Itemid=2589&action=vikappointments&vik_ajax_client=site';
} else {
// set default "no" recurrence
recurrence = [-1, -1, -1].join(',');
}
jQuery('.option-required').removeClass('vapoptred');
UIAjax.do(
_url,
{
id_ser: id_ser,
id_emp: id_emp,
date: day,
hour: hour,
min: min,
people: people,
options: options,
recurrence: recurrence,
duration_factor: factor,
},
(resp) => {
// check if we have recurring items
if (typeof resp.items !== 'undefined') {
// ok count
if (resp.count > 0) {
// recurring appointments -> get number of items added
vapDisplayRightMessage(resp.count);
// we can proceed with the checkout
vapCheckoutProceed = 1;
}
var wrong = [];
// fetch all error messages
resp.items.forEach((item) => {
if (item.status == 0) {
wrong.push(item.error);
}
});
if (wrong.length) {
// at least an error found, display a wrong message too
vapDisplayWrongMessage(Math.max(wrong.length * 1500, 2500), wrong.join(' '));
}
} else {
// display message for one service only
vapDisplayRightMessage(1);
// we can proceed with the checkout
vapCheckoutProceed = 1;
}
/**
* Refresh timeline on success.
*
* @since 1.7.5
*/
vapGetTimeline();
// inject received response within the event to dispatch
var event = jQuery.Event('vikappointments.cart.add');
event.params = resp;
// trigger event
jQuery(window).trigger(event);
},
(err) => {
vapDisplayWrongMessage(0, err.responseText || Joomla.JText._('VAPBOOKNOTIMESELECTED'));
}
);
}
function vapDisplayRightMessage(count) {
if (!jQuery('.vapbooksuccessdiv').is(':visible')) {
_items_add_count = count;
} else {
_items_add_count++;
}
if (!_items_bad_timeout) {
// no registered timer for error messages, auto hide them
jQuery('.vapbookerrordiv').hide();
}
if (_items_add_count == 1) {
jQuery('.vapbooksuccessdiv #booksuccess-msg').text(Joomla.JText._('VAPCARTITEMADDOK'));
} else {
jQuery('.vapbooksuccessdiv #booksuccess-msg').text(_items_add_count + ' ' + Joomla.JText._('VAPCARTMULTIITEMSADDOK'));
}
if (_items_timeout != null) {
clearTimeout(_items_timeout);
}
jQuery('.vapbooksuccessdiv').stop(true, true).fadeIn();
_items_timeout = setTimeout(function() {
jQuery('.vapbooksuccessdiv').fadeOut();
}, 2500);
}
function vapDisplayWrongMessage(ms, html) {
if (_items_bad_timeout != null) {
clearTimeout(_items_bad_timeout);
}
if (html) {
jQuery('.vapbookerrordiv #bookerror-msg').html(html);
}
jQuery('.vapbookerrordiv').stop(true, true).fadeIn();
if (ms > 0) {
_items_bad_timeout = setTimeout(function() {
jQuery('.vapbookerrordiv').fadeOut();
}, ms);
}
}
function vapRecurrenceSelectChanged() {
var val = jQuery('#vaprepeatbyrecsel').val();
if (val > 0) {
if (jQuery('#vapfornextrecsel option[value="' + val + '"]').length > 0) {
// update select to have the same interval
jQuery('#vapfornextrecsel').select2('val', val);
} else if (jQuery('#vapfornextrecsel').val() == "0") {
// option not found, select the first index available
jQuery('#vapfornextrecsel').prop('selectedIndex', 1);
// update val on select2
jQuery('#vapfornextrecsel').select2('val', jQuery('#vapfornextrecsel').val());
}
} else {
jQuery('#vaprecokcheck').prop('checked', false);
jQuery('.vaprecurrencenextdiv').hide();
jQuery('.vaprecurrenceprediv').fadeIn();
}
}
function vapRecurrenceConfirmValueChanged() {
// change index
jQuery('#vaprepeatbyrecsel').prop('selectedIndex', 1);
// update val on select2
jQuery('#vaprepeatbyrecsel').select2('val', jQuery('#vaprepeatbyrecsel').val());
// trigger change to update [fornext] select
vapRecurrenceSelectChanged();
jQuery('.vaprecurrenceprediv').hide();
jQuery('.vaprecurrencenextdiv').fadeIn();
}
function vapGetSelectedRecurrence() {
var enabled = 0;
if (!enabled) {
return false;
}
var recurrence = [];
recurrence.push(parseInt(jQuery('#vaprepeatbyrecsel').val()));
recurrence.push(parseInt(jQuery('#vapfornextrecsel').val()));
recurrence.push(parseInt(jQuery('#vapamountrecsel').val()));
if (!recurrence[0]) {
return false;
}
return recurrence.join(',');
}
/**
* @usedby views/servicesearch/tmpl/default_calendars.php
* @usedby layouts/blocks/checkout.php
*/
var LAST_TIMESTAMP_USED = null;