The rules a form's fields carry are checked on the server, after the post. With
client on the {form} the browser checks them too, as the visitor types and
before the form leaves - with the same rules and the same messages, so the two never
disagree. The server still checks every post: the browser's check only saves a round trip.
|
PHP fragments/client_validation_1.php |
HTML fragments/client_validation_1.pad |
|---|---|
|
|
data-pad-rules attribute, and the first such form
of the page brings a small script along. A field is checked when it is left, again
while it is typed in once it showed a message, and every field when the form is sent - a
form that fails is not sent, and the first field with a message gets the focus.<span class="error"> after the field, tied to it with
aria-invalid and aria-describedby - in the words of the field's
label; the form's error= shows above the fields.client needs a name and fields with rules=. A
regex: rule JavaScript cannot read as PCRE does is left to the server.A React, Vue or Alpine form is no {form} of the template. Keep the rules in the page's
PHP instead - one list for both sides: padValidate ( $rules ) checks the post, and
padValidateClient ( $rules ) exports the same list for the browser, every rule
with the message padValidate would give:
|
PHP fragments/client_validation_2.php |
HTML fragments/client_validation_2.pad |
Result |
|---|---|---|
|
|
{
"email": {
"label": "Email",
"number": false,
"list": false,
"single": ":label must be a single value",
"rules": [
[
"required",
"",
":label is required",
""
],
[
"email",
"",
":label must be a valid e-mail address",
""
]
]
},
"qty": {
"label": "Qty",
"number": true,
"list": false,
"single": ":label must be a single value",
"rules": [
[
"integer",
"",
":label must be a whole number",
""
],
[
"min",
"1",
":label must be at least :n",
"1"
],
[
"max",
"10",
":label must be at most :n",
"10"
]
]
}
}
|
{validator} in the template brings the checker without a form, and the component asks it:
<div x-data="{ rules: {^rules}, form: {}, errors: {} }">
<input x-model="form.email" @blur="errors = padValidate.check(rules, form)">
<span class="error" x-text="errors.email"></span>
</div>
{validator}
padValidate.check ( rules, values ) answers the message of every field that broke
a rule; padValidate.field ( rules.email, value, values ) one field's, empty when it
holds. A field named tags[] takes a list.