Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Validators API #5

Open
mohsen1 opened this issue Mar 3, 2015 · 19 comments
Open

Validators API #5

mohsen1 opened this issue Mar 3, 2015 · 19 comments

Comments

@mohsen1
Copy link
Member

mohsen1 commented Mar 3, 2015

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 fails
  • fn(function) validation function that can return boolean, accept the user input and a callback or returns promise that resolve to boolean

The 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

{
  type: "object",

  "properties": {
    "email": {
      "type": "email",
      "validators": [
        {
          message: 'You were unlucky!',
          fn: function(){
            return Math.random() > 0.4; // :D
          }
        }
      ]
    }, 
    "password": {
      "type": "password",
      "validators": [
        {
          message: 'Password can not have letter M in it!',
          fn: function(password) {
            return password.indexOf('M') === -1; // ?!?
          }
      ]
    }
  }, 

  "validators": [{
    message: 'email and password should not be equal',
    fn: function(obj) {
      return obj.password != obj.email;
    }
  }]
}
@bvaughn
Copy link
Member

bvaughn commented Mar 3, 2015

Might be nice for custom validation functions to be allowed to reject with an error message that overrides the one specified in message.

@bvaughn
Copy link
Member

bvaughn commented Mar 3, 2015

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?

@mohsen1
Copy link
Member Author

mohsen1 commented Mar 3, 2015

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

@kentcdodds
Copy link
Member

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.

@bvaughn
Copy link
Member

bvaughn commented Mar 3, 2015

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...

@mohsen1
Copy link
Member Author

mohsen1 commented Mar 3, 2015

@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
          }
        }
      ]
    }

@kentcdodds
Copy link
Member

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.

@mohsen1
Copy link
Member Author

mohsen1 commented Mar 3, 2015

@kentcdodds overriding validators sounds interesting! Can you write an example of that? I'm not sure I did understand it right.

@kentcdodds
Copy link
Member

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 :-)
    }
  }
}

@kentcdodds
Copy link
Member

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';
    }
  }
}

@bvaughn
Copy link
Member

bvaughn commented Mar 3, 2015

+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?

@mohsen1
Copy link
Member Author

mohsen1 commented Mar 3, 2015

forms-js should not solve that problem. User have to pass everything in one object or write custom validators that call third party validators.

@bvaughn
Copy link
Member

bvaughn commented Mar 3, 2015

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.)

@mohsen1
Copy link
Member Author

mohsen1 commented Mar 3, 2015

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

@bvaughn
Copy link
Member

bvaughn commented Mar 3, 2015

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?

@mchapman
Copy link

mchapman commented Mar 3, 2015

@bvaughn I think we are no heading back into the area of #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).

@mohsen1
Copy link
Member Author

mohsen1 commented Mar 3, 2015

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...

@mohsen1
Copy link
Member Author

mohsen1 commented Mar 3, 2015

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. 😄

@bvaughn
Copy link
Member

bvaughn commented Mar 3, 2015

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?"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants