diff --git a/src/ng/directive/input.js b/src/ng/directive/input.js index 10374c3fd04c..d5ebe489978f 100644 --- a/src/ng/directive/input.js +++ b/src/ng/directive/input.js @@ -880,6 +880,7 @@ 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. @@ -902,6 +903,15 @@ function textInputType(scope, element, attr, ctrl, $sniffer, $browser) { var value = element.val(), event = ev && ev.type; + // 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 389dd7bdede0..e9b28f1e7464 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