Replies: 7 comments 5 replies
-
@terryatgithub I moved the discussion here, starting to evaluate options more seriously. |
Beta Was this translation helpful? Give feedback.
-
I finally found time to make some progress here, check out the branch for current code: https://github.com/Instawork/hyperview/compare/adam/validate This prototype supports some basic validation that can be triggered via a behavior action. The example shows validation on button press, input change, or focus/blur: validation_prototype.mp4Markup for this video: <form>
<view style="FormGroup">
<text style="label">Validate with button press</text>
<text-field
placeholder="First name"
placeholderTextColor="#8D9494"
name="text"
style="input"
id="input-1"
>
<v:required message="First name required" />
<v:length min-length="2" max-length="5" message="Length must be between 2 and 5" />
</text-field>
<text style="help help--error" v:role="message" v:source="input-1" />
<view style="Button">
<behavior trigger="press" action="validate" target="input-1" />
<text style="Button__Label">Validate</text>
</view>
</view>
<view style="FormGroup">
<text style="label">Validate on change</text>
<text-field
placeholder="First name"
placeholderTextColor="#8D9494"
name="text"
style="input"
id="input-2"
>
<behavior trigger="change" action="validate" target="input-2" />
<v:required message="First name required" />
<v:length min-length="2" max-length="5" message="Length must be between 2 and 5" />
</text-field>
<text style="help help--error" v:role="message" v:source="input-2" />
</view>
<view style="FormGroup">
<text style="label">Validate on focus & blur</text>
<text-field
placeholder="First name"
placeholderTextColor="#8D9494"
name="text"
style="input"
id="input-3"
>
<behavior trigger="blur" action="validate" target="input-3" />
<behavior trigger="focus" action="validate" target="input-3" />
<v:required message="First name required" />
<v:length min-length="2" max-length="5" message="Length must be between 2 and 5" />
</text-field>
<text style="help help--error" v:role="message" v:source="input-3" />
</view>
</form |
Beta Was this translation helpful? Give feedback.
-
Thanks @adamstep for your great job. Sorry for the late reply, I haven't followed Github for a while. We have recently adopted Hyperview for a new project, and they also have a lot of business involving front-end form validation. We are all happy to see this progress and looking forward to the official release asap. Thank you again and wish all the best. |
Beta Was this translation helpful? Give feedback.
-
Can’t wait to see the new version! @adamstep. |
Beta Was this translation helpful? Give feedback.
-
Hello @adamstep, my company's products use Hyperview to dynamically load app views. This form validation feature seems to be very necessary, may I ask when it will be updated. Thank you so much! |
Beta Was this translation helpful? Give feedback.
-
You are amazon @adamstep, this has been long awaited. Now i can start my project with hyperview. |
Beta Was this translation helpful? Give feedback.
-
Updated with an approach to changing styles on elements other than input field. Latest code is here: https://github.com/Instawork/hyperview/compare/adam/validate2 |
Beta Was this translation helpful? Give feedback.
-
As explored in #305, there's a need to support client-side form validation in Hyperview. This doc will explore some approaches before we implement the feature.
What do we want to support?
What are we not supporting for now?
Design considerations
Declarative syntax
One of the design principles in Hyperview is that HXML should be completely declarative. The visual UI and behaviors should be defined as pure XML elements and attributes. Support for more sophisticated interactions is done by creating custom components and behaviors, which have the full power of arbitrary JS code.
Client-side validation should follow this same design principle. Validation logic should be expressed in pure HXML. Custom validation logic can be supported through an extension mechanism similar to behaviors.
Language agnostic
Another design principle in Hyperview is that the core library is as language agnostic as possible. Copy that appears in the app should be defined in the XML. For form validation, that means we don't want to hard-code the string "This field is required" anywhere in the app. This may make the syntax a little more verbose, but that's a similar tradeoff we make in other places as well.
However, do we want to pre-render all possible errors as hidden UI elements on the page, and toggle visibility? That doesn't seem very elegant. Perhaps we need a way to populate a single error UI element with the error message.
New namespace
We want to use XML namespaces for new features to avoid clashes when it comes to element names and attributes.
Prior Art
<behavior>
.role
to identify elements controlled by the custom component. In our S3 file upload component, a<text>
element withrole="upload-progress-text"
gets populated with a text representation of the upload progress, eg "30%". We can use a similar idea for showing theProposal
All elements and attributes for validation will use the namespace
https://hyperview.org/hyperview-validation
. In examples, this will be aliased tov
.Declaring Validation
Validators on inputs are defined as child elements. Each child element must have a unique tag name. Other attributes on the validator element specify the validation parameters and error messages.
For example, here's the validator for a required input:
Here's a validator to ensure the input value is an integer:
This validator include extra attribute to specify a min/max range of the input value:
A validator can only appear as a child element of an input element (
<text-field>
,<select-single>
, etc). Each input can have many validators. For example, to define a required age input:During field validation, the validators are checked in the order in which they appear under the input element. Checking the validators stops at the first failed check. If a check fails, the input is considered invalid with the message corresponding to the failed check. Subsequent validators are not checked during an instance of validation once a field is invalid. If all validator checks pass, the input is considered valid. Take the example above:
"Age is required"
."Age must be between 18 and 99"
.Creating custom validation rules
Like components and behaviors, users can register custom validators. A custom validator is implemented as a function that takes the value and validator element. It returns a JS object with a required key "valid" (boolean) and optional key "message" (string). As an example, here's a custom validator that checks the input value against a regular expression:
Registering a custom validator is similar to registering a custom behavior. The
Hyperview
RN component takes avalidators
prop, which is an array of objects. Each object has a key "name" with the name of the validator, and "callback" which is the validator function:The XML could now refer to a "regex" validator in any screen:
Triggering Validation
Validation is triggered with a new
validate
behavior action. The target of the behavior can be a<form>
element or an input element.When validating an entire
<form>
, each input element in the<form>
will be validated independently. In the example above, we will validateage
even ifusername
is invalid. Validating on individual inputs can be useful if triggered onblur
:Validation state is reflected in the XML through the addition of a
v:state
attribute to the<form>
, input, and validator elements. Thev:state
attribute values arevalid
,invalid
, andindeterminate
. Lack of the attribute impliesindeterminate
state. Post-validation, the form would have the following XML:Note that
<form>
,<text-field>
,<v:required>
and<v:range>
elements all contain thev:state
attributes.The
state
attribute can be set from the server. This is useful to combine server-side validation with client-side validation.Showing Validation State
Error Messages
Styles
We already have the concept of "modifier" styles. Current modifiers can reflect whether the element is pressed, selected, or focused. To support validation states, I recommend we add modifiers for
valid
andinvalid
states. The unmodified style corresponds toindeterminate
state of the elements. The modifier would be applied immediately when thev:state
attribute on an element changes.Sometimes, it may be useful to modify the style of an element around the text field. For example, perhaps the label above the text field should turn red when the input is invalid. This can be achieved by adding the attribute
v:role="style"
to the element, and av:source
attribute with the ID of the validated input element. When the input element changes validation state, the corresponding elements will re-render with appropriate modifier styles.Summary of changes:
validate
action for behaviorsv:state
attributes on validated forms and inputs.v:role
andv:source
attributes to modify elements in response to a validation:v:role="message"
populates error messages in<text>
elements.v:role="style"
applies thevalid
orinvalid
style modifier to the element.valid
andinvalid
style modifiersBeta Was this translation helpful? Give feedback.
All reactions