bootstrap-ui
bootstrap-ui copied to clipboard
Support custom confirmJs on postLink (with access to formName of parent::postLink)
This is a (multiple allowed):
-
[ ] bug
-
[x] enhancement
-
[ ] feature-discussion (RFC)
-
BootstrapUI Version: 4.0.1
-
Bootstrap Framework Version: 5.2.3
-
jQuery: -
-
Platform and Target: -
What you did
For modal forms, it could be useful, to have the formName (created in core postLink) for later submit from the modal available.
- Add (overload bootstrap-ui) FormHelper and add postLink
- Take confirmJs from $options[]
- Add confirmJs to templates
I tested it by overloading the helper of bootstrap-ui: FormHelper.php:
namespace App\View\Helper;
use BootstrapUI\View\Helper\FormHelper as BootstrapFormHelper;
class FormHelper extends BootstrapFormHelper
{
/**
* Wrapper function for postLink Helper to allow custom js on postlinks
*
* @param string $title
* @param string|array|null $url
* @param array $options
*
* @return string
*/
public function postLink(string $title, $url = null, array $options = []): string
{
if (isset($options['confirmJs'])) {
$this->setTemplates(['confirmJs' => $options['confirmJs']]);
unset($options['confirmJs']);
}
return parent::postLink($title, $url, $options);
}
}
Here a standard use-case to trigger the bootstrap modal related javascript code (showModal()) somewhere in a view template:
<?= $this->Form->postLink(__('Delete'), ['action' => 'delete', $item->id], [
'confirm' => __('Are you sure to delete item {0}?', $item->id),
'title' => __('Delete'),
'class' => 'btn btn-danger',
'data-bs-toggle' => "modal",
'data-bs-target' => "#bootstrapModal",
'confirmJs' => 'addToModal("{{formName}}"); return false;', // --> suppress the standard confirm {{confirm}}
]) ?>
Advantage I would see:
- no need to repeat and set always the template confirmJs before calling postLink in templates
- keeps templates more readable
- core helper untouched
Would you recommend to do a hint in the docs instead of going for this enhancement ? (I believe, using modal windows for confirm messages instead of standard ones is a very common use-case. We could also add the necessary js and modal part to the layout as an example ?)
*) credits to James McDonald for his video CakePHP 4 - Replacing the Default Javascript Confirm Dialog with a Bootstrap 5 Modal and Kevin Pfeifers comments
Add-on and similar for the html link helper (2 examples)
use BootstrapUI\View\Helper\HtmlHelper as BootstrapHtmlHelper;
class HtmlHelper extends BootstrapHtmlHelper
{
public function linkModal($title, $url = null, array $options = []): string
{
// suppress the standard core confirm script
$this->setTemplates(['confirmJs' => 'return false;']);
return parent::link($title, $url, $options);
}
public function link($title, $url = null, array $options = []): string
{
if (isset($options['confirmJs'])) {
$confirmJs = $options['confirmJs'];
unset($options['confirmJs']);
$this->setTemplates(['confirmJs' => $confirmJs]);
}
return parent::link($title, $url, $options);
}
}
Usage:
<?= $this->Html->linkModal(
__('Confirm link'),
['action' => 'index', uniqid('link')],
[
'confirm' => 'Do you want to go to this page ?',
'class' => 'nav-link',
'data-bs-toggle' => "modal",
'data-bs-target' => "#bootstrapModal",
]
) ?>
It would be easier to directly make PRs here
Thank you, will close the issue and come back with a PR.
You can keep it open for now, no worries. Maybe others would like to also give some early feedback.
no need to repeat and set always the template confirmJs before calling postLink in templates
Having to set ['confirmJs' => 'foo'] instead of already possible ['templates' => ['confirmJs' => 'foo'] isn't much of an improvement. String templates were introduced to avoid bloating helper functions with custom options.
agree, I am pretty sure to have checked this as well admad … problem I had was the missing handling of variables in templates, but will recheck if templates is supported for Forms postLink(…) …
as far as I can see now, templates is only supported for controls. Html and Form Helper do use core implementation for link and postLink. here the journey started. may be there is a smarter way than I did currently and use templates option of 'link' and postLink like it was introduced for controls. Let's see. Another possibility which came into my mind was to redefine core function _confirm.
Please open an issue for the core to allow using templates options for the link methods.
Or you can just load a templates file to override the default templates and avoid having to do so for each call.