Join GitHub today
GitHub is home to over 50 million developers working together to host and review code, manage projects, and build software together.Sign up
GitHub is where the world builds software
Millions of developers and companies build, ship, and maintain their software on GitHub — the largest and most advanced development platform in the world.
External validation with HTTP/database services #1304
Right now this is possible, but only indirectly:
This approach has some limitations:
This comment contains ideas moved from the wiki.
Currently, Form Runner only supports "internal" validation, that is validation expressed with types and constraints (like in plain XForms).
Often, you need external validation, which might involve complex calculations or lookups that are hard or inconvenient to implement with XForms. E.g.:
A possible way
A possible way of implementing this is documented in this how-to: Perform external validation.
This works in limited cases but has limitations, including:
These limitations are likely not acceptable for Form Runner as we want this feature to be future-proof.
With internal validation, data is frequently revalidated, typically whenever a field changes.
With external validation, this by default might be too costly. In that case, external validation:
Validation information is provided by a service:
The exact format of the response is TBD, but could be:
In XForms, Model Item Properties (MIPs) are declarative, so don't need to be "persisted" in an instance DOM as they can be recomputed as needed.
With external validation, we might need to introduce a type of persistent, imperative MIPs, settable with an action:
<xxf:setmip ref="foo/bar" name="valid" value="false()"/>
and readable as an XPath function:
xxf:getmip($name as xs:string) as item()
An action to clear all MIPs, or all MIPs of a given type, might be needed:
<xxf:clearmip ref="instance()" name="valid"/>
NOTE: Persistent MIPs do not replace declarative MIPs: they combine with them.
When nodes are removed from an instance, these MIPs are automatically removed.
Impact on the XForms engine
This has the following impact on the implementation:
Impact on Form Runner
Impact on Form Builder
None for now, this has to be configured through properties.
At this point, I am not 100% sure that the "persistent MIP idea" is the best one. But the idea that external validation could be triggered by default only upon save/submit is good, and maybe configurable via independent properties or directly in the save/send processes properties.
There should probably also be ways to trigger external validation separately, maybe by adding an action once we have separated Form Builder actions from services.
As a first step, it might be ok to say the following:
Comment on the proposal above: we could send the whole XForms instance, or possibly pass a list of control names to send. Then only those values would be sent, as URL parameters or in a
Clearly an important step is to determine the format(s) of the request/response.
With datasets, the workaround can look like:
This is still heavy but doesn't require hidden controls. A single service call can return all validity information.
<xf:bind ref="instance('fr-form-instance')//*[empty(*)]" constraint=" for $name in name(.), $ds in fr:dataset('validation-dataset') return empty($ds/*[name() = $name]/[@valid = 'false']) " />
Above assuming a validation document like:
<validation> <name valid="false"/> <foo valid="false"/> <bar valid="false"/> </validation
You can vary the format of the validation document.