scanner-8.x-1.0-rc3/js/select-all.js

js/select-all.js
/**
 * @file
 * Provides Javascript behaviors to handle select all/none with checkboxes.
 *
 * If there are any elements with the 'data-scanner-select-all' attribute,
 * 'Select all' and 'Select none' buttons are added after the first legend
 * element. When clicked they select/deselect any enabled checkboxes within the
 * element with the custom attribute.
 */

(function (Drupal, once) {
  /**
   * Inserts a themed button element after a target element.
   *
   * @param {HTMLElement} target
   *   The target element; the button will be inserted after it.
   * @param {string} label
   *   The visible label.
   * @param {string} screenReaderLabel
   *   The label for assistive technologies such as screen readers.
   * @param {string} identifier
   *   A button identifier that will be directly added as an attribute.
   *
   * @returns {HTMLElement}
   *   The button element.
   */
  function addButton(target, label, screenReaderLabel, identifier) {
    const html = Drupal.theme.scannerSelectButton(
      label,
      screenReaderLabel,
      identifier,
    );
    target.insertAdjacentHTML('afterend', html);
    return target.parentNode.querySelector(`[${identifier}]`);
  }

  /**
   * Adds 'Select all' and 'Select none' buttons to groups of checkboxes.
   *
   * @param {HTMLElement} container
   *   The element that contains the group of checkboxes.
   */
  function addButtons(container) {
    const checkboxes = container.querySelectorAll(
      'input[type=checkbox]:not([disabled])',
    );
    // Don't do anything if there aren't multiple checkboxes.
    if (checkboxes.length < 2) {
      return;
    }

    // Add the buttons after the legend element.
    const legend = container.querySelector('legend');
    const selectNoneButton = addButton(
      legend,
      Drupal.t('Select none'),
      container.dataset.scannerSelectNoneScreenReaderLabel,
      'data-scanner-select-none-button',
    );
    const selectAllButton = addButton(
      legend,
      Drupal.t('Select all'),
      container.dataset.scannerSelectAllScreenReaderLabel,
      'data-scanner-select-all-button',
    );

    /**
     * Updates the disabled attribute on the buttons.
     */
    const updateButtons = function () {
      // Filter the checkboxes by value.
      const filter = function (value) {
        return Array.prototype.filter.call(checkboxes, function (c) {
          return c.checked === value;
        });
      };
      selectNoneButton.disabled = filter(true).length === 0;
      selectAllButton.disabled = filter(false).length === 0;
    };

    /**
     * Returns an event handler that sets all checkboxes to a preset value.
     *
     * @param {boolean} value
     *   The value to set the checkboxes to.
     *
     * @returns {function}
     *   The event handler.
     */
    const updateCheckboxes = function (value) {
      return function () {
        checkboxes.forEach((checkbox) => {
          checkbox.checked = value;
        });
        // Dispatch a single 'change' event on an arbitrary checkbox in case
        // there's a listener on the checkboxes. This means it doesn't perfectly
        // simulate a user clicking all the checkboxes, but also in case of an
        // AJAX listener, it won't submit a request per checkbox.
        checkboxes[0].dispatchEvent(new Event('change'));
      };
    };

    // Make the buttons change the checkbox values.
    selectNoneButton.addEventListener('click', updateCheckboxes(false));
    selectAllButton.addEventListener('click', updateCheckboxes(true));

    // Update the buttons' disabled attribute every time a checkbox is changed.
    checkboxes.forEach((checkbox) => {
      checkbox.addEventListener('change', updateButtons);
    });

    // Update the buttons based on the initial state.
    updateButtons();
  }

  /**
   * Behaviors to handle select all/none with checkboxes.
   *
   * @type {Drupal~behavior}
   *
   * @prop {Drupal~behaviorAttach} attach
   *   Attaches the select all/none buttons.
   */
  Drupal.behaviors.scannerSelectAll = {
    attach(context) {
      once('scanner-select-all', '[data-scanner-select-all]', context).forEach(
        addButtons,
      );
    },
  };

  /**
   * Returns markup for a select all/none button.
   *
   * @param {string} label
   *   The visible text for the button.
   * @param {string} screenReaderLabel
   *   The label for assistive technologies.
   * @param {string} identifier
   *   An attribute to uniquely identify the button within a single group of
   *   checkboxes.
   *
   * @return {string}
   *   The button markup.
   */
  Drupal.theme.scannerSelectButton = function (
    label,
    screenReaderLabel,
    identifier,
  ) {
    return (
      `<button ${identifier} type="button" class="button button--extrasmall">` +
      `<span aria-hidden="true">${label}</span>` +
      `<span class="visually-hidden">${screenReaderLabel}</span>` +
      `</button>`
    );
  };
})(Drupal, once);

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc