From ff428e72837c85b9540ee9e5a3daa2c9477c90bb Mon Sep 17 00:00:00 2001 From: Caitlin Potter Date: Thu, 23 Jan 2014 14:25:14 -0500 Subject: [PATCH] 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 --- src/ng/directive/input.js | 10 ++++++++++ test/ng/directive/inputSpec.js | 17 +++++++++++++++++ 2 files changed, 27 insertions(+) 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