Spaces:
No application file
No application file
| Mautic.modalContentXhr = {}; | |
| Mautic.activeModal = ''; | |
| Mautic.backgroundedModal = ''; | |
| /** | |
| * Load a modal with ajax content | |
| * | |
| * @param el | |
| * @param event | |
| * | |
| * @returns {boolean} | |
| */ | |
| Mautic.ajaxifyModal = function (el, event) { | |
| let element = mQuery(el); | |
| if (element.hasClass('disabled')) { | |
| return false; | |
| } | |
| mQuery('body').addClass('noscroll'); | |
| let target = element.attr('data-target'); | |
| let route = element.attr('data-href') ? element.attr('data-href') : element.attr('href'); | |
| if (route.indexOf('javascript') >= 0) { | |
| return false; | |
| } | |
| let method = element.attr('data-method') ? element.attr('data-method') : 'GET'; | |
| let header = element.attr('data-header'); | |
| let footer = element.attr('data-footer'); | |
| let modalOpenCallback = element.attr('data-modal-open-callback') ? element.attr('data-modal-open-callback') : null; | |
| let modalCloseCallback = element.attr('data-modal-close-callback') ? element.attr('data-modal-close-callback') : null; | |
| let preventDismissal = element.attr('data-prevent-dismiss'); | |
| if (preventDismissal) { | |
| // Reset | |
| element.removeAttr('data-prevent-dismiss'); | |
| } | |
| /* | |
| * If we have an onLoadCallback, proxy it through this function so that | |
| * we can pass the element to the callback. The callback must exist on | |
| * the window.Mautic object. | |
| */ | |
| let modalOpenCallbackReal = null; | |
| if (modalOpenCallback && window["Mautic"].hasOwnProperty(modalOpenCallback)) { | |
| modalOpenCallbackReal = function() { | |
| Mautic[modalOpenCallback](el); | |
| }; | |
| } | |
| let modalCloseCallbackReal = null; | |
| if (modalCloseCallback && window["Mautic"].hasOwnProperty(modalOpenCallback)) { | |
| modalCloseCallbackReal = function() { | |
| Mautic[modalCloseCallback](el); | |
| }; | |
| } | |
| Mautic.loadAjaxModal(target, route, method, header, footer, preventDismissal, modalOpenCallbackReal, modalCloseCallbackReal); | |
| }; | |
| /** | |
| * Retrieve ajax content for modal | |
| * @param target | |
| * @param route | |
| * @param method | |
| * @param header | |
| * @param footer | |
| * @param preventDismissal | |
| * @param modalOpenCallback | |
| * @param modalCloseCallback | |
| */ | |
| Mautic.loadAjaxModal = function (target, route, method, header, footer, preventDismissal, modalOpenCallback, modalCloseCallback) { | |
| let element = mQuery(target); | |
| if (element.find('.loading-placeholder').length) { | |
| element.find('.loading-placeholder').removeClass('hide'); | |
| element.find('.modal-body-content').addClass('hide'); | |
| if (element.find('.modal-loading-bar').length) { | |
| element.find('.modal-loading-bar').addClass('active'); | |
| } | |
| } | |
| if (footer == 'false') { | |
| element.find(".modal-footer").addClass('hide'); | |
| } | |
| //move the modal to the body tag to get around positioned div issues | |
| element.one('show.bs.modal', function () { | |
| if (header) { | |
| element.find(".modal-title").html(header); | |
| } | |
| if (footer && footer != 'false') { | |
| element.find(".modal-footer").html(header); | |
| } | |
| if (modalOpenCallback) { | |
| modalOpenCallback(); | |
| } | |
| }); | |
| //clean slate upon close | |
| element.one('hidden.bs.modal', function () { | |
| if (typeof Mautic.modalContentXhr[target] != 'undefined') { | |
| Mautic.modalContentXhr[target].abort(); | |
| delete Mautic.modalContentXhr[target]; | |
| } | |
| mQuery('body').removeClass('noscroll'); | |
| let response = {}; | |
| if (Mautic.modalMauticContent) { | |
| response.mauticContent = Mautic.modalMauticContent; | |
| delete Mautic.modalMauticContent; | |
| } | |
| if (modalCloseCallback) { | |
| modalCloseCallback(); | |
| } | |
| //unload | |
| Mautic.onPageUnload(target, response); | |
| Mautic.resetModal(target); | |
| }); | |
| // Check if dismissal is allowed | |
| if (typeof element.data('bs.modal') !== 'undefined' && typeof element.data('bs.modal').options !== 'undefined') { | |
| if (preventDismissal) { | |
| element.data('bs.modal').options.keyboard = false; | |
| element.data('bs.modal').options.backdrop = 'static'; | |
| } else { | |
| element.data('bs.modal').options.keyboard = true; | |
| element.data('bs.modal').options.backdrop = true; | |
| } | |
| } else { | |
| if (preventDismissal) { | |
| element.modal({ | |
| backdrop: 'static', | |
| keyboard: false | |
| }); | |
| } else { | |
| element.modal({ | |
| backdrop: true, | |
| keyboard: true | |
| }); | |
| } | |
| } | |
| Mautic.showModal(target); | |
| if (typeof Mautic.modalContentXhr == 'undefined') { | |
| Mautic.modalContentXhr = {}; | |
| } else if (typeof Mautic.modalContentXhr[target] != 'undefined') { | |
| Mautic.modalContentXhr[target].abort(); | |
| } | |
| Mautic.modalContentXhr[target] = mQuery.ajax({ | |
| url: route, | |
| type: method, | |
| dataType: "json", | |
| success: function (response) { | |
| if (response) { | |
| Mautic.processModalContent(response, target); | |
| } | |
| Mautic.stopIconSpinPostEvent(); | |
| }, | |
| error: function (request, textStatus, errorThrown) { | |
| Mautic.processAjaxError(request, textStatus, errorThrown); | |
| Mautic.stopIconSpinPostEvent(); | |
| }, | |
| complete: function () { | |
| Mautic.stopModalLoadingBar(target); | |
| delete Mautic.modalContentXhr[target]; | |
| } | |
| }); | |
| }; | |
| /** | |
| * Clears content from a shared modal | |
| * @param target | |
| */ | |
| Mautic.resetModal = function (target) { | |
| if (mQuery(target).hasClass('in')) { | |
| return; | |
| } | |
| mQuery(target + " .modal-title").html(''); | |
| mQuery(target + " .modal-body-content").html(''); | |
| if (mQuery(target + " loading-placeholder").length) { | |
| mQuery(target + " loading-placeholder").removeClass('hide'); | |
| } | |
| if (mQuery(target + " .modal-footer").length) { | |
| var hasFooterButtons = mQuery(target + " .modal-footer .modal-form-buttons").length; | |
| mQuery(target + " .modal-footer").html(''); | |
| if (hasFooterButtons) { | |
| //add footer buttons | |
| mQuery('<div class="modal-form-buttons" />').appendTo(target + " .modal-footer"); | |
| } | |
| mQuery(target + " .modal-footer").removeClass('hide'); | |
| } | |
| }; | |
| /** | |
| * Handles modal content post ajax request | |
| * @param response | |
| * @param target | |
| */ | |
| Mautic.processModalContent = function (response, target) { | |
| Mautic.stopIconSpinPostEvent(); | |
| if (response.error) { | |
| if (response.errors) { | |
| alert(response.errors[0].message); | |
| } else if (response.error.message) { | |
| alert(response.error.message); | |
| } else { | |
| alert(response.error); | |
| } | |
| return; | |
| } | |
| if (response.sessionExpired || (response.closeModal && response.newContent && !response.updateModalContent)) { | |
| mQuery(target).modal('hide'); | |
| mQuery('body').removeClass('modal-open'); | |
| mQuery('.modal-backdrop').remove(); | |
| //assume the content is to refresh main app | |
| Mautic.processPageContent(response); | |
| } else { | |
| if (response.notifications) { | |
| Mautic.setNotifications(response.notifications); | |
| } | |
| if (response.callback) { | |
| window["Mautic"][response.callback].apply('window', [response]); | |
| return; | |
| } | |
| if (response.target) { | |
| mQuery(response.target).html(response.newContent); | |
| //activate content specific stuff | |
| Mautic.onPageLoad(response.target, response, true); | |
| } else if (response.newContent) { | |
| //load the content | |
| if (mQuery(target + ' .loading-placeholder').length) { | |
| mQuery(target + ' .loading-placeholder').addClass('hide'); | |
| mQuery(target + ' .modal-body-content').html(response.newContent); | |
| mQuery(target + ' .modal-body-content').removeClass('hide'); | |
| } else { | |
| mQuery(target + ' .modal-body').html(response.newContent); | |
| } | |
| } | |
| //activate content specific stuff | |
| Mautic.onPageLoad(target, response, true); | |
| Mautic.modalMauticContent = false; | |
| if (response.closeModal) { | |
| mQuery('body').removeClass('noscroll'); | |
| mQuery(target).modal('hide'); | |
| if (!response.updateModalContent) { | |
| Mautic.onPageUnload(target, response); | |
| } | |
| } else { | |
| // Note for the hidden event | |
| Mautic.modalMauticContent = response.mauticContent ? response.mauticContent : false; | |
| } | |
| } | |
| }; | |
| /** | |
| * Display confirmation modal | |
| */ | |
| Mautic.showConfirmation = function (el) { | |
| var precheck = mQuery(el).data('precheck'); | |
| if (precheck) { | |
| if (typeof precheck == 'function') { | |
| if (!precheck()) { | |
| return; | |
| } | |
| } else if (typeof Mautic[precheck] == 'function') { | |
| if (!Mautic[precheck]()) { | |
| return; | |
| } | |
| } | |
| } | |
| var message = mQuery(el).data('message'); | |
| var confirmText = mQuery(el).data('confirm-text'); | |
| var confirmAction = mQuery(el).attr('href'); | |
| var confirmCallback = mQuery(el).data('confirm-callback'); | |
| var cancelText = mQuery(el).data('cancel-text'); | |
| var cancelCallback = mQuery(el).data('cancel-callback'); | |
| const confirmBtnClass = mQuery(el).data('confirm-btn-class') | |
| ? mQuery(el).data('confirm-btn-class') : 'btn btn-danger'; | |
| var confirmContainer = mQuery("<div />").attr({"class": "modal fade confirmation-modal"}); | |
| var confirmDialogDiv = mQuery("<div />").attr({"class": "modal-dialog"}); | |
| var confirmContentDiv = mQuery("<div />").attr({"class": "modal-content"}); | |
| var confirmFooterDiv = mQuery("<div />").attr({"class": "modal-body text-center"}); | |
| var confirmHeaderDiv = mQuery("<div />").attr({"class": "modal-header"}); | |
| confirmHeaderDiv.append(mQuery('<h4 />').attr({"class": "modal-title"}).text(message)); | |
| var confirmButton = mQuery('<button type="button" />') | |
| .addClass(confirmBtnClass) | |
| .css("marginRight", "5px") | |
| .css("marginLeft", "5px") | |
| .click(function () { | |
| if (typeof Mautic[confirmCallback] === "function") { | |
| window["Mautic"][confirmCallback].apply('window', [confirmAction, el]); | |
| } | |
| }) | |
| .html(confirmText); | |
| if (cancelText) { | |
| var cancelButton = mQuery('<button type="button" />') | |
| .addClass("btn btn-primary") | |
| .click(function () { | |
| if (cancelCallback && typeof Mautic[cancelCallback] === "function") { | |
| window["Mautic"][cancelCallback].apply('window', [el]); | |
| } else { | |
| Mautic.dismissConfirmation(); | |
| } | |
| }) | |
| .html(cancelText); | |
| } | |
| if (typeof cancelButton != 'undefined') { | |
| confirmFooterDiv.append(cancelButton); | |
| } | |
| if (confirmText) { | |
| confirmFooterDiv.append(confirmButton); | |
| } | |
| confirmContentDiv.append(confirmHeaderDiv); | |
| confirmContentDiv.append(confirmFooterDiv); | |
| confirmContainer.append(confirmDialogDiv.append(confirmContentDiv)); | |
| mQuery('body').append(confirmContainer); | |
| mQuery('.confirmation-modal').on('hidden.bs.modal', function () { | |
| mQuery(this).remove(); | |
| }); | |
| mQuery('.confirmation-modal').modal('show'); | |
| }; | |
| /** | |
| * Dismiss confirmation modal | |
| */ | |
| Mautic.dismissConfirmation = function () { | |
| if (mQuery('.confirmation-modal').length) { | |
| mQuery('.confirmation-modal').modal('hide'); | |
| } | |
| }; | |
| /** | |
| * Close the given modal and redirect to a URL | |
| * | |
| * @param el | |
| * @param url | |
| */ | |
| Mautic.closeModalAndRedirect = function(el, url) { | |
| Mautic.startModalLoadingBar(el); | |
| Mautic.loadContent(url); | |
| mQuery('body').removeClass('noscroll'); | |
| }; | |
| /** | |
| * Open modal route when a specific value is selected from a select list | |
| * | |
| * @param el | |
| * @param url | |
| * @param header | |
| */ | |
| Mautic.loadAjaxModalBySelectValue = function (el, value, route, header) { | |
| var selectVal = mQuery(el).val(); | |
| var hasValue = (selectVal == value); | |
| if (!hasValue && mQuery.isArray(selectVal)) { | |
| hasValue = (mQuery.inArray(value, selectVal) !== -1); | |
| } | |
| if (hasValue) { | |
| // Remove it from the select | |
| route = route + (route.indexOf('?') > -1 ? '&' : '?') + 'modal=1&contentOnly=1&updateSelect=' + mQuery(el).attr('id'); | |
| mQuery(el).find('option[value="' + value + '"]').prop('selected', false); | |
| mQuery(el).trigger("chosen:updated"); | |
| Mautic.loadAjaxModal('#MauticSharedModal', route, 'get', header); | |
| } | |
| }; | |
| /** | |
| * Push active modal to the background and bring it back once this one closes | |
| * | |
| * @param target | |
| */ | |
| Mautic.showModal = function(target) { | |
| if (mQuery('.modal.in').length) { | |
| // another modal is activated so let's stack | |
| // is this modal within another modal? | |
| if (mQuery(target).closest('.modal').length) { | |
| // the modal has to be moved outside of it's parent for this to work so take note where it needs to | |
| // moved back to | |
| mQuery('<div />').attr('data-modal-placeholder', target).insertAfter(mQuery(target)); | |
| mQuery(target).attr('data-modal-moved', 1); | |
| mQuery(target).appendTo('body'); | |
| } | |
| var activeModal = mQuery('.modal.in .modal-dialog:not(:has(.aside))').parents('.modal').last(), | |
| targetModal = mQuery(target); | |
| if (activeModal.length && activeModal.attr('id') !== targetModal.attr('id')) { | |
| targetModal.attr('data-previous-modal', '#'+activeModal.attr('id')); | |
| activeModal.find('.modal-dialog').addClass('aside'); | |
| var stackedDialogCount = mQuery('.modal.in .modal-dialog.aside').length; | |
| if (stackedDialogCount <= 5) { | |
| activeModal.find('.modal-dialog').addClass('aside-' + stackedDialogCount); | |
| } | |
| mQuery(target).on('hide.bs.modal', function () { | |
| var modal = mQuery(this); | |
| var previous = modal.attr('data-previous-modal'); | |
| if (previous) { | |
| mQuery(previous).find('.modal-dialog').removeClass('aside'); | |
| mQuery(modal).attr('data-previous-modal', undefined); | |
| } | |
| if (mQuery(modal).attr('data-modal-moved')) { | |
| mQuery('[data-modal-placeholder]').replaceWith(mQuery(modal)); | |
| mQuery(modal).attr('data-modal-moved', undefined); | |
| } | |
| }); | |
| } | |
| } | |
| mQuery(target).modal('show'); | |
| }; | |