Skip to content

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 angular#2614
Closes angular#5960
  • Loading branch information
caitp committed Jan 23, 2014
1 parent e020916 commit e6193cf
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 1 deletion.
11 changes: 10 additions & 1 deletion src/ng/directive/input.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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. <input ng-model="foo" ng-trim="false">
Expand Down
22 changes: 22 additions & 0 deletions test/ng/directive/inputSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -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('<input type="text" ng-model="name" name="name" />');

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
Expand Down

0 comments on commit e6193cf

Please sign in to comment.