Bulk select form does not submit all selected items from different pages through pager

Created on 20 July 2017, over 7 years ago
Updated 18 September 2023, over 1 year ago

Set up an Entity Browser view as instructed in the module.

In FIELDS, include "Entity browser bulk select form" field.
Pager: user Full pager, paged, x items (e.g. 10 items), No more link.

Assign this entity browser to an entity reference field of a content type.

When the browser is invoked in content creation, select entity items from different pages using the pager, submit the selection: only those items that are on the last page containing selected items are submitted.

✨ Feature request
Status

Active

Version

1.0

Component

Core API

Created by

πŸ‡ΊπŸ‡ΈUnited States seeallie New Hampshire

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Comments & Activities

Not all content is available!

It's likely this issue predates Contrib.social: some issue and comment data are missing.

  • πŸ‡ΊπŸ‡Έ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");

Production build 0.71.5 2024