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

Commit 83feaaf

Browse files
committed
fix(ngmodel): fixing many keys incorrectly marking inputs as dirty
1 parent 8b86a9e commit 83feaaf

File tree

2 files changed

+44
-3
lines changed

2 files changed

+44
-3
lines changed

src/ng/directive/input.js

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -949,6 +949,10 @@ function baseInputType(scope, element, attr, ctrl, $sniffer, $browser) {
949949
}
950950

951951
var listener = function(ev) {
952+
if (timeout) {
953+
$browser.defer.cancel(timeout);
954+
timeout = null;
955+
}
952956
if (composing) return;
953957
var value = element.val(),
954958
event = ev && ev.type;
@@ -975,11 +979,13 @@ function baseInputType(scope, element, attr, ctrl, $sniffer, $browser) {
975979
} else {
976980
var timeout;
977981

978-
var deferListener = function(ev) {
982+
var deferListener = function(ev, input, origValue) {
979983
if (!timeout) {
980984
timeout = $browser.defer(function() {
981-
listener(ev);
982985
timeout = null;
986+
if (!input || input.value !== origValue) {
987+
listener(ev);
988+
}
983989
});
984990
}
985991
};
@@ -991,7 +997,7 @@ function baseInputType(scope, element, attr, ctrl, $sniffer, $browser) {
991997
// command modifiers arrows
992998
if (key === 91 || (15 < key && key < 19) || (37 <= key && key <= 40)) return;
993999

994-
deferListener(event);
1000+
deferListener(event, this, this.value);
9951001
});
9961002

9971003
// if user modifies input value using context menu in IE, we need "paste" and "cut" events to catch it

test/ng/directive/inputSpec.js

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1569,6 +1569,41 @@ describe('input', function() {
15691569
expect(inputElm).toBeDirty();
15701570
}
15711571
}));
1572+
1573+
1574+
//Cases created by using change/keydown/paste/cut instead of the input event
1575+
//TODO: these need to be verified better and preferably switched to integration tests
1576+
it('should dirty on keydown if the value changes', inject(function($browser) {
1577+
if (msie) {
1578+
compileInput('<input type="text" ng-model="name" />');
1579+
browserTrigger(inputElm, 'keydown');
1580+
$browser.defer.flush();
1581+
expect(inputElm).toBePristine();
1582+
1583+
browserTrigger(inputElm, 'keydown');
1584+
inputElm.val('f');
1585+
$browser.defer.flush();
1586+
expect(inputElm).toBeDirty();
1587+
}
1588+
}));
1589+
1590+
it('should cancel the delayed dirty if a change occurs', inject(function($browser) {
1591+
if (msie) {
1592+
compileInput('<input type="text" ng-model="name" />');
1593+
var ctrl = inputElm.controller('ngModel');
1594+
1595+
browserTrigger(inputElm, 'keydown', {target: inputElm[0]});
1596+
inputElm.val('f');
1597+
browserTrigger(inputElm, 'change');
1598+
expect(inputElm).toBeDirty();
1599+
1600+
ctrl.$setPristine();
1601+
expect(inputElm).toBePristine();
1602+
1603+
$browser.defer.flush();
1604+
expect(inputElm).toBePristine();
1605+
}
1606+
}));
15721607
});
15731608

15741609

0 commit comments

Comments
 (0)