Skip to content

Commit 77daa56

Browse files
committed
fix(input): don't dirty model when input event triggered due to placeholder change
Certain versions of IE inexplicably trigger an input event in response to a placeholder being set. It is not possible to sniff for this behaviour nicely as the event is not triggered if the element is not attached to the document, and the event triggers asynchronously so it is not possible to accomplish this without deferring DOM compilation and slowing down load times. Closes angular#2614 Closes angular#5960
1 parent 2b73027 commit 77daa56

File tree

2 files changed

+27
-1
lines changed

2 files changed

+27
-1
lines changed

Diff for: src/ng/directive/input.js

+10-1
Original file line numberDiff line numberDiff line change
@@ -435,6 +435,7 @@ function validate(ctrl, validatorName, validity, value){
435435
}
436436

437437
function textInputType(scope, element, attr, ctrl, $sniffer, $browser) {
438+
var placeholder = element[0].placeholder, noevent = {};
438439
// In composition mode, users are still inputing intermediate text buffer,
439440
// hold the listener until composition is done.
440441
// More about composition events: https://developer.mozilla.org/en-US/docs/Web/API/CompositionEvent
@@ -451,10 +452,18 @@ function textInputType(scope, element, attr, ctrl, $sniffer, $browser) {
451452
});
452453
}
453454

454-
var listener = function() {
455+
var listener = function(event) {
455456
if (composing) return;
456457
var value = element.val();
457458

459+
// Some versions of MSIE emit an 'input' event when the placeholder attribute/property
460+
// change. This hack prevents an otherwise pristine field from being dirtied on IE
461+
// browsers.
462+
if (msie && (event || noevent).type === 'input' && element[0].placeholder !== placeholder) {
463+
placeholder = element[0].placeholder;
464+
return;
465+
}
466+
458467
// By default we will trim the value
459468
// If the attribute ng-trim exists we will avoid trimming
460469
// e.g. <input ng-model="foo" ng-trim="false">

Diff for: test/ng/directive/inputSpec.js

+17
Original file line numberDiff line numberDiff line change
@@ -520,6 +520,23 @@ describe('input', function() {
520520
}
521521
});
522522

523+
it('should not dirty the model on an input event in response to a placeholder change', inject(function($sniffer) {
524+
if (msie && $sniffer.hasEvent('input')) {
525+
compileInput('<input type="text" ng-model="name" name="name" />');
526+
inputElm.attr('placeholder', 'Test');
527+
browserTrigger(inputElm, 'input');
528+
529+
expect(inputElm.attr('placeholder')).toBe('Test');
530+
expect(inputElm).toBePristine();
531+
532+
inputElm.attr('placeholder', 'Test Again');
533+
browserTrigger(inputElm, 'input');
534+
535+
expect(inputElm.attr('placeholder')).toBe('Test Again');
536+
expect(inputElm).toBePristine();
537+
}
538+
}));
539+
523540
describe('"change" event', function() {
524541
function assertBrowserSupportsChangeEvent(inputEventSupported) {
525542
// Force browser to report a lack of an 'input' event

0 commit comments

Comments
 (0)