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