Files
LEDMatrix/web_interface/static/v3/js/widgets/checkbox-group.js
Chuck 97d798b471 fix(js): resolve ESLint no-undef warnings across 6 JS files
Three distinct patterns:

1. Vendor library globals — htmx is injected by <script> before these
   extension files load; ESLint lints files in isolation and doesn't know.
   Fix: add /* global htmx */ to htmx-sse.js and htmx-json-enc.js.

2. Cross-file globals — showNotification is defined as window.showNotification
   in app.js/notification.js but called bare in app.js and error_handler.js.
   ESLint doesn't connect window.X = Y with a bare call to X.
   Fix: add /* global showNotification */ to app.js and error_handler.js.

3. Forward-reference window.* functions — in array-table.js, checkbox-group.js,
   and custom-feeds.js, functions like removeArrayTableRow are called early
   inside event-handler closures but assigned to window.* later in the file.
   At runtime this works (the handler fires after the assignment), but ESLint
   sees the bare name at the call site.
   Fix: change bare calls to window.removeArrayTableRow(this) etc. so the
   reference is explicit and ESLint-safe.

Also guard the updateSystemStats call in app.js reconnectSSE: the function
is called but defined nowhere in the codebase. Guard with typeof check so
it won't throw ReferenceError if the reconnect path is hit.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-14 10:54:05 -04:00

122 lines
4.3 KiB
JavaScript

/**
* Checkbox Group Widget
*
* Handles multi-select checkbox groups for array fields with enum items.
* Updates a hidden input with JSON array of selected values.
*
* @module CheckboxGroupWidget
*/
(function() {
'use strict';
// Ensure LEDMatrixWidgets registry exists
if (typeof window.LEDMatrixWidgets === 'undefined') {
console.error('[CheckboxGroupWidget] LEDMatrixWidgets registry not found. Load registry.js first.');
return;
}
/**
* Register the checkbox-group widget
*/
window.LEDMatrixWidgets.register('checkbox-group', {
name: 'Checkbox Group Widget',
version: '1.0.0',
/**
* Render the checkbox group widget
* Note: This widget is currently server-side rendered via Jinja2 template.
* This registration ensures the handlers are available globally.
*/
render: function(container, config, value, options) {
// For now, widgets are server-side rendered
// This function is a placeholder for future client-side rendering
console.log('[CheckboxGroupWidget] Render called (server-side rendered)');
},
/**
* Get current value from widget
* @param {string} fieldId - Field ID
* @returns {Array} Array of selected values
*/
getValue: function(fieldId) {
const hiddenInput = document.getElementById(`${fieldId}_data`);
if (hiddenInput && hiddenInput.value) {
try {
return JSON.parse(hiddenInput.value);
} catch (e) {
console.error('Error parsing checkbox group data:', e);
return [];
}
}
return [];
},
/**
* Set value in widget
* @param {string} fieldId - Field ID
* @param {Array} values - Array of values to select
*/
setValue: function(fieldId, values) {
if (!Array.isArray(values)) {
console.error('[CheckboxGroupWidget] setValue expects an array');
return;
}
// Normalize values to strings for consistent comparison
const normalizedValues = values.map(String);
// Update checkboxes
const checkboxes = document.querySelectorAll(`input[type="checkbox"][data-checkbox-group="${fieldId}"]`);
checkboxes.forEach(checkbox => {
const optionValue = checkbox.getAttribute('data-option-value') || checkbox.value;
// Normalize optionValue to string for comparison
checkbox.checked = normalizedValues.includes(String(optionValue));
});
// Update hidden input
window.updateCheckboxGroupData(fieldId);
},
handlers: {
// Handlers are attached to window for backwards compatibility
}
});
/**
* Update checkbox group data in hidden input
* Called when any checkbox in the group changes
* @param {string} fieldId - Field ID
*/
window.updateCheckboxGroupData = function(fieldId) {
// Update hidden _data input with currently checked values
const hiddenInput = document.getElementById(fieldId + '_data');
if (!hiddenInput) {
console.warn(`[CheckboxGroupWidget] Hidden input not found for fieldId: ${fieldId}`);
return;
}
const checkboxes = document.querySelectorAll(`input[type="checkbox"][data-checkbox-group="${fieldId}"]`);
const selectedValues = [];
checkboxes.forEach(checkbox => {
if (checkbox.checked) {
const optionValue = checkbox.getAttribute('data-option-value') || checkbox.value;
selectedValues.push(optionValue);
}
});
hiddenInput.value = JSON.stringify(selectedValues);
// Trigger change event for form validation
const event = new CustomEvent('widget-change', {
detail: { fieldId, value: selectedValues },
bubbles: true,
cancelable: true
});
hiddenInput.dispatchEvent(event);
};
console.log('[CheckboxGroupWidget] Checkbox group widget registered');
})();