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

fix(input): don't dirty model when input event triggered due to placeholder change #5960

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion src/ng/directive/input.js
Original file line number Diff line number Diff line change
Expand Up @@ -435,6 +435,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 @@ -451,10 +452,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) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Make note of affected IE versions here

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you change this to msie < 11 and test it on IE11?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We're running Angular 1.0.8, and only had the placeholder problem in IE10 (IE v10.0.9200.16899 on Windows 8). We added the changes to the textInputType function, and it solved the problem.

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')) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lastly, could remove the msie check from both the test and the code, which is probably okay but I'm not positive

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