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(
- '%s ',
+ '%s ',
'#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
%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)
}
/**