Table of Contents & Menu
Navigation

Confirmation Dialogs

Hyvä confirmation dialogs are built upon modal dialogs. All concepts and methods discussed for modal dialogs also apply to confirmation dialogs.

Available since 1.1.13

Confirmation dialogs are available since version 1.1.13 of Hyva_Theme. If you are using an older version, be sure to upgrade the theme module.

To create a confirmation modal instance in PHP, use the confirm method on the modal view model:

$confirmation = $modalViewModel->confirm(__('Are you sure?')

Then customize the dialog as needed, just like a regular Hyvä modal.

The default confirmation modal template is Hyva_Theme::modal/confirmation.phtml.

Triggering actions

To execute an action after the user interacts with the dialog, chain a promise to the show() method. The promise resolves to `true` if the 'OK' button is clicked, and a falsy value if the dialog is cancelled.

Simple Example

This simple example demonstrates logging 'OK' or 'Cancel' to the browser console based on the user's selection. In a production environment, the callback would typically be an Alpine.js component method or an event dispatch.

<div x-data="hyva.modal()">
    <?php $confirmation = $modalViewModel->confirm(__('Are you sure?')) ?>
    <button @click="<?= $confirmation->getShowJs() ?>.then(result => result && console.log('OK') || console.log('Cancel'))"
            type="button" class="btn mt-2" aria-haspopup="dialog">Show</button>
    <?= $confirmation ?>
</div>

Customizing Confirmation Dialogs

In addition to the standard modal dialog methods, four confirmation-specific methods are available:

withTitle($title)

The confirmation dialog's title is set when calling `confirm('the title')` on the modal view model. Alternatively, use the `withTitle($title)` method. The template escapes the title:

<div class="font-bold text-xl"><?= $escaper->escapeHtml($block->getData('title')) ?></div>

withDetails($details)

The `withDetails($details)` method allows you to add optional details, which are rendered between the title and the buttons.

<?php if ($block->hasData('details')): ?>
    <div>
        <?= /** @noEscape */ $block->getData('details') ?>
    </div>
<?php endif; ?>

The details are not escaped, so they may contain HTML.

setContent() vs. setDetails()

While `setContent()` offers full control over the modal's content (and bypasses the template), it can be confusing for confirmation dialogs. As a best practice, use `setDetails()` for confirmation dialogs.

withOKLabel($okLabel)

Customize the default 'OK' button label with `withOKLabel($okLabel)`. Button labels are escaped during rendering:

<?= $escaper->escapeHtml($block->getData('ok') ?: __('OK')) ?>

withCancelLabel($cancelLabel)

Customize the default 'Cancel' button label with `withCancelLabel($cancelLabel)`. Button labels are escaped during rendering:

<?= $escaper->escapeHtml($block->getData('cancel') ?: __('Cancel')) ?>

Changing the confirmation template file

Confirmation dialog templates can be customized via theme overrides. For a specific dialog, set a unique template using the `setTemplate` method:

$confirmation->withTemplate('Hyva_Theme::modal/custom-confirmation.phtml');

Dialogs with more than two choices

You can create custom confirmation dialogs with more than two buttons. The `show` promise resolves to the argument passed to the `hide` method, enabling multiple choices via the modal view model. This requires a custom template. Ensure each button passes a distinct value to `hide()` to indicate the user's selection.

<button @click="hide('a')" type="button" class="btn">
    <?= $escaper->escapeHtml(__('Option A')) ?>
</button>
<button @click="hide('b')" type="button" class="btn">
    <?= $escaper->escapeHtml(__('Option B')) ?>
</button>
<button x-focus-first @click="hide('c')" type="button" class="btn btn-primary">
    <?= $escaper->escapeHtml(__('Option C')) ?>
</button>

Confirmation dialogs without the view model (Alpine.js only)

You can create confirmation dialogs using Hyvä modals directly with Alpine.js, bypassing the PHP view model.

<div x-data="hyva.modal()">
    <button @click="show($event).then(result => console.log(result))"
            type="button" class="btn mt-2" aria-haspopup="dialog">Show</button>

    <div x-cloak x-spread="overlay()" x-bind="overlay()"
         class="fixed inset-0 flex items-center justify-center text-left bg-black bg-opacity-50">

        <div x-ref="dialog" role="dialog" aria-labelledby="the-label"
             class="inline-block max-h-screen overflow-auto bg-white shadow-xl rounded-lg p-10 text-gray-700">
            <div id="the-label">Are you sure?</div>
            <div>Think before you click...</div>
            <div class="mt-20 flex justify-between gap-2">
                <button @click="cancel" type="button" class="btn">Cancel</button>
                <button x-focus-first @click="ok" type="button" class="btn btn-primary">OK</button>
            </div>
        </div>

    </div>
</div>

Important

Be sure to use a unique x-ref name if there is more than one modal dialog on the page.

Examples

Below are various examples:

Confirmation dialog with only details

<div x-data="hyva.modal()">
    <?php $confirmation = $modalViewModel->confirm()
                              ->withDetails($escaper->escapeHtml(__('Are you sure?'))) ?>
    <button @click="<?= $confirmation->getShowJs() ?>.then(result => console.log(result))"
            type="button" class="btn mt-2" aria-haspopup="dialog">Show</button>
    <?= $confirmation ?>
</div>

Confirmation dialog with title and details

<div x-data="hyva.modal()">
    <?php $confirmation = $modalViewModel->confirm(__('Are you sure?'))
                              ->withDetails('<em>Think before clicking.</em>') ?>
    <button @click="<?= $confirmation->getShowJs() ?>.then(result => console.log(result))"
            type="button" class="btn mt-2" aria-haspopup="dialog" aria-haspopup="dialog">Show</button>
    <?= $confirmation ?>
</div>

Confirmation dialog with custom button labels

<div x-data="hyva.modal()">
    <?php $confirmation = $modalViewModel->confirm(__('Is that all?'))
                              ->withOKLabel(__('Yes'))
                              ->withCancelLabel(__('No')) ?>
    <button @click="<?= $confirmation->getShowJs() ?>.then(result => console.log(result))"
            type="button" class="btn mt-2" aria-haspopup="dialog">Show</button>
    <?= $confirmation ?>
</div>

Under the hood:

For a deeper understanding of the modal system's inner workings, refer to these PHP classes:

  • \Hyva\Theme\ViewModel\Modal::confirm()
  • \Hyva\Theme\Model\Modal\ConfirmationBuilderInterface