Skip to content
This repository was archived by the owner on Apr 12, 2024. It is now read-only.

Commit 109e5d1

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 #2614 Closes #5960
1 parent 227822d commit 109e5d1

File tree

2 files changed

+28
-0
lines changed

2 files changed

+28
-0
lines changed

src/ng/directive/input.js

+11
Original file line numberDiff line numberDiff line change
@@ -455,6 +455,8 @@ function addNativeHtml5Validators(ctrl, validatorName, element) {
455455

456456
function textInputType(scope, element, attr, ctrl, $sniffer, $browser) {
457457
var validity = element.prop('validity');
458+
var placeholder = element[0].placeholder, noevent = {};
459+
458460
// In composition mode, users are still inputing intermediate text buffer,
459461
// hold the listener until composition is done.
460462
// More about composition events: https://developer.mozilla.org/en-US/docs/Web/API/CompositionEvent
@@ -475,6 +477,15 @@ function textInputType(scope, element, attr, ctrl, $sniffer, $browser) {
475477
if (composing) return;
476478
var value = element.val();
477479

480+
// IE (11 and under) seem to emit an 'input' event if the placeholder value changes.
481+
// We don't want to dirty the value when this happens, so we abort here. Unfortunately,
482+
// IE also sends input events for other non-input-related things, (such as focusing on a
483+
// form control), so this change is not entirely enough to solve this.
484+
if (msie && (ev || noevent).type === 'input' && element[0].placeholder !== placeholder) {
485+
placeholder = element[0].placeholder;
486+
return;
487+
}
488+
478489
// By default we will trim the value
479490
// If the attribute ng-trim exists we will avoid trimming
480491
// e.g. <input ng-model="foo" ng-trim="false">

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)