- πΊπΈUnited States robphillips
Here's a workaround for persistent selections between page navigation and any other views Ajax event. The previous selections are stored in a JavaScript object. When the form is submitted any of the missing previous selections are appended to the form before the request is sent. Didn't create a patch because there's a chance it won't scale with thousands of selections and obviously doesn't work if JavaScript is disabled. With that said, it's worth a try as a short term low effort solution.
Per #8... long term solution should use form state to store persistent values because scalability and consistency.
1. Create
entity-browser.js
file in a custom module:/** * @file * JavaScript behaviors for entity browser. */ (function ($, Drupal, once) { /** * Keep track of selections. * * @type Object */ let selections = {}; Drupal.behaviors.EntityBrowserSelections = { attach: function (context, settings) { once("entity-browser-form", 'form.entity-browser-form', context).forEach((form) => { // Reset selections when the form is opened. selections = {}; form.addEventListener("submit", (event) => { Object.keys(selections).forEach((key) => { if (!form.contains(selections[key])) { // Add previous selections when they don't exist. form.appendChild(selections[key]); } }); }); }); once("entity-browser-input", 'form.entity-browser-form > .view').forEach((view) => { const counter = document.createElement("div"); counter.className = "entity-browser-selection-counter"; counter.innerText = Drupal.formatPlural(Object.keys(selections).length, "1 selection", "@count selections"); const table = view.querySelector(".view-content > table"); table.parentNode.insertBefore(counter, table); view.querySelectorAll('input[type="checkbox"][value]').forEach((element) => { if (selections[element.name]) { // Restore selection from the previous page. element.checked = true; } $(element).on("change", () => { if (element.checked) { selections[element.name] = element.cloneNode(); selections[element.name].type = "hidden"; } else { delete selections[element.name]; } counter.innerText = Drupal.formatPlural(Object.keys(selections).length, "1 selection", "@count selections"); }); }); }); } }; })(jQuery, Drupal, once);
2. Add JavaScript to a Drupal library:
entity-browser: js: entity-browser.js: {} dependencies: - core/jquery - core/drupal - core/once
3. Attach the Drupal library to the entity browser form:
/** * Implements hook_form_FORM_ID_alter(). */ function EXAMPLE_MODULE_form_entity_browser_form_alter(&$form, FormStateInterface $form_state, $form_id): void { $form['#attached']['library'][] = 'example_module/entity-browser'; }
- πΊπΈUnited States banoodle San Francisco, CA
#9 worked great for me (thank you!), but I did have to change this line, from:
const table = view.querySelector(".view-content > table");
to:
const table = view.querySelector(".view-content table");