From 2ac93846949d579789429aab99f7a9d42448d2b4 Mon Sep 17 00:00:00 2001 From: Alex Tselegidis Date: Mon, 18 Jul 2016 22:22:28 +0200 Subject: [PATCH] Added popover functionality to table view (#182). --- .../js/backend_calendar_appointments_modal.js | 4 +- src/assets/js/backend_calendar_table_view.js | 236 ++++++++++++++++++ ...backend_calendar_unavailabilities_modal.js | 4 +- 3 files changed, 240 insertions(+), 4 deletions(-) diff --git a/src/assets/js/backend_calendar_appointments_modal.js b/src/assets/js/backend_calendar_appointments_modal.js index 1af9bf5a..36cb40d0 100644 --- a/src/assets/js/backend_calendar_appointments_modal.js +++ b/src/assets/js/backend_calendar_appointments_modal.js @@ -124,7 +124,7 @@ window.BackendCalendarAppointmentsModal = window.BackendCalendarAppointmentsModa * create a new appointment. */ $('#insert-appointment').click(function() { - _resetAppointmentDialog(); + BackendCalendarAppointmentsModal.resetAppointmentDialog(); var $dialog = $('#manage-appointment'); // Set the selected filter item and find the next appointment time as the default modal values. @@ -325,7 +325,7 @@ window.BackendCalendarAppointmentsModal = window.BackendCalendarAppointmentsModa * This method resets the manage appointment dialog modal to its initial state. After that you can make * any modification might be necessary in order to bring the dialog to the desired state. */ - function _resetAppointmentDialog() { + exports.resetAppointmentDialog = function() { var $dialog = $('#manage-appointment'); // Empty form fields. diff --git a/src/assets/js/backend_calendar_table_view.js b/src/assets/js/backend_calendar_table_view.js index 3ecf9591..08599dfc 100644 --- a/src/assets/js/backend_calendar_table_view.js +++ b/src/assets/js/backend_calendar_table_view.js @@ -74,7 +74,239 @@ window.BackendCalendarTableView = window.BackendCalendarTableView || {}; $('#select-provider').val(providerId).trigger('change'); }); + var lastFocusedEventData; + $calendar.on('click', '.event', function(event) { + event.stopPropagation(); + + $('.popover').remove(); // Close all open popovers. + + var html; + var entry = $(this).data(); + + if ($(this).hasClass('unavailability')) { + var notes = 'Notes ' + entry.notes; + + html = + '' + + '' + EALang['start'] + ' ' + + GeneralFunctions.formatDate(entry.start_datetime, GlobalVariables.dateFormat, true) + + '
' + + '' + EALang['end'] + ' ' + + GeneralFunctions.formatDate(entry.end_datetime, GlobalVariables.dateFormat, true) + + '
' + + notes + + '
' + + '
' + + '' + + '' + + '' + + '
'; + } else { + html = + '' + + '' + EALang['start'] + ' ' + + GeneralFunctions.formatDate(entry.start_datetime, GlobalVariables.dateFormat, true) + + '
' + + '' + EALang['end'] + ' ' + + GeneralFunctions.formatDate(entry.end_datetime, GlobalVariables.dateFormat, true) + + '
' + + '' + EALang['service'] + ' ' + + entry.service.name + + '
' + + '' + EALang['provider'] + ' ' + + entry.provider.first_name + ' ' + + entry.provider.last_name + + '
' + + '' + EALang['customer'] + ' ' + + entry.customer.first_name + ' ' + + entry.customer.last_name + + '
' + + '
' + + '' + + '' + + '' + + '
'; + } + + $(event.target).popover({ + placement: 'top', + title: entry.service.name + ' - ' + entry.customer.first_name + ' ' + entry.customer.last_name, + content: html, + html: true, + container: '#calendar', + trigger: 'manual' + }); + + lastFocusedEventData = entry; + $(event.target).popover('toggle'); + + // Fix popover position + if ($('.popover').length > 0) { + if ($('.popover').position().top < 200) $('.popover').css('top', '200px'); + } + }); + $(window).on('resize', _setCalendarSize); + + /** + * Event: Popover Close Button "Click" + * + * Hides the open popover element. + */ + $calendar.on('click', '.close-popover', function() { + $(this).parents().eq(2).popover('destroy'); + }); + + /** + * Event: Popover Edit Button "Click" + * + * Enables the edit dialog of the selected calendar event. + */ + $calendar.on('click', '.edit-popover', function() { + $(this).parents().eq(2).popover('destroy'); // Hide the popover + + var $dialog; + + if (lastFocusedEventData.is_unavailable == false) { + var appointment = lastFocusedEventData; + $dialog = $('#manage-appointment'); + + BackendCalendarAppointmentsModal.resetAppointmentDialog(); + + // Apply appointment data and show modal dialog. + $dialog.find('.modal-header h3').text(EALang['edit_appointment_title']); + $dialog.find('#appointment-id').val(appointment['id']); + $dialog.find('#select-service').val(appointment['id_services']).trigger('change'); + $dialog.find('#select-provider').val(appointment['id_users_provider']); + + // Set the start and end datetime of the appointment. + var startDatetime = Date.parseExact(appointment['start_datetime'], + 'yyyy-MM-dd HH:mm:ss'); + $dialog.find('#start-datetime').datetimepicker('setDate', startDatetime); + + var endDatetime = Date.parseExact(appointment['end_datetime'], + 'yyyy-MM-dd HH:mm:ss'); + $dialog.find('#end-datetime').datetimepicker('setDate', endDatetime); + + var customer = appointment['customer']; + $dialog.find('#customer-id').val(appointment['id_users_customer']); + $dialog.find('#first-name').val(customer['first_name']); + $dialog.find('#last-name').val(customer['last_name']); + $dialog.find('#email').val(customer['email']); + $dialog.find('#phone-number').val(customer['phone_number']); + $dialog.find('#address').val(customer['address']); + $dialog.find('#city').val(customer['city']); + $dialog.find('#zip-code').val(customer['zip_code']); + $dialog.find('#appointment-notes').val(appointment['notes']); + $dialog.find('#customer-notes').val(customer['notes']); + } else { + var unavailable = lastFocusedEventData.data; + + // Replace string date values with actual date objects. + unavailable.start_datetime = GeneralFunctions.clone(lastFocusedEventData.start_datetime); + unavailable.end_datetime = GeneralFunctions.clone(lastFocusedEventData.end_datetime); + + $dialog = $('#manage-unavailable'); + BackendCalendarUnavailbilities.resetUnavailableDialog(); + + // Apply unvailable data to dialog. + $dialog.find('.modal-header h3').text('Edit Unavailable Period'); + $dialog.find('#unavailable-start').datetimepicker('setDate', unavailable.start_datetime); + $dialog.find('#unavailable-id').val(unavailable.id); + $dialog.find('#unavailable-end').datetimepicker('setDate', unavailable.end_datetime); + $dialog.find('#unavailable-notes').val(unavailable.notes); + } + + // :: DISPLAY EDIT DIALOG + $dialog.modal('show'); + }); + + /** + * Event: Popover Delete Button "Click" + * + * Displays a prompt on whether the user wants the appoinmtent to be deleted. If he confirms the + * deletion then an ajax call is made to the server and deletes the appointment from the database. + */ + $calendar.on('click', '.delete-popover', function() { + $(this).parents().eq(2).popover('destroy'); // Hide the popover + + if (lastFocusedEventData.is_unavailable == false) { + var messageButtons = {}; + messageButtons['OK'] = function() { + var postUrl = GlobalVariables.baseUrl + '/index.php/backend_api/ajax_delete_appointment'; + var postData = { + csrfToken: GlobalVariables.csrfToken, + appointment_id : lastFocusedEventData['id'], + delete_reason: $('#delete-reason').val() + }; + + $.post(postUrl, postData, function(response) { + $('#message_box').dialog('close'); + + if (response.exceptions) { + response.exceptions = GeneralFunctions.parseExceptions(response.exceptions); + GeneralFunctions.displayMessageBox(GeneralFunctions.EXCEPTIONS_TITLE, + GeneralFunctions.EXCEPTIONS_MESSAGE); + $('#message_box').append(GeneralFunctions.exceptionsToHtml(response.exceptions)); + return; + } + + if (response.warnings) { + response.warnings = GeneralFunctions.parseExceptions(response.warnings); + GeneralFunctions.displayMessageBox(GeneralFunctions.WARNINGS_TITLE, + GeneralFunctions.WARNINGS_MESSAGE); + $('#message_box').append(GeneralFunctions.exceptionsToHtml(response.warnings)); + } + + // Refresh calendar event items. + $('#select-filter-item').trigger('change'); + }, 'json').fail(GeneralFunctions.ajaxFailureHandler); + }; + + messageButtons[EALang['cancel']] = function() { + $('#message_box').dialog('close'); + }; + + GeneralFunctions.displayMessageBox(EALang['delete_appointment_title'], + EALang['write_appointment_removal_reason'], messageButtons); + + $('#message_box').append(''); + $('#delete-reason').css('width', '100%'); + } else { + // Do not display confirmation promt. + var postUrl = GlobalVariables.baseUrl + '/index.php/backend_api/ajax_delete_unavailable'; + var postData = { + csrfToken: GlobalVariables.csrfToken, + unavailable_id : lastFocusedEventData.id + }; + + $.post(postUrl, postData, function(response) { + $('#message_box').dialog('close'); + + if (response.exceptions) { + response.exceptions = GeneralFunctions.parseExceptions(response.exceptions); + GeneralFunctions.displayMessageBox(GeneralFunctions.EXCEPTIONS_TITLE, GeneralFunctions.EXCEPTIONS_MESSAGE); + $('#message_box').append(GeneralFunctions.exceptionsToHtml(response.exceptions)); + return; + } + + if (response.warnings) { + response.warnings = GeneralFunctions.parseExceptions(response.warnings); + GeneralFunctions.displayMessageBox(GeneralFunctions.WARNINGS_TITLE, GeneralFunctions.WARNINGS_MESSAGE); + $('#message_box').append(GeneralFunctions.exceptionsToHtml(response.warnings)); + } + + // Refresh calendar event items. + $('#select-filter-item').trigger('change'); + }, 'json').fail(GeneralFunctions.ajaxFailureHandler); + } + }); } function _createHeader() { @@ -243,6 +475,8 @@ window.BackendCalendarTableView = window.BackendCalendarTableView || {}; (appointment.customer.first_name + ' ' + appointment.customer.last_name).trim() ); + $event.data(appointment); + $tbody.find('tr').each(function(index, tr) { var $td = $(tr).find('td:first'); @@ -283,6 +517,8 @@ window.BackendCalendarTableView = window.BackendCalendarTableView || {}; $event.html(unavailability.notes || EALang['unavailable']); + $event.data(unavailability); + $tbody.find('tr').each(function(index, tr) { var $td = $(tr).find('td:first'); diff --git a/src/assets/js/backend_calendar_unavailabilities_modal.js b/src/assets/js/backend_calendar_unavailabilities_modal.js index eb056a19..5945726d 100644 --- a/src/assets/js/backend_calendar_unavailabilities_modal.js +++ b/src/assets/js/backend_calendar_unavailabilities_modal.js @@ -118,7 +118,7 @@ window.BackendCalendarUnavailabilitiesModal = window.BackendCalendarUnavailabili * he cannot accept any appointments. */ $('#insert-unavailable').click(function() { - _resetUnavailableDialog(); + BackendCalendarUnavailbilities.resetUnavailableDialog(); var $dialog = $('#manage-unavailable'); // Set the default datetime values. @@ -148,7 +148,7 @@ window.BackendCalendarUnavailabilitiesModal = window.BackendCalendarUnavailabili * Reset the "#manage-unavailable" dialog. Use this method to bring the dialog to the initial state * before it becomes visible to the user. */ - function _resetUnavailableDialog() { + exports.resetUnavailableDialog = function() { var $dialog = $('#manage-unavailable'); $dialog.find('#unavailable-id').val('');