selectify-1.0.3/js/selectify-radio-checkbox.js

js/selectify-radio-checkbox.js
/**
 * @file
 * Contains utility functions for Selectify module.
 *
 * Filename: selectify-radio-checkbox.js
 * Website: https://www.flashwebcenter.com
 * Developer: Alaa Haddad https://www.alaahaddad.com.
 */

((Drupal, once) => {
  'use strict';

  /**
   * Drupal behavior to enhance checkboxes and radio buttons.
   */
  Drupal.behaviors.selectifyRadioCheckbox = {
    attach: (context, settings) => {
      const checkboxes = once('selectifyCheckbox', 'input[type="checkbox"].selectify-checkbox', context);
      const radios = once('selectifyRadio', 'input[type="radio"].selectify-radio', context);

      // Initialize checkboxes
      checkboxes.forEach((checkbox) => {
        detectMultiSelect(checkbox);
        updateCheckedState(checkbox);
        updateDisabledState(checkbox);
        updateIndeterminateState(checkbox);

        checkbox.addEventListener('change', () => {
          updateCheckedState(checkbox);
          updateIndeterminateState(checkbox);
        });

        addFocusAndHoverListeners(checkbox);
      });

      // Initialize radio buttons
      radios.forEach((radio) => {
        detectRadioGroup(radio);
        updateCheckedState(radio);
        updateDisabledState(radio);

        radio.addEventListener('change', () => {
          updateRadioGroupState(radio);
        });

        addFocusAndHoverListeners(radio);
        enableToggleableRadio(radio); // Optional: Allow deselecting radios
      });

      // Inject ARIA labels if needed
      Drupal.selectify.injectAriaLabelledBy();
    }
  };

  /**
   * Detects whether a checkbox allows multiple selections.
   * Adds a class to indicate if it's part of a group.
   *
   * @param {HTMLInputElement} checkbox
   *   The checkbox element to analyze.
   */
  function detectMultiSelect(checkbox) {
    const name = checkbox.name;
    if (name) {
      const checkboxesInGroup = document.querySelectorAll(`input[type="checkbox"][name="${name}"]`);
      if (checkboxesInGroup.length > 1) {
        checkbox.classList.add('selectify-multi-checkbox');
      } else {
        checkbox.classList.add('selectify-single-checkbox');
      }
    }
  }

  /**
   * Detects and marks radio buttons in groups.
   *
   * @param {HTMLInputElement} radio
   *   The radio button element to analyze.
   */
  function detectRadioGroup(radio) {
    const name = radio.name;
    if (name) {
      const radiosInGroup = document.querySelectorAll(`input[type="radio"][name="${name}"]`);
      if (radiosInGroup.length > 1) {
        radio.classList.add('selectify-radio-group');
      }
    }
  }

  /**
   * Ensures only the selected radio in a group has the active class.
   *
   * @param {HTMLInputElement} selectedRadio
   *   The radio button that was selected.
   */
  function updateRadioGroupState(selectedRadio) {
    const name = selectedRadio.name;
    const radiosInGroup = document.querySelectorAll(`input[type="radio"][name="${name}"]`);
    radiosInGroup.forEach((radio) => {
      updateCheckedState(radio);
    });
  }

  /**
   * Updates the checked state class for checkboxes and radios.
   *
   * @param {HTMLInputElement} element
   *   The input element to update.
   */
  function updateCheckedState(element) {
    if (element.checked) {
      element.classList.add('selectify-checked');
    } else {
      element.classList.remove('selectify-checked');
    }
  }

  /**
   * Adds or removes disabled state class.
   *
   * @param {HTMLInputElement} element
   *   The input element to update.
   */
  function updateDisabledState(element) {
    if (element.disabled) {
      element.classList.add('selectify-disabled');
    } else {
      element.classList.remove('selectify-disabled');
    }
  }

  /**
   * Handles indeterminate checkboxes.
   *
   * @param {HTMLInputElement} checkbox
   *   The checkbox element to update.
   */
  function updateIndeterminateState(checkbox) {
    if (checkbox.indeterminate) {
      checkbox.classList.add('selectify-indeterminate');
    } else {
      checkbox.classList.remove('selectify-indeterminate');
    }
  }

  /**
   * Adds event listeners for focus and hover states.
   *
   * @param {HTMLInputElement} element
   *   The input element to enhance.
   */
  function addFocusAndHoverListeners(element) {
    element.addEventListener('focus', () => {
      element.classList.add('selectify-focused');
    });

    element.addEventListener('blur', () => {
      element.classList.remove('selectify-focused');
    });

    element.addEventListener('mouseover', () => {
      element.classList.add('selectify-hover');
    });

    element.addEventListener('mouseout', () => {
      element.classList.remove('selectify-hover');
    });
  }

  /**
   * Enables toggleable radio buttons (optional feature).
   * Allows users to deselect a radio button by clicking it again.
   *
   * @param {HTMLInputElement} radio
   *   The radio button to make toggleable.
   */
  function enableToggleableRadio(radio) {
    radio.addEventListener('click', function(event) {
      const name = this.name;
      const radiosInGroup = document.querySelectorAll(`input[type="radio"][name="${name}"]`);

      // If the clicked radio was already checked, allow deselection
      if (this.checked && this.dataset.wasChecked === "true") {
        this.checked = false;
        this.dataset.wasChecked = "false";

        // Ensure other radios in the group can now be selected properly
        radiosInGroup.forEach(radio => radio.dataset.wasChecked = "false");

        // Update visual state
        updateCheckedState(this);
      } else {
        // Reset all radios in the group before setting new selection
        radiosInGroup.forEach(radio => {
          radio.dataset.wasChecked = "false";
          updateCheckedState(radio);
        });

        // Mark the clicked radio as selected
        this.dataset.wasChecked = "true";
        updateCheckedState(this);
      }
    });
  }

})(Drupal, once);

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

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