diff --git a/src/ng/directive/input.js b/src/ng/directive/input.js index b49b625e0a42..685944248c5b 100644 --- a/src/ng/directive/input.js +++ b/src/ng/directive/input.js @@ -455,6 +455,8 @@ function addNativeHtml5Validators(ctrl, validatorName, element) { function textInputType(scope, element, attr, ctrl, $sniffer, $browser) { var validity = element.prop('validity'); + var placeholder = element[0].placeholder, noevent = {}; + // In composition mode, users are still inputing intermediate text buffer, // hold the listener until composition is done. // 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) { if (composing) return; var value = element.val(); + // IE (11 and under) seem to emit an 'input' event if the placeholder value changes. + // We don't want to dirty the value when this happens, so we abort here. Unfortunately, + // IE also sends input events for other non-input-related things, (such as focusing on a + // form control), so this change is not entirely enough to solve this. + if (msie && (ev || noevent).type === 'input' && element[0].placeholder !== placeholder) { + placeholder = element[0].placeholder; + return; + } + // By default we will trim the value // If the attribute ng-trim exists we will avoid trimming // e.g. diff --git a/test/ng/directive/inputSpec.js b/test/ng/directive/inputSpec.js index e3e50e02a69e..d14e1a2601c0 100644 --- a/test/ng/directive/inputSpec.js +++ b/test/ng/directive/inputSpec.js @@ -520,6 +520,23 @@ describe('input', function() { } }); + it('should not dirty the model on an input event in response to a placeholder change', inject(function($sniffer) { + if (msie && $sniffer.hasEvent('input')) { + compileInput(''); + inputElm.attr('placeholder', 'Test'); + browserTrigger(inputElm, 'input'); + + expect(inputElm.attr('placeholder')).toBe('Test'); + expect(inputElm).toBePristine(); + + inputElm.attr('placeholder', 'Test Again'); + browserTrigger(inputElm, 'input'); + + expect(inputElm.attr('placeholder')).toBe('Test Again'); + expect(inputElm).toBePristine(); + } + })); + describe('"change" event', function() { function assertBrowserSupportsChangeEvent(inputEventSupported) { // Force browser to report a lack of an 'input' event