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

Commit 49dfdf8

Browse files
committed
fix(ngModel): use keydown/change events on IE9 instead of input
On IE9 the input event is not fired when backspace or delete key are pressed or when cut is performed. This makes listening on the input event unreliable and therefore it's better for us to just use keydown/change events instead. Closes #879
1 parent 5bcb749 commit 49dfdf8

File tree

4 files changed

+22
-8
lines changed

4 files changed

+22
-8
lines changed

src/ng/directive/input.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -379,7 +379,8 @@ function textInputType(scope, element, attr, ctrl, $sniffer, $browser) {
379379
}
380380
};
381381

382-
// if the browser does support "input" event, we are fine
382+
// if the browser does support "input" event, we are fine - except on IE9 which doesn't fire the
383+
// input event on backspace, delete or cut
383384
if ($sniffer.hasEvent('input')) {
384385
element.bind('input', listener);
385386
} else {

src/ng/sniffer.js

+5
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,11 @@ function $SnifferProvider() {
2222
// IE8 compatible mode lies
2323
(!$window.document.documentMode || $window.document.documentMode > 7),
2424
hasEvent: function(event) {
25+
// IE9 implements 'input' event it's so fubared that we rather pretend that it doesn't have
26+
// it. In particular the event is not fired when backspace or delete key are pressed or
27+
// when cut operation is performed.
28+
if (event == 'input' && msie == 9) return false;
29+
2530
if (isUndefined(eventSupport[event])) {
2631
var divElm = $window.document.createElement('div');
2732
eventSupport[event] = 'on' + event in divElm;

test/ng/directive/inputSpec.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -254,7 +254,7 @@ describe('ngModel', function() {
254254
expect(element.hasClass('ng-invalid-email')).toBe(true);
255255

256256
element.val('invalid-again');
257-
browserTrigger(element, $sniffer.hasEvent('input') ? 'input' : 'change');
257+
browserTrigger(element, ($sniffer.hasEvent('input')) ? 'input' : 'change');
258258
expect(element).toBeInvalid();
259259
expect(element).toBeDirty();
260260
expect(element.hasClass('ng-valid-email')).toBe(false);

test/ng/snifferSpec.js

+14-6
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,10 @@ describe('$sniffer', function() {
4545
});
4646

4747

48-
it('should return true if "oninput" is present in a div element', function() {
49-
mockDivElement = {oninput: noop};
48+
it('should return true if "onchange" is present in a div element', function() {
49+
mockDivElement = {onchange: noop};
5050

51-
expect($sniffer.hasEvent('input')).toBe(true);
51+
expect($sniffer.hasEvent('change')).toBe(true);
5252
});
5353

5454

@@ -62,11 +62,19 @@ describe('$sniffer', function() {
6262
it('should only create the element once', function() {
6363
mockDivElement = {};
6464

65-
$sniffer.hasEvent('input');
66-
$sniffer.hasEvent('input');
67-
$sniffer.hasEvent('input');
65+
$sniffer.hasEvent('change');
66+
$sniffer.hasEvent('change');
67+
$sniffer.hasEvent('change');
6868

6969
expect(mockDocument.createElement).toHaveBeenCalledOnce();
7070
});
71+
72+
73+
it('should claim that IE9 doesn\'t have support for "oninput"', function() {
74+
// IE9 implementation is fubared, so it's better to pretend that it doesn't have the support
75+
mockDivElement = {oninput: noop};
76+
77+
expect($sniffer.hasEvent('input')).toBe((msie == 9) ? false : true);
78+
});
7179
});
7280
});

0 commit comments

Comments
 (0)