chg: [helpers:bootstrap] Allows passing modal footer buttons

pull/59/head
mokaddem 2021-06-14 13:03:58 +02:00
parent 034ff034df
commit 47384925c6
2 changed files with 100 additions and 43 deletions

View File

@ -768,7 +768,7 @@ class BoostrapModal extends BootstrapGeneric {
function __construct($options) { function __construct($options) {
$this->allowedOptionValues = [ $this->allowedOptionValues = [
'size' => ['sm', 'lg', 'xl', ''], 'size' => ['sm', 'lg', 'xl', ''],
'type' => ['ok-only','confirm','confirm-success','confirm-warning','confirm-danger'], 'type' => ['ok-only','confirm','confirm-success','confirm-warning','confirm-danger', 'custom'],
'variant' => array_merge(BootstrapGeneric::$variants, ['']), 'variant' => array_merge(BootstrapGeneric::$variants, ['']),
]; ];
$this->processOptions($options); $this->processOptions($options);
@ -834,7 +834,10 @@ class BoostrapModal extends BootstrapGeneric {
private function genFooter() private function genFooter()
{ {
$footer = $this->openNode('div', ['class' => array_merge(['modal-footer'], $this->options['footerClass'])]); $footer = $this->openNode('div', [
'class' => array_merge(['modal-footer'], $this->options['footerClass']),
'data-custom-footer' => $this->options['type'] == 'custom'
]);
if (!empty($this->options['footerHtml'])) { if (!empty($this->options['footerHtml'])) {
$footer .= $this->options['footerHtml']; $footer .= $this->options['footerHtml'];
} else { } else {
@ -849,6 +852,8 @@ class BoostrapModal extends BootstrapGeneric {
return $this->getFooterOkOnly(); return $this->getFooterOkOnly();
} else if (str_contains($this->options['type'], 'confirm')) { } else if (str_contains($this->options['type'], 'confirm')) {
return $this->getFooterConfirm(); return $this->getFooterConfirm();
} else if ($this->options['type'] == 'custom') {
return $this->getFooterCustom();
} else { } else {
return $this->getFooterOkOnly(); return $this->getFooterOkOnly();
} }
@ -893,6 +898,23 @@ class BoostrapModal extends BootstrapGeneric {
]))->button(); ]))->button();
return $buttonCancel . $buttonConfirm; return $buttonCancel . $buttonConfirm;
} }
private function getFooterCustom()
{
$buttons = [];
foreach ($this->options['footerButtons'] as $buttonConfig) {
$buttons[] = (new BoostrapButton([
'variant' => h($buttonConfig['variant'] ?? 'primary'),
'text' => h($buttonConfig['text']),
'class' => 'modal-confirm-button',
'params' => [
'data-dismiss' => !empty($buttonConfig['clickFunction']) ? '' : 'modal',
'data-clickFunction' => sprintf('%s', $buttonConfig['clickFunction'])
]
]))->button();
}
return implode('', $buttons);
}
} }
class BoostrapProgress extends BootstrapGeneric { class BoostrapProgress extends BootstrapGeneric {

View File

@ -668,13 +668,17 @@ class ModalFactory {
} }
/** Generate the function that will be called when the user confirm the modal */ /** Generate the function that will be called when the user confirm the modal */
getConfirmationHandlerFunction() { getConfirmationHandlerFunction(i) {
return (evt) => { return (evt) => {
let confirmFunction = this.options.confirm let confirmFunction = this.options.confirm
if (this.options.APIConfirm) { const tmpApi = new AJAXApi({
const tmpApi = new AJAXApi({ statusNode: evt.target
statusNode: evt.target })
}) if (this.options.APIConfirms) {
if (i !== undefined && this.options.APIConfirms[i] !== undefined) {
confirmFunction = () => { return this.options.APIConfirms[i](tmpApi) }
}
} else if (this.options.APIConfirm) {
confirmFunction = () => { return this.options.APIConfirm(tmpApi) } confirmFunction = () => { return this.options.APIConfirm(tmpApi) }
} }
let confirmResult = confirmFunction(() => { this.hide() }, this, evt) let confirmResult = confirmFunction(() => { this.hide() }, this, evt)
@ -695,24 +699,73 @@ class ModalFactory {
/** Attach the submission click listener for modals that have been generated by raw HTML */ /** Attach the submission click listener for modals that have been generated by raw HTML */
findSubmitButtonAndAddListener() { findSubmitButtonAndAddListener() {
let $submitButton = this.$modal.find('.modal-footer #submitButton') let $modalFooter = this.$modal.find('.modal-footer')
if (!$submitButton[0]) { if ($modalFooter.data('custom-footer')) { // setup basic listener as callback are defined in the template
$submitButton = this.$modal.find('.modal-footer .modal-confirm-button') let $submitButtons = this.$modal.find('.modal-footer .modal-confirm-button')
} var selfModal = this;
if ($submitButton[0]) { selfModal.options.APIConfirms = [];
const formID = $submitButton.data('form-id') $submitButtons.each(function(i) {
let $form const $submitButton = $(this)
if (formID) { if ($submitButton.data('clickfunction') !== undefined && $submitButton.data('clickfunction') !== '') {
$form = $(formID) const clickHandler = window[$submitButton.data('clickfunction')]
} else { selfModal.options.APIConfirms[i] = (tmpApi) => {
$form = this.$modal.find('form') let clickResult = clickHandler(selfModal, tmpApi)
if (clickResult !== undefined) {
return clickResult
.then((data) => {
if (data.success) {
selfModal.options.POSTSuccessCallback(data)
} else { // Validation error
selfModal.injectFormValidationFeedback(form, data.errors)
return Promise.reject('Validation error');
}
})
.catch((errorMessage) => {
selfModal.options.POSTFailCallback(errorMessage)
return Promise.reject(errorMessage);
})
}
}
}
$submitButton.click(selfModal.getConfirmationHandlerFunction(i))
})
} else {
let $submitButton = this.$modal.find('.modal-footer #submitButton')
if (!$submitButton[0]) {
$submitButton = this.$modal.find('.modal-footer .modal-confirm-button')
} }
if ($submitButton.data('confirmfunction') !== undefined && $submitButton.data('confirmfunction') !== '') { if ($submitButton[0]) {
const clickHandler = window[$submitButton.data('confirmfunction')] const formID = $submitButton.data('form-id')
this.options.APIConfirm = (tmpApi) => { let $form
let clickResult = clickHandler(this, tmpApi) if (formID) {
if (clickResult !== undefined) { $form = $(formID)
return clickResult } else {
$form = this.$modal.find('form')
}
if ($submitButton.data('confirmfunction') !== undefined && $submitButton.data('confirmfunction') !== '') {
const clickHandler = window[$submitButton.data('confirmfunction')]
this.options.APIConfirm = (tmpApi) => {
let clickResult = clickHandler(this, tmpApi)
if (clickResult !== undefined) {
return clickResult
.then((data) => {
if (data.success) {
this.options.POSTSuccessCallback(data)
} else { // Validation error
this.injectFormValidationFeedback(form, data.errors)
return Promise.reject('Validation error');
}
})
.catch((errorMessage) => {
this.options.POSTFailCallback(errorMessage)
return Promise.reject(errorMessage);
})
}
}
} else {
$submitButton[0].removeAttribute('onclick')
this.options.APIConfirm = (tmpApi) => {
return tmpApi.postForm($form[0])
.then((data) => { .then((data) => {
if (data.success) { if (data.success) {
this.options.POSTSuccessCallback(data) this.options.POSTSuccessCallback(data)
@ -727,26 +780,8 @@ class ModalFactory {
}) })
} }
} }
} else { $submitButton.click(this.getConfirmationHandlerFunction())
$submitButton[0].removeAttribute('onclick')
this.options.APIConfirm = (tmpApi) => {
return tmpApi.postForm($form[0])
.then((data) => {
if (data.success) {
this.options.POSTSuccessCallback(data)
} else { // Validation error
this.injectFormValidationFeedback(form, data.errors)
return Promise.reject('Validation error');
}
})
.catch((errorMessage) => {
this.options.POSTFailCallback(errorMessage)
return Promise.reject(errorMessage);
})
}
} }
$submitButton.click(this.getConfirmationHandlerFunction())
} }
} }
} }