countdown-8.x-1.8/modules/countdown_field/js/countdown_field.widget.js
modules/countdown_field/js/countdown_field.widget.js
/**
* @file
* Widget enhancements for countdown field configuration.
*/
(function ($, Drupal, drupalSettings, once) {
'use strict';
/**
* Countdown field widget behavior.
*
* @type {Drupal~behavior}
*/
Drupal.behaviors.countdownFieldWidget = {
attach: function (context, settings) {
// Initialize widget enhancements.
const widgets = once('countdown-field-widget', '.countdown-widget-wrapper', context);
widgets.forEach(function (widget) {
// Initialize preview if enabled.
const previewContainer = widget.querySelector('.countdown-preview-container');
if (previewContainer) {
Drupal.behaviors.countdownFieldWidget.initializePreview(widget, previewContainer);
}
// Add change listeners for live preview updates.
Drupal.behaviors.countdownFieldWidget.attachListeners(widget);
});
},
/**
* Initialize countdown preview.
*
* @param {HTMLElement} widget
* The widget container.
* @param {HTMLElement} previewContainer
* The preview container element.
*/
initializePreview: function (widget, previewContainer) {
// Get current values from form.
const library = widget.querySelector('select[name*="[library]"]')?.value;
const targetInput = widget.querySelector('input[name*="[target_date]"]');
if (!library || !targetInput) {
return;
}
const targetDate = targetInput.value;
if (!targetDate) {
previewContainer.innerHTML = '<div class="countdown-preview-placeholder">' +
Drupal.t('Select a target date to see preview') + '</div>';
return;
}
// Create preview element.
const previewId = 'preview-' + Math.random().toString(36).substr(2, 9);
const previewElement = document.createElement('div');
previewElement.id = previewId;
previewElement.className = 'countdown-timer countdown-field-preview';
previewElement.dataset.countdownLibrary = library;
previewElement.dataset.countdownTarget = targetDate;
previewElement.dataset.countdownPreview = 'true';
// Clear and append preview.
previewContainer.innerHTML = '';
previewContainer.appendChild(previewElement);
// Initialize countdown if main integration is available.
if (Drupal.countdown && Drupal.countdown.initializeCountdown) {
setTimeout(function () {
Drupal.countdown.initializeCountdown(previewElement, drupalSettings);
}, 100);
}
},
/**
* Attach change listeners for live preview updates.
*
* @param {HTMLElement} widget
* The widget container.
*/
attachListeners: function (widget) {
const previewContainer = widget.querySelector('.countdown-preview-container');
if (!previewContainer) {
return;
}
// Elements to monitor for changes.
const elements = [
'select[name*="[library]"]',
'input[name*="[target_date]"]',
];
elements.forEach(function (selector) {
const inputs = widget.querySelectorAll(selector);
inputs.forEach(function (input) {
// Remove existing listeners to prevent duplicates.
$(input).off('change.countdown-preview');
// Add new listener.
$(input).on('change.countdown-preview', function () {
// Debounce the update.
clearTimeout(widget.previewTimeout);
widget.previewTimeout = setTimeout(function () {
Drupal.behaviors.countdownFieldWidget.initializePreview(widget, previewContainer);
}, 500);
});
});
});
},
/**
* Detach behavior cleanup.
*
* @param {HTMLElement|Document} context
* The context being detached.
* @param {Object} settings
* The drupalSettings object.
* @param {string} trigger
* The trigger for the detach.
*/
detach: function (context, settings, trigger) {
if (trigger === 'unload') {
// Clean up preview instances.
const previews = context.querySelectorAll('.countdown-field-preview');
previews.forEach(function (preview) {
if (Drupal.countdown && Drupal.countdown.stop) {
Drupal.countdown.stop(preview);
}
});
// Remove event listeners.
$('.countdown-widget-wrapper', context).find('input, select')
.off('change.countdown-preview');
}
}
};
})(jQuery, Drupal, drupalSettings, once);
