Skip to content
This repository has been archived by the owner on Apr 12, 2024. It is now read-only.

Commit

Permalink
fix(input): don't dirty model when input event triggered due to place…
Browse files Browse the repository at this point in the history
…holder 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
  • Loading branch information
caitp committed Apr 18, 2014
1 parent 227822d commit 109e5d1
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 0 deletions.
11 changes: 11 additions & 0 deletions src/ng/directive/input.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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. <input ng-model="foo" ng-trim="false">
Expand Down
17 changes: 17 additions & 0 deletions test/ng/directive/inputSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -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('<input type="text" ng-model="name" name="name" />');
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
Expand Down

0 comments on commit 109e5d1

Please sign in to comment.