UXValidator
UXValidator is an ordered list of rules. validate says whether a
value passes them all; firstError returns the message of the
first rule that fails.
#use <UXKit> // or #import "UXValidator.xc"Overview
Section titled “Overview”UXValidator* name = new UXValidator();name.requireNonEmpty((u8*)"a name is required");name.requireMinLength(2, (u8*)"at least 2 characters");name.requireMaxLength(8, (u8*)"at most 8 characters");
name.validate((u8*)"Alice"); // truename.firstError((u8*)"J"); // "at least 2 characters"name.firstError((u8*)"Alice"); // 0 — nothing wrongIt contains no window code, so a form’s Submit gate can be tested without typing. A text field consults the same object on every keystroke, and a dialog consults it before closing.
The message is part of the rule
Section titled “The message is part of the rule”Each rule knows what to say when it fails, so the error label has one source:
u8* err = v.firstError(field.stringValue());errorLabel.setText(err == (u8*)0 ? (u8*)"" : err);submit.setEnabled(err == (u8*)0);The enabled state and the message come from one call, so they cannot disagree. A form cannot show no error while refusing to submit.
Order is message priority
Section titled “Order is message priority”Rules are checked in the order they were added, and firstError stops at the
first failure. The order you add them is the order the user is told about them:
'' -> "age is required"'17' -> "must be 18 to 120"'42' -> okPut the coarsest rule first. Empty text also fails a range check, but “age is required” is more useful to read than “must be 18 to 120”.
A regex rule matches the whole value
Section titled “A regex rule matches the whole value”code.requireMatch((u8*)"^[A-Z][A-Z]-\\d\\d$", (u8*)"format is XX-99");
code.validate((u8*)"GB-42"); // truecode.validate((u8*)"see GB-42 here"); // falseThe rule uses UXRegex.matches, so the
pattern must describe the entire field, as a field format should. A pattern
written to be found inside a value will reject everything.
The ^ and $ above are therefore redundant, but they show a reader that the
whole value is intended.
The integer range is lenient about what a number is
Section titled “The integer range is lenient about what a number is”An empty validator passes everything
Section titled “An empty validator passes everything”new UXValidator().validate(anything); // trueWith no rules, nothing can fail. This is the right default for an optional field, and a form can hold one validator per field without special-casing fields that have no rules.
Topics
Section titled “Topics”requireNonEmpty · requireMatch · requireMinLength · requireMaxLength · requireIntRange · validate · firstError · ruleCount · addRule
requireNonEmpty
Section titled “requireNonEmpty”void requireNonEmpty(u8* msg)At least one byte. A value of spaces is not empty; trim it with
UXText.trimWhitespace first if
you want to treat it as empty.
requireMatch
Section titled “requireMatch”void requireMatch(u8* pattern, u8* msg)A whole-value regex match.
requireMinLength
Section titled “requireMinLength”void requireMinLength(i32 n, u8* msg)requireMaxLength
Section titled “requireMaxLength”void requireMaxLength(i32 n, u8* msg)Length is in bytes, so a non-ASCII UTF-8 character counts as more than one. This suits a field with a hard storage limit; for “at most 20 letters” it is approximate.
requireIntRange
Section titled “requireIntRange”void requireIntRange(i32 lo, i32 hi, u8* msg)Inclusive at both ends. See the caution.
validate
Section titled “validate”bool validate(u8* value)True if all rules pass. Stops at the first failure.
firstError
Section titled “firstError”u8* firstError(u8* value)The message of the first failing rule, or null if all pass. It returns null
and not "", so “no error” is distinguishable from an empty message.
ruleCount
Section titled “ruleCount”i32 ruleCount(void)addRule
Section titled “addRule”void addRule(i32 type, UXRegex* rx, i32 a, i32 b, u8* msg)The general form the require* methods use, with UXV_REQUIRED, UXV_REGEX,
UXV_MINLEN, UXV_MAXLEN or UXV_INTRANGE. Use it to add a rule with an
already-compiled regex, or to build rules from a table.
Messages are kept, not copied. Pass literals, or strings that outlive the validator.
Example
Section titled “Example” '': a name is required 'J': at least 2 characters 'Jonathan Smith': at most 8 characters 'Alice': ok 'GB-42': ok 'gb-42': format is XX-99 'see GB-42 here': format is XX-99 '': age is required '17': must be 18 to 120 '42': ok '55': ok 'banana': ok empty validator rules=0 passes=1banana passing the 0–100 range shows the lenient parse. The program is
website/site/examples/uxkit/rules.xc. The doc-examples gate compiles it,
and the block above is its output.
Conforms to
Section titled “Conforms to”- A plain class (not an
Objectsubclass)
See also
Section titled “See also”UXValidationRule: one ruleUXRegex: whatrequireMatchcompilesUXTextField: the control this usually guards