diff --git a/src/Controller/AuthKeysController.php b/src/Controller/AuthKeysController.php
index 27bb57d..ca562b0 100644
--- a/src/Controller/AuthKeysController.php
+++ b/src/Controller/AuthKeysController.php
@@ -17,7 +17,7 @@ class AuthKeysController extends AppController
public function index()
{
$this->CRUD->index([
- 'filters' => ['users.username', 'authkey', 'comment', 'users.id'],
+ 'filters' => ['Users.username', 'authkey', 'comment', 'Users.id'],
'quickFilters' => ['authkey', 'comment'],
'contain' => ['Users'],
'exclude_fields' => ['authkey']
@@ -45,7 +45,9 @@ class AuthKeysController extends AppController
$this->CRUD->add([
'displayOnSuccess' => 'authkey_display'
]);
- $responsePayload = $this->CRUD->getResponsePayload();
+ $responsePayload = $this->CRUD->getResponsePayload([
+ 'displayOnSuccess' => 'authkey_display'
+ ]);
if (!empty($responsePayload)) {
return $responsePayload;
}
diff --git a/src/Controller/Component/CRUDComponent.php b/src/Controller/Component/CRUDComponent.php
index faafe66..47e3650 100644
--- a/src/Controller/Component/CRUDComponent.php
+++ b/src/Controller/Component/CRUDComponent.php
@@ -6,6 +6,7 @@ use Cake\Controller\Component;
use Cake\Error\Debugger;
use Cake\Utility\Hash;
use Cake\Utility\Inflector;
+use Cake\View\ViewBuilder;
class CRUDComponent extends Component
{
@@ -108,17 +109,16 @@ class CRUDComponent extends Component
$this->saveMetaFields($data->id, $input);
}
if ($this->Controller->ParamHandler->isRest()) {
- $this->Controller->restResponsePayload = $this->RestResponse->viewData($data, 'json');
+ $this->Controller->restResponsePayload = $this->RestResponse->viewData($savedData, 'json');
} else if ($this->Controller->ParamHandler->isAjax()) {
- $this->Controller->ajaxResponsePayload = $this->Controller->RestResponse->ajaxSuccessResponse($this->ObjectAlias, 'add', $savedData, $message);
+ if (!empty($params['displayOnSuccess'])) {
+ $displayOnSuccess = $this->renderViewInVariable($params['displayOnSuccess'], ['entity' => $data]);
+ $this->Controller->ajaxResponsePayload = $this->Controller->RestResponse->ajaxSuccessResponse($this->ObjectAlias, 'add', $savedData, $message, ['displayOnSuccess' => $displayOnSuccess]);
+ } else {
+ $this->Controller->ajaxResponsePayload = $this->Controller->RestResponse->ajaxSuccessResponse($this->ObjectAlias, 'add', $savedData, $message);
+ }
} else {
$this->Controller->Flash->success($message);
- if (!empty($params['displayOnSuccess'])) {
- $this->Controller->set('entity', $data);
- $this->Controller->set('referer', $this->Controller->referer());
- $this->Controller->render($params['displayOnSuccess']);
- return;
- }
if (empty($params['redirect'])) {
$this->Controller->redirect(['action' => 'view', $data->id]);
} else {
@@ -503,4 +503,12 @@ class CRUDComponent extends Component
return $this->Table->find()->distinct([$field])->all()->extract($field)->toList();
}
}
+
+ private function renderViewInVariable($templateRelativeName, $data)
+ {
+ $builder = new ViewBuilder();
+ $builder->disableAutoLayout()->setTemplate("{$this->TableAlias}/{$templateRelativeName}");
+ $view = $builder->build($data);
+ return $view->render();
+ }
}
diff --git a/src/Controller/Component/RestResponseComponent.php b/src/Controller/Component/RestResponseComponent.php
index 94b6efc..ef9bf53 100644
--- a/src/Controller/Component/RestResponseComponent.php
+++ b/src/Controller/Component/RestResponseComponent.php
@@ -420,7 +420,7 @@ class RestResponseComponent extends Component
return $this->__sendResponse($response, 200, $format);
}
- public function ajaxSuccessResponse($ObjectAlias, $action, $entity, $message)
+ public function ajaxSuccessResponse($ObjectAlias, $action, $entity, $message, $additionalData=[])
{
$action = $this->__dissectAdminRouting($action);
$response = [
@@ -429,6 +429,9 @@ class RestResponseComponent extends Component
'data' => $entity->toArray(),
'url' => $this->__generateURL($action, $ObjectAlias, $entity->id)
];
+ if (!empty($additionalData)) {
+ $response['additionalData'] = $additionalData;
+ }
return $this->viewData($response);
}
diff --git a/templates/AuthKeys/authkey_display.php b/templates/AuthKeys/authkey_display.php
index e131596..2072d17 100644
--- a/templates/AuthKeys/authkey_display.php
+++ b/templates/AuthKeys/authkey_display.php
@@ -1,5 +1,13 @@
-
= __('Authkey created'); ?>
-= __('Please make sure that you note down the authkey below, this is the only time the authkey is shown in plain text, so make sure you save it. If you lose the key, simply remove the entry and generate a new one.'); ?>
-=__('Cerebrate will use the first and the last 4 digit for identification purposes.')?>
-= sprintf('%s: %s ', __('Authkey'), h($entity->authkey_raw)) ?>
-= __('I have noted down my key, take me back now') ?>
+element('genericElements/genericModal', [
+ 'title' => __('Authkey created'),
+ 'body' => sprintf(
+ '%s
%s
%s
',
+ __('Please make sure that you note down the authkey below, this is the only time the authkey is shown in plain text, so make sure you save it. If you lose the key, simply remove the entry and generate a new one.'),
+ __('Cerebrate will use the first and the last 4 digit for identification purposes.'),
+ sprintf('%s: %s ', __('Authkey'), h($entity->authkey_raw))
+ ),
+ 'actionButton' => sprintf('%s ', __('I have noted down my key, take me back now')),
+ 'noCancel' => true,
+ 'staticBackdrop' => true,
+]);
diff --git a/templates/AuthKeys/index.php b/templates/AuthKeys/index.php
index 0964ca1..b5fbc35 100644
--- a/templates/AuthKeys/index.php
+++ b/templates/AuthKeys/index.php
@@ -10,7 +10,6 @@ echo $this->element('genericElements/IndexTable/index_table', [
'data' => [
'type' => 'simple',
'text' => __('Add authentication key'),
- 'class' => 'btn btn-primary',
'popover_url' => '/authKeys/add'
]
]
diff --git a/templates/element/genericElements/genericModal.php b/templates/element/genericElements/genericModal.php
index b12ec15..36c71a8 100644
--- a/templates/element/genericElements/genericModal.php
+++ b/templates/element/genericElements/genericModal.php
@@ -1,4 +1,4 @@
-
+
role="document">
diff --git a/webroot/js/bootstrap-helper.js b/webroot/js/bootstrap-helper.js
index 57aaaf0..a234ff2 100644
--- a/webroot/js/bootstrap-helper.js
+++ b/webroot/js/bootstrap-helper.js
@@ -34,7 +34,7 @@ class UIFactory {
modalFromURL(url, POSTSuccessCallback, POSTFailCallback) {
return AJAXApi.quickFetchURL(url).then((modalHTML) => {
const theModal = new ModalFactory({
- rawHTML: modalHTML,
+ rawHtml: modalHTML,
POSTSuccessCallback: POSTSuccessCallback !== undefined ? POSTSuccessCallback : () => {},
POSTFailCallback: POSTFailCallback !== undefined ? POSTFailCallback : (errorMessage) => {},
});
@@ -46,31 +46,43 @@ class UIFactory {
}
/**
- * Create and display a modal where the modal's content is fetched from the provided URL. Reload the table after a successful operation
+ * 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
* @param {string} url - The URL from which the modal's content should be fetched
* @param {string} tableId - 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, () => {
+ 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) {
- return UI.reload(`/${currentModel}/index`, $container, $elligibleTable)
+ UI.reload(`/${currentModel}/index`, $container, $elligibleTable)
+ reloaded = true
} else {
$container = $elligibleTable.closest('div[id^="single-view-table-container-"]')
if ($container.length == 1) {
- return UI.reload(location.pathname, $container, $elligibleTable)
+ UI.reload(location.pathname, $container, $elligibleTable)
+ reloaded = true
}
}
}
} else {
- return UI.reload(reloadUrl, $(`#table-container-${tableId}`), $(`#table-container-${tableId} table.table`))
+ UI.reload(reloadUrl, $(`#table-container-${tableId}`), $(`#table-container-${tableId} table.table`))
+ reloaded = true
+ }
+ if (data.additionalData !== undefined && data.additionalData.displayOnSuccess !== undefined) {
+ UI.modal({
+ rawHtml: data.additionalData.displayOnSuccess
+ })
+ } else {
+ if (!reloaded) {
+ location.reload()
+ }
}
- location.reload()
})
}
@@ -247,7 +259,7 @@ class ModalFactory {
*/
constructor(options) {
this.options = Object.assign({}, ModalFactory.defaultOptions, options)
- if (this.options.rawHTML) {
+ if (this.options.rawHtml && options.POSTSuccessCallback !== undefined) {
this.attachSubmitButtonListener = true
}
if (options.type === undefined && options.cancel !== undefined) {
@@ -256,6 +268,9 @@ class ModalFactory {
this.bsModalOptions = {
show: true
}
+ if (this.options.backdropStatic) {
+ this.bsModalOptions['backdrop'] = 'static'
+ }
}
/**
@@ -305,11 +320,12 @@ class ModalFactory {
* @property {string=('sm'|'lg'|'xl'|'')} size - The size of the modal
* @property {boolean} centered - Should the modal be vertically centered
* @property {boolean} scrollable - Should the modal be scrollable
+ * @property {boolean} backdropStatic - When set, the modal will not close when clicking outside it.
* @property {string} title - The title's content of the modal
* @property {string} titleHtml - The raw HTML title's content of the modal
* @property {string} body - The body's content of the modal
* @property {string} bodyHtml - The raw HTML body's content of the modal
- * @property {string} rawHTML - The raw HTML of the whole modal. If provided, will override any other content
+ * @property {string} rawHtml - The raw HTML of the whole modal. If provided, will override any other content
* @property {string=('primary'|'secondary'|'success'|'danger'|'warning'|'info'|'light'|'dark'|'white'|'transparent')} variant - The variant of the modal
* @property {string} modalClass - Classes to be added to the modal's container
* @property {string} headerClass - Classes to be added to the modal's header
@@ -334,11 +350,12 @@ class ModalFactory {
size: 'md',
centered: false,
scrollable: false,
+ backdropStatic: false,
title: '',
titleHtml: false,
body: false,
bodyHtml: false,
- rawHTML: false,
+ rawHtml: false,
variant: '',
modalClass: '',
headerClass: '',
@@ -375,6 +392,8 @@ class ModalFactory {
if (this.isValid()) {
this.$modal = this.buildModal()
$('#mainModalContainer').append(this.$modal)
+ } else {
+ console.log('Modal not valid')
}
}
@@ -393,6 +412,8 @@ class ModalFactory {
that.findSubmitButtonAndAddListener()
}
})
+ } else {
+ console.log('Modal not valid')
}
}
@@ -413,7 +434,7 @@ class ModalFactory {
isValid() {
return this.options.title !== false || this.options.titleHtml !== false ||
this.options.body !== false || this.options.bodyHtml !== false ||
- this.options.rawHTML !== false
+ this.options.rawHtml !== false
}
/**
@@ -430,8 +451,11 @@ class ModalFactory {
$modal.addClass(this.options.modalClass)
}
let $modalDialog
- if (this.options.rawHTML) {
- $modalDialog = $(this.options.rawHTML)
+ if (this.options.rawHtml) {
+ $modalDialog = $(this.options.rawHtml)
+ if ($modalDialog.data('backdrop') == 'static') {
+ this.bsModalOptions['backdrop'] = 'static'
+ }
} else {
$modalDialog = $('
')
const $modalContent = $('
')
@@ -564,14 +588,12 @@ class ModalFactory {
}
this.options.APIConfirm = (tmpApi) => {
- tmpApi.mergeOptions({forceHTMLOnValidationFailure: true})
return tmpApi.postForm($form[0])
.then((data) => {
if (data.success) {
this.options.POSTSuccessCallback(data)
- } else { // Validation error, replace modal content with new html
- this.$modal.html(data.html)
- this.findSubmitButtonAndAddListener()
+ } else { // Validation error
+ this.injectFormValidationFeedback(form, data.errors)
return Promise.reject('Validation error');
}
})