Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow BatchAction without modal #4341

Closed
xxorax opened this issue Apr 27, 2021 · 6 comments
Closed

Allow BatchAction without modal #4341

xxorax opened this issue Apr 27, 2021 · 6 comments
Labels
Milestone

Comments

@xxorax
Copy link

xxorax commented Apr 27, 2021

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

@javiereguiluz javiereguiluz added this to the 3.x milestone May 12, 2021
@fabienlem
Copy link

fabienlem commented Sep 26, 2021

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.

@daviddavo
Copy link

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

@daviddavo
Copy link

daviddavo commented Mar 3, 2022

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

@NicolasGraph
Copy link

NicolasGraph commented Oct 22, 2022

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();
    });
});

@maxhelias
Copy link
Contributor

See #6375

@javiereguiluz
Copy link
Collaborator

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

6 participants