From 3bd2b7583ec9e09b06c7e8253617c30a6e635615 Mon Sep 17 00:00:00 2001 From: mokaddem Date: Wed, 10 Mar 2021 14:54:52 +0100 Subject: [PATCH] chg: [js:bootstrap-helper] Made submission modal more explicit --- .../genericElements/Form/submitButton.php | 2 +- .../IndexTable/Fields/actions.php | 2 +- .../IndexTable/Fields/alignments.php | 4 +- .../ListTopBar/element_simple.php | 6 +- .../ListTopBar/group_search.php | 6 +- .../SingleViews/Fields/alignmentField.php | 6 +- .../genericElements/side_menu_scaffold.php | 2 +- webroot/js/bootstrap-helper.js | 127 +++++++++++++----- 8 files changed, 106 insertions(+), 49 deletions(-) diff --git a/templates/element/genericElements/Form/submitButton.php b/templates/element/genericElements/Form/submitButton.php index 9a2a82c..134e857 100644 --- a/templates/element/genericElements/Form/submitButton.php +++ b/templates/element/genericElements/Form/submitButton.php @@ -3,7 +3,7 @@ echo sprintf( '%s', sprintf( - '', + '', '#form-' . h($formRandomValue), __('Submit') ) diff --git a/templates/element/genericElements/IndexTable/Fields/actions.php b/templates/element/genericElements/IndexTable/Fields/actions.php index fd03628..e099d41 100644 --- a/templates/element/genericElements/IndexTable/Fields/actions.php +++ b/templates/element/genericElements/IndexTable/Fields/actions.php @@ -87,7 +87,7 @@ $action['open_modal'] ); $reload_url = !empty($action['reload_url']) ? $action['reload_url'] : $this->Url->build(['action' => 'index']); - $action['onclick'] = sprintf('UI.openModalFromURL(\'%s\', \'%s\', \'%s\')', $modal_url, $reload_url, $tableRandomValue); + $action['onclick'] = sprintf('UI.submissionModalForIndex(\'%s\', \'%s\', \'%s\')', $modal_url, $reload_url, $tableRandomValue); } echo sprintf( ' ', diff --git a/templates/element/genericElements/IndexTable/Fields/alignments.php b/templates/element/genericElements/IndexTable/Fields/alignments.php index 611f990..f761c2a 100644 --- a/templates/element/genericElements/IndexTable/Fields/alignments.php +++ b/templates/element/genericElements/IndexTable/Fields/alignments.php @@ -14,7 +14,7 @@ if ($field['scope'] === 'individuals') { h($alignment['organisation']['name']) ), !$canRemove ? '' : sprintf( - "UI.openModalFromURL(%s);", + "UI.submissionModalForIndex(%s);", sprintf( "'/alignments/delete/%s'", h($alignment['id']) @@ -34,7 +34,7 @@ if ($field['scope'] === 'individuals') { h($alignment['individual']['email']) ), !$canRemove ? '' : sprintf( - "UI.openModalFromURL(%s);", + "UI.submissionModalForIndex(%s);", sprintf( "'/alignments/delete/%s'", h($alignment['id']) diff --git a/templates/element/genericElements/ListTopBar/element_simple.php b/templates/element/genericElements/ListTopBar/element_simple.php index 6747eb1..a14976f 100644 --- a/templates/element/genericElements/ListTopBar/element_simple.php +++ b/templates/element/genericElements/ListTopBar/element_simple.php @@ -71,12 +71,8 @@ \ No newline at end of file diff --git a/templates/element/genericElements/ListTopBar/group_search.php b/templates/element/genericElements/ListTopBar/group_search.php index 8e85f39..f405640 100644 --- a/templates/element/genericElements/ListTopBar/group_search.php +++ b/templates/element/genericElements/ListTopBar/group_search.php @@ -144,11 +144,7 @@ } function openFilteringModal(clicked, url, reloadUrl, tableId) { - const loadingOverlay = new OverlayFactory(clicked); - loadingOverlay.show() - UI.openModalFromURL(url, reloadUrl, tableId).finally(() => { - loadingOverlay.hide() - }) + UI.overlayUntilResolve(clicked, UI.submissionModalForIndex(url, reloadUrl, tableId)) } }); diff --git a/templates/element/genericElements/SingleViews/Fields/alignmentField.php b/templates/element/genericElements/SingleViews/Fields/alignmentField.php index eb922b9..50e9162 100644 --- a/templates/element/genericElements/SingleViews/Fields/alignmentField.php +++ b/templates/element/genericElements/SingleViews/Fields/alignmentField.php @@ -20,7 +20,7 @@ if ($field['scope'] === 'individuals') { h($alignment['organisation']['name']) ), sprintf( - "UI.openModalFromURL(%s);", + "UI.submissionModalForSinglePage(%s);", sprintf( "'/alignments/delete/%s'", $alignment['id'] @@ -40,7 +40,7 @@ if ($field['scope'] === 'individuals') { h($alignment['individual']['email']) ), sprintf( - "UI.openModalFromURL(%s);", + "UI.submissionModalForSinglePage(%s);", sprintf( "'/alignments/delete/%s'", $alignment['id'] @@ -53,7 +53,7 @@ echo sprintf( '
%s
', $alignments, sprintf( - "UI.openModalFromURL('/alignments/add/%s/%s');", + "UI.submissionModalForSinglePage('/alignments/add/%s/%s');", h($field['scope']), h($extracted['id']) ), diff --git a/templates/element/genericElements/side_menu_scaffold.php b/templates/element/genericElements/side_menu_scaffold.php index bd6ab03..5edb5e2 100644 --- a/templates/element/genericElements/side_menu_scaffold.php +++ b/templates/element/genericElements/side_menu_scaffold.php @@ -35,7 +35,7 @@ if (isset($menu[$metaGroup])) { } $active = ($scope === $this->request->getParam('controller') && $action === $this->request->getParam('action')); if (!empty($data['popup'])) { - $link_template = '%s'; + $link_template = '%s'; } else { $link_template = '%s'; } diff --git a/webroot/js/bootstrap-helper.js b/webroot/js/bootstrap-helper.js index 26c6ecb..ec61568 100644 --- a/webroot/js/bootstrap-helper.js +++ b/webroot/js/bootstrap-helper.js @@ -25,13 +25,13 @@ class UIFactory { } /** - * Create and display a modal where the modal's content is fetched from the provided URL. + * Create and display a modal where the modal's content is fetched from the provided URL. Link an AJAXApi to the submission button * @param {string} url - The URL from which the modal's content should be fetched * @param {ModalFactory~POSTSuccessCallback} POSTSuccessCallback - The callback that handles successful form submission * @param {ModalFactory~POSTFailCallback} POSTFailCallback - The callback that handles form submissions errors and validation errors. * @return {Promise} Promise object resolving to the ModalFactory object */ - modalFromURL(url, POSTSuccessCallback, POSTFailCallback) { + submissionModal(url, POSTSuccessCallback, POSTFailCallback) { return AJAXApi.quickFetchURL(url).then((modalHTML) => { const theModal = new ModalFactory({ rawHtml: modalHTML, @@ -46,45 +46,110 @@ class UIFactory { } /** - * Creates and displays a modal where the modal's content is fetched from the provided URL. Reloads the table after a successful operation and handles displayOnSuccess option + * Creates and displays a modal where the modal's content is fetched from the provided URL. Reloads the single page view after a successful operation. + * Supports `displayOnSuccess` option to show another modal after the submission * @param {string} url - The URL from which the modal's content should be fetched - * @param {string} reloadUrl - The URL from which the data should be fetched after confirming - * @param {string} tableId - The table ID which should be reloaded on success + * @param {(boolean|string)} [reloadUrl=false] - The URL from which the data should be fetched after confirming + * @param {(jQuery|string)} [$table=false] - The table ID which should be reloaded on success * @return {Promise} Promise object resolving to the ModalFactory object */ - openModalFromURL(url, reloadUrl=false, tableId=false) { - return UI.modalFromURL(url, (data) => { - let reloaded = false - if (reloadUrl === false || tableId === false) { // Try to get information from the DOM - let $elligibleTable = $('table.table') - let currentModel = location.pathname.split('/')[1] - if ($elligibleTable.length == 1 && currentModel.length > 0) { - let $container = $elligibleTable.closest('div[id^="table-container-"]') - if ($container.length == 1) { - UI.reload(`/${currentModel}/index`, $container, $elligibleTable) - reloaded = true - } else { - $container = $elligibleTable.closest('div[id^="single-view-table-container-"]') - if ($container.length == 1) { - UI.reload(location.pathname, $container, $elligibleTable) - reloaded = true - } - } - } + submissionModalForSinglePage(url, reloadUrl=false, $table=false) { + let $statusNode, $reloadedElement + if (reloadUrl === false) { + reloadUrl = location.pathname + } + if ($table === false) { // Try to get information from the DOM + const $elligibleTable = $('table[id^="single-view-table-"]') + const $container = $elligibleTable.closest('div[id^="single-view-table-container-"]') + $reloadedElement = $container + $statusNode = $elligibleTable + } else { + if ($table instanceof jQuery) { + $reloadedElement = $table + $statusNode = $table.find('table[id^="single-view-table-"]') } else { - UI.reload(reloadUrl, $(`#table-container-${tableId}`), $(`#table-container-${tableId} table.table`)) - reloaded = true + $reloadedElement = $(`single-view-table-container-${$table}`) + $statusNode = $(`single-view-table-${$table}`) } + } + if ($reloadedElement.length == 0) { + UI.Toaster({ + variant: 'danger', + title: 'Could not find element to be reloaded', + body: 'The content of this page may have changed and has not been reflected. Reloading the page is advised.' + }) + return + } + return UI.submissionReloaderModal(url, reloadUrl, $reloadedElement, $statusNode); + } + + /** + * Creates and displays a modal where the modal's content is fetched from the provided URL. Reloads the index table after a successful operation. + * Supports `displayOnSuccess` option to show another modal after the submission + * @param {string} url - The URL from which the modal's content should be fetched + * @param {(boolean|string)} [reloadUrl=false] - The URL from which the data should be fetched after confirming + * @param {(jQuery|string)} [$table=false] - The table ID which should be reloaded on success + * @return {Promise} Promise object resolving to the ModalFactory object + */ + submissionModalForIndex(url, reloadUrl=false, $table=false) { + let $statusNode, $reloadedElement + if (reloadUrl === false) { + const currentModel = location.pathname.split('/')[1] + if (currentModel.length > 0) { + reloadUrl = `/${currentModel}/index` + } else { + UI.Toaster({ + variant: 'danger', + title: 'Could not find URL for the reload', + body: 'The content of this page may have changed and has not been reflected. Reloading the page is advised.' + }) + return + } + } + if ($table === false) { // Try to get information from the DOM + const $elligibleTable = $('table.table') + const $container = $elligibleTable.closest('div[id^="table-container-"]') + $reloadedElement = $container + $statusNode = $elligibleTable + } else { + if ($table instanceof jQuery) { + $reloadedElement = $table + $statusNode = $table.find('table.table') + } else { + $reloadedElement = $(`#table-container-${$table}`) + $statusNode = $(`#table-container-${$table} table.table`) + } + } + if ($reloadedElement.length == 0) { + UI.Toaster({ + variant: 'danger', + title: 'Could not find element to be reloaded', + body: 'The content of this page may have changed and has not been reflected. Reloading the page is advised.' + }) + return + } + return UI.submissionReloaderModal(url, reloadUrl, $reloadedElement, $statusNode); + } + + /** + * Creates and displays a modal where the modal's content is fetched from the provided URL. Reloads the provided element after a successful operation. + * Supports `displayOnSuccess` option to show another modal after the submission + * @param {string} url - The URL from which the modal's content should be fetched + * @param {string} reloadUrl - The URL from which the data should be fetched after confirming + * @param {(jQuery|string)} $reloadedElement - The element which should be reloaded on success + * @param {(jQuery|string)} [$statusNode=null] - A reference to a HTML node on which the loading animation should be displayed. If not provided, $container will be used + * @return {Promise} Promise object resolving to the ModalFactory object + */ + submissionReloaderModal(url, reloadUrl, $reloadedElement, $statusNode=null) { + const successCallback = function (data) { + UI.reload(reloadUrl, $reloadedElement, $statusNode) if (data.additionalData !== undefined && data.additionalData.displayOnSuccess !== undefined) { UI.modal({ rawHtml: data.additionalData.displayOnSuccess }) - } else { - if (!reloaded) { - location.reload() - } } - }) + } + return UI.submissionModal(url, successCallback) } /**