Enhancement - support nested constraint - validations
Closed this issue · 2 comments
Background is in this issue
#35
Use Case
checkbox
input
when a user either leaves the input field or does a page submit, perform validation such that
checkbox checked, input blank - validation warning
checkbox checked, input filled in - no validation warning
checkbox unchecked, input blank or filled in - no validation warning
Approach
When writing custom constraints, update Regula to support a means so that a constraint can invoke another built-in or custom constraint. (Nested constraints/validations). This will help support use cases like above and add a lot of capability to custom constraints.
I will add this to 1.2.4. I will provide a way to reference validators from within an existing validator. I imagine I would do something like this:
function(params, validators) {
//you can use the validators object to access the validator functions on constraints
}
I imagine that the validators object would have something like this:
validators.Core.Required.validator(this, params); //for core constraints.
validators.Custom.MyCustomConstraint.validator(this, params); //for custom/compound constraints.
I have to see how HTML5 constraints play into this as well.
This feature has been implemented. It is pretty similar to what I envisioned earlier, except that there is no separation of core and custom constraints. That seemed unnecessary. When you have a custom validator, you now receive a validator
object that contains references to all-existing validators. This includes asynchronous validators as well.
For a synchronous validator, the signature of the validator becomes:
function(params, validator) {
}
And for an asynchronous validator it becomes:
function(params, validator, resultCallback) {
}
The validator
object exposes functions that match up to the constraint name, except that it is in camelCase. For example, for the Checked
constraint, the validator is validator.checked
, whereas for HTML5Required
, the validator is validator.html5Required
.
Keep in mind that for asynchronous constraints, you basically end up providing the resultCallback
because that is the only way you can examine the result of an asynchronous validation.
The reason that these validators aren't exposed through the regula
object is that they bypass the usual validation life-cycle, and so are minimally useful when used in isolation.
Also note that though it is possible to write compound constraints using the exposed validators, it is not recommended, since it bypasses the life-cycle for validating and defining compound constraints. Furthermore, in complicated scenarios, it is easy to end up creating a cyclical composition thereby resulting in an infinite loop.