Closed kylefinley closed 12 years ago
I can't reproduce this on MacOS 10.7 with Chrome 20.0.1132.34 beta or 21.0.1179.0 canary.
If anything this is a browser bug - the browser doesn't trigger the "input" event when the autofill is committed by selecting the email address from the list and hitting enter or clicking on it.
I'm going to close this issue for now, but if you are still affected by it, please do let us know. You could also try to test the latest canary version and see if you can reproduce it there.
If we do need to follow up on this issue, it will most likely be by refiling this as a Chrome bug, but for that we need to be able to reproduce it.
I figured out what is going on. The reason that it's difficult to reproduce is because there are two ways that Chrome will populate fields.
In this case Autofill is creating the problem. Autofill only populates the form when the following two conditions are met.
method="POST"
attribute.So to reproduce:
When using autofill you should then see the issue.
This simplest solution is to remove the method="POST"
from the form, which is the documented way to use Angular forms. The problem with this approach is it disregards User's Autofill information. If you still can reproduce this or you deem the work around acceptable, please feel free to leave the issue close. Now that I have a way to circumvent autofills behavior, I'm content.
I can recreate this issue on Chrome Stable 19 and Angular 1.0 and 1.0.1. I'm doing exactly what kylefinley was doing. The form method is POST and I'd like to let people use autofill if they have it. I'd settle for a way to trigger an angular update manually when they click "continue" button.
After some trial and error and re-reading Igor's post I discovered I can simply do this to get the browser to fire input events for things that may have been filled in by autofill but haven't updated. example: $('#myform input,myform select').trigger('input');
(Edit to fix typo) If you have a submit or click handler for the form submission you can trigger the input event on all your inputs so that angular will pick up the changes by autofill.
Fire input event on all inputs: $('#myform input,#myform select').each(function() { $(this).trigger('input'); });
Or you can try firing an input event when other events happen like change or blur: $('#myform input,#myform select').on('change blur', function() { $(this).trigger('input'); });
PSA: This probably has performance implications and over triggers events.
Thank you @robrbecker for investigating this. It's good to have an alternative that works with Chrome's Autofill.
@robrbecker: Thanks for sharing, but I'm running into the problem that I get
Error: $apply already in progress
It works for the automatically populated fields, but deletes the data for all others. Very strange. Maybe I'm doing something wrong, but I would definitely suggest, to not use this fix for production builds.
@johannesjo Make sure you register these event listeners only once at dom ready. For instance this is what I'm doing.
var app = angular.module('app',[]); app.run(function() { // Trigger input event on change to fix auto-complete $('input, select').on('change',function() { $(this).trigger('input'); }); });
Do your own testing on your own app of course.
This works for me:
function MyController($scope) {
setTimeout(function() {
$scope.$apply(function () {
$('input[ng-model]').trigger('change');
});
}, 250);
}
As long as jQuery is loaded before Angular, of course!!
You can also use $timeout...
I'm getting this in Chrome 28 now even without method="POST".
I came here searching for a solution as i have the same problem. Removing method="POST" is not an option for me unfortunately.
I now use the following directive:
var ValidSubmit = ['$parse','$timeout', function ($parse, $timeout) {
return {
require: '^form',
link: function(scope, element, attrs, form) {
form.$submitted = false;
var fn = $parse(attrs.validSubmit);
element.on('submit', function(event) {
var inputs = element.find("*[ng-model]")
for(var i=0; i < inputs.length; i++) {
var ele = inputs.eq(i);
var field = form[inputs[i].name];
if(field != void 0) {
if(inputs[i].type == "checkbox" || inputs[i].type == "hidden") {
field.$setViewValue(field.$viewValue);
} else {
field.$setViewValue(ele.val());
}
}
}
scope.$apply(function() {
element.addClass('ng-submitted');
form.$submitted = true;
if(form.$valid) {
fn(scope, {$event:event});
}
});
});
}
}
}]
app.directive('validSubmit', ValidSubmit);
Hi malixsys,
Can you please also tell how you are using that directive? I tried adding it to the
Check https://github.com/malixsys/matryoshka/blob/master/app/client/app/anonymous/views/state_login.html et. al. The validation appears only on submit...
As discussed here: https://groups.google.com/forum/?fromgroups#!topic/angular/GQVX5F3v7Xk
When using Chrome autofill angular is not reevaluating the email address after the fill, therefore, it believes it to be invalid.
Here's a jsfiddle demonstrating the issue: http://jsfiddle.net/kylefinley/DuM6D/14/
There's a screen shot in the linked thread.
This issues appears in the following Chromium browsers:
Iron Version 19.0.1100.0 (139545) Chromium Version 21.0.1180.0 (142701) Chrome Version 19 - 20.0.1132.34 beta
Please let me know if you are not able to reproduce this.
Thank you,
Kyle