feat(18.1-01): task 2 taglist string mode, customTags and all save sites
- string mode: split on the separator (comma or whitespace), normalised, stored joined by a comma or one space; null stores an empty string - customTags false refuses a tag outside options (taglist.not_allowed) - taglist checked and hydrated on relation forms and settings forms; settings bind taglist columns; required checked on the tags - admin: TaglistField string mode and closed option lists, preview renders the tags read-only as a comma-separated list; rebuilt dist - docs: Taglist section covers both modes, separator and customTags
This commit is contained in:
@@ -509,7 +509,12 @@ In the admin SPA the field is a text input in decimal mode, right-aligned in tab
|
||||
|
||||
## Taglist
|
||||
|
||||
`type: taglist` edits a list of tags, as the WinterCMS tag list does. In `mode: array` the value travels as a JSON array of strings (`["alpha", "beta"]`) and is stored as that JSON array in one column: the column is a type whose pointer implements `sql.Scanner` and that implements `driver.Valuer`, such as `lagoon.Jsonable[[]string]` over a `text` column. Any other column type stops the start-up naming the field.
|
||||
`type: taglist` edits a list of tags, as the WinterCMS tag list does. It has two modes:
|
||||
|
||||
- `mode: array`: the value travels as a JSON array of strings (`["alpha", "beta"]`) and is stored as that JSON array in one column. The column is a type whose pointer implements `sql.Scanner` and that implements `driver.Valuer`, such as `lagoon.Jsonable[[]string]` over a `text` column.
|
||||
- `mode: string`, the default as in WinterCMS: the value travels as one string of tags joined by the separator (`"alpha,beta"`, or `"alpha beta"` with `separator: space`) and is stored as that string in a `string` (or `*string`) column.
|
||||
|
||||
Any other column type stops the start-up naming the field.
|
||||
|
||||
```yaml
|
||||
fields:
|
||||
@@ -518,20 +523,34 @@ fields:
|
||||
type: taglist
|
||||
mode: array
|
||||
options: [Support, Reports, Export]
|
||||
customTags: false
|
||||
keywords:
|
||||
label: acme.shop::lang.plans.keywords
|
||||
type: taglist
|
||||
separator: space
|
||||
```
|
||||
|
||||
The field takes the generic keys plus:
|
||||
|
||||
| Key | Meaning |
|
||||
|-----|---------|
|
||||
| `mode` | `array` stores a JSON array of strings. |
|
||||
| `mode` | `string` (the default) stores a separator-joined string; `array` stores a JSON array of strings. |
|
||||
| `separator` | String mode only: `comma` (the default) joins the stored tags with `,`, `space` with a single space. Refused in array mode. |
|
||||
| `options` | A YAML list of tags offered as suggestions while typing. A mapping or a method name stops the start-up. |
|
||||
| `customTags` | `true` (the default) accepts any tag; `false` accepts only the tags listed in `options`. |
|
||||
|
||||
`nameFrom`, `emptyOption`, `dependsOn`, `preset` and the money keys are refused on a taglist field, `separator` and `customTags` are refused on every other type, and a taglist inside a [repeater](#repeater) row stops the start-up.
|
||||
|
||||
A save normalises every submitted tag list before the transaction: each tag is trimmed, empty tags are dropped and a repeated tag is kept once, at its first position, so `[" alpha ", "beta", "alpha", ""]` stores `["alpha","beta"]`. `null` and an empty list store `[]`, never NULL. A value that is not a list of strings (a string, a number, a list holding a number) is a 422 on the field with `backend::lang.taglist.invalid`. A `required: true` taglist needs at least one tag. The record GET serves the stored list; a NULL or unreadable column is served as an empty list.
|
||||
A save normalises every submitted tag list before the transaction: each tag is trimmed, empty tags are dropped and a repeated tag is kept once, at its first position. In array mode `[" alpha ", "beta", "alpha", ""]` stores `["alpha","beta"]`, and `null` or an empty list stores `[]`, never NULL. In string mode the string is split on the separator (a comma, or any run of whitespace for `space`), normalised and joined again, so `"x y x"` with `separator: space` stores `"x y"`, and `null` stores an empty string. A save answers a 422 on the field with one of two `backend::lang.taglist` messages:
|
||||
|
||||
In the admin SPA the field shows its tags as chips, each with a remove button, followed by an input that adds the typed text as a tag on Enter or on typing a comma; empty text and a tag already in the list are ignored, and the options are offered as suggestions. Read-only shows the chips alone, or an em dash when empty.
|
||||
| Value | Answer |
|
||||
|-------|--------|
|
||||
| Not a list of strings in array mode (a string, a number, a list holding a number), or not a string in string mode | `taglist.invalid`, with `:field` |
|
||||
| With `customTags: false`, a tag that is not one of the `options` | `taglist.not_allowed`, with `:tag` naming the first such tag |
|
||||
|
||||
A `required: true` taglist needs at least one tag. The record GET serves the stored list in array mode (a NULL or unreadable column is served as an empty list) and the stored string in string mode. The same checks run on settings forms and relation forms.
|
||||
|
||||
In the admin SPA the field shows its tags as chips, each with a remove button, followed by an input that adds the typed text as a tag on Enter or on typing the separator (a comma, or a space with `separator: space`); empty text, a tag already in the list and, with `customTags: false`, a tag outside the options are ignored, and the options are offered as suggestions. Read-only and preview show the chips alone, read as a comma-separated list by screen readers, or an em dash when empty.
|
||||
|
||||
## What a save may write
|
||||
|
||||
|
||||
Reference in New Issue
Block a user