/**
* This namespace 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.
*
* @namespace FrontendBook
*/
var FrontendBook = {
/**
* Determines the functionality of the page.
*
* @type Boolean
*/
manageMode : false,
/**
* This method initializes the book appointment page.
*
* @param {bool} bindEventHandlers (OPTIONAL) Determines whether
* the default event handlers will be binded to the dom elements.
* @param {bool} manageMode (OPTIONAL) Determines whether the customer
* is going to make changes to an existing appointment rather than
* booking a new one.
*/
initialize : function(bindEventHandlers, manageMode) {
if (bindEventHandlers === undefined) {
bindEventHandlers = true; // Default Value
}
if (manageMode === undefined) {
manageMode = false; // Default Value
}
FrontendBook.manageMode = manageMode;
// Initialize page's components (tooltips, datepickers etc).
$('.book-step').qtip({
position: {
my: 'top center',
at: 'bottom center'
},
style: {
classes: 'qtip-green qtip-shadow custom-qtip'
}
});
$('#select-date').datepicker({
dateFormat : 'dd-mm-yy',
minDate : 0,
defaultDate : Date.today(),
onSelect : function(dateText, instance) {
FrontendBook.getAvailableHours(dateText);
FrontendBook.updateConfirmFrame();
}
});
// Bind the event handlers (might not be necessary every time
// we use this class).
if (bindEventHandlers) {
FrontendBook.bindEventHandlers();
}
// If the manage mode is true, the appointments data should be
// loaded by default.
if (FrontendBook.manageMode) {
FrontendBook.applyAppointmentData(GlobalVariables.appointmentData,
GlobalVariables.providerData, GlobalVariables.customerData);
} else {
$('#select-service').trigger('change'); // Load the available hours.
}
},
/**
* This method binds the necessary event handlers for the book
* appointments page.
*/
bindEventHandlers : function() {
/**
* Event : Selected Provider "Changed"
*
* Whenever the provider changes the available appointment
* date - time periods must be updated.
*/
$('#select-provider').change(function() {
FrontendBook.getAvailableHours(Date.today().toString('dd-MM-yyyy'));
FrontendBook.updateConfirmFrame();
});
/**
* Event : Selected Service "Changed"
*
* When the user clicks on a service, its available providers should
* become visible.
*/
$('#select-service').change(function() {
var currServiceId = $('#select-service').val();
$('#select-provider').empty();
$.each(GlobalVariables.availableProviders, function(indexProvider, provider) {
$.each(provider['services'], function(indexService, serviceId) {
// If the current provider is able to provide the selected service,
// add him to the listbox.
if (serviceId == currServiceId) {
var optionHtml = '';
$('#select-provider').append(optionHtml);
}
});
});
FrontendBook.getAvailableHours(Date.today().toString('dd-MM-yyyy'));
FrontendBook.updateConfirmFrame();
});
/**
* Event : Next Step Button "Clicked"
*
* This handler is triggered every time the user pressed the
* "next" button on the book wizard. Some special tasks might
* be perfomed, depending the current wizard step.
*/
$('.button-next').click(function() {
// If we are on the 2nd tab then the user should have
// an appointment hour selected.
if ($(this).attr('data-step_index') === '2') {
if ($('.selected-hour').length == 0) {
if ($('#select-hour-prompt').length == 0) {
$('#available-hours').append('
'
+ ''
+ 'Please select an appointment hour before continuing!'
+ '');
}
return;
}
}
// If we are on the 3rd tab then we will need to validate the user's
// input before proceeding to the next step.
if ($(this).attr('data-step_index') === '3') {
if (!FrontendBook.validateCustomerForm()) {
return; // Validation failed, do not continue.
} else {
FrontendBook.updateConfirmFrame();
}
}
// Display the next step tab (uses jquery animation effect).
var nextTabIndex = parseInt($(this).attr('data-step_index')) + 1;
$(this).parents().eq(1).hide('fade', function() {
$('.active-step').removeClass('active-step');
$('#step-' + nextTabIndex).addClass('active-step');
$('#wizard-frame-' + nextTabIndex).show('fade');
});
});
/**
* Event : Back Step Button "Clicked"
*
* This handler is triggered every time the user pressed the
* "back" button on the book wizard.
*/
$('.button-back').click(function() {
var prevTabIndex = parseInt($(this).attr('data-step_index')) - 1;
$(this).parents().eq(1).hide('fade', function() {
$('.active-step').removeClass('active-step');
$('#step-' + prevTabIndex).addClass('active-step');
$('#wizard-frame-' + prevTabIndex).show('fade');
});
});
/**
* Event : Available Hour "Click"
*
* Triggered whenever the user clicks on an available hour
* for his appointment.
*/
$('#available-hours').on('click', '.available-hour', function() {
$('.selected-hour').removeClass('selected-hour');
$(this).addClass('selected-hour');
FrontendBook.updateConfirmFrame();
});
if (FrontendBook.manageMode) {
/**
* Event: Cancel Appointment Button "Click"
*
* When the user clicks the "Cancel" button this form is going to
* be submitted. We need the user to confirm this action because
* once the appointment is cancelled, it will be delete from the
* database.
*/
$('#cancel-appointment').click(function() {
event.preventDefault();
var dialogButtons = {
'Yes' : function() {
$('#cancel-appointment-form').submit();
},
'No' : function() {
$('#message_box').dialog('close');
}
};
GeneralFunctions.displayMessageBox('Cancel Appointment', 'Are you sure '
+ 'that you want to cancel this appointment? This action can\'t '
+ 'be undone.', dialogButtons);
});
}
},
/**
* This function makes an ajax call and returns the available
* hours for the selected service, provider and date.
*
* @param {string} selDate The selected date of which the available
* hours we need to receive.
*/
getAvailableHours : function(selDate) {
// Find the selected service duration (it is going to
// be send within the "postData" object.
var selServiceDuration = 15; // Default value of duration (in minutes).
$.each(GlobalVariables.availableServices, function(index, service) {
if (service['id'] == $('#select-service').val()) {
selServiceDuration = service['duration'];
}
});
// If the manage mode is true then the appointment's start
// date should return as available too.
var appointmentId = (FrontendBook.manageMode)
? GlobalVariables.appointmentData['id'] : undefined;
var postData = {
'service_id' : $('#select-service').val(),
'provider_id' : $('#select-provider').val(),
'selected_date' : selDate,
'service_duration' : selServiceDuration,
'manage_mode' : FrontendBook.manageMode,
'appointment_id' : appointmentId
};
// Make ajax post request and get the available hours.
var ajaxurl = GlobalVariables.baseUrl + 'appointments/ajax_get_available_hours';
jQuery.post(ajaxurl, postData, function(postResponse) {
////////////////////////////////////////////////////////////////////////////////
//console.log('\n\n Get Available Hours Post Response :', postResponse, '\n\n');
////////////////////////////////////////////////////////////////////////////////
try {
var jsonResponse = jQuery.parseJSON(postResponse);
////////////////////////////////////////////////////////////////////////////////
//console.log('\n\n Get Available Hours JSON Response :', jsonResponse, '\n\n');
////////////////////////////////////////////////////////////////////////////////
if (jsonResponse.length > 0) {
// Fill the available time div
var currColumn = 1;
$('#available-hours').html('
'
+ $('#select-provider option:selected').text()
+ '
'
+ ''
+ selectedDate + ' ' + $('.selected-hour').text()
+ '' +
'
' +
'Phone: ' + $('#phone-number').val() +
'
' +
'Email: ' + $('#email').val() +
'
' +
'Address: ' + $('#address').val() +
'
' +
'City: ' + $('#city').val() +
'
' +
'Zip Code: ' + $('#zip-code').val() +
'