bootstrap-ui icon indicating copy to clipboard operation
bootstrap-ui copied to clipboard

Support custom confirmJs on postLink (with access to formName of parent::postLink)

Open gludie opened this issue 2 years ago • 9 comments

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

gludie avatar Mar 12 '23 22:03 gludie

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",
        ]
    ) ?>

gludie avatar Mar 12 '23 23:03 gludie

It would be easier to directly make PRs here

dereuromark avatar Mar 13 '23 00:03 dereuromark

Thank you, will close the issue and come back with a PR. 

gludie avatar Mar 13 '23 00:03 gludie

You can keep it open for now, no worries. Maybe others would like to also give some early feedback.

dereuromark avatar Mar 13 '23 00:03 dereuromark

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.

ADmad avatar Mar 13 '23 03:03 ADmad

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(…) …

gludie avatar Mar 13 '23 07:03 gludie

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.

gludie avatar Mar 13 '23 08:03 gludie

Please open an issue for the core to allow using templates options for the link methods.

ADmad avatar Mar 13 '23 08:03 ADmad

Or you can just load a templates file to override the default templates and avoid having to do so for each call.

ADmad avatar Mar 13 '23 08:03 ADmad