Open soullivaneuh opened 4 years ago
Also related to #1279 and #2978.
You apparently did some work about a feature like this, but it was too complicated.
I'm not sure to understand. How a confirmation message to display is too complicated? The proposed configuration way looks ok to me. :thinking:
It looks we already have enough resource to make the confirmation modal with ease thanks to the delete action implement:
Another nice to have thing would be alternative actions to propose in addition to "Cancel". For example:
public function configureActions(Actions $actions): Actions
{
return parent::configureActions($actions)
->add(
Crud::PAGE_DETAIL,
Action::new('reset', 'Reset')
->linkToCrudAction('reset')
->askConfirmation('Are you very very sure? This will destroy the world!', [
Action::new('index', 'Return to list')->linkToCrudAction('index'),
])
,
)
;
}
What do you think?
The askConfirmation
may even take 3 parameters: Title, message (optional), alternativeActions (optional).
This would look like this:
Action::new('reset', 'Reset')
->linkToCrudAction('reset')
->askConfirmation(
'Are you very very sure to reset the source of life?',
'This will destroy the world!',
[
Action::new('index', 'Return to list')->linkToCrudAction('index'),
],
)
;
Hi @soullivaneuh,
I had the same problem here... A lot of custom action who should ask confirm before process... I found a solution right now, and hope it can help you...
I take my inspiration from the delete-action which already toggle a confirm modal :D
So, here we go :
{% extends '@!EasyAdmin/layout.html.twig' %}
{% block content_footer_wrapper %}
<div id="modal-confirm" class="modal fade" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-body">
<h4>Êtes vous sûr ?</h4>
<p>Parce que ça va faire des trucs de fifou</p>
</div>
<div class="modal-footer">
<button type="button" data-bs-dismiss="modal" class="btn btn-secondary">
<span class="btn-label">{{ 'action.cancel'|trans([], 'EasyAdminBundle') }}</span>
</button>
<button type="button" data-bs-dismiss="modal" class="btn btn-success" id="modal-confirm-button">
<span class="btn-label">{{ 'action.confirm'|trans([], 'EasyAdminBundle') }}</span>
</button>
</div>
</div>
</div>
</div>
{% endblock %}
data-bs-toggle
and data-bs-target
to your custom action PLUS the CSS class confirm-action
$validAction = Action::new('valid', 'Valider', 'fa fa-check')
->displayAsLink()
->linkToCrudAction('validate')
->addCssClass('confirm-action')
->setHtmlAttributes([
'data-bs-toggle' => 'modal',
'data-bs-target' => '#modal-confirm',
])
;
document.addEventListener("DOMContentLoaded",(
function() {
document.querySelectorAll(".confirm-action").forEach((function(e){
e.addEventListener("click",(function(t){
t.preventDefault();
document.querySelector("#modal-confirm-button").addEventListener("click",(function(){
location.replace(e.getAttribute("href"));
}));
}));
}));
}
));
public function configureAssets(Assets $assets): Assets
{
$assets->addJsFile('assets/js/confirm-modal.js');
return parent::configureAssets($assets);
}
It's my first shot, it's not perfectly integrated but it Works ! Now I just have to adjust some things to make this more generic.
I'm glad that I can share this with you, personally, this thing made my day 🥇
Hello ! I tried this solution by updating 'edit/new actions' to get a confirmation modal but when I confirm into the modal window, the page page reload and nothing persist in the database. Any solutions ?
ModuleCrudController (src/Controller/Admin/ModuleCrudController.php) :
public function configureActions(Actions $actions): Actions
{
return $actions
->update(Crud::PAGE_INDEX, Action::NEW,
fn(Action $action) => $action
->setLabel('Ajouter un module'))
->update(Crud::PAGE_INDEX, Action::BATCH_DELETE,
fn(Action$action) => $action
->setLabel('Supprimer'))
->update(Crud::PAGE_NEW, Action::SAVE_AND_ADD_ANOTHER,
fn(Action $action) => $action
->setLabel('Créer et ajouter un nouveau module')
->displayAsLink()
->addCssClass('confirm-action')
->setHtmlAttributes([
'data-bs-toggle' => 'modal',
'data-bs-target' => '#modal-confirm',
]));
ModuleCrudController (src/Controller/Admin/ModuleCrudController.php) :
public function configureAssets(Assets $assets): Assets
{
$assets->addJsFile('assets/js/confirm-modal.js');
return parent::configureAssets($assets);
}
layout.html.twig (templates/bundles/EasyAdminBundle/layout.html.twig) :
{% extends '@!EasyAdmin/layout.html.twig' %}
{% block content_footer_wrapper %}
<div id="modal-confirm" class="modal fade" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-body">
<h4>Êtes-vous sûr ?</h4>
<p>Parce que ça va faire des trucs de fifou</p>
</div>
<div class="modal-footer">
<button type="button" data-bs-dismiss="modal" class="btn btn-secondary">
<span class="btn-label">{{ 'action.cancel'|trans([], 'EasyAdminBundle') }}</span>
</button>
<button type="button" data-bs-dismiss="modal" class="btn btn-success" id="modal-confirm-button">
<span class="btn-label">{{ 'action.confirm'|trans([], 'EasyAdminBundle') }}</span>
</button>
</div>
</div>
</div>
</div>
{% endblock %}
confirm-modal.js (public/assets/js/confirm-modal.js) :
document.addEventListener("DOMContentLoaded",(
function() {
document.querySelectorAll(".confirm-action").forEach((function(e){
e.addEventListener("click",(function(t){
t.preventDefault();
document.querySelector("#modal-confirm-button").addEventListener("click",(function(){
location.replace(e.getAttribute("href"));
}));
}));
}));
}
));
Are you on the EDIT or LIST page ?
Because on EDIT page, the layout is not include. You can rewrite "crud/detail.html.twig" with the same {% block content_footer_wrapper %}
Same thing with stimulus.js (symfony ux)
overrided ea layout.html.twig
{% extends '@!EasyAdmin/layout.html.twig' %}
{% block content %}
<div data-controller="confirm-modal">
{{ include('/admin/crud/includes/_action_modal.html.twig') }}
{{ parent() }}
</div>
{% endblock %}
_action_modal.html.twig
<div id="modal-confirm" class="modal fade" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-body">
<h4>{{ 'action.modal.archive_title'|trans([], 'admin') }}</h4>
</div>
<div class="modal-footer">
<button type="button" data-bs-dismiss="modal" class="btn btn-secondary">
<span class="btn-label">{{ 'action.cancel'|trans([], 'EasyAdminBundle') }}</span>
</button>
<button type="button" data-confirm-modal-target="confirm" data-bs-dismiss="modal" class="btn btn-danger" id="modal-confirm-button">
<span class="btn-label">{{ 'batch_action_modal.action'|trans(domain = 'EasyAdminBundle') }}</span>
</button>
</div>
</div>
</div>
</div>
In your controller custom action config
$archiveBatch = Action::new('archive', 'action.archive', 'fa fa-archive')
->linkToCrudAction('archiveBatch')
->addCssClass('text-danger')
->setHtmlAttributes([
'data-action' => 'click->confirm-modal#confirm',
'data-bs-toggle' => 'modal',
'data-bs-target' => '#modal-confirm',
]);
confirm_modal_controller.js
import { Controller } from '@hotwired/stimulus';
/*
* The following line makes this controller "lazy": it won't be downloaded until needed
* See https://github.com/symfony/stimulus-bridge#lazy-controllers
*/
/* stimulusFetch: 'lazy' */
export default class extends Controller {
static targets = ['confirm']
confirm(event) {
event.preventDefault();
this.confirmTarget.addEventListener('click', function() {
location.replace(event.target.getAttribute('href'));
});
}
}
news about this?
This would be a useful feature
Bump this issue :D
Just leaving this here in case someone is looking for a quick and easy solution https://github.com/EasyCorp/EasyAdminBundle/issues/2978#issuecomment-1505515228
Short description of what this feature will allow to do:
Be able to quickly configure a confirmation page/popup about a custom action
Example of how to use this feature
Something like this:
I found an option on the twig files that looks like the feature I want: https://github.com/EasyCorp/EasyAdminBundle/blob/a025860a53c722cb3d50fb34ed79803432dd6971/src/Resources/views/crud/form_theme.html.twig#L459
But I don't find anything on the documentation about how to use it.