altcolor-1.0.0-beta1/js/altcolor_admin.js
js/altcolor_admin.js
/**
* @file
* Administrative functionality for the Alternative Color module. This ensures
* that the form fields update and fire the custom event when the user changes
* any of the field values.
*/
((Drupal, settings, once) => {
const colorArray = [];
const colorSchemeOptions = settings.altcolor.colorSchemes;
const colorsChangedEvent = new CustomEvent('altcolor-change', {
bubbles: true,
detail: { colors: colorArray },
});
/**
* Dispatches a custom 'altcolor-change' event with the new color array in
* the event details. This allows other JavaScripts to listen to updating
* colors.
*/
function dispatchChangedEvent() {
document.querySelector('#altcolor_form').dispatchEvent(colorsChangedEvent);
}
/**
* Event listener that triggers when a color field is changed.
*
* @param {HTMLFormElement} target
* The input event.
*/
function colorFieldChanged({ target }) {
colorArray[target.dataset.altcolorName] = target.value;
dispatchChangedEvent();
}
/**
* Updates individual colors when a pre-defined color scheme is selected.
*
* @param {HTMLFormElement} target
* input element for which the value has changed.
*/
function setColorScheme({ target }) {
// If the select element has no value (custom scheme), do nothing.
if (!target.value) return;
// Look up the color scheme from the settings and update the input fields.
const selectedColorScheme = colorSchemeOptions[target.value].colors;
if (selectedColorScheme) {
Object.entries(selectedColorScheme).forEach(([key, color]) => {
const input = document.querySelector(
`input[type="color"][name="altcolor[colors][${key}]"]`,
);
if (input.value !== color) {
input.value = color;
}
});
dispatchChangedEvent();
}
}
/**
* Initializes the color scheme selection element (selectElement).
*
* @param {HTMLSelectElement} selectElement
* The element to initialize.
*/
function initColorSchemeSelect(selectElement) {
// Add an event listener to the style selection input element to allow the
// individual color input elements to change if the style selection
// element's value changes.
selectElement.addEventListener('change', setColorScheme);
// Iterate over all color schemes and see if the current color values match
// with a known scheme. If so, set the selectElement's value to the scheme.
Object.entries(colorSchemeOptions).forEach(([scheme, values]) => {
const { label, colors } = values;
let allColorsMatch = true;
Object.entries(colors).forEach(([colorName, colorHex]) => {
const field = document.querySelector(
`input[type="color"][name="altcolor[colors][${colorName}]"]`,
);
if (field.value !== colorHex) {
allColorsMatch = false;
}
});
if (allColorsMatch) {
selectElement.value = scheme;
}
});
}
/**
* Changes the selectElement to have an empty value.
*/
function unsetSchemeSelect() {
const selectElement = document.querySelector('#altcolor_form select');
if (selectElement.value !== '') {
selectElement.value = '';
}
}
/**
* Initializes the Alternative Color administration interface.
*
* @type {Drupal~behavior}
*
* @prop {Drupal~behaviorAttach} attach
* Attaches the behavior for Alternative Color.
*/
Drupal.behaviors.altColor = {
attach: (context) => {
once('altcolor-select', '#edit-scheme', context).forEach(
(selectElement) => {
initColorSchemeSelect(selectElement);
},
);
once(
'altcolor-inputs',
'#altcolor_form input[type="color"]',
context,
).forEach((colorInput) => {
// Set this color field value in the color array.
colorArray[colorInput.dataset.altcolorName] = colorInput.value;
colorInput.addEventListener('input', unsetSchemeSelect);
colorInput.addEventListener('input', colorFieldChanged);
colorInput.addEventListener('change', colorFieldChanged);
});
},
};
/**
* Helper to allow external JavaScript to update the preview.
*
* Adds altcolor to the Drupal object so that we can request an update from
* JavaScript outside of this file.
*/
Drupal.altcolor = {
getColors() {
return colorArray;
},
};
})(Drupal, drupalSettings, once);
