Open mohsen1 opened 9 years ago
Might be nice for custom validation functions to be allowed to reject with an error message that overrides the one specified in message
.
In general, I also prefer more descriptive attribute names (ex "function" vs "fn"). I realize that function is one of those special words, but maybe something like validator? or method?
How about this: You can return (or resolve to) boolean or string(custom error)
I'm open for a replacing fn
with something more meaningful
I must say that I am against the JSON schema-like format of having field configuration separate from the validation config. I think that field config should be able to stand on its own. It is much easier to build abstractions for different field types this way.
Could you clarify a little Kent?
Are you proposing that the full form markup should be generated from a single configuration object? Or something else...
@kentcdodds I'm not sure if I understand your concern correctly. Each filed can have it's own list of validators and is completely independent from it's parent and siblings. For example email
itself in my example is a complete schema.
Being recursive is a key feature of JSON Schema
{
"type": "email",
"validators": [
{
message: 'You were unlucky!',
fn: function(){
return Math.random() > 0.4; // :D
}
}
]
}
Ah, I think I misread that. Sounds good to me. I don't mind the fn
abbreviation. In angular-formly, I use expression
because it can either be a string expression (as you'd see in an angular template) or a function. But fn
I think is pretty well accepted by people. Also, would probably be a good idea to make it be an object instead of an array. That way you can override validators. This follows the $validators
api of angular which I think was a good decision.
@kentcdodds overriding validators sounds interesting! Can you write an example of that? I'm not sure I did understand it right.
Type definition:
{
name: 'foo',
defaultOptions: {
validators: {
isFoo: function(val) {
return val === 'foo';
}
}
}
}
then later, in a field definition:
{
type: 'foo',
validators: {
isFoo: {
message: 'That is not foo!',
pattern: /^foo$/ // <-- just kinda threw that in there, I think we should allow them to specify a fn, a pattern and anything else that makes sense :-)
}
}
}
Oh, also notice that in the type definition, the validator isFoo
is a function. In this scenario, it would be the same as:
{
isFoo: {
message: null,
fn: function(val) {
return val === 'foo';
}
}
}
+1 for using named validations. I like the flexibility of being able to override requirements for a specific context.
Although this kind of raises another question- if our validations are spread across multiple schema files- how do we pass them to form-js?
forms-js should not solve that problem. User have to pass everything in one object or write custom validators that call third party validators.
Sorry, let me rephrase. My question is higher-level than that: what interface does forms-js expose for validations? (How do you pass any validation to forms-js.)
oh you mean global static validators? I think we should avoid that. It's going to lead to a lot of surprises. The most global validators list is the one in the schema root
No, sorry. We're still misunderstanding each other.
Assertion: form-js will help with the generation and validation of forms. To instrument validation, it will need to be provided with some sort of validation configuration (POJO or JSON schema).
Question: If we go with a JSON schema, how do we pass that schema to forms-js?
@bvaughn I think we are no heading back into the area of https://github.com/forms-js/discussions/issues/2 (although I just put a curve ball in there).
I would like to see support (as in forms-angular) for schemas hard coded into a controller (in angular speak) and for schemas requested from the server on the fly. How they are built up on the server is outside the scope of this project (I will predictably be building mine from Mongoose schemas).
We are extending the JSON Schema. The extension contains functions so it's not JSON anymore and it's POJO. All validation logic should be included in the Schema itself.
Here is the example of what I mean:
<forms-js
action="/"
method="post"
schema="{
type: 'string',
title: 'Name'
validators: {
noScript: {fn: function(name) {
return name.indexOf('<script>') === -1;
},
message: 'No scripts'
}
}
}">
<button type="submit">Submit</button>
</forms-js>
That should make a form like this:
<forms-js action="/" method="post">
Name: <input type="string" title="Name"> <span style="display:none">No Scripts!</span>
<button type="submit">Submit</button>
</forms-js>
There will be event listeners for input
change event and so on...
Note that in my example I'm using forms-js
like <form>
. It's because we will make forms-js
web component extend form
element. 😄
I strongly disagree with auto-generating the forms from the validation rules. This limits our users too much and only allows for very simple/plain forms to be generated.
We are extending the JSON Schema. The extension contains functions so it's not JSON anymore and it's POJO. All validation logic should be included in the Schema itself.
I think we're also still not saying the same thing.
Yes validation rules will be in the schema. Validation logic might also be there (if people are using our subset of the schema). But something should be instrumenting when the validation rules are applied and governing higher-level things like "is the form valid?" "can the form be submitted?"
My proposal:
each schema can have a
validators
property which is an array of validator objects. A validator object have the following properties:message
(string) the error message shown if validation failsfn
(function) validation function that can return boolean, accept the user input and a callback or returns promise that resolve to booleanThe validation functions will get executed with the array order and if all validations passed the entry is valid. The validator starts with leafs of the Schema tree and crawls up to the root of the schema.
Example