octobercms / october

Self-hosted CMS platform based on the Laravel PHP Framework.
https://octobercms.com/
Other
11.01k stars 2.21k forks source link

Watch data-list-checked-request without user button click #5779

Closed sqwk closed 7 months ago

sqwk commented 7 months ago

It is currently possible to get the selected rows from a backend plugin list using data-list-checked-request (https://docs.octobercms.com/3.x/extend/lists/list-controller.html#adding-a-toolbar). Is it possible to monitor the checked items without user interaction? i.e. to show the user how many items are selected in a table header or perform an addition of column values across the selected rows?

daftspunk commented 7 months ago

Hey @sqwk

I'm not sure I'm following. The data-list-checked-request is engaged via the ajax:setup event, not from user interaction. Can you describe this in more detail? Perhaps with examples.

sqwk commented 7 months ago

According to the docs the selected elements can be passed to an ajax request through data-list-checked-request. In the example from the docs below that would require the user to press the button.

    type="button"
    class="btn btn-primary"
    data-request="onDelete"
    data-list-checked-request>
    Delete Selected
</button>

Is it possible to monitor the checked items without the user triggering the request? Is it possible to run a backend method every time checkboxes are selected / deselected and update a partial above outside <?= $this->listRender() ?>? Is there an example on how to get the selected row ids when checkboxes are selected without using the data- attribute? Or do I have to parse HTML Elements, with the possibility that the list code may change in a future version?

EDIT: Specifically; I would like to add specific columns of the selected rows and show the user a total, either in a header or as part of a scoreboard above the entry list.

daftspunk commented 7 months ago

This is a persistent event, where you bind to a persistent element to look for child elements. It is usually done in jQuery

$('#Lists').on('click', '.list-checkbox input[type=checkbox]', function(ev) {
    console.log('clicked using jQuery' + ev.target);
});

However you can do it in vanilla JS with oc.Events.on

oc.Events.on(document.querySelector('#Lists'), 'click', '.list-checkbox input[type=checkbox]', function(ev) {
    console.log('clicked ' + ev.target);
});

Then grab all the checked items with

Array.from(document.querySelectorAll('#Lists .list-checkbox input[name="checked[]"]'))
    .filter(el => el.checked)
    .map(el => el.value);

I hope this helps.