Validation
A login form with two fields. Submitting it empty shows a message under each field. Entering a nine-character password shows the length rule's message. Neither the message text nor the number ten appears in the screen's code. They come from the rules file.
Rules shared with the server
If validation rules are written in the screen, the server cannot use them, and paths that bypass the screen (bulk import, API calls, other screens) are not validated. So the rules are in one file, read by both the screen and the server.
SA001Login
account required アカウントは必須です。 errorOutput: field
password required パスワードは必須です。 errorOutput: field
password minLength 10文字以上で入力を。 errorOutput: field, options: [10]
The screen's code is one line.
Validate rules: rules for: 'SA001Login' state: self payload
The result is a list of failed rules, keyed by the field name used in the request, not by CSS selector. Where each message is displayed is decided by the screen.
Waiting for the rules
The rules are fetched from the server, not embedded in the code. If the submit button could be pressed before the rules arrive, the form would pass with no validation at all, so the button is disabled until the rules arrive.
Server errors are shown in the same place
Pressing "サーバが弾いたことにする" (simulate a server rejection) displays the server's error list in the same place as the screen's own validation results.
The rules file also says where each message goes: next to the field, or collected at the top of the page. The component returns which fields failed; the screen places the messages.
Adding a validator
To add a validator, write one class that implements the Validator protocol.
Object subclass: #Alphanumeric protocols: (Validator).
Alphanumeric >> failsFor: v options: os in: all = ...
No registration is needed. Validator implementors returns every class that implements the protocol, keyed by class name with the first letter in lowercase: Alphanumeric is alphanumeric, which is how the rules file names it. A Java service scans a package for annotated classes to build the same table; in LPScript, the compiler already has the list.
A validator receives the field's value as a string, the options from the rules file, and the whole JSON document being validated. The third argument allows rules that span fields.
The server has the final say
There are two implementations of required, one on the screen and one on the server. The screen's exists to inform the user early. The server decides. If the screen's validation is more lenient, the server rejects the request and its error list is shown in the same place.