diff --git a/config.yaml b/config.yaml
index c50b2df..d8b503a 100644
--- a/config.yaml
+++ b/config.yaml
@@ -143,6 +143,29 @@ actions:
- type: confirmation
title: Are you sure?!
+ # Checklist arguments let users pick multiple predefined options. Selected
+ # values are passed to the action as a comma-separated string.
+ #
+ # Docs: https://docs.olivetin.app/args/input_checklist.html
+ - title: Backup selected directories
+ icon: backup
+ shell: 'echo "Backing up: {{ directories }}"'
+ arguments:
+ - name: directories
+ title: Directories to back up
+ type: checklist
+ description: Select one or more directories to include in the backup.
+ choices:
+ - title: Documents
+ value: documents
+ - title: Photos
+ value: photos
+ - title: Music
+ value: music
+ - title: Videos
+ value: videos
+ default: documents,photos
+
# This is an action that runs a script included with OliveTin, that will
# download themes. You will still need to set theme "themeName" in your config.
#
diff --git a/docs/modules/ROOT/nav.adoc b/docs/modules/ROOT/nav.adoc
index 29896a8..ac12883 100644
--- a/docs/modules/ROOT/nav.adoc
+++ b/docs/modules/ROOT/nav.adoc
@@ -73,6 +73,7 @@
** xref:args/regex.adoc[Input: Regex]
** xref:args/password.adoc[Input: Password]
** xref:args/input_checkbox.adoc[Input: Checkbox/Boolean]
+** xref:args/input_checklist.adoc[Input: Checklist]
** xref:args/input_dropdown.adoc[Input: Dropdown]
** xref:args/input_datetime.adoc[Input: Date & Time]
** xref:args/input_confirmation.adoc[Input: Confirmation]
diff --git a/docs/modules/ROOT/pages/args/input_checklist.adoc b/docs/modules/ROOT/pages/args/input_checklist.adoc
new file mode 100644
index 0000000..229814e
--- /dev/null
+++ b/docs/modules/ROOT/pages/args/input_checklist.adoc
@@ -0,0 +1,80 @@
+[#checklist]
+= Input: Checklist
+
+The `checklist` type argument renders multiple checkboxes from predefined `choices`. Users can select one or more options, and the selected values are passed to your action as a comma-separated string.
+
+[source,yaml]
+----
+actions:
+ - title: Backup selected directories
+ shell: echo "Backing up: {{ directories }}"
+ arguments:
+ - name: directories
+ title: Directories to back up
+ type: checklist
+ choices:
+ - title: Documents
+ value: documents
+ - title: Photos
+ value: photos
+ - title: Music
+ value: music
+ default: documents,photos
+----
+
+When the example above runs with Documents and Photos selected, the shell command becomes:
+
+[source,shell]
+----
+echo "Backing up: documents,photos"
+----
+
+== Select all / Select none
+
+The web interface includes **Select all** and **Select none** controls above the checkbox list.
+
+== Empty selections
+
+If no options are selected, the argument value is an empty string. Use `rejectNull: true` when at least one selection is required.
+
+[source,yaml]
+----
+arguments:
+ - name: directories
+ type: checklist
+ rejectNull: true
+ choices:
+ - value: documents
+ - value: photos
+----
+
+== Choice values
+
+Choice `value` fields must not contain commas, because commas are used to join multiple selections together.
+
+Each `title` is shown in the web interface. If a submitted segment matches a choice `title`, OliveTin maps it to the corresponding `value` before validation, matching the behaviour of xref:args/input_checkbox.adoc[checkbox] arguments with choices.
+
+== Using Entities
+
+Checklist options can be generated from entities, using the same pattern as xref:args/input_dropdown.adoc#args-dropdown-entities[entity-backed dropdowns]. Define one choice template and set `entity` to the entity type name:
+
+[source,yaml]
+----
+actions:
+ - title: Restart selected containers
+ shell: 'docker restart {{ containers }}'
+ arguments:
+ - name: containers
+ title: Containers to restart
+ type: checklist
+ entity: container
+ choices:
+ - value: '{{ container.Names }}'
+ title: '{{ container.Names }}'
+
+entities:
+ - file: entities/containers.json
+ name: container
+----
+
+OliveTin expands the template once per entity instance and renders each result as a checkbox. Selected values are still passed as a comma-separated string.
diff --git a/docs/modules/ROOT/pages/args/types.adoc b/docs/modules/ROOT/pages/args/types.adoc
index ffdfed0..6d6f687 100644
--- a/docs/modules/ROOT/pages/args/types.adoc
+++ b/docs/modules/ROOT/pages/args/types.adoc
@@ -9,9 +9,9 @@ A full list of argument types are below;
| Type | Rendered as | Allowed values
| (default) | xref:args/input.adoc[Textbox] | If a `type:` is not set, and `choices:` is empty, then ascii will be used, and a warning will be logged. It is recommended that you set the type explicitly, rather than relying on defaults.
| ascii | xref:args/input.adoc[Textbox] | a-z (case insensitive), 0-9, but no spaces or punctuation
-| ascii_identifier | xref:args/input.adoc[Textbox] | Like a DNS name, a-Z (case insensitive), 0-9, `-`, `.`, and `_`.
+| ascii_identifier | xref:args/input.adoc[Textbox] | Like a DNS name, a-Z (case insensitive), 0-9, `-`, `.`, and `_`.
| shell_safe_identifier | xref:args/input.adoc[Textbox] | Like an ascii identifier, but also allows `@` and `+`. Useful for shell-safe usernames and email-style identifiers.
-| ascii_sentence | xref:args/input.adoc[Textbox] | a-z (case insensitive), 0-9, with spaces, `.` and `,`.
+| ascii_sentence | xref:args/input.adoc[Textbox] | a-z (case insensitive), 0-9, with spaces, `.` and `,`.
| unicode_identifier | xref:args/input.adoc[Textbox] | Like an ascii identifier, but allows unicode characters. This is useful for languages that use non-ascii characters, such as Chinese, Japanese, etc.
| email | xref:args/input.adoc[Textbox] | An email address.
| password | xref:args/password.adoc[Password] | A password, which is hidden when typed.
@@ -20,6 +20,7 @@ A full list of argument types are below;
| int | xref:args/input.adoc[Textbox] | Any number, made up of the characters 0 to 9. Negative numbers are not supported.
| url | xref:args/input.adoc[Textbox] | A URL (e.g. https://example.com). Accepts any scheme, including `file://` and `ftp://`. See warning below.
| confirmation | xref:args/input_confirmation.adoc[Confirmation] | A "hidden" argument that makes the action require a confirmation before launching.
+| checklist | xref:args/input_checklist.adoc[Checklist] | Multiple checkboxes from predefined choices. Selected values are passed as a comma-separated string.
| n/a, but `choices` used | xref:args/input_dropdown.adoc[Dropdown] | A "hidden" argument that makes the action require a confirmation before launching.
| raw_string_multiline | xref:args/input_textarea.adoc[Textarea] | Anything. This is **dangerous**, as effectively people can type anything they like
|===
@@ -31,4 +32,3 @@ The `url` argument type does not restrict the URL scheme. Users can enter `file:
If your action might be used by untrusted users, validate or filter the URL in your script (e.g. allow only `https://`) before using the value.
====
-
diff --git a/frontend/resources/vue/components/ChoiceChecklist.vue b/frontend/resources/vue/components/ChoiceChecklist.vue
new file mode 100644
index 0000000..04235d6
--- /dev/null
+++ b/frontend/resources/vue/components/ChoiceChecklist.vue
@@ -0,0 +1,156 @@
+
+