diff --git a/src/assets/js/backend_calendar.js b/src/assets/js/backend_calendar.js index 55100f8e..f4312f9b 100644 --- a/src/assets/js/backend_calendar.js +++ b/src/assets/js/backend_calendar.js @@ -444,7 +444,7 @@ var BackendCalendar = { // Refresh calendar event items. $('#select-filter-item').trigger('change'); - }, 'json'); + }, 'json').fail(GeneralFunctions.ajaxFailureHandler); }; messageButtons[EALang['cancel']] = function() { @@ -486,7 +486,7 @@ var BackendCalendar = { // Refresh calendar event items. $('#select-filter-item').trigger('change'); - }, 'json'); + }, 'json').fail(GeneralFunctions.ajaxFailureHandler); } }); @@ -740,7 +740,7 @@ var BackendCalendar = { $('#select-google-calendar').modal('show'); - }, 'json'); + }, 'json').fail(GeneralFunctions.ajaxFailureHandler); } } }, 100); @@ -970,7 +970,7 @@ var BackendCalendar = { if (!GeneralFunctions.handleAjaxExceptions(response)) return; Backend.displayNotification(EALang['google_calendar_selected']); $('#select-google-calendar').modal('hide'); - }); + }, 'json').fail(GeneralFunctions.ajaxFailureHandler); }); /** @@ -1038,7 +1038,7 @@ var BackendCalendar = { }; calendarEvents.push(event); - }); + }, 'json').fail(GeneralFunctions.ajaxFailureHandler); $calendar.fullCalendar('removeEvents'); $calendar.fullCalendar('addEventSource', calendarEvents); @@ -1403,7 +1403,7 @@ var BackendCalendar = { $.post(postUrl, postData, function(response) { $('#notification').hide('blind'); revertFunc(); - }); + }, 'json').fail(GeneralFunctions.ajaxFailureHandler); }; Backend.displayNotification(EALang['appointment_updated'], [ @@ -1459,7 +1459,7 @@ var BackendCalendar = { $.post(postUrl, postData, function(response) { $('#notification').hide('blind'); revertFunc(); - }); + }, 'json').fail(GeneralFunctions.ajaxFailureHandler); }; Backend.displayNotification(EALang['unavailable_updated'], [ @@ -1686,7 +1686,7 @@ var BackendCalendar = { $.post(postUrl, postData, function(response) { $('#notification').hide('blind'); revertFunc(); - }); + }, 'json').fail(GeneralFunctions.ajaxFailureHandler); }; Backend.displayNotification(EALang['appointment_updated'], [ @@ -1751,7 +1751,7 @@ var BackendCalendar = { $.post(postUrl, postData, function(response) { $('#notification').hide('blind'); revertFunc(); - }); + }, 'json').fail(GeneralFunctions.ajaxFailureHandler); }; Backend.displayNotification(EALang['unavailable_updated'], [ @@ -1823,7 +1823,7 @@ var BackendCalendar = { $('#message_box').append(GeneralFunctions.exceptionsToHtml(response.exceptions)); return; } - }, 'json'); + }, 'json').fail(GeneralFunctions.ajaxFailureHandler); }, /** diff --git a/src/assets/js/backend_customers.js b/src/assets/js/backend_customers.js index 42b4482b..465423c8 100644 --- a/src/assets/js/backend_customers.js +++ b/src/assets/js/backend_customers.js @@ -1,52 +1,52 @@ /* ---------------------------------------------------------------------------- * Easy!Appointments - Open Source Web Scheduler - * + * * @package EasyAppointments * @author A.Tselegidis * @copyright Copyright (c) 2013 - 2015, Alex Tselegidis - * @license http://opensource.org/licenses/GPL-3.0 - GPLv3 + * @license http://opensource.org/licenses/GPL-3.0 - GPLv3 * @link http://easyappointments.org * @since v1.0.0 * ---------------------------------------------------------------------------- */ /** - * Backend Customers javasript namespace. Contains the main functionality - * of the backend customers page. If you need to use this namespace in a + * Backend Customers javasript namespace. Contains the main functionality + * of the backend customers page. If you need to use this namespace in a * different page, do not bind the default event handlers during initialization. * * @namespace BackendCustomers */ var BackendCustomers = { /** - * The page helper contains methods that implement each record type functionality + * The page helper contains methods that implement each record type functionality * (for now there is only the CustomersHelper). - * + * * @type {object{ */ helper: {}, - + /** * This method initializes the backend customers page. If you use this namespace - * in a different page do not use this method. - * - * @param {bool} defaultEventHandlers (OPTIONAL = false) Whether to bind the default - * event handlers or not. + * in a different page do not use this method. + * + * @param {bool} defaultEventHandlers (OPTIONAL = false) Whether to bind the default + * event handlers or not. */ initialize: function(defaultEventHandlers) { - if (defaultEventHandlers == undefined) defaultEventHandlers = false; - + if (defaultEventHandlers == undefined) defaultEventHandlers = false; + BackendCustomers.helper = new CustomersHelper(); BackendCustomers.helper.resetForm(); BackendCustomers.helper.filter(''); - + $('#filter-customers .results').jScrollPane(); $('#customer-appointments').jScrollPane(); - + if (defaultEventHandlers) { BackendCustomers.bindEventHandlers(); } }, - + /** * Default event handlers declaration for backend customers page. */ @@ -57,7 +57,7 @@ var BackendCustomers = { /** * This class contains the methods that are used in the backend customers page. - * + * * @class CustomersHelper */ var CustomersHelper = function() { @@ -78,7 +78,7 @@ CustomersHelper.prototype.bindEventHandlers = function() { BackendCustomers.helper.filter(key); return false; }); - + /** * Event: Filter Customers Clear Button "Click" */ @@ -86,17 +86,17 @@ CustomersHelper.prototype.bindEventHandlers = function() { $('#filter-customers .key').val(''); BackendCustomers.helper.filter(''); }); - + /** * Event: Customer Row "Click" - * + * * Display the customer data of the selected row. */ $(document).on('click', '.customer-row', function() { if ($('#filter-customers .filter').prop('disabled')) { return; // Do nothing when user edits a customer record. } - + var customerId = $(this).attr('data-id'); var customer = {}; $.each(BackendCustomers.helper.filterResults, function(index, item) { @@ -105,7 +105,7 @@ CustomersHelper.prototype.bindEventHandlers = function() { return false; } }); - + BackendCustomers.helper.display(customer); $('#filter-customers .selected-row').removeClass('selected-row'); $(this).addClass('selected-row'); @@ -114,7 +114,7 @@ CustomersHelper.prototype.bindEventHandlers = function() { /** * Event: Appointment Row "Click" - * + * * Display appointment data of the selected row. */ $(document).on('click', '.appointment-row', function() { @@ -194,9 +194,9 @@ CustomersHelper.prototype.bindEventHandlers = function() { if ($('#customer-id').val() != '') { customer.id = $('#customer-id').val(); } - + if (!BackendCustomers.helper.validate(customer)) return; - + BackendCustomers.helper.save(customer); }); @@ -205,9 +205,9 @@ CustomersHelper.prototype.bindEventHandlers = function() { */ $('#delete-customer').click(function() { var customerId = $('#customer-id').val(); - + var messageBtns = {}; - messageBtns[EALang['delete']] = function() { + messageBtns[EALang['delete']] = function() { BackendCustomers.helper.delete(customerId); $('#message_box').dialog('close'); }; @@ -215,71 +215,71 @@ CustomersHelper.prototype.bindEventHandlers = function() { $('#message_box').dialog('close'); }; - GeneralFunctions.displayMessageBox(EALang['delete_customer'], + GeneralFunctions.displayMessageBox(EALang['delete_customer'], EALang['delete_record_prompt'], messageBtns); }); }; /** * Save a customer record to the database (via ajax post). - * + * * @param {object} customer Contains the customer data. */ CustomersHelper.prototype.save = function(customer) { var postUrl = GlobalVariables.baseUrl + '/index.php/backend_api/ajax_save_customer'; - var postData = { + var postData = { 'csrfToken': GlobalVariables.csrfToken, - 'customer': JSON.stringify(customer) + 'customer': JSON.stringify(customer) }; - + $.post(postUrl, postData, function(response) { /////////////////////////////////////////////////////////// console.log('Save Customer Response:', response); /////////////////////////////////////////////////////////// - + if (!GeneralFunctions.handleAjaxExceptions(response)) return; - + Backend.displayNotification(EALang['customer_saved']); BackendCustomers.helper.resetForm(); $('#filter-customers .key').val(''); BackendCustomers.helper.filter('', response.id, true); - }, 'json'); + }, 'json').fail(GeneralFunctions.ajaxFailureHandler); }; /** * Delete a customer record from database. - * - * @param {numeric} id Record id to be deleted. + * + * @param {numeric} id Record id to be deleted. */ CustomersHelper.prototype.delete = function(id) { var postUrl = GlobalVariables.baseUrl + '/index.php/backend_api/ajax_delete_customer'; - var postData = { + var postData = { 'csrfToken': GlobalVariables.csrfToken, - 'customer_id': id + 'customer_id': id }; - + $.post(postUrl, postData, function(response) { //////////////////////////////////////////////////// //console.log('Delete customer response:', response); //////////////////////////////////////////////////// - + if (!GeneralFunctions.handleAjaxExceptions(response)) return; - + Backend.displayNotification(EALang['customer_deleted']); BackendCustomers.helper.resetForm(); BackendCustomers.helper.filter($('#filter-customers .key').val()); - }, 'json'); + }, 'json').fail(GeneralFunctions.ajaxFailureHandler); }; /** * Validate customer data before save (insert or update). - * + * * @param {object} customer Contains the customer data. */ CustomersHelper.prototype.validate = function(customer) { $('#form-message').hide(); $('.required').css('border', ''); - + try { // Validate required fields. var missingRequired = false; @@ -311,18 +311,18 @@ CustomersHelper.prototype.validate = function(customer) { * Bring the customer form back to its initial state. */ CustomersHelper.prototype.resetForm = function() { - $('.details').find('input, textarea').val(''); - $('.details').find('input, textarea').prop('readonly', true); - + $('.details').find('input, textarea').val(''); + $('.details').find('input, textarea').prop('readonly', true); + $('#customer-appointments').html(''); $('#appointment-details').html(''); $('#edit-customer, #delete-customer').prop('disabled', true); $('#add-edit-delete-group').show(); $('#save-cancel-group').hide(); - + $('.details .required').css('border', ''); $('.details #form-message').hide(); - + $('#filter-customers button').prop('disabled', false); $('#filter-customers .selected-row').removeClass('selected-row'); $('#filter-customers .results').css('color', ''); @@ -330,7 +330,7 @@ CustomersHelper.prototype.resetForm = function() { /** * Display a customer record into the form. - * + * * @param {object} customer Contains the customer record data. */ CustomersHelper.prototype.display = function(customer) { @@ -349,109 +349,109 @@ CustomersHelper.prototype.display = function(customer) { $.each(customer.appointments, function(index, appointment) { var start = Date.parse(appointment.start_datetime).toString('dd/MM/yyyy HH:mm'); var end = Date.parse(appointment.end_datetime).toString('dd/MM/yyyy HH:mm'); - var html = - '
' + + var html = + '
' + start + ' - ' + end + '
' + - appointment.service.name + ', ' + + appointment.service.name + ', ' + appointment.provider.first_name + ' ' + appointment.provider.last_name + - '
'; + '
'; $('#customer-appointments').append(html); }); $('#customer-appointments').jScrollPane({ mouseWheelSpeed: 70 }); - + $('#appointment-details').empty(); }; /** * Filter customer records. - * + * * @param {string} key This key string is used to filter the customer records. - * @param {numeric} selectId (OPTIONAL = undefined) If set then after the filter + * @param {numeric} selectId (OPTIONAL = undefined) If set then after the filter * operation the record with the given id will be selected (but not displayed). * @param {bool} display (OPTIONAL = false) If true then the selected record will * be displayed on the form. */ CustomersHelper.prototype.filter = function(key, selectId, display) { if (display == undefined) display = false; - + var postUrl = GlobalVariables.baseUrl + '/index.php/backend_api/ajax_filter_customers'; - var postData = { + var postData = { 'csrfToken': GlobalVariables.csrfToken, - 'key': key + 'key': key }; - + $.post(postUrl, postData, function(response) { /////////////////////////////////////////////////////// console.log('Filter Customers Response:', response); /////////////////////////////////////////////////////// - + if (!GeneralFunctions.handleAjaxExceptions(response)) return; - + BackendCustomers.helper.filterResults = response; - - $('#filter-customers .results').data('jsp').destroy(); + + $('#filter-customers .results').data('jsp').destroy(); $('#filter-customers .results').html(''); $.each(response, function(index, customer) { var html = BackendCustomers.helper.getFilterHtml(customer); $('#filter-customers .results').append(html); }); $('#filter-customers .results').jScrollPane({ mouseWheelSpeed: 70 }); - + if (response.length == 0) { $('#filter-customers .results').html('' + EALang['no_records_found'] + ''); } - + if (selectId != undefined) { BackendCustomers.helper.select(selectId, display); } - - }, 'json'); + + }, 'json').fail(GeneralFunctions.ajaxFailureHandler); }; /** * Get the filter results row html code. - * + * * @param {object} customer Contains the customer data. * @return {string} Returns the record html code. */ CustomersHelper.prototype.getFilterHtml = function(customer) { var name = customer.first_name + ' ' + customer.last_name; - var info = customer.email; - info = (customer.phone_number != '' && customer.phone_number != null) + var info = customer.email; + info = (customer.phone_number != '' && customer.phone_number != null) ? info + ', ' + customer.phone_number : info; - - var html = + + var html = '
' + - '' + - name + - '
' + + '' + + name + + '
' + info + '

'; - + return html; }; - + /** - * Select a specific record from the current filter results. If the customer id does not exist - * in the list then no record will be selected. - * + * Select a specific record from the current filter results. If the customer id does not exist + * in the list then no record will be selected. + * * @param {numeric} id The record id to be selected from the filter results. * @param {bool} display (OPTIONAL = false) If true then the method will display the record * on the form. */ CustomersHelper.prototype.select = function(id, display) { if (display == undefined) display = false; - + $('#filter-customers .selected-row').removeClass('selected-row'); - + $('#filter-customers .customer-row').each(function() { if ($(this).attr('data-id') == id) { $(this).addClass('selected-row'); return false; } }); - - if (display) { + + if (display) { $.each(BackendCustomers.helper.filterResults, function(index, customer) { if (customer.id == id) { BackendCustomers.helper.display(customer); @@ -460,23 +460,23 @@ CustomersHelper.prototype.select = function(id, display) { } }); } -}; - +}; + /** * Display appointment details on customers backend page. - * + * * @param {object} appointment Appointment data */ CustomersHelper.prototype.displayAppointment = function(appointment) { var start = Date.parse(appointment.start_datetime).toString('dd/MM/yyyy HH:mm'); var end = Date.parse(appointment.end_datetime).toString('dd/MM/yyyy HH:mm'); - var html = - '
' + - '' + appointment.service.name + '
' + + var html = + '
' + + '' + appointment.service.name + '
' + appointment.provider.first_name + ' ' + appointment.provider.last_name + '
' + start + ' - ' + end + '
' + '
'; $('#appointment-details').html(html); -}; \ No newline at end of file +}; diff --git a/src/assets/js/backend_services.js b/src/assets/js/backend_services.js index a285a192..ef064e3f 100644 --- a/src/assets/js/backend_services.js +++ b/src/assets/js/backend_services.js @@ -1,59 +1,59 @@ /* ---------------------------------------------------------------------------- * Easy!Appointments - Open Source Web Scheduler - * + * * @package EasyAppointments * @author A.Tselegidis * @copyright Copyright (c) 2013 - 2015, Alex Tselegidis - * @license http://opensource.org/licenses/GPL-3.0 - GPLv3 + * @license http://opensource.org/licenses/GPL-3.0 - GPLv3 * @link http://easyappointments.org * @since v1.0.0 * ---------------------------------------------------------------------------- */ /** * This namespace handles the js functionality of the backend services page. - * + * * @namespace BackendServices */ var BackendServices = { /** * Contains the basic record methods for the page. - * + * * @type ServicesHelper|CategoriesHelper */ helper: {}, - + /** * Default initialize method of the page. - * - * @param {bool} bindEventHandlers (OPTIONAL) Determines whether to bind the + * + * @param {bool} bindEventHandlers (OPTIONAL) Determines whether to bind the * default event handlers (default: true). */ initialize: function(bindEventHandlers) { if (bindEventHandlers === undefined) bindEventHandlers = true; - + // Fill available service categories listbox. $.each(GlobalVariables.categories, function(index, category) { var option = new Option(category.name, category.id); $('#service-category').append(option); }); $('#service-category').append(new Option('- ' + EALang['no_category'] + ' -', null)).val('null'); - + $('#service-duration').spinner({ 'min': 0, 'disabled': true //default }); - + // Instantiate helper object (service helper by default). BackendServices.helper = new ServicesHelper(); BackendServices.helper.resetForm(); BackendServices.helper.filter(''); - + $('#filter-services .results').jScrollPane(); $('#filter-categories .results').jScrollPane(); - - if (bindEventHandlers) BackendServices.bindEventHandlers(); + + if (bindEventHandlers) BackendServices.bindEventHandlers(); }, - + /** * Binds the default event handlers of the backend services page. Do not use this method * if you include the "BackendServices" namespace on another page. @@ -61,14 +61,14 @@ var BackendServices = { bindEventHandlers: function() { /** * Event: Page Tab Button "Click" - * + * * Changes the displayed tab. */ $('.tab').click(function() { $(this).parent().find('.active').removeClass('active'); $(this).addClass('active'); $('.tab-content').hide(); - + if ($(this).hasClass('services-tab')) { // display services tab $('#services').show(); BackendServices.helper = new ServicesHelper(); @@ -76,36 +76,36 @@ var BackendServices = { $('#categories').show(); BackendServices.helper = new CategoriesHelper(); } - + BackendServices.helper.resetForm(); BackendServices.helper.filter(''); $('.filter-key').val(''); Backend.placeFooterToBottom(); }); - + ServicesHelper.prototype.bindEventHandlers(); CategoriesHelper.prototype.bindEventHandlers(); - + }, - + /** * Update the service category listbox. Use this method every time a change is made * to the service categories db table. */ updateAvailableCategories: function() { var postUrl = GlobalVariables.baseUrl + '/index.php/backend_api/ajax_filter_service_categories'; - var postData = { + var postData = { 'csrfToken': GlobalVariables.csrfToken, - 'key': '' + 'key': '' }; - + $.post(postUrl, postData, function(response) { /////////////////////////////////////////////////////////////// console.log('Update Available Categories Response:', response); /////////////////////////////////////////////////////////////// - + if (!GeneralFunctions.handleAjaxExceptions(response)) return; - + GlobalVariables.categories = response; var $select = $('#service-category'); $select.empty(); @@ -114,7 +114,7 @@ var BackendServices = { $select.append(option); }); $select.append(new Option('- ' + EALang['no_category'] + ' -', null)).val('null'); - }, 'json'); + }, 'json').fail(GeneralFunctions.ajaxFailureHandler); } }; @@ -148,7 +148,7 @@ ServicesHelper.prototype.bindEventHandlers = function() { /** * Event: Filter Service Row "Click" - * + * * Display the selected service data to the user. */ $(document).on('click', '.service-row', function() { @@ -157,7 +157,7 @@ ServicesHelper.prototype.bindEventHandlers = function() { return; // exit because we are on edit mode } - var serviceId = $(this).attr('data-id'); + var serviceId = $(this).attr('data-id'); var service = {}; $.each(BackendServices.helper.filterResults, function(index, item) { if (item.id === serviceId) { @@ -189,7 +189,7 @@ ServicesHelper.prototype.bindEventHandlers = function() { /** * Event: Cancel Service Button "Click" - * + * * Cancel add or edit of a service record. */ $('#cancel-service').click(function() { @@ -257,14 +257,14 @@ ServicesHelper.prototype.bindEventHandlers = function() { $('#message_box').dialog('close'); }; - GeneralFunctions.displayMessageBox(EALang['delete_service'], + GeneralFunctions.displayMessageBox(EALang['delete_service'], EALang['delete_record_prompt'], messageBtns); }); }; /** * Save service record to database. - * + * * @param {object} service Contains the service record data. If an 'id' value is provided * then the update operation is going to be executed. */ @@ -272,61 +272,61 @@ ServicesHelper.prototype.save = function(service) { //////////////////////////////////////////////// //console.log('Service data to save:', service); //////////////////////////////////////////////// - + var postUrl = GlobalVariables.baseUrl + '/index.php/backend_api/ajax_save_service'; - var postData = { + var postData = { 'csrfToken': GlobalVariables.csrfToken, - 'service': JSON.stringify(service) + 'service': JSON.stringify(service) }; - + $.post(postUrl, postData, function(response) { ////////////////////////////////////////////////// //console.log('Save Service Response:', response); ////////////////////////////////////////////////// if (!GeneralFunctions.handleAjaxExceptions(response)) return; - + Backend.displayNotification(EALang['service_saved']); BackendServices.helper.resetForm(); $('#filter-services .key').val(''); BackendServices.helper.filter('', response.id, true); - }, 'json'); + }, 'json').fail(GeneralFunctions.ajaxFailureHandler); }; /** * Delete a service record from database. - * - * @param {numeric} id Record id to be deleted. + * + * @param {numeric} id Record id to be deleted. */ ServicesHelper.prototype.delete = function(id) { var postUrl = GlobalVariables.baseUrl + '/index.php/backend_api/ajax_delete_service'; - var postData = { + var postData = { 'csrfToken': GlobalVariables.csrfToken, - 'service_id': id + 'service_id': id }; - + $.post(postUrl, postData, function(response) { //////////////////////////////////////////////////// //console.log('Delete service response:', response); //////////////////////////////////////////////////// - + if (!GeneralFunctions.handleAjaxExceptions(response)) return; - + Backend.displayNotification(EALang['service_deleted']); - + BackendServices.helper.resetForm(); BackendServices.helper.filter($('#filter-services .key').val()); - }, 'json'); + }, 'json').fail(GeneralFunctions.ajaxFailureHandler); }; /** * Validates a service record. - * + * * @param {object} service Contains the service data. * @returns {bool} Returns the validation result. */ ServicesHelper.prototype.validate = function(service) { $('#services .required').css('border', ''); - + try { // validate required fields. var missingRequired = false; @@ -336,11 +336,11 @@ ServicesHelper.prototype.validate = function(service) { missingRequired = true; } }); - - if (missingRequired) + + if (missingRequired) throw EALang['fields_are_required']; - - + + return true; } catch(exc) { return false; @@ -348,7 +348,7 @@ ServicesHelper.prototype.validate = function(service) { }; /** - * Resets the service tab form back to its initial state. + * Resets the service tab form back to its initial state. */ ServicesHelper.prototype.resetForm = function() { $('#services .details').find('input, textarea').val(''); @@ -359,7 +359,7 @@ ServicesHelper.prototype.resetForm = function() { $('#services .details').find('input, textarea').prop('readonly', true); $('#service-category').prop('disabled', true); $('#service-duration').spinner('disable'); - + $('#filter-services .selected-row').removeClass('selected-row'); $('#filter-services button').prop('disabled', false); $('#filter-services .results').css('color', ''); @@ -367,7 +367,7 @@ ServicesHelper.prototype.resetForm = function() { /** * Display a service record into the service form. - * + * * @param {object} service Contains the service record data. */ ServicesHelper.prototype.display = function(service) { @@ -377,67 +377,67 @@ ServicesHelper.prototype.display = function(service) { $('#service-price').val(service.price); $('#service-currency').val(service.currency); $('#service-description').val(service.description); - + var categoryId = (service.id_service_categories != null) ? service.id_service_categories : 'null'; $('#service-category').val(categoryId); }; /** * Filters service records depending a string key. - * + * * @param {string} key This is used to filter the service records of the database. - * @param {numeric} selectId (OPTIONAL = undefined) If set then after the filter + * @param {numeric} selectId (OPTIONAL = undefined) If set then after the filter * operation the record with this id will be selected (but not displayed). - * @param {bool} display (OPTIONAL = false) If true then the selected record will + * @param {bool} display (OPTIONAL = false) If true then the selected record will * be displayed on the form. */ ServicesHelper.prototype.filter = function(key, selectId, display) { if (display == undefined) display = false; - + var postUrl = GlobalVariables.baseUrl + '/index.php/backend_api/ajax_filter_services'; - var postData = { + var postData = { 'csrfToken': GlobalVariables.csrfToken, - 'key': key + 'key': key }; - + $.post(postUrl, postData, function(response) { ///////////////////////////////////////////////////// //console.log('Filter services response:', response); ///////////////////////////////////////////////////// - + if (!GeneralFunctions.handleAjaxExceptions(response)) return; BackendServices.helper.filterResults = response; - + $('#filter-services .results').data('jsp').destroy(); $('#filter-services .results').html(''); $.each(response, function(index, service) { var html = ServicesHelper.prototype.getFilterHtml(service); $('#filter-services .results').append(html); - }); + }); $('#filter-services .results').jScrollPane({ mouseWheelSpeed: 70 }); - + if (response.length == 0) { $('#filter-services .results').html('' + EALang['no_records_found'] + ''); } - + if (selectId != undefined) { BackendServices.helper.select(selectId, display); } - }, 'json'); + }, 'json').fail(GeneralFunctions.ajaxFailureHandler); }; /** * Get a service row html code that is going to be displayed on the filter results list. - * + * * @param {object} service Contains the service record data. * @returns {string} The html code that represents the record on the filter results list. */ ServicesHelper.prototype.getFilterHtml = function(service) { var html = - '
' + + '
' + '' + service.name + '
' + - service.duration + ' min - ' + + service.duration + ' min - ' + service.price + ' ' + service.currency + '
' + '

'; @@ -445,26 +445,26 @@ ServicesHelper.prototype.getFilterHtml = function(service) { }; /** - * Select a specific record from the current filter results. If the service id does not exist - * in the list then no record will be selected. - * + * Select a specific record from the current filter results. If the service id does not exist + * in the list then no record will be selected. + * * @param {numeric} id The record id to be selected from the filter results. * @param {bool} display (OPTIONAL = false) If true then the method will display the record * on the form. */ ServicesHelper.prototype.select = function(id, display) { if (display == undefined) display = false; - + $('#filter-services .selected-row').removeClass('selected-row'); - + $('#filter-services .service-row').each(function() { if ($(this).attr('data-id') == id) { $(this).addClass('selected-row'); return false; } }); - - if (display) { + + if (display) { $.each(BackendServices.helper.filterResults, function(index, service) { if (service.id == id) { BackendServices.helper.display(service); @@ -478,7 +478,7 @@ ServicesHelper.prototype.select = function(id, display) { /** * This class contains the core method implementations that belong to the categories tab * of the backend services page. - * + * * @class CategoriesHelper */ var CategoriesHelper = function() { @@ -507,10 +507,10 @@ CategoriesHelper.prototype.bindEventHandlers = function() { BackendServices.helper.filter(key); return false; }); - + /** * Event: Filter Categories Row "Click" - * + * * Displays the selected row data on the right side of the page. */ $(document).on('click', '.category-row', function() { @@ -533,7 +533,7 @@ CategoriesHelper.prototype.bindEventHandlers = function() { $(this).addClass('selected-row'); $('#edit-category, #delete-category').prop('disabled', false); }); - + /** * Event: Add Category Button "Click" */ @@ -545,7 +545,7 @@ CategoriesHelper.prototype.bindEventHandlers = function() { $('#filter-categories button').prop('disabled', true); $('#filter-categories .results').css('color', '#AAA'); }); - + /** * Event: Edit Category Button "Click" */ @@ -557,7 +557,7 @@ CategoriesHelper.prototype.bindEventHandlers = function() { $('#filter-categories button').prop('disabled', true); $('#filter-categories .results').css('color', '#AAA'); }); - + /** * Event: Delete Category Button "Click" */ @@ -573,10 +573,10 @@ CategoriesHelper.prototype.bindEventHandlers = function() { $('#message_box').dialog('close'); }; - GeneralFunctions.displayMessageBox(EALang['delete_category'], + GeneralFunctions.displayMessageBox(EALang['delete_category'], EALang['delete_record_prompt'], messageBtns); }); - + /** * Event: Categories Save Button "Click" */ @@ -594,7 +594,7 @@ CategoriesHelper.prototype.bindEventHandlers = function() { BackendServices.helper.save(category); }); - + /** * Event: Cancel Category Button "Click" */ @@ -609,29 +609,29 @@ CategoriesHelper.prototype.bindEventHandlers = function() { /** * Filter service categories records. - * + * * @param {string} key This key string is used to filter the category records. - * @param {numeric} selectId (OPTIONAL = undefined) If set then after the filter + * @param {numeric} selectId (OPTIONAL = undefined) If set then after the filter * operation the record with the given id will be selected (but not displayed). * @param {bool} display (OPTIONAL = false) If true then the selected record will * be displayed on the form. */ CategoriesHelper.prototype.filter = function(key, selectId, display) { var postUrl = GlobalVariables.baseUrl + '/index.php/backend_api/ajax_filter_service_categories'; - var postData = { + var postData = { 'csrfToken': GlobalVariables.csrfToken, - 'key': key + 'key': key }; - + $.post(postUrl, postData, function(response) { /////////////////////////////////////////////////////// console.log('Filter Categories Response:', response); /////////////////////////////////////////////////////// - + if (!GeneralFunctions.handleAjaxExceptions(response)) return; - + BackendServices.helper.filterResults = response; - + $('#filter-categories .results').data('jsp').destroy(); $('#filter-categories .results').html(''); $.each(response, function(index, category) { @@ -639,75 +639,75 @@ CategoriesHelper.prototype.filter = function(key, selectId, display) { $('#filter-categories .results').append(html); }); $('#filter-categories .results').jScrollPane({ mouseWheelSpeed: 70 }); - + if (response.length == 0) { $('#filter-categories .results').html('' + EALang['no_records_found'] + ''); } - + if (selectId != undefined) { BackendServices.helper.select(selectId, display); } - - }, 'json'); + + }, 'json').fail(GeneralFunctions.ajaxFailureHandler); }; /** * Save a category record to the database (via ajax post). - * + * * @param {object} category Contains the category data. */ CategoriesHelper.prototype.save = function(category) { var postUrl = GlobalVariables.baseUrl + '/index.php/backend_api/ajax_save_service_category'; - var postData = { + var postData = { 'csrfToken': GlobalVariables.csrfToken, - 'category': JSON.stringify(category) + 'category': JSON.stringify(category) }; - + $.post(postUrl, postData, function(response) { /////////////////////////////////////////////////////////// console.log('Save Service Category Response:', response); /////////////////////////////////////////////////////////// - + if (!GeneralFunctions.handleAjaxExceptions(response)) return; - + Backend.displayNotification(EALang['service_category_saved']); BackendServices.helper.resetForm(); $('#filter-categories .key').val(''); BackendServices.helper.filter('', response.id, true); BackendServices.updateAvailableCategories(); - }, 'json'); + }, 'json').fail(GeneralFunctions.ajaxFailureHandler); }; /** * Delete category record. - * + * * @param {int} id Record id to be deleted. */ CategoriesHelper.prototype.delete = function(id) { var postUrl = GlobalVariables.baseUrl + '/index.php/backend_api/ajax_delete_service_category'; - var postData = { + var postData = { 'csrfToken': GlobalVariables.csrfToken, - 'category_id': id + 'category_id': id }; - + $.post(postUrl, postData, function(response) { //////////////////////////////////////////////////// console.log('Delete category response:', response); //////////////////////////////////////////////////// - + if (!GeneralFunctions.handleAjaxExceptions(response)) return; - + Backend.displayNotification(EALang['service_category_deleted']); - + BackendServices.helper.resetForm(); BackendServices.helper.filter($('#filter-categories .key').val()); BackendServices.updateAvailableCategories(); - }, 'json'); + }, 'json').fail(GeneralFunctions.ajaxFailureHandler); }; /** * Display a category record on the form. - * + * * @param {object} category Contains the category data. */ CategoriesHelper.prototype.display = function(category) { @@ -718,12 +718,12 @@ CategoriesHelper.prototype.display = function(category) { /** * Validate category data before save (insert or update). - * + * * @param {object} category Contains the category data. */ CategoriesHelper.prototype.validate = function(category) { $('#categories .details').find('input, textarea').css('border', ''); - + try { var missingRequired = false; $('#categories .required').each(function() { @@ -733,9 +733,9 @@ CategoriesHelper.prototype.validate = function(category) { } }); if (missingRequired) throw EALang['fields_are_required']; - + return true; - + } catch(exc) { console.log('Category Record Validation Exc:', exc); return false; @@ -751,7 +751,7 @@ CategoriesHelper.prototype.resetForm = function() { $('#categories .details').find('input, textarea').val(''); $('#categories .details').find('input, textarea').prop('readonly', true); $('#edit-category, #delete-category').prop('disabled', true); - + $('#filter-categories .selected-row').removeClass('selected-row'); $('#filter-categories .results').css('color', ''); $('#filter-categories button').prop('disabled', false); @@ -759,13 +759,13 @@ CategoriesHelper.prototype.resetForm = function() { /** * Get the filter results row html code. - * + * * @param {object} category Contains the category data. * @return {string} Returns the record html code. */ -CategoriesHelper.prototype.getFilterHtml = function(category) { +CategoriesHelper.prototype.getFilterHtml = function(category) { var html = - '
' + + '
' + '' + category.name + '' + '

'; @@ -773,26 +773,26 @@ CategoriesHelper.prototype.getFilterHtml = function(category) { }; /** - * Select a specific record from the current filter results. If the category id does not exist - * in the list then no record will be selected. - * + * Select a specific record from the current filter results. If the category id does not exist + * in the list then no record will be selected. + * * @param {numeric} id The record id to be selected from the filter results. * @param {bool} display (OPTIONAL = false) If true then the method will display the record * on the form. */ CategoriesHelper.prototype.select = function(id, display) { if (display == undefined) display = false; - + $('#filter-categories .selected-row').removeClass('selected-row'); - + $('#filter-categories .category-row').each(function() { if ($(this).attr('data-id') == id) { $(this).addClass('selected-row'); return false; } }); - - if (display) { + + if (display) { $.each(BackendServices.helper.filterResults, function(index, category) { if (category.id == id) { BackendServices.helper.display(category); @@ -801,4 +801,4 @@ CategoriesHelper.prototype.select = function(id, display) { } }); } -}; \ No newline at end of file +}; diff --git a/src/assets/js/backend_settings.js b/src/assets/js/backend_settings.js index 8ea4dd45..0974e6b3 100644 --- a/src/assets/js/backend_settings.js +++ b/src/assets/js/backend_settings.js @@ -1,70 +1,70 @@ /* ---------------------------------------------------------------------------- * Easy!Appointments - Open Source Web Scheduler - * + * * @package EasyAppointments * @author A.Tselegidis * @copyright Copyright (c) 2013 - 2015, Alex Tselegidis - * @license http://opensource.org/licenses/GPL-3.0 - GPLv3 + * @license http://opensource.org/licenses/GPL-3.0 - GPLv3 * @link http://easyappointments.org * @since v1.0.0 * ---------------------------------------------------------------------------- */ /** - * Contains the functionality of the backend settings page. Can either work for + * Contains the functionality of the backend settings page. Can either work for * system or user settings, but the actions allowed to the user are restricted to * his role (only admin has full privileges). - * + * * @namespace BackendSettings */ var BackendSettings = { SETTINGS_SYSTEM: 'SETTINGS_SYSTEM', SETTINGS_USER: 'SETTINGS_USER', - + /** * Use this WorkingPlan class instance to perform actions on the page's working plan * tables. */ wp: {}, - + /** * Tab settings object. - * + * * @type {object} */ settings: {}, - + /** * Initialize Page - * + * * @param {bool} bindEventHandlers (OPTIONAL)Determines whether to bind the default event * handlers (default = true). * @returns {undefined} */ initialize: function(bindEventHandlers) { if (bindEventHandlers == undefined) bindEventHandlers = true; - + // Apply setting values from database. $.each(GlobalVariables.settings.system, function(index, setting) { $('input[data-field="' + setting.name + '"]').val(setting.value); }); - + var workingPlan = {}; $.each(GlobalVariables.settings.system, function(index, setting) { if (setting.name == 'company_working_plan') { - workingPlan = $.parseJSON(setting.value); + workingPlan = $.parseJSON(setting.value); return false; } }); - + BackendSettings.wp = new WorkingPlan(); BackendSettings.wp.setup(workingPlan); BackendSettings.wp.timepickers(false); - + // Book Advance Timeout Spinner $('#book-advance-timeout').spinner({ 'min': 0 }); - + // Load user settings into form $('#user-id').val(GlobalVariables.settings.user.id); $('#first-name').val(GlobalVariables.settings.user.first_name); @@ -77,87 +77,87 @@ var BackendSettings = { $('#state').val(GlobalVariables.settings.user.state); $('#zip-code').val(GlobalVariables.settings.user.zip_code); $('#notes').val(GlobalVariables.settings.user.notes); - + $('#username').val(GlobalVariables.settings.user.settings.username); $('#password, #retype-password').val(''); - - if (GlobalVariables.settings.user.settings.notifications == true) { + + if (GlobalVariables.settings.user.settings.notifications == true) { $('#user-notifications').addClass('active'); } else { $('#user-notifications').removeClass('active'); } - + // Set default settings helper. BackendSettings.settings = new SystemSettings(); - + if (bindEventHandlers) { BackendSettings.bindEventHandlers(); $('#settings-page .nav li').first().addClass('active'); $('#settings-page .nav li').first().find('a').trigger('click'); } - + // Apply Privileges if (GlobalVariables.user.privileges.system_settings.edit == false) { $('#general, #business-logic').find('select, input, textarea').prop('readonly', true); $('#general, #business-logic').find('button').prop('disabled', true); } - + if (GlobalVariables.user.privileges.user_settings.edit == false) { $('#user').find('select, input, textarea').prop('readonly', true); $('#user').find('button').prop('disabled', true); } - + Backend.placeFooterToBottom(); }, - + /** - * Bind the backend/settings default event handlers. This method depends on the + * Bind the backend/settings default event handlers. This method depends on the * backend/settings html, so do not use this method on a different page. */ bindEventHandlers: function() { BackendSettings.wp.bindEventHandlers(); - + /** * Event: Tab "Click" - * + * * Change the visible tab contents. */ $('.tab').click(function() { // Bootstrap has a bug with toggle buttons. Their toggle state is lost when the - // button is hidden or shown. Show before anything else we need to store the toggle + // button is hidden or shown. Show before anything else we need to store the toggle // and apply it whenever the user tab is clicked.. var areNotificationsActive = $('#user-notifications').hasClass('active'); - + $(this).parent().find('.active').removeClass('active'); $(this).addClass('active'); $('.tab-content').hide(); - - if ($(this).hasClass('general-tab')) { + + if ($(this).hasClass('general-tab')) { $('#general').show(); BackendSettings.settings = new SystemSettings(); - } else if ($(this).hasClass('business-logic-tab')) { + } else if ($(this).hasClass('business-logic-tab')) { $('#business-logic').show(); BackendSettings.settings = new SystemSettings(); } else if ($(this).hasClass('user-tab')) { $('#user').show(); BackendSettings.settings = new UserSettings(); - + // Apply toggle state to user notifications button. if (areNotificationsActive) { $('#user-notifications').addClass('active'); } else { - $('#user-notifications').removeClass('active'); + $('#user-notifications').removeClass('active'); } } else if ($(this).hasClass('about-tab')) { $('#about').show(); } - + Backend.placeFooterToBottom(); }); - + /** * Event: Save Settings Button "Click" - * + * * Store the setting changes into the database. */ $('.save-settings').click(function() { @@ -167,25 +167,25 @@ var BackendSettings = { //console.log('Settings To Save: ', settings); ////////////////////////////////////////////// }); - + /** - * Event: Username "Focusout" - * - * When the user leaves the username input field we will need to check if the username + * Event: Username "Focusout" + * + * When the user leaves the username input field we will need to check if the username * is not taken by another record in the system. Usernames must be unique. */ $('#username').focusout(function() { var $input = $(this); - + if ($input.prop('readonly') == true || $input.val() == '') return; - + var postUrl = GlobalVariables.baseUrl + '/index.php/backend_api/ajax_validate_username'; - var postData = { + var postData = { 'csrfToken': GlobalVariables.csrfToken, - 'username': $input.val(), + 'username': $input.val(), 'user_id': $input.parents().eq(2).find('#user-id').val() }; - + $.post(postUrl, postData, function(response) { /////////////////////////////////////////////////////// //console.log('Validate Username Response:', response); @@ -199,7 +199,7 @@ var BackendSettings = { $input.css('border', ''); $input.attr('already-exists', 'false'); } - }, 'json'); + }, 'json').fail(GeneralFunctions.ajaxFailureHandler); }); } }; @@ -211,9 +211,9 @@ var BackendSettings = { var SystemSettings = function() {}; /** - * Save the system settings. This method is run after changes are detected on the + * Save the system settings. This method is run after changes are detected on the * tab input fields. - * + * * @param {array} settings Contains the system settings data. */ SystemSettings.prototype.save = function(settings) { @@ -223,37 +223,37 @@ SystemSettings.prototype.save = function(settings) { 'settings': JSON.stringify(settings), 'type': BackendSettings.SETTINGS_SYSTEM }; - + $.post(postUrl, postData, function(response) { /////////////////////////////////////////////////////////// console.log('Save General Settings Response:', response); /////////////////////////////////////////////////////////// - + if (!GeneralFunctions.handleAjaxExceptions(response)) return; - + Backend.displayNotification(EALang['settings_saved']); - + // Update the logo title on the header. $('#header-logo span').text($('#company-name').val()); - + // We need to refresh the working plan. var workingPlan = BackendSettings.wp.get(); $('.breaks').empty(); BackendSettings.wp.setup(workingPlan); BackendSettings.wp.timepickers(false); - - }, 'json'); + + }, 'json').fail(GeneralFunctions.ajaxFailureHandler); }; /** - * Prepare the system settings array. This method uses the DOM elements of the + * Prepare the system settings array. This method uses the DOM elements of the * backend/settings page, so it can't be used in another page. - * + * * @returns {array} Returns the system settings array. */ SystemSettings.prototype.get = function() { var settings = []; - + // General Settings Tab $('#general input').each(function() { settings.push({ @@ -261,30 +261,30 @@ SystemSettings.prototype.get = function() { 'value': $(this).val() }); }); - + // Business Logic Tab settings.push({ 'name': 'company_working_plan', 'value': JSON.stringify(BackendSettings.wp.get()) }); - + settings.push({ 'name': 'book_advance_timeout', 'value': $('#book-advance-timeout').val() }); - + return settings; }; /** - * Validate the settings data. If the validation fails then display a + * Validate the settings data. If the validation fails then display a * message to the user. - * + * * @returns {bool} Returns the validation result. */ SystemSettings.prototype.validate = function() { $('#general .required').css('border', ''); - + try { // Validate required fields. var missingRequired = false; @@ -297,13 +297,13 @@ SystemSettings.prototype.validate = function() { if (missingRequired) { throw EALang['fields_are_required']; } - + // Validate company email address. if (!GeneralFunctions.validateEmail($('#company-email').val())) { $('#company-email').css('border', '2px solid red'); throw EALang['invalid_email']; } - + return true; } catch(exc) { Backend.displayNotification(exc); @@ -319,7 +319,7 @@ var UserSettings = function() {}; /** * Get the settings data for the user settings. - * + * * @returns {object} Returns the user settings array. */ UserSettings.prototype.get = function() { @@ -340,17 +340,17 @@ UserSettings.prototype.get = function() { 'notifications': $('#user-notifications').hasClass('active') } }; - + if ($('#password').val() != '') { user.settings.password = $('#password').val(); } - + return user; }; /** * Store the user settings into the database. - * + * * @param {array} settings Contains the user settings. */ UserSettings.prototype.save = function(settings) { @@ -358,32 +358,32 @@ UserSettings.prototype.save = function(settings) { Backend.displayNotification(EALang['user_settings_are_invalid']); return; // Validation failed, do not procceed. } - + var postUrl = GlobalVariables.baseUrl + '/index.php/backend_api/ajax_save_settings'; var postData = { 'csrfToken': GlobalVariables.csrfToken, 'type': BackendSettings.SETTINGS_USER, 'settings': JSON.stringify(settings) }; - + $.post(postUrl, postData, function(response) { ////////////////////////////////////////////////////////// console.log('Save User Settings Response: ', response); ////////////////////////////////////////////////////////// - + if (!GeneralFunctions.handleAjaxExceptions(response)) return; Backend.displayNotification(EALang['settings_saved']); - + // Update footer greetings. $('#footer-user-display-name').text('Hello, ' + $('#first-name').val() + ' ' + $('#last-name').val() + '!'); - - }, 'json'); + + }, 'json').fail(GeneralFunctions.ajaxFailureHandler); }; /** - * Validate the settings data. If the validation fails then display a + * Validate the settings data. If the validation fails then display a * message to the user. - * + * * @returns {bool} Returns the validation result. */ UserSettings.prototype.validate = function() { @@ -402,24 +402,24 @@ UserSettings.prototype.validate = function() { if (missingRequired) { throw EALang['fields_are_required']; } - + // Validate passwords (if provided). if ($('#password').val() != $('#retype-password').val()) { $('#password, #retype-password').css('border', '2px solid red'); throw EALang['passwords_mismatch']; } - + // Validate user email. if (!GeneralFunctions.validateEmail($('#email').val())) { $('#email').css('border', '2px solid red'); throw EALang['invalid_email']; } - + if ($('#username').attr('already-exists') === 'true') { $('#username').css('border', '2px solid red'); throw EALang['username_already_exists']; } - + return true; } catch(exc) { Backend.displayNotification(exc); diff --git a/src/assets/js/backend_users.js b/src/assets/js/backend_users.js index efefdfff..5e3cc3ee 100644 --- a/src/assets/js/backend_users.js +++ b/src/assets/js/backend_users.js @@ -1,90 +1,90 @@ /* ---------------------------------------------------------------------------- * Easy!Appointments - Open Source Web Scheduler - * + * * @package EasyAppointments * @author A.Tselegidis * @copyright Copyright (c) 2013 - 2015, Alex Tselegidis - * @license http://opensource.org/licenses/GPL-3.0 - GPLv3 + * @license http://opensource.org/licenses/GPL-3.0 - GPLv3 * @link http://easyappointments.org * @since v1.0.0 * ---------------------------------------------------------------------------- */ /** * This namespace handles the js functionality of the users backend page. It uses three other - * classes (defined below) in order to handle the admin, provider and secretary record types. - * + * classes (defined below) in order to handle the admin, provider and secretary record types. + * * @namespace BackendUsers */ var BackendUsers = { - MIN_PASSWORD_LENGTH: 7, - + MIN_PASSWORD_LENGTH: 7, + /** * Contains the current tab record methods for the page. - * + * * @type AdminsHelper|ProvidersHelper|SecretariesHelper */ helper: {}, - + /** * Use this class instance for performing actions on the working plan. - * + * * @type {object} */ wp: {}, - + /** * Initialize the backend users page. - * - * @param {bool} defaultEventHandlers (OPTIONAL) Whether to bind the default event handlers + * + * @param {bool} defaultEventHandlers (OPTIONAL) Whether to bind the default event handlers * (default: true). */ initialize: function(defaultEventHandlers) { if (defaultEventHandlers == undefined) defaultEventHandlers = true; - + // Initialize jScrollPane Scrollbars $('#filter-admins .results').jScrollPane(); $('#filter-providers .results').jScrollPane(); $('#filter-secretaries .results').jScrollPane(); - + // Instanciate default helper object (admin). BackendUsers.helper = new AdminsHelper(); BackendUsers.helper.resetForm(); BackendUsers.helper.filter(''); - + BackendUsers.wp = new WorkingPlan(); BackendUsers.wp.bindEventHandlers(); - + // Fill the services and providers list boxes. var html = '
'; $.each(GlobalVariables.services, function(index, service) { - html += + html += '
' + '' + '
'; - + }); html += '
'; $('#provider-services').html(html); $('#provider-services').jScrollPane({ mouseWheelSpeed: 70 }); - + var html = '
'; $.each(GlobalVariables.providers, function(index, provider) { - html += + html += '
' + '' + '
'; - + }); html += '
'; $('#secretary-providers').html(html); $('#secretary-providers').jScrollPane({ mouseWheelSpeed: 70 }); - + $('#reset-working-plan').qtip({ position: { my: 'top center', @@ -94,26 +94,26 @@ var BackendUsers = { classes: 'qtip-green qtip-shadow custom-qtip' } }); - + // Bind event handlers. if (defaultEventHandlers) BackendUsers.bindEventHandlers(); }, - + /** - * Binds the defauly backend users event handlers. Do not use this method on a different + * Binds the defauly backend users event handlers. Do not use this method on a different * page because it needs the backend users page DOM. */ bindEventHandlers: function() { /** * Event: Page Tab Button "Click" - * + * * Changes the displayed tab. */ $('.tab').click(function() { $(this).parent().find('.active').removeClass('active'); $(this).addClass('active'); $('.tab-content').hide(); - + if ($(this).hasClass('admins-tab')) { // display admins tab $('#admins').show(); BackendUsers.helper = new AdminsHelper(); @@ -125,68 +125,68 @@ var BackendUsers = { } else if ($(this).hasClass('secretaries-tab')) { // display secretaries tab $('#secretaries').show(); BackendUsers.helper = new SecretariesHelper(); - + // Update the list with the all the available providers. var postUrl = GlobalVariables.baseUrl + '/index.php/backend_api/ajax_filter_providers'; - var postData = { + var postData = { 'csrfToken': GlobalVariables.csrfToken, - 'key': '' + 'key': '' }; $.post(postUrl, postData, function(response) { ////////////////////////////////////////////////////////// //console.log('Get all db providers response:', response); ////////////////////////////////////////////////////////// - + if (!GeneralFunctions.handleAjaxExceptions(response)) return; - + GlobalVariables.providers = response; - + $('#secretary-providers').data('jsp').destroy(); var html = '
'; $.each(GlobalVariables.providers, function(index, provider) { - html += + html += '
' + '' + '
'; - + }); html += '
'; $('#secretary-providers').html(html); - + $('#secretary-providers input[type="checkbox"]').prop('disabled', true); $('#secretary-providers').jScrollPane({ mouseWheelSpeed: 70 }); - }, 'json'); + }, 'json').fail(GeneralFunctions.ajaxFailureHandler); } - + BackendUsers.helper.resetForm(); BackendUsers.helper.filter(''); $('.filter-key').val(''); }); - + /** - * Event: Admin, Provider, Secretary Username "Focusout" - * - * When the user leaves the username input field we will need to check if the username + * Event: Admin, Provider, Secretary Username "Focusout" + * + * When the user leaves the username input field we will need to check if the username * is not taken by another record in the system. Usernames must be unique. */ $('#admin-username, #provider-username, #secretary-username').focusout(function() { var $input = $(this); - + if ($input.prop('readonly') == true || $input.val() == '') { return; } - + var postUrl = GlobalVariables.baseUrl + '/index.php/backend_api/ajax_validate_username'; var postData = { - 'csrfToken': GlobalVariables.csrfToken, - 'username': $input.val(), + 'csrfToken': GlobalVariables.csrfToken, + 'username': $input.val(), 'user_id': $input.parents().eq(2).find('.record-id').val() }; - + $.post(postUrl, postData, function(response) { /////////////////////////////////////////////////////// console.log('Validate Username Response:', response); @@ -204,21 +204,21 @@ var BackendUsers = { $input.parents().eq(3).find('.form-message').hide(); } } - }, 'json'); + }, 'json').fail(GeneralFunctions.ajaxFailureHandler); }); - + // ------------------------------------------------------------------------ - + AdminsHelper.prototype.bindEventHandlers(); - + // ------------------------------------------------------------------------ - + ProvidersHelper.prototype.bindEventHandlers(); - + // ------------------------------------------------------------------------ - + SecretariesHelper.prototype.bindEventHandlers(); - + // ------------------------------------------------------------------------ } -}; \ No newline at end of file +}; diff --git a/src/assets/js/backend_users_admins.js b/src/assets/js/backend_users_admins.js index f10d58c0..f127d599 100644 --- a/src/assets/js/backend_users_admins.js +++ b/src/assets/js/backend_users_admins.js @@ -1,19 +1,19 @@ /* ---------------------------------------------------------------------------- * Easy!Appointments - Open Source Web Scheduler - * + * * @package EasyAppointments * @author A.Tselegidis * @copyright Copyright (c) 2013 - 2015, Alex Tselegidis - * @license http://opensource.org/licenses/GPL-3.0 - GPLv3 + * @license http://opensource.org/licenses/GPL-3.0 - GPLv3 * @link http://easyappointments.org * @since v1.0.0 * ---------------------------------------------------------------------------- */ /** - * This class contains the Admins helper class declaration, along with the "Admins" tab + * This class contains the Admins helper class declaration, along with the "Admins" tab * event handlers. By deviding the backend/users tab functionality into separate files * it is easier to maintain the code. - * + * * @class AdminsHelper */ var AdminsHelper = function() { @@ -26,7 +26,7 @@ var AdminsHelper = function() { AdminsHelper.prototype.bindEventHandlers = function() { /** * Event: Filter Admins Form "Sumbit" - * + * * Filter the admin records with the given key string. */ $('#filter-admins form').submit(function(event) { @@ -36,7 +36,7 @@ AdminsHelper.prototype.bindEventHandlers = function() { BackendUsers.helper.filter(key); return false; }); - + /** * Event: Clear Filter Results Button "Click" */ @@ -47,7 +47,7 @@ AdminsHelper.prototype.bindEventHandlers = function() { /** * Event: Filter Admin Row "Click" - * + * * Display the selected admin data to the user. */ $(document).on('click', '.admin-row', function() { @@ -64,7 +64,7 @@ AdminsHelper.prototype.bindEventHandlers = function() { return false; } }); - + BackendUsers.helper.display(admin); $('#filter-admins .selected-row').removeClass('selected-row'); $(this).addClass('selected-row'); @@ -94,7 +94,7 @@ AdminsHelper.prototype.bindEventHandlers = function() { $('#admins .details').find('input, textarea').prop('readonly', false); $('#admin-password, #admin-password-confirm').removeClass('required'); $('#admin-notifications').prop('disabled', false); - + $('#filter-admins .filter').prop('disabled', true); $('#filter-admins .results').css('color', '#AAA'); }); @@ -114,7 +114,7 @@ AdminsHelper.prototype.bindEventHandlers = function() { $('#message_box').dialog('close'); }; - GeneralFunctions.displayMessageBox(EALang['delete_admin'], + GeneralFunctions.displayMessageBox(EALang['delete_admin'], EALang['delete_record_prompt'], messageBtns); }); @@ -134,7 +134,7 @@ AdminsHelper.prototype.bindEventHandlers = function() { 'zip_code': $('#admin-zip-code').val(), 'notes': $('#admin-notes').val(), 'settings': { - 'username': $('#admin-username').val(), + 'username': $('#admin-username').val(), 'notifications': $('#admin-notifications').hasClass('active') } }; @@ -156,7 +156,7 @@ AdminsHelper.prototype.bindEventHandlers = function() { /** * Event: Cancel Admin Button "Click" - * + * * Cancel add or edit of an admin record. */ $('#cancel-admin').click(function() { @@ -170,7 +170,7 @@ AdminsHelper.prototype.bindEventHandlers = function() { /** * Save admin record to database. - * + * * @param {object} admin Contains the admin record data. If an 'id' value is provided * then the update operation is going to be executed. */ @@ -178,13 +178,13 @@ AdminsHelper.prototype.save = function(admin) { //////////////////////////////////////////// //console.log('Admin data to save:', admin); //////////////////////////////////////////// - + var postUrl = GlobalVariables.baseUrl + '/index.php/backend_api/ajax_save_admin'; - var postData = { + var postData = { 'csrfToken': GlobalVariables.csrfToken, - 'admin': JSON.stringify(admin) + 'admin': JSON.stringify(admin) }; - + $.post(postUrl, postData, function(response) { //////////////////////////////////////////////// //console.log('Save Admin Response:', response); @@ -193,22 +193,22 @@ AdminsHelper.prototype.save = function(admin) { Backend.displayNotification(EALang['admin_saved']); BackendUsers.helper.resetForm(); $('#filter-admins .key').val(''); - BackendUsers.helper.filter('', response.id, true); - }, 'json'); + BackendUsers.helper.filter('', response.id, true); + }, 'json').fail(GeneralFunctions.ajaxFailureHandler); }; /** * Delete an admin record from database. - * - * @param {int} id Record id to be deleted. + * + * @param {int} id Record id to be deleted. */ AdminsHelper.prototype.delete = function(id) { var postUrl = GlobalVariables.baseUrl + '/index.php/backend_api/ajax_delete_admin'; - var postData = { + var postData = { 'csrfToken': GlobalVariables.csrfToken, - 'admin_id': id + 'admin_id': id }; - + $.post(postUrl, postData, function(response) { ////////////////////////////////////////////////// //console.log('Delete admin response:', response); @@ -217,19 +217,19 @@ AdminsHelper.prototype.delete = function(id) { Backend.displayNotification(EALang['admin_deleted']); BackendUsers.helper.resetForm(); BackendUsers.helper.filter($('#filter-admins .key').val()); - }, 'json'); + }, 'json').fail(GeneralFunctions.ajaxFailureHandler); }; /** * Validates an admin record. - * + * * @param {object} admin Contains the admin data to be validated. * @returns {bool} Returns the validation result. */ AdminsHelper.prototype.validate = function(admin) { $('#admins .required').css('border', ''); $('#admin-password, #admin-password-confirm').css('border', ''); - + try { // Validate required fields. var missingRequired = false; @@ -242,32 +242,32 @@ AdminsHelper.prototype.validate = function(admin) { if (missingRequired) { throw 'Fields with * are required.'; } - + // Validate passwords. if ($('#admin-password').val() != $('#admin-password-confirm').val()) { $('#admin-password, #admin-password-confirm').css('border', '2px solid red'); throw EALang['passwords_mismatch']; } - + if ($('#admin-password').val().length < BackendUsers.MIN_PASSWORD_LENGTH && $('#admin-password').val() != '') { $('#admin-password, #admin-password-confirm').css('border', '2px solid red'); - + throw EALang['password_length_notice'].replace('$number', BackendUsers.MIN_PASSWORD_LENGTH); } - + // Validate user email. if (!GeneralFunctions.validateEmail($('#admin-email').val())) { $('#admin-email').css('border', '2px solid red'); throw EALang['invalid_email']; } - + // Check if username exists if ($('#admin-username').attr('already-exists') == 'true') { $('#admin-username').css('border', '2px solid red'); throw EALang['username_already_exists']; - } - + } + return true; } catch(exc) { $('#admins .form-message').text(exc); @@ -277,20 +277,20 @@ AdminsHelper.prototype.validate = function(admin) { }; /** - * Resets the admin form back to its initial state. + * Resets the admin form back to its initial state. */ AdminsHelper.prototype.resetForm = function() { $('#admins .add-edit-delete-group').show(); $('#admins .save-cancel-group').hide(); $('#admins .details').find('input, textarea').prop('readonly', true); - $('#admins .form-message').hide(); + $('#admins .form-message').hide(); $('#admin-notifications').prop('disabled', true); $('#admins .required').css('border', ''); $('#admin-password, #admin-password-confirm').css('border', ''); $('#admins .details').find('input, textarea').val(''); $('#admin-notifications').removeClass('active'); $('#edit-admin, #delete-admin').prop('disabled', true); - + $('#filter-admins .selected-row').removeClass('selected-row'); $('#filter-admins button').prop('disabled', false); $('#filter-admins .results').css('color', ''); @@ -298,7 +298,7 @@ AdminsHelper.prototype.resetForm = function() { /** * Display a admin record into the admin form. - * + * * @param {object} admin Contains the admin record data. */ AdminsHelper.prototype.display = function(admin) { @@ -313,7 +313,7 @@ AdminsHelper.prototype.display = function(admin) { $('#admin-state').val(admin.state); $('#admin-zip-code').val(admin.zip_code); $('#admin-notes').val(admin.notes); - + $('#admin-username').val(admin.settings.username); if (admin.settings.notifications == true) { $('#admin-notifications').addClass('active'); @@ -324,31 +324,31 @@ AdminsHelper.prototype.display = function(admin) { /** * Filters admin records depending a key string. - * + * * @param {string} key This string is used to filter the admin records of the database. - * @param {numeric} selectId (OPTIONAL = undefined) This record id will be selected when + * @param {numeric} selectId (OPTIONAL = undefined) This record id will be selected when * the filter operation is finished. * @param {bool} display (OPTIONAL = false) If true the selected record data are going * to be displayed on the details column (requires a selected record though). */ AdminsHelper.prototype.filter = function(key, selectId, display) { if (display == undefined) display = false; - + var postUrl = GlobalVariables.baseUrl + '/index.php/backend_api/ajax_filter_admins'; - var postData = { + var postData = { 'csrfToken': GlobalVariables.csrfToken, - 'key': key + 'key': key }; - + $.post(postUrl, postData, function(response) { /////////////////////////////////////////////////// //console.log('Filter admins response:', response); /////////////////////////////////////////////////// - + if (!GeneralFunctions.handleAjaxExceptions(response)) return; - + BackendUsers.helper.filterResults = response; - + $('#filter-admins .results').data('jsp').destroy(); $('#filter-admins .results').html(''); $.each(response, function(index, admin) { @@ -356,61 +356,61 @@ AdminsHelper.prototype.filter = function(key, selectId, display) { $('#filter-admins .results').append(html); }); $('#filter-admins .results').jScrollPane({ mouseWheelSpeed: 70 }); - + if (response.length == 0) { $('#filter-admins .results').html('' + EALang['no_records_found'] + '') } - + if (selectId != undefined) { BackendUsers.helper.select(selectId, display); } - }, 'json'); + }, 'json').fail(GeneralFunctions.ajaxFailureHandler); }; /** * Get an admin row html code that is going to be displayed on the filter results list. - * + * * @param {object} admin Contains the admin record data. * @returns {string} The html code that represents the record on the filter results list. */ AdminsHelper.prototype.getFilterHtml = function(admin) { var name = admin.first_name + ' ' + admin.last_name; var info = admin.email; - info = (admin.mobile_number != '' && admin.mobile_number != null) + info = (admin.mobile_number != '' && admin.mobile_number != null) ? info + ', ' + admin.mobile_number : info; - info = (admin.phone_number != '' && admin.phone_number != null) + info = (admin.phone_number != '' && admin.phone_number != null) ? info + ', ' + admin.phone_number : info; - + var html = - '
' + + '
' + '' + name + '
' + - info + '
' + + info + '
' + '

'; return html; }; /** - * Select a specific record from the current filter results. If the admin id does not exist - * in the list then no record will be selected. - * + * Select a specific record from the current filter results. If the admin id does not exist + * in the list then no record will be selected. + * * @param {numeric} id The record id to be selected from the filter results. * @param {bool} display (OPTIONAL = false) If true then the method will display the record * on the form. */ AdminsHelper.prototype.select = function(id, display) { if (display == undefined) display = false; - + $('#filter-admins .selected-row').removeClass('selected-row'); - + $('.admin-row').each(function() { if ($(this).attr('data-id') == id) { $(this).addClass('selected-row'); return false; } }); - - if (display) { + + if (display) { $.each(BackendUsers.helper.filterResults, function(index, admin) { if (admin.id == id) { BackendUsers.helper.display(admin); diff --git a/src/assets/js/backend_users_providers.js b/src/assets/js/backend_users_providers.js index a819b64c..b830fc26 100644 --- a/src/assets/js/backend_users_providers.js +++ b/src/assets/js/backend_users_providers.js @@ -1,19 +1,19 @@ /* ---------------------------------------------------------------------------- * Easy!Appointments - Open Source Web Scheduler - * + * * @package EasyAppointments * @author A.Tselegidis * @copyright Copyright (c) 2013 - 2015, Alex Tselegidis - * @license http://opensource.org/licenses/GPL-3.0 - GPLv3 + * @license http://opensource.org/licenses/GPL-3.0 - GPLv3 * @link http://easyappointments.org * @since v1.0.0 * ---------------------------------------------------------------------------- */ /** - * This class contains the Providers helper class declaration, along with the "Providers" tab + * This class contains the Providers helper class declaration, along with the "Providers" tab * event handlers. By deviding the backend/users tab functionality into separate files * it is easier to maintain the code. - * + * * @class ProvidersHelper */ var ProvidersHelper = function() { @@ -26,7 +26,7 @@ var ProvidersHelper = function() { ProvidersHelper.prototype.bindEventHandlers = function() { /** * Event: Filter Providers Form "Submit" - * + * * Filter the provider records with the given key string. */ $('#filter-providers form').submit(function(event) { @@ -47,7 +47,7 @@ ProvidersHelper.prototype.bindEventHandlers = function() { /** * Event: Filter Provider Row "Click" - * + * * Display the selected provider data to the user. */ $(document).on('click', '.provider-row', function() { @@ -55,7 +55,7 @@ ProvidersHelper.prototype.bindEventHandlers = function() { $('#filter-providers .results').css('color', '#AAA'); return; // Exit because we are currently on edit mode. } - + var providerId = $(this).attr('data-id'); var provider = {}; $.each(BackendUsers.helper.filterResults, function(index, item) { @@ -64,7 +64,7 @@ ProvidersHelper.prototype.bindEventHandlers = function() { return false; } }); - + BackendUsers.helper.display(provider); $('#filter-providers .selected-row').removeClass('selected-row'); $(this).addClass('selected-row'); @@ -124,7 +124,7 @@ ProvidersHelper.prototype.bindEventHandlers = function() { $('#message_box').dialog('close'); }; - GeneralFunctions.displayMessageBox(EALang['delete_provider'], + GeneralFunctions.displayMessageBox(EALang['delete_provider'], EALang['delete_record_prompt'], messageBtns); }); @@ -144,7 +144,7 @@ ProvidersHelper.prototype.bindEventHandlers = function() { 'zip_code': $('#provider-zip-code').val(), 'notes': $('#provider-notes').val(), 'settings': { - 'username': $('#provider-username').val(), + 'username': $('#provider-username').val(), 'working_plan': JSON.stringify(BackendUsers.wp.get()), 'notifications': $('#provider-notifications').hasClass('active') } @@ -175,7 +175,7 @@ ProvidersHelper.prototype.bindEventHandlers = function() { /** * Event: Cancel Provider Button "Click" - * + * * Cancel add or edit of an provider record. */ $('#cancel-provider').click(function() { @@ -207,7 +207,7 @@ ProvidersHelper.prototype.bindEventHandlers = function() { $('.working-plan-view').show('fade'); }); }); - + /** * Event: Reset Working Plan Button "Click". */ @@ -221,7 +221,7 @@ ProvidersHelper.prototype.bindEventHandlers = function() { /** * Save provider record to database. - * + * * @param {object} provider Contains the admin record data. If an 'id' value is provided * then the update operation is going to be executed. */ @@ -229,13 +229,13 @@ ProvidersHelper.prototype.save = function(provider) { ////////////////////////////////////////////////// //console.log('Provider data to save:', provider); ////////////////////////////////////////////////// - + var postUrl = GlobalVariables.baseUrl + '/index.php/backend_api/ajax_save_provider'; - var postData = { + var postData = { 'csrfToken': GlobalVariables.csrfToken, - 'provider': JSON.stringify(provider) + 'provider': JSON.stringify(provider) }; - + $.post(postUrl, postData, function(response) { /////////////////////////////////////////////////// //console.log('Save Provider Response:', response); @@ -244,22 +244,22 @@ ProvidersHelper.prototype.save = function(provider) { Backend.displayNotification(EALang['provider_saved']); BackendUsers.helper.resetForm(); $('#filter-providers .key').val(''); - BackendUsers.helper.filter('', response.id, true); - }, 'json'); + BackendUsers.helper.filter('', response.id, true); + }, 'json').fail(GeneralFunctions.ajaxFailureHandler); }; /** * Delete a provider record from database. - * - * @param {numeric} id Record id to be deleted. + * + * @param {numeric} id Record id to be deleted. */ ProvidersHelper.prototype.delete = function(id) { var postUrl = GlobalVariables.baseUrl + '/index.php/backend_api/ajax_delete_provider'; - var postData = { + var postData = { 'csrfToken': GlobalVariables.csrfToken, - 'provider_id': id + 'provider_id': id }; - + $.post(postUrl, postData, function(response) { ///////////////////////////////////////////////////// //console.log('Delete provider response:', response); @@ -268,19 +268,19 @@ ProvidersHelper.prototype.delete = function(id) { Backend.displayNotification(EALang['provider_deleted']); BackendUsers.helper.resetForm(); BackendUsers.helper.filter($('#filter-providers .key').val()); - }, 'json'); + }, 'json').fail(GeneralFunctions.ajaxFailureHandler); }; /** * Validates a provider record. - * + * * @param {object} provider Contains the admin data to be validated. * @returns {bool} Returns the validation result. */ ProvidersHelper.prototype.validate = function(provider) { $('#providers .required').css('border', ''); $('#provider-password, #provider-password-confirm').css('border', ''); - + try { // Validate required fields. var missingRequired = false; @@ -293,31 +293,31 @@ ProvidersHelper.prototype.validate = function(provider) { if (missingRequired) { throw EALang['fields_are_required']; } - + // Validate passwords. if ($('#provider-password').val() != $('#provider-password-confirm').val()) { $('#provider-password, #provider-password-confirm').css('border', '2px solid red'); throw EALang['passwords_mismatch']; } - + if ($('#provider-password').val().length < BackendUsers.MIN_PASSWORD_LENGTH && $('#provider-password').val() != '') { $('#provider-password, #provider-password-confirm').css('border', '2px solid red'); throw EALang['password_length_notice'].replace('$number', BackendUsers.MIN_PASSWORD_LENGTH); } - + // Validate user email. if (!GeneralFunctions.validateEmail($('#provider-email').val())) { $('#provider-email').css('border', '2px solid red'); throw EALang['invalid_email']; } - + // Check if username exists if ($('#provider-username').attr('already-exists') == 'true') { $('#provider-username').css('border', '2px solid red'); throw EALang['username_already_exists']; - } - + } + return true; } catch(exc) { $('#providers .form-message').text(exc); @@ -327,17 +327,17 @@ ProvidersHelper.prototype.validate = function(provider) { }; /** - * Resets the admin tab form back to its initial state. + * Resets the admin tab form back to its initial state. */ ProvidersHelper.prototype.resetForm = function() { $('#filter-providers .selected-row').removeClass('selected-row'); $('#filter-providers button').prop('disabled', false); $('#filter-providers .results').css('color', ''); - + $('#providers .add-edit-delete-group').show(); $('#providers .save-cancel-group').hide(); $('#providers .details').find('input, textarea').prop('readonly', true); - $('#providers .form-message').hide(); + $('#providers .form-message').hide(); $('#provider-notifications').removeClass('active'); $('#provider-notifications').prop('disabled', true); $('#provider-services input[type="checkbox"]').prop('disabled', true); @@ -359,7 +359,7 @@ ProvidersHelper.prototype.resetForm = function() { /** * Display a provider record into the admin form. - * + * * @param {object} provider Contains the provider record data. */ ProvidersHelper.prototype.display = function(provider) { @@ -374,14 +374,14 @@ ProvidersHelper.prototype.display = function(provider) { $('#provider-state').val(provider.state); $('#provider-zip-code').val(provider.zip_code); $('#provider-notes').val(provider.notes); - + $('#provider-username').val(provider.settings.username); if (provider.settings.notifications == true) { $('#provider-notifications').addClass('active'); } else { $('#provider-notifications').removeClass('active'); } - + $('#provider-services input[type="checkbox"]').prop('checked', false); $.each(provider.services, function(index, serviceId) { $('#provider-services input[type="checkbox"]').each(function() { @@ -390,7 +390,7 @@ ProvidersHelper.prototype.display = function(provider) { } }); }); - + // Display working plan $('#providers .breaks tbody').empty(); var workingPlan = $.parseJSON(provider.settings.working_plan); @@ -400,32 +400,32 @@ ProvidersHelper.prototype.display = function(provider) { /** * Filters provider records depending a string key. - * + * * @param {string} key This is used to filter the provider records of the database. * @param {numeric} selectId (OPTIONAL = undefined) If set, when the function is complete - * a result row can be set as selected. - * @param {bool} display (OPTIONAL = false) If true then the selected record will be also + * a result row can be set as selected. + * @param {bool} display (OPTIONAL = false) If true then the selected record will be also * displayed. */ ProvidersHelper.prototype.filter = function(key, selectId, display) { if (display == undefined) display = false; - + var postUrl = GlobalVariables.baseUrl + '/index.php/backend_api/ajax_filter_providers'; - var postData = { + var postData = { 'csrfToken': GlobalVariables.csrfToken, - 'key': key + 'key': key }; - + $.post(postUrl, postData, function(response) { ////////////////////////////////////////////////////// //console.log('Filter providers response:', response); ////////////////////////////////////////////////////// - + if (!GeneralFunctions.handleAjaxExceptions(response)) return; - + BackendUsers.helper.filterResults = response; - - + + $('#filter-providers .results').data('jsp').destroy; $('#filter-providers .results').html(''); $.each(response, function(index, provider) { @@ -433,20 +433,20 @@ ProvidersHelper.prototype.filter = function(key, selectId, display) { $('#filter-providers .results').append(html); }); $('#filter-providers .results').jScrollPane({ mouseWheelSpeed: 70 }); - + if (response.length == 0) { $('#filter-providers .results').html('' + EALang['no_records_found'] + '') } - + if (selectId != undefined) { BackendUsers.helper.select(selectId, display); } - }, 'json'); + }, 'json').fail(GeneralFunctions.ajaxFailureHandler); }; /** * Get an provider row html code that is going to be displayed on the filter results list. - * + * * @param {object} provider Contains the provider record data. * @returns {string} The html code that represents the record on the filter results list. */ @@ -456,12 +456,12 @@ ProvidersHelper.prototype.getFilterHtml = function(provider) { info = (provider.mobile_number != '' && provider.mobile_number != null) ? info + ', ' + provider.mobile_number : info; info = (provider.phone_number != '' && provider.phone_number != null) - ? info + ', ' + provider.phone_number : info; - + ? info + ', ' + provider.phone_number : info; + var html = - '
' + + '
' + '' + name + '
' + - info + '
' + + info + '
' + '

'; return html; @@ -469,7 +469,7 @@ ProvidersHelper.prototype.getFilterHtml = function(provider) { /** * Initialize the editable functionality to the break day table cells. - * + * * @param {object} $selector The cells to be initialized. */ ProvidersHelper.prototype.editableBreakDay = function($selector) { @@ -507,9 +507,9 @@ ProvidersHelper.prototype.editableBreakDay = function($selector) { /** * Initialize the editable functionality to the break time table cells. - * + * * @param {object} $selector The cells to be initialized. - */ + */ ProvidersHelper.prototype.editableBreakTime = function($selector) { $selector.editable(function(value, settings) { // Do not return the value because the user needs to press the "Save" button. @@ -531,13 +531,13 @@ ProvidersHelper.prototype.editableBreakTime = function($selector) { /** * Select and display a providers filter result on the form. - * + * * @param {numeric} id Record id to be selected. * @param {bool} display (OPTIONAL = false) If true the record will be displayed on the form. */ ProvidersHelper.prototype.select = function(id, display) { if (display == undefined) display = false; - + // Select record in filter results. $('#filter-providers .provider-row').each(function() { if ($(this).attr('data-id') == id) { @@ -545,7 +545,7 @@ ProvidersHelper.prototype.select = function(id, display) { return false; } }); - + // Display record in form (if display = true). if (display) { $.each(BackendUsers.helper.filterResults, function(index, provider) { @@ -556,4 +556,4 @@ ProvidersHelper.prototype.select = function(id, display) { } }); } -}; \ No newline at end of file +}; diff --git a/src/assets/js/backend_users_secretaries.js b/src/assets/js/backend_users_secretaries.js index ee0912f6..a1af6250 100644 --- a/src/assets/js/backend_users_secretaries.js +++ b/src/assets/js/backend_users_secretaries.js @@ -1,19 +1,19 @@ /* ---------------------------------------------------------------------------- * Easy!Appointments - Open Source Web Scheduler - * + * * @package EasyAppointments * @author A.Tselegidis * @copyright Copyright (c) 2013 - 2015, Alex Tselegidis - * @license http://opensource.org/licenses/GPL-3.0 - GPLv3 + * @license http://opensource.org/licenses/GPL-3.0 - GPLv3 * @link http://easyappointments.org * @since v1.0.0 * ---------------------------------------------------------------------------- */ /** - * This class contains the Secretaries helper class declaration, along with the "Secretaries" + * This class contains the Secretaries helper class declaration, along with the "Secretaries" * tab event handlers. By deviding the backend/users tab functionality into separate files * it is easier to maintain the code. - * + * * @class SecretariesHelper */ var SecretariesHelper = function() { @@ -26,7 +26,7 @@ var SecretariesHelper = function() { SecretariesHelper.prototype.bindEventHandlers = function() { /** * Event: Filter Secretaries Form "Submit" - * + * * Filter the secretary records with the given key string. */ $('#filter-secretaries form').submit(function(event) { @@ -47,7 +47,7 @@ SecretariesHelper.prototype.bindEventHandlers = function() { /** * Event: Filter Secretary Row "Click" - * + * * Display the selected secretary data to the user. */ $(document).on('click', '.secretary-row', function() { @@ -56,7 +56,7 @@ SecretariesHelper.prototype.bindEventHandlers = function() { return; // exit because we are currently on edit mode } - var secretaryId = $(this).attr('data-id'); + var secretaryId = $(this).attr('data-id'); var secretary = {}; $.each(BackendUsers.helper.filterResults, function(index, item) { if (item.id === secretaryId) { @@ -64,7 +64,7 @@ SecretariesHelper.prototype.bindEventHandlers = function() { return false; } }); - + BackendUsers.helper.display(secretary); $('#filter-secretaries .selected-row').removeClass('selected-row'); $(this).addClass('selected-row'); @@ -78,7 +78,7 @@ SecretariesHelper.prototype.bindEventHandlers = function() { BackendUsers.helper.resetForm(); $('#filter-secretaries button').prop('disabled', true); $('#filter-secretaries .results').css('color', '#AAA'); - + $('#secretaries .add-edit-delete-group').hide(); $('#secretaries .save-cancel-group').show(); $('#secretaries .details').find('input, textarea').prop('readonly', false); @@ -93,7 +93,7 @@ SecretariesHelper.prototype.bindEventHandlers = function() { $('#edit-secretary').click(function() { $('#filter-secretaries button').prop('disabled', true); $('#filter-secretaries .results').css('color', '#AAA'); - + $('#secretaries .add-edit-delete-group').hide(); $('#secretaries .save-cancel-group').show(); $('#secretaries .details').find('input, textarea').prop('readonly', false); @@ -117,7 +117,7 @@ SecretariesHelper.prototype.bindEventHandlers = function() { $('#message_box').dialog('close'); }; - GeneralFunctions.displayMessageBox(EALang['delete_secretary'], + GeneralFunctions.displayMessageBox(EALang['delete_secretary'], EALang['delete_record_prompt'], messageBtns); }); @@ -137,7 +137,7 @@ SecretariesHelper.prototype.bindEventHandlers = function() { 'zip_code': $('#secretary-zip-code').val(), 'notes': $('#secretary-notes').val(), 'settings': { - 'username': $('#secretary-username').val(), + 'username': $('#secretary-username').val(), 'notifications': $('#secretary-notifications').hasClass('active') } }; @@ -167,7 +167,7 @@ SecretariesHelper.prototype.bindEventHandlers = function() { /** * Event: Cancel Secretary Button "Click" - * + * * Cancel add or edit of an secretary record. */ $('#cancel-secretary').click(function() { @@ -181,7 +181,7 @@ SecretariesHelper.prototype.bindEventHandlers = function() { /** * Save secretary record to database. - * + * * @param {object} secretary Contains the admin record data. If an 'id' value is provided * then the update operation is going to be executed. */ @@ -189,13 +189,13 @@ SecretariesHelper.prototype.save = function(secretary) { //////////////////////////////////////////////////// //console.log('Secretary data to save:', secretary); //////////////////////////////////////////////////// - + var postUrl = GlobalVariables.baseUrl + '/index.php/backend_api/ajax_save_secretary'; - var postData = { + var postData = { 'csrfToken': GlobalVariables.csrfToken, - 'secretary': JSON.stringify(secretary) + 'secretary': JSON.stringify(secretary) }; - + $.post(postUrl, postData, function(response) { //////////////////////////////////////////////////// //console.log('Save Secretary Response:', response); @@ -205,21 +205,21 @@ SecretariesHelper.prototype.save = function(secretary) { BackendUsers.helper.resetForm(); $('#filter-secretaries .key').val(''); BackendUsers.helper.filter('', response.id, true); - }, 'json'); + }, 'json').fail(GeneralFunctions.ajaxFailureHandler); }; /** * Delete a secretary record from database. - * - * @param {int} id Record id to be deleted. + * + * @param {int} id Record id to be deleted. */ SecretariesHelper.prototype.delete = function(id) { var postUrl = GlobalVariables.baseUrl + '/index.php/backend_api/ajax_delete_secretary'; - var postData = { + var postData = { 'csrfToken': GlobalVariables.csrfToken, - 'secretary_id': id + 'secretary_id': id }; - + $.post(postUrl, postData, function(response) { ////////////////////////////////////////////////////// //console.log('Delete secretary response:', response); @@ -228,19 +228,19 @@ SecretariesHelper.prototype.delete = function(id) { Backend.displayNotification(EALang['secretary_deleted']); BackendUsers.helper.resetForm(); BackendUsers.helper.filter($('#filter-secretaries .key').val()); - }, 'json'); + }, 'json').fail(GeneralFunctions.ajaxFailureHandler); }; /** * Validates a secretary record. - * + * * @param {object} secretary Contains the admin data to be validated. * @returns {bool} Returns the validation result. */ SecretariesHelper.prototype.validate = function(secretary) { $('#secretaries .required').css('border', ''); $('#secretary-password, #secretary-password-confirm').css('border', ''); - + try { // Validate required fields. var missingRequired = false; @@ -253,32 +253,32 @@ SecretariesHelper.prototype.validate = function(secretary) { if (missingRequired) { throw 'Fields with * are required.'; } - + // Validate passwords. if ($('#secretary-password').val() != $('#secretary-password-confirm').val()) { $('#secretary-password, #secretary-password-confirm').css('border', '2px solid red'); throw 'Passwords mismatch!'; } - + if ($('#secretary-password').val().length < BackendUsers.MIN_PASSWORD_LENGTH && $('#secretary-password').val() != '') { $('#secretary-password, #secretary-password-confirm').css('border', '2px solid red'); - throw 'Password must be at least ' + BackendUsers.MIN_PASSWORD_LENGTH + throw 'Password must be at least ' + BackendUsers.MIN_PASSWORD_LENGTH + ' characters long.'; } - + // Validate user email. if (!GeneralFunctions.validateEmail($('#secretary-email').val())) { $('#secretary-email').css('border', '2px solid red'); throw 'Invalid email address!'; } - + // Check if username exists if ($('#secretary-username').attr('already-exists') == 'true') { $('#secretary-username').css('border', '2px solid red'); throw 'Username already exists.'; - } - + } + return true; } catch(exc) { $('#secretaries .form-message').text(exc); @@ -288,7 +288,7 @@ SecretariesHelper.prototype.validate = function(secretary) { }; /** - * Resets the admin tab form back to its initial state. + * Resets the admin tab form back to its initial state. */ SecretariesHelper.prototype.resetForm = function() { $('#secretaries .details').find('input, textarea').val(''); @@ -296,14 +296,14 @@ SecretariesHelper.prototype.resetForm = function() { $('#secretaries .save-cancel-group').hide(); $('#edit-secretary, #delete-secretary').prop('disabled', true); $('#secretaries .details').find('input, textarea').prop('readonly', true); - $('#secretaries .form-message').hide(); + $('#secretaries .form-message').hide(); $('#secretary-notifications').removeClass('active'); $('#secretary-notifications').prop('disabled', true); $('#secretary-providers input[type="checkbox"]').prop('checked', false); $('#secretary-providers input[type="checkbox"]').prop('disabled', true); $('#secretaries .required').css('border', ''); $('#secretary-password, #secretary-password-confirm').css('border', ''); - + $('#filter-secretaries .selected-row').removeClass('selected-row'); $('#filter-secretaries button').prop('disabled', false); $('#filter-secretaries .results').css('color', ''); @@ -311,7 +311,7 @@ SecretariesHelper.prototype.resetForm = function() { /** * Display a secretary record into the admin form. - * + * * @param {object} secretary Contains the secretary record data. */ SecretariesHelper.prototype.display = function(secretary) { @@ -326,14 +326,14 @@ SecretariesHelper.prototype.display = function(secretary) { $('#secretary-state').val(secretary.state); $('#secretary-zip-code').val(secretary.zip_code); $('#secretary-notes').val(secretary.notes); - + $('#secretary-username').val(secretary.settings.username); if (secretary.settings.notifications == true) { $('#secretary-notifications').addClass('active'); } else { $('#secretary-notifications').removeClass('active'); } - + $('#secretary-providers input[type="checkbox"]').prop('checked', false); $.each(secretary.providers, function(index, providerId) { $('#secretary-providers input[type="checkbox"]').each(function() { @@ -346,30 +346,30 @@ SecretariesHelper.prototype.display = function(secretary) { /** * Filters secretary records depending a string key. - * + * * @param {string} key This is used to filter the secretary records of the database. - * @param {numeric} selectId (OPTIONAL = undefined) If provided then the given id will be + * @param {numeric} selectId (OPTIONAL = undefined) If provided then the given id will be * selected in the filter results (only selected, not displayed). * @param {bool} display (OPTIONAL = false) */ SecretariesHelper.prototype.filter = function(key, selectId, display) { if (display == undefined) display = false; - + var postUrl = GlobalVariables.baseUrl + '/index.php/backend_api/ajax_filter_secretaries'; - var postData = { + var postData = { 'csrfToken': GlobalVariables.csrfToken, - 'key': key + 'key': key }; - + $.post(postUrl, postData, function(response) { //////////////////////////////////////////////////////// //console.log('Filter secretaries response:', response); //////////////////////////////////////////////////////// - + if (!GeneralFunctions.handleAjaxExceptions(response)) return; - + BackendUsers.helper.filterResults = response; - + $('#filter-secretaries .results').data('jsp').destroy(); $('#filter-secretaries .results').html(''); $.each(response, function(index, secretary) { @@ -377,20 +377,20 @@ SecretariesHelper.prototype.filter = function(key, selectId, display) { $('#filter-secretaries .results').append(html); }); $('#filter-secretaries .results').jScrollPane({ mouseWheelSpeed: 70 }); - + if (response.length == 0) { $('#filter-secretaries .results').html('' + EALang['no_records_found'] + '') } - + if (selectId != undefined) { BackendUsers.helper.select(selectId, display); } - }, 'json'); + }, 'json').fail(GeneralFunctions.ajaxFailureHandler); }; /** * Get an secretary row html code that is going to be displayed on the filter results list. - * + * * @param {object} secretary Contains the secretary record data. * @returns {string} The html code that represents the record on the filter results list. */ @@ -400,38 +400,38 @@ SecretariesHelper.prototype.getFilterHtml = function(secretary) { info = (secretary.mobile_number != '' && secretary.mobile_number != null) ? info + ', ' + secretary.mobile_number : info; info = (secretary.phone_number != '' && secretary.phone_number != null) - ? info + ', ' + secretary.phone_number : info; - + ? info + ', ' + secretary.phone_number : info; + var html = - '
' + + '
' + '' + name + '
' + - info + '
' + + info + '
' + '

'; return html; }; /** - * Select a specific record from the current filter results. If the secretary id does not exist - * in the list then no record will be selected. - * + * Select a specific record from the current filter results. If the secretary id does not exist + * in the list then no record will be selected. + * * @param {numeric} id The record id to be selected from the filter results. * @param {bool} display (OPTIONAL = false) If true then the method will display the record * on the form. */ SecretariesHelper.prototype.select = function(id, display) { if (display == undefined) display = false; - + $('#filter-secretaries .selected-row').removeClass('selected-row'); - + $('#filter-secretaries .secretary-row').each(function() { if ($(this).attr('data-id') == id) { $(this).addClass('selected-row'); return false; } }); - - if (display) { + + if (display) { $.each(BackendUsers.helper.filterResults, function(index, admin) { if (admin.id == id) { BackendUsers.helper.display(admin); @@ -440,4 +440,4 @@ SecretariesHelper.prototype.select = function(id, display) { } }); } -}; \ No newline at end of file +}; diff --git a/src/assets/js/frontend_book.js b/src/assets/js/frontend_book.js index 6b336b6e..106c1985 100644 --- a/src/assets/js/frontend_book.js +++ b/src/assets/js/frontend_book.js @@ -1,48 +1,48 @@ /* ---------------------------------------------------------------------------- * Easy!Appointments - Open Source Web Scheduler - * + * * @package EasyAppointments * @author A.Tselegidis * @copyright Copyright (c) 2013 - 2015, Alex Tselegidis - * @license http://opensource.org/licenses/GPL-3.0 - GPLv3 + * @license http://opensource.org/licenses/GPL-3.0 - GPLv3 * @link http://easyappointments.org * @since v1.0.0 * ---------------------------------------------------------------------------- */ /** - * This namespace contains functions that implement the book appointment page - * functionality. Once the initialize() method is called the page is fully + * 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 {bool} */ - manageMode: false, - + manageMode: false, + /** * This method initializes the book appointment page. - * - * @param {bool} bindEventHandlers (OPTIONAL) Determines whether the default + * + * @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 + * @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: { @@ -53,20 +53,20 @@ var FrontendBook = { classes: 'qtip-green qtip-shadow custom-qtip' } }); - + $('#select-date').datepicker({ dateFormat: 'dd-mm-yy', firstDay: 1, // Monday minDate: 0, defaultDate: Date.today(), - + dayNames: [EALang['sunday'], EALang['monday'], EALang['tuesday'], EALang['wednesday'], EALang['thursday'], EALang['friday'], EALang['saturday']], - dayNamesShort: [EALang['sunday'].substr(0,3), EALang['monday'].substr(0,3), - EALang['tuesday'].substr(0,3), EALang['wednesday'].substr(0,3), + dayNamesShort: [EALang['sunday'].substr(0,3), EALang['monday'].substr(0,3), + EALang['tuesday'].substr(0,3), EALang['wednesday'].substr(0,3), EALang['thursday'].substr(0,3), EALang['friday'].substr(0,3), EALang['saturday'].substr(0,3)], - dayNamesMin: [EALang['sunday'].substr(0,2), EALang['monday'].substr(0,2), - EALang['tuesday'].substr(0,2), EALang['wednesday'].substr(0,2), + dayNamesMin: [EALang['sunday'].substr(0,2), EALang['monday'].substr(0,2), + EALang['tuesday'].substr(0,2), EALang['wednesday'].substr(0,2), EALang['thursday'].substr(0,2), EALang['friday'].substr(0,2), EALang['saturday'].substr(0,2)], monthNames: [EALang['january'], EALang['february'], EALang['march'], EALang['april'], @@ -76,20 +76,20 @@ var FrontendBook = { nextText: EALang['next'], currentText: EALang['now'], closeText: EALang['close'], - + 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) { @@ -99,15 +99,15 @@ var FrontendBook = { $('#select-service').trigger('change'); // Load the available hours. } }, - + /** - * This method binds the necessary event handlers for the book + * 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. */ @@ -115,12 +115,12 @@ var FrontendBook = { 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. + * + * When the user clicks on a service, its available providers should + * become visible. */ $('#select-service').change(function() { var currServiceId = $('#select-service').val(); @@ -129,10 +129,10 @@ var FrontendBook = { $.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); } @@ -143,30 +143,30 @@ var FrontendBook = { FrontendBook.updateConfirmFrame(); FrontendBook.updateServiceDescription($('#select-service').val(), $('#service-description')); }); - + /** * 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 + * + * 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 + // 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('

' + '' - + EALang['appointment_hour_missing'] + + EALang['appointment_hour_missing'] + ''); } return; } } - - // If we are on the 3rd tab then we will need to validate the user's + + // 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()) { @@ -175,11 +175,11 @@ var FrontendBook = { 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() { + $(this).parents().eq(1).hide('fade', function() { $('.active-step').removeClass('active-step'); $('#step-' + nextTabIndex).addClass('active-step'); $('#wizard-frame-' + nextTabIndex).show('fade'); @@ -188,14 +188,14 @@ var FrontendBook = { /** * Event: Back Step Button "Clicked" - * - * This handler is triggered every time the user pressed the + * + * 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() { + $(this).parents().eq(1).hide('fade', function() { $('.active-step').removeClass('active-step'); $('#step-' + prevTabIndex).addClass('active-step'); $('#wizard-frame-' + prevTabIndex).show('fade'); @@ -204,7 +204,7 @@ var FrontendBook = { /** * Event: Available Hour "Click" - * + * * Triggered whenever the user clicks on an available hour * for his appointment. */ @@ -213,14 +213,14 @@ var FrontendBook = { $(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 + * once the appointment is cancelled, it will be delete from the * database. */ $('#cancel-appointment').click(function(event) { @@ -233,48 +233,48 @@ var FrontendBook = { $('#cancel-appointment-form textarea').val($('#cancel-reason').val()); $('#cancel-appointment-form').submit(); }; - + dialogButtons[EALang['cancel']] = function() { $('#message_box').dialog('close'); }; - - GeneralFunctions.displayMessageBox(EALang['cancel_appointment_title'], + + GeneralFunctions.displayMessageBox(EALang['cancel_appointment_title'], EALang['write_appointment_removal_reason'], dialogButtons); - + $('#message_box').append(''); $('#cancel-reason').css('width', '100%'); return false; }); } - + /** * Event: Book Appointment Form "Submit" - * + * * Before the form is submitted to the server we need to make sure that * in the meantime the selected appointment date/time wasn't reserved by - * another customer or event. + * another customer or event. */ $('#book-appointment-submit').click(function(event) { var formData = jQuery.parseJSON($('input[name="post_data"]').val()); - + var postData = { 'csrfToken': GlobalVariables.csrfToken, 'id_users_provider': formData['appointment']['id_users_provider'], 'id_services': formData['appointment']['id_services'], 'start_datetime': formData['appointment']['start_datetime'], }; - + if (GlobalVariables.manageMode) { postData.exclude_appointment_id = GlobalVariables.appointmentData.id; } - + var postUrl = GlobalVariables.baseUrl + '/index.php/appointments/ajax_check_datetime_availability'; - + $.post(postUrl, postData, function(response) { //////////////////////////////////////////////////////////////////////// console.log('Check Date/Time Availability Post Response :', response); //////////////////////////////////////////////////////////////////////// - + if (response.exceptions) { response.exceptions = GeneralFunctions.parseExceptions(response.exceptions); GeneralFunctions.displayMessageBox('Unexpected Issues', 'Unfortunately ' @@ -282,8 +282,8 @@ var FrontendBook = { + 'The following issues occurred:'); $('#message_box').append(GeneralFunctions.exceptionsToHtml(response.exceptions)); return false; - } - + } + if (response === true) { $('#book-appointment-form').submit(); } else { @@ -292,34 +292,37 @@ var FrontendBook = { + 'another hour.'); FrontendBook.getAvailableHours($('#select-date').val()); } - }, 'json'); + }, 'json').fail(GeneralFunctions.ajaxFailureHandler); }); }, - + /** - * This function makes an ajax call and returns the available + * 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) { $('#available-hours').empty(); - - // Find the selected service duration (it is going to + + // 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']; + selServiceDuration = service['duration']; } }); - - // If the manage mode is true then the appointment's start + + // If the manage mode is true then the appointment's start // date should return as available too. - var appointmentId = (FrontendBook.manageMode) + var appointmentId = (FrontendBook.manageMode) ? GlobalVariables.appointmentData['id'] : undefined; + // Make ajax post request and get the available hours. + var postUrl = GlobalVariables.baseUrl + '/index.php/appointments/ajax_get_available_hours'; + var postData = { 'csrfToken': GlobalVariables.csrfToken, 'service_id': $('#select-service').val(), @@ -330,17 +333,15 @@ var FrontendBook = { 'appointment_id': appointmentId }; - // Make ajax post request and get the available hours. - var ajaxurl = GlobalVariables.baseUrl + '/index.php/appointments/ajax_get_available_hours'; - $.post(ajaxurl, postData, function(response) { + $.post(postUrl, postData, function(response) { /////////////////////////////////////////////////////////////// console.log('Get Available Hours JSON Response:', response); /////////////////////////////////////////////////////////////// - + if (!GeneralFunctions.handleAjaxExceptions(response)) return; // The response contains the available hours for the selected provider and - // service. Fill the available hours div with response data. + // service. Fill the available hours div with response data. if (response.length > 0) { var currColumn = 1; $('#available-hours').html('
'); @@ -369,22 +370,22 @@ var FrontendBook = { } FrontendBook.updateConfirmFrame(); - + } else { $('#available-hours').text(EALang['no_available_hours']); } - }, 'json'); + }, 'json').fail(GeneralFunctions.ajaxFailureHandler); }, /** * This function validates the customer's data input. The user cannot contiue * without passing all the validation checks. - * + * * @return {bool} Returns the validation result. */ validateCustomerForm: function() { $('#wizard-frame-3 input').css('border', ''); - + try { // Validate required fields. var missingRequiredField = false; @@ -398,14 +399,14 @@ var FrontendBook = { if (missingRequiredField) { throw EALang['fields_are_required']; } - + // Validate email address. if (!GeneralFunctions.validateEmail($('#email').val())) { $('#email').parents('.form-group').addClass('has-error'); // $('#email').css('border', '2px solid red'); throw EALang['invalid_email']; } - + return true; } catch(exc) { $('#form-message').text(exc); @@ -415,7 +416,7 @@ var FrontendBook = { /** * Every time this function is executed, it updates the confirmation - * page with the latest customer settigns and input for the appointment + * page with the latest customer settigns and input for the appointment * booking. */ updateConfirmFrame: function() { @@ -436,36 +437,36 @@ var FrontendBook = { }); $('#appointment-details').html( - '

' + $('#select-service option:selected').text() + '

' + - '

' - + '' + '

' + $('#select-service option:selected').text() + '

' + + '

' + + '' + $('#select-provider option:selected').text() + '
' - + selectedDate + ' ' + $('.selected-hour').text() + + selectedDate + ' ' + $('.selected-hour').text() + servicePrice + ' ' + serviceCurrency - + '
' + + + '
' + '

' ); // Customer Details $('#customer-details').html( - '

' + $('#first-name').val() + ' ' + $('#last-name').val() + '

' + - '

' + - EALang['phone'] + ': ' + $('#phone-number').val() + - '
' + - EALang['email'] + ': ' + $('#email').val() + - '
' + - EALang['address'] + ': ' + $('#address').val() + - '
' + - EALang['city'] + ': ' + $('#city').val() + - '
' + - EALang['zip_code'] + ': ' + $('#zip-code').val() + + '

' + $('#first-name').val() + ' ' + $('#last-name').val() + '

' + + '

' + + EALang['phone'] + ': ' + $('#phone-number').val() + + '
' + + EALang['email'] + ': ' + $('#email').val() + + '
' + + EALang['address'] + ': ' + $('#address').val() + + '
' + + EALang['city'] + ': ' + $('#city').val() + + '
' + + EALang['zip_code'] + ': ' + $('#zip-code').val() + '

' ); - + // Update appointment form data for submission to server when the user confirms // the appointment. var postData = new Object(); - + postData['customer'] = { 'last_name': $('#last-name').val(), 'first_name': $('#first-name').val(), @@ -475,9 +476,9 @@ var FrontendBook = { 'city': $('#city').val(), 'zip_code': $('#zip-code').val() }; - + postData['appointment'] = { - 'start_datetime': $('#select-date').datepicker('getDate').toString('yyyy-MM-dd') + 'start_datetime': $('#select-date').datepicker('getDate').toString('yyyy-MM-dd') + ' ' + $('.selected-hour').text() + ':00', 'end_datetime': FrontendBook.calcEndDatetime(), 'notes': $('#notes').val(), @@ -485,9 +486,9 @@ var FrontendBook = { 'id_users_provider': $('#select-provider').val(), 'id_services': $('#select-service').val() }; - + postData['manage_mode'] = FrontendBook.manageMode; - + if (FrontendBook.manageMode) { postData['appointment']['id'] = GlobalVariables.appointmentData['id']; postData['customer']['id'] = GlobalVariables.customerData['id']; @@ -495,43 +496,43 @@ var FrontendBook = { $('input[name="csrfToken"]').val(GlobalVariables.csrfToken); $('input[name="post_data"]').val(JSON.stringify(postData)); }, - - /** - * 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 fieldss. - * + * * @return {string} Returns the end datetime in string format. */ calcEndDatetime: function() { - // Find selected service duration. + // Find selected service duration. var selServiceDuration = undefined; - + $.each(GlobalVariables.availableServices, function(index, service) { if (service.id == $('#select-service').val()) { selServiceDuration = service.duration; - return false; // Stop searching ... + return false; // Stop searching ... } }); - + // Add the duration to the start datetime. - var startDatetime = $('#select-date').datepicker('getDate').toString('dd-MM-yyyy') + var startDatetime = $('#select-date').datepicker('getDate').toString('dd-MM-yyyy') + ' ' + $('.selected-hour').text(); startDatetime = Date.parseExact(startDatetime, 'dd-MM-yyyy HH:mm'); var endDatetime = undefined; - + if (selServiceDuration !== undefined && startDatetime !== null) { endDatetime = startDatetime.add({ 'minutes' : parseInt(selServiceDuration) }); } else { endDatetime = new Date(); } - + return endDatetime.toString('yyyy-MM-dd HH:mm:ss'); }, - + /** - * This method applies the appointment's data to the wizard so + * This method applies the appointment's data to the wizard so * that the user can start making changes on an existing record. - * + * * @param {object} appointment Selected appointment's data. * @param {object} provider Selected provider's data. * @param {object} customer Selected customer's data. @@ -542,12 +543,12 @@ var FrontendBook = { // Select Service & Provider $('#select-service').val(appointment['id_services']).trigger('change'); $('#select-provider').val(appointment['id_users_provider']); - + // Set Appointment Date - $('#select-date').datepicker('setDate', + $('#select-date').datepicker('setDate', Date.parseExact(appointment['start_datetime'], 'yyyy-MM-dd HH:mm:ss')); FrontendBook.getAvailableHours($('#select-date').val()); - + // Apply Customer's Data $('#last-name').val(customer['last_name']); $('#first-name').val(customer['first_name']); @@ -556,62 +557,62 @@ var FrontendBook = { $('#address').val(customer['address']); $('#city').val(customer['city']); $('#zip-code').val(customer['zip_code']); - var appointmentNotes = (appointment['notes'] !== null) + var appointmentNotes = (appointment['notes'] !== null) ? appointment['notes'] : ''; $('#notes').val(appointmentNotes); - + FrontendBook.updateConfirmFrame(); - + return true; } catch(exc) { console.log(exc); // log exception return false; } }, - + /** - * This method updates a div's html content with a brief description of the - * user selected service (only if available in db). This is usefull for 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 usefull for the * customers upon selecting the correct service. - * + * * @param {int} serviceId The selected service record id. - * @param {object} $div The destination div jquery object (e.g. provide $('#div-id') + * @param {object} $div The destination div jquery object (e.g. provide $('#div-id') * object as value). */ updateServiceDescription: function(serviceId, $div) { - var html = ''; - + var html = ''; + $.each(GlobalVariables.availableServices, function(index, service) { if (service.id == serviceId) { // Just found the service. html = '' + service.name + ' '; - + if (service.description != '' && service.description != null) { html += '
' + service.description + '
'; } - + if (service.duration != '' && service.duration != null) { - html += '[' + EALang['duration'] + ' ' + service.duration + html += '[' + EALang['duration'] + ' ' + service.duration + ' ' + EALang['minutes'] + '] '; } - + if (service.price != '' && service.price != null) { html += '[' + EALang['price'] + ' ' + service.price + ' ' + service.currency + ']'; - } - + } + html += '
'; - + return false; } }); - + $div.html(html); - + if (html != '') { $div.show(); } else { $div.hide(); } - + } - -}; \ No newline at end of file + +}; diff --git a/src/assets/js/general_functions.js b/src/assets/js/general_functions.js index 7a8d1d18..0cb32008 100644 --- a/src/assets/js/general_functions.js +++ b/src/assets/js/general_functions.js @@ -331,7 +331,27 @@ var GeneralFunctions = { if (!GeneralFunctions.handleAjaxExceptions(response)) return; document.location.reload(true); - }, 'json'); + }, 'json').fail(GeneralFunctions.ajaxFailureHandler); }); + }, + + /** + * Use this method for common error handling between + * + * @param {object} jqxhr + * @param {string} textStatus + * @param {object} errorThrown + */ + ajaxFailureHandler: function(jqxhr, textStatus, errorThrown) { + var exceptions = [ + { + message: 'AJAX Error: ' + textStatus + } + ]; + + console.log('AJAX Failure Handler:', jqxhr, textStatus, errorThrown); + GeneralFunctions.displayMessageBox(GeneralFunctions.EXCEPTIONS_TITLE, + GeneralFunctions.EXCEPTIONS_MESSAGE); + $('#message_box').append(GeneralFunctions.exceptionsToHtml(exceptions)); } };