krescruz / angular-materialize

Angularjs directives for Materialize CSS Framework https://github.com/Dogfalo/materialize
MIT License
396 stars 129 forks source link

Why inputs are touched onload? #167

Open carscx opened 8 years ago

carscx commented 8 years ago

The inputs onload initial are touched set true.

Steps to reproduce

I've create a JSFiddle with angular only http://jsfiddle.net/carscx/mjud3r47/1/ and I've modified their JSFiddle http://jsfiddle.net/nb8116u4/2/ to see the differences

A link to a page clearly demonstrating the issue

http://jsfiddle.net/nb8116u4/2/

webbiesdk commented 8 years ago

Yep, looks like a bug.

I think it is some of the initialization done by Materialize that is causing it, which is difficult to change.

I'll look more at it later.

carscx commented 8 years ago

Other example, if you to init the field, touched is false.

But is false always. If you erase all text touched be true.

http://jsfiddle.net/carscx/nb8116u4/3/

kildareflare commented 8 years ago

We are seeing the same issue. We are using ngMessages for our clientside validation messages. This bug means that all input fields have the ng-touched classed set before they have actually been used, and results in the input fields marked as in error.

Looking through the code is appears to be related to this line::

element.trigger("blur");

in the below code:

  angular.module("ui.materialize.ngModel", [])
        .directive("ngModel",["$timeout", function($timeout){
            return {
                restrict: 'A',
                priority: -1, // lower priority than built-in ng-model so it runs first
                link: function(scope, element, attr) {
                    scope.$watch(attr.ngModel,function(value, oldValue){
                        $timeout(function () {
                            // To stop an infinite feedback-loop with material multiple-select.
                            if (value instanceof Array && oldValue instanceof Array) {
                                if (value.length == oldValue.length) {
                                    return;
                                }
                            }
                            if (value){
                                element.trigger("change");
                            } else if(element.attr('placeholder') === undefined) {
                                if(!element.is(":focus"))
                                    element.trigger("blur"); //this line causes the issue
                            }
                        });
                    });
                }
            };
        }]);

If I remove that line all is good. Any ideas why that line is needed?

webbiesdk commented 8 years ago

The element.trigger("blur"); is there to ensure that the "blur" events are triggered correctly, when the inputs are updated externally by ng-model. So that line stays, in some form.

The fix might be to restrict when element.trigger("blur") is executed.

mdobrzanski commented 6 years ago

Ah, this got me today. I may be wrong, but it's blur suppose to happen when user clicks on different element? As an opposite to focus. It messes up how validation works in angularjs.