From a9a42812ac694098ac71a210b47c3de41f150899 Mon Sep 17 00:00:00 2001 From: Chuck Date: Tue, 6 Jan 2026 17:51:26 -0500 Subject: [PATCH] feat(web): Add checkbox-group widget support for plugin config arrays Add server-side rendering support for checkbox-group widget in plugin configuration forms. This allows plugins to use checkboxes for multi-select array fields instead of comma-separated text inputs. The implementation: - Checks for x-widget: 'checkbox-group' in schema - Renders checkboxes for each enum item in items.enum - Supports custom labels via x-options.labels - Works with any plugin that follows the pattern Already used by: - ledmatrix-news plugin (enabled_feeds) - odds-ticker plugin (enabled_leagues) --- .../templates/v3/partials/plugin_config.html | 26 ++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/web_interface/templates/v3/partials/plugin_config.html b/web_interface/templates/v3/partials/plugin_config.html index d5033a86..937d1fd7 100644 --- a/web_interface/templates/v3/partials/plugin_config.html +++ b/web_interface/templates/v3/partials/plugin_config.html @@ -58,7 +58,7 @@ {% if field_type == 'integer' %}step="1"{% else %}step="any"{% endif %} class="form-input w-full rounded-md border-gray-300 shadow-sm focus:border-blue-500 focus:ring-blue-500 bg-white text-black placeholder:text-gray-500"> - {# Array - check for file upload widget first (to avoid breaking static-image plugin), then array of objects #} + {# Array - check for file upload widget first (to avoid breaking static-image plugin), then checkbox-group, then array of objects #} {% elif field_type == 'array' %} {% set x_widget = prop.get('x-widget') or prop.get('x_widget') %} {% if x_widget == 'file-upload' %} @@ -152,6 +152,30 @@ + {% elif x_widget == 'checkbox-group' %} + {# Checkbox group widget for multi-select arrays with enum items #} + {% set array_value = value if value is not none and value is iterable and value is not string else (prop.default if prop.default is defined and prop.default is iterable and prop.default is not string else []) %} + {% set items_schema = prop.get('items') or {} %} + {% set enum_items = items_schema.get('enum') or [] %} + {% set x_options = prop.get('x-options') or {} %} + {% set labels = x_options.get('labels') or {} %} + +
+ {% for option in enum_items %} + {% set is_checked = option in array_value %} + {% set option_label = labels.get(option, option|replace('_', ' ')|title) %} + {% set checkbox_id = (field_id ~ '_' ~ option)|replace('.', '_')|replace(' ', '_') %} + + {% endfor %} +
{% else %} {# Check if it's an array of objects (like custom_feeds) - use simple table interface #} {% set items_schema = prop.get('items') or {} %}