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

Validation on submit #27

Closed
torstenrudolf opened this issue Jul 21, 2014 · 19 comments
Closed

Validation on submit #27

torstenrudolf opened this issue Jul 21, 2014 · 19 comments

Comments

@torstenrudolf
Copy link
Contributor

I have a question regarding the validation process.
I tried to dig through the code, but I'm not sure if I got it right. I'm also pretty new to angular.

In my examples it seems like, I can submit the form even that there are validation issues.
Is there a full validation before the form gets submitted?
I think that would be a good improvement if not.

Also, can I call a function, that goes through the schema and validates the fields and updates the valid state of the form fields?

@davidlgj
Copy link
Contributor

Hi!

There is no full validation before submit, per design I didn't want schema form to mess around with the submit part, since there might not be one. For instance we're using it and saving any value on 'blur' of the field.

The idea was to keep it "angularish" and that the user could use ng-submit if they wanted and rely on using the form controller (i.e. name on a form tag, https://docs.angularjs.org/api/ng/directive/form) to check if the entire form is valid or not, as you would with any kind of validation in angular. So basically thats the way to check if the form is valid or not. Does that make sense? Should probably be documented better :-)

There is a fine point here though, if you omit fields in your form definition, the form might be valid, but if you validate the model object against the schema it is not valid, which can be a problem if you validate on the backend.

@torstenrudolf
Copy link
Contributor Author

Thx for this response David!

I think you are right, maybe I wanted to over engineer the whole form part and forgot that its anyway only client side validation. Thx for the tip how to use form validation in angular.

@torstenrudolf
Copy link
Contributor Author

I'm just wondering whats the angular way to display the errors on submit. The problem are the fields that are unchanged but invalid.

In my submit function i now set the form-controller $dirty and loop over the form-controllers error-fields and set them to $dirty (since the $setDirty() doesn't propagate to child fields).

formCtrl.$setDirty();
 _.each(formCtrl.$error, function (fields, errorType) {
    _.each(fields, function (field) {
        field.$pristine = false;
    });
 });

Probably this should be done with a directive that intercepts the submit event and set a $submitted flag or somethin? But then I would have to change the hasError() code in the schema-validate directive.

@davidlgj
Copy link
Contributor

Good question! I don't have a good answer though :(
Are you using "required" in the schema? Then it should block submit in most browsers I guess.

Currently we hook up a "disabled" attribute on the submit button to formCtrl.$invalid so we just don't run into that problem.

@chachou29
Copy link

So there is no way to know the validity of the whole form ?

@davidlgj
Copy link
Contributor

@chachou29 there is! Just check what the form controller says, as you would do with any form in angular. See my comment above.

@torstenrudolf
Copy link
Contributor Author

@davidlgj Yes, with the required option it should work on most browsers. I just like it better to disable the browser validation and have full control.

Also I think it would not be nice to disable the submit button, since the user doesn't know then what is wrong.

I like this approach here (from section "Manually Checking for Errors" downwards): http://blog.yodersolutions.com/bootstrap-form-validation-done-right-in-angularjs/

Does this look reasonable to you?

@davidlgj
Copy link
Contributor

@torstenrudolf I think it looks very reasonable, although I disagree about disabling the submit button always is a bad thing. If the form has clearly marked "required" fields, then it is clear for the user, either they haven't filled in the entire form or they have a big validation error message to read. Also validating as you type can be both great and a bit of a bother, great when the first invalid character in a "username" directly prompts the user with the rules, but the email validation that just goes wrong is not that fun.

That said schema form should obviously try to support doing "manual" validation on submit and validation on blur instead of on change.

So IMHO a couple of things are needed

  1. A way to trigger validation of the form, maybe through an event? It should handle "required" in the schema as well.
  2. An option in the form definition on each field, and maybe a global default that can be changed, that says if that field should validate on blur or on change. Having it on each field might be an overkill though.
  3. An onBlur option similar to onChange for good measure.

Do you see anything missing?

@chachou29
Copy link

Hello David,
I understand i could use angular form properties ($error, $pristine, $dirty, $valid) ... but it's not working ...
The form is named "MyForm' and MyForm.$valid is never defined.
I missed something ?
Philippe

@davidlgj
Copy link
Contributor

@chachou29 But "MyForm" is defined? Could you make a jsfiddle or send me an example? Mail me at david.lgj@gmail.com

@torstenrudolf
Copy link
Contributor Author

@chachou29 : I assume MyForm is the name of your form? Than this variable is only defined inside the scope of the form.

<form name="myForm" ...>

form is valid: {{ myForm.$valid }}  // that should work
</form>

form is valid: {{ myForm.$valid }}  // that should not work

@torstenrudolf
Copy link
Contributor Author

@davidlgj I would really like the option to validate on blur! Still I think clicking the "submit" button and then having the required fields highlighted, but probably everyone has it's own taste there ;)

at 1: I think to manage the validation of the form by an event is the right way.
at 2: would be nice if you could set the default inside the form directive like

<form ... sf-validation-on-blur="true"></form>

@chachou29
Copy link

Hello,
@davidlgj
Form properties ($error, $pristine, $dirty, $valid) are correctly defined if you do not set a sf-decorator.
http://jsfiddle.net/JV7L4/28/
By the way, what sf-decorator is for ?

@torstenrudolf
Yes, MyForm is the name of my form :-)
Form properties are defined outside the scope of the form. (oufffff)

@torstenrudolf
Copy link
Contributor Author

@chachou29 maybe this helps: http://jsfiddle.net/JV7L4/29/

@davidlgj
Copy link
Contributor

Hi @chachou29, (and thanks for helping out @torstenrudolf)

sorry it took so long to answer. The problem is with scoping. I was a bit surprised that the first version works for you at all, I usually find that the form controller exposed by setting the name attribute on form only is available "inside" the form, i.e. on the scope the form directive introduces. But since you fiddle works I guess the form directive does not create a scope in its own after all.

A solution to working with the forms controller is to not put the sf-schema directive on the form but a div inside it. That way you can have everything inside proper scope. See http://jsfiddle.net/JV7L4/30/

That said you actually found a bug :-) A bit embarrassing bug actually...

Let me first explain what the sf-decorator attribute is for. Its read in the code for the sf-schema directive, and the thought is that schema form should be able to be extended with several flavors of "decorators", bootstrap 3 being one of them. It's not really used since there only is one "decorator" right now, and has it's problem (see #29).

The bug is that sf-decorator is also the name of the default directive for creating a field, i.e. the directive that is used inside the generated html code,we have a name clash! So when you put sf-decorator on it actually triggers a directive and that directive creates a new scope, probably why the second example in your fiddle does not work. I've opened a bug on it, #49.

@davidlgj
Copy link
Contributor

Hi @chachou29 and @torstenrudolf,

there are some commit to development that fixes some of these issues. Basically you can issue a $scope.$broadcast('schemaFormValidate') and the entire form will validate (broadcasting it on just a fields scope validates that field). This can be used in ng-submit and afterwards you can check the form controller to see if it's valid.

Also I have made sort of a solution to validating on blur instead of on change. Basically it boils down to this: Angular 1.3 has support for it with the directive ngModelOptions so I've added it and made it so you can set it via the form definition per field or via a global setting for the entire form.

Hope that works for you.

@davidlgj
Copy link
Contributor

@torstenrudolf
Copy link
Contributor Author

Thanks @davidlgj !!
I will have a look into this soonish.
btw: you are doing an awesome job here!

@torstenrudolf
Copy link
Contributor Author

It works like a charm!

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

No branches or pull requests

3 participants