From d0858e84a963a8fa4f51449b435627867feb3417 Mon Sep 17 00:00:00 2001 From: Ilia Ross Date: Wed, 9 Sep 2026 01:05:53 +0200 Subject: [PATCH] Add multi-selection attribute and label examples --- ui-demo/README.md | 12 +++++++++++- ui-demo/lang/en | 7 +++++++ ui-demo/ui-demo-pages.pl | 20 ++++++++++++++++++++ 3 files changed, 38 insertions(+), 1 deletion(-) diff --git a/ui-demo/README.md b/ui-demo/README.md index ed29248d8..ff6e05eb4 100644 --- a/ui-demo/README.md +++ b/ui-demo/README.md @@ -28,7 +28,7 @@ The page itself is wrapped in `ui_page_start` / `ui_page_end`, which load the stylesheet and script from `unauthenticated/css/ui-lib.css` and `unauthenticated/js/ui-lib.js` once per page. -In either `ui_multi_select_list` example on the Choices tab, click an +In a `ui_multi_select_list` example on the Choices tab, click an entry and Shift-click another to select or clear the range between them. Checkboxes, labels and row backgrounds work alike; filtered, folded and disabled entries are skipped. @@ -44,6 +44,16 @@ or closes an empty filter; the funnel and Escape close and clear it. The empty server example uses `empty_label` to replace the default "No entries" with a plain, caller-supplied message. +The "Option attributes" example passes legacy `[ value, label, attributes ]` +entries. Two rows are disabled, including a checked membership; the other +rows remain editable. Titles and styles apply to the row, so the optional +membership is italic and shows a tooltip. + +"Label comparison" passes `staff (Office accounts)` in the options of one +list and only in the selected values of a legacy positional call. Both +show the full description and submit `staff`. Positional calls also retain +selected-value order and accept pre-escaped labels from existing callers. + ## Page chrome Around the gallery, `index.cgi` and `demo_page_actions` show the parts diff --git a/ui-demo/lang/en b/ui-demo/lang/en index 0e67c85fb..1168fd897 100644 --- a/ui-demo/lang/en +++ b/ui-demo/lang/en @@ -346,3 +346,10 @@ index_c_subservers=Include sub-servers of those selected index_c_subs=+$1 sub-servers index_c_member=Group membership index_c_secgroups=Secondary groups +index_c_attrs=Option attributes +index_c_managed=Managed by policy +index_c_optional=Optional membership +index_c_labels=Label comparison +index_c_option_label=Description in options +index_c_selected_label=Description in selected values (legacy) +index_c_staff_desc=$1 (Office accounts) diff --git a/ui-demo/ui-demo-pages.pl b/ui-demo/ui-demo-pages.pl index 097390527..dfef0111d 100644 --- a/ui-demo/ui-demo-pages.pl +++ b/ui-demo/ui-demo-pages.pl @@ -741,6 +741,26 @@ $rv .= ui_table_row($text{'index_c_secgroups'}, ( 'adm', 'audio', 'backup', 'cdrom', 'dialout', 'docker', 'lp', 'plugdev', 'sudo', 'video', 'wheel', 'www-data' ) ]), 2); +# Legacy option attributes: locked selections, unavailable entries and row styling. +my $locked = "disabled title=\"".html_escape($text{'index_c_managed'})."\""; +$rv .= ui_table_row($text{'index_c_attrs'}, + ui_multi_select_list('group_attrs', [ 'backup' ], [ + [ 'backup', 'backup', $locked ], + [ 'docker', 'docker', $locked ], + [ 'audio', 'audio', "style='font-style:italic' title=\"". + html_escape($text{'index_c_optional'})."\"" ], + [ 'wheel', 'wheel' ] ], { 'search' => 1 }), 2); +$rv .= ui_table_end(); + +# Both APIs retain descriptions in their respective label arguments. +my $staff_label = text('index_c_staff_desc', 'staff'); +$rv .= ui_table_start($text{'index_c_labels'}, 'width=100%', 4); +$rv .= ui_table_row($text{'index_c_option_label'}, + ui_multi_select_list('option_label', [ [ 'staff', 'staff' ] ], + [ [ 'staff', $staff_label ] ])); +$rv .= ui_table_row($text{'index_c_selected_label'}, + ui_multi_select_list('selected_label', [ [ 'staff', $staff_label ] ], + [ [ 'staff', 'staff' ] ], 5)); $rv .= ui_table_end(); $rv .= ui_form_end([ [ undef, $text{'save'} ] ]); return $rv;