jonsamwell / angular-auto-validate

An automatic validation module for AngularJS which gets rid of excess html in favour of dynamic element modification to notify the user of validation errors
MIT License
346 stars 76 forks source link

Missing documentation for register-custom-form-control directive #34

Open jonsamwell opened 9 years ago

jonsamwell commented 9 years ago

Missing documentation for register-custom-form-control directive

pjwalmsley commented 9 years ago

I should/may be able to get around to this this weekend.

I also struggled a bit with getting a nested form to validate. It may be worth noting in the documentation that the inner form must have an element type of ng-form. While this isn't an issue with your code it isn't blatantly obvious. :)

jonsamwell commented 9 years ago

Thanks, I'll add the bit about a nested ng-form to the docs!

pjwalmsley commented 9 years ago

Thanks for all your work on this library. Another small typo i spotted: "you can still do that by just specifying which element modifier should be used to modifier the elements visual state" - 'modifier' should be 'modify'. :)

jonsamwell commented 9 years ago

Thanks - I'll update soon

jonsamwell commented 9 years ago

Typo updated

pjwalmsley commented 9 years ago

Worth noting or changing the limit of ten elements deep. I've got a really deep form and this threw me off.

The recursion limit of ten elements is on line 1023 if you feel it is worth increasing or making recursve based on the existence of a parent.

jonsamwell commented 9 years ago

Maybe a config options i.e. recursionDepth

pjwalmsley commented 9 years ago

That would work. I mean there really isn't much danger/speed loss when its higher.

Of better yet if we used a recursive function there would be no need to worry about recursion depth. Perhaps we could replace this function with the following.

var findParentForm = function (el) {
    var form;
    var recursive = function (parent) {
        if (parent !== undefined) {
            if (parent.nodeName.toLowerCase() === 'form') {
                form = parent;
            } else {
                recursive(angular.element(parent).parent()[0]);
            }
        }
    }
    recursive(el);
}
pjwalmsley commented 9 years ago

Just sent over a pull request.

pjwalmsley commented 9 years ago

So i messed up that pull request. The change, as described above, can be seen on my branch. It's commit 0908f71 .

hinok commented 9 years ago

Can someone provide very basic example why we need this directive? I use inside a form and everything is still propery validated.

plnkr http://plnkr.co/edit/GMoTi673v8cCR2UwQPRf?p=preview

pjwalmsley commented 9 years ago

Standard elements such as input, select, textfield, or button will be tracked by angular-auto-validate. Custom fields that may provide a better user experience are not picked up (we find by tag type rather than ng-model).

In my case I have a custom multi-select drop down, a field that combines/controls two input fields to exposes a single usable value, and a special field that can be cleared.

It is not needed in your example. :)

hinok commented 9 years ago

To be honest, I still don't get it. For example I have my own file-upload directive which inject some upload validation errors into form.

In template it looks like this

<form name="userForm">
    <file-upload name="userAvatar" validation-max-size="1024"></file-upload>
    <button>Submit</button>
</form>

This directive will do something like this in case of uploading too big image

userForm.userAvatar.$setValidity('validationMaxSize', false)

As I understood, I could use register-custom-form-control to display errors? How should I do it? Should I add input hidden with proper name inside file-upload's template? Thanks for patience :)

pjwalmsley commented 9 years ago

Nope, your on the right track. Auto validate's role is to add the error message, not necessarily do the validation.

If you sought to validate that you would add register-custom-form-control. Your directive would look something like:

<form name="userForm">
    <file-upload name="userAvatar" validation-max-size="1024"  register-custom-form-control>
    </file-upload>
    <button>Submit</button>
</form>

This watches for error conditions (such as validationMaxSize). Then you would add a value for validationMaxSize to your lang file (see examples for errors like required or minLength). When an error condition occurs (check to see if there is a validationMaxSize error class on the elm) it will look this up and append the message.

To actually have the error condition thrown you probably need to write a validation directive. It looks like you may have already done this. For a more traditional validation it will look something like:

myApp.directive("validationMaxSizeOfModel", function(){
    return {
    restrict: 'A',
    require: 'ngModel',
    link: function(scope, ele, attrs, ctrl){
        validateFn = function(value) {
            if(value == attrs.validateMaxSizeOfModel){
                ctrl.$setValidity('validationMaxSize', valid);
            } else {
                ctrl.$setValidity('validationMaxSize', invalid);
            }
            return value;
        }
        elm.$parsers.push(validateFn);
        elm.$formatters.push(validateFn);
   }
});

You may handle this differently because your uploading stuff but thats the general idea. There are some guides and docs for doing this that you may want to check. The example I threw up was just freehand referencing some of our validations.

hinok commented 9 years ago

@pjwalmsley Thank you! I changed *elementModifier a bit and problably this is the reason why I couldn't see any appended validation errors in element while using register-custom-form-control. All is clear now, thank you again.