From e6193cf0287d016f5c0ba9d242c7f42fab8c065f 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 | 11 ++++++++++- test/ng/directive/inputSpec.js | 22 ++++++++++++++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/src/ng/directive/input.js b/src/ng/directive/input.js index 53a8ddd4d70a..3b5e7a40e8ec 100644 --- a/src/ng/directive/input.js +++ b/src/ng/directive/input.js @@ -405,6 +405,7 @@ function validate(ctrl, validatorName, validity, value){ } function textInputType(scope, element, attr, ctrl, $sniffer, $browser) { + 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 @@ -420,10 +421,18 @@ function textInputType(scope, element, attr, ctrl, $sniffer, $browser) { }); } - var listener = function() { + var listener = function(event) { if (composing) return; var value = element.val(); + // Some versions of MSIE emit an 'input' event when the placeholder attribute/property + // change. This hack prevents an otherwise pristine field from being dirtied on IE + // browsers. + if (msie && (event || 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 668fa0b54a1e..52adab3dbb65 100644 --- a/test/ng/directive/inputSpec.js +++ b/test/ng/directive/inputSpec.js @@ -509,6 +509,28 @@ describe('input', function() { }); } + + iit('should not dirty the model on an input event in response to a placeholder change', inject(function($sniffer) { + if (msie && $sniffer.hasEvent('input')) { + compileInput(''); + + expect(inputElm).toBePristine(); + + 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