EasyAdminBundle icon indicating copy to clipboard operation
EasyAdminBundle copied to clipboard

Allow BatchAction without modal

Open xxorax opened this issue 4 years ago • 5 comments

A modal seems to be always mandatory for batchAction. I'd like to have an option for disable it.

It seems not possible actualy, it's done in ActionFactory.php#L134 which always overrides html attributes of the ActionDto.

Maybe related to #3455

Thanks

xxorax avatar Apr 27 '21 15:04 xxorax

I worked on a workaround as I needed this feature.

Add the following Javascript:

// js/app.js 

function handleBatchDisableConfirm() {
    document.querySelectorAll('.disable-confirm').forEach(actionBtn => {
        actionBtn.addEventListener('click', function() {
            let modal = document.getElementById('modal-batch-action');
            document.querySelector('.modal-backdrop').classList.add('invisible');
            modal.classList.add('invisible');
            modal.querySelector('#modal-batch-action-button').click();
        });
    });
}

document.addEventListener('readystatechange', function(event) {
    if ('complete' === document.readyState) {
        handleBatchDisableConfirm();
    }
});
class DashboardController extends AbstractDashboardController
{
    public function configureAssets(): Assets
    {
        return Assets::new()->addJsFile('js/app.js');
    }
}

And then, add disable-confirm CSS class to your batch action button:

Action::new('my_batch_action', 'my_batch_action_name')->addCssClass('btn btn-primary disable-confirm');

It do the trick.

fabienlem avatar Sep 26 '21 13:09 fabienlem

But this is not compatible with target="_blank" :_(

daviddavo avatar Mar 03 '22 21:03 daviddavo

I managed to change the <button> tag to <a> overriding the _batch_action_modal.html.twig template, but it doesn't work because the thing that redirects you to the actions seems to be embedded on the bundle javascript.

The only option now would be to override the on click action

https://symfony.com/doc/current/bundles/override.html

daviddavo avatar Mar 03 '22 21:03 daviddavo

If it can help, here is the workaround I'm using to not toggle the modal at all on defined batch actions.

/**
 * {@inheritDoc}
 */
public function configureActions(Actions $actions): Actions
{
    return parent::configureActions($actions)
        ->addBatchAction(
            Action::new('batchDownload', 'Download', 'fa fa-download')
                ->linkToCrudAction('batchDownload')
                ->setHtmlAttributes(['data-action-no-modal' => true]) // Do not display the confirmation modal.
        )
    ;
}

/**
 * {@inheritDoc}
 */
public function configureAssets(Assets $assets): Assets
{
    return parent::configureAssets($assets)
        ->addWebpackEncoreEntry('app') // Adds the JS managing batch actions using the data-action-no-modal attribute.
    ;
}
{# templates/bundles/EasyAdminBundle/crud/action.html.twig #}

{% if action.htmlAttributes['data-action-no-modal'] is defined %}
    {% set htmlAttributes = action.htmlAttributes|filter((v, k) => k not in ['data-bs-toggle', 'data-bs-target']) %}
    {% do action.setHtmlAttributes(htmlAttributes) %}
{% endif %}

{% include '@!EasyAdmin/crud/action.html.twig' %}
// assets/app.js

// Manage batch actions using the data-action-no-modal attribute.
// @see vendor/easycorp/easyadmin-bundle/assets/js/app.js.
document.querySelectorAll('[data-action-no-modal]').forEach((dataActionBatch) => {
    dataActionBatch.addEventListener('click', (event) => {
      console.log('test');
        event.preventDefault();

        const actionElement = event.target.tagName.toUpperCase() === 'A' ? event.target : event.target.parentNode;
        const selectedItems = document.querySelectorAll('input[type="checkbox"].form-batch-checkbox:checked');

        // prevent double submission of the batch action form
        actionElement.setAttribute('disabled', 'disabled');

        const batchFormFields = {
            'batchActionName': actionElement.getAttribute('data-action-name'),
            'entityFqcn': actionElement.getAttribute('data-entity-fqcn'),
            'batchActionUrl': actionElement.getAttribute('data-action-url'),
            'batchActionCsrfToken': actionElement.getAttribute('data-action-csrf-token'),
        };
        selectedItems.forEach((item, i) => {
            batchFormFields[`batchActionEntityIds[${i}]`] = item.value;
        });

        const batchForm = document.createElement('form');
        batchForm.setAttribute('method', 'POST');
        batchForm.setAttribute('action', actionElement.getAttribute('data-action-url'));
        for (let fieldName in batchFormFields) {
            const formField = document.createElement('input');
            formField.setAttribute('type', 'hidden');
            formField.setAttribute('name', fieldName);
            formField.setAttribute('value', batchFormFields[fieldName]);
            batchForm.appendChild(formField);
        }

        document.body.appendChild(batchForm);
        batchForm.submit();
    });
});

NicolasGraph avatar Oct 22 '22 22:10 NicolasGraph

See #6375

maxhelias avatar Jul 29 '24 15:07 maxhelias

Thanks for this proposal. I'm closing this issue in favor of #6674, which tries to solve this and other closely related issues. Thanks!

javiereguiluz avatar Dec 30 '24 20:12 javiereguiluz