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

Commit

Permalink
fix(ngModel): use keydown/change events on IE9 instead of input
Browse files Browse the repository at this point in the history
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
  • Loading branch information
IgorMinar committed May 7, 2012
1 parent 5bcb749 commit 49dfdf8
Show file tree
Hide file tree
Showing 4 changed files with 22 additions and 8 deletions.
3 changes: 2 additions & 1 deletion src/ng/directive/input.js
Original file line number Diff line number Diff line change
Expand Up @@ -379,7 +379,8 @@ function textInputType(scope, element, attr, ctrl, $sniffer, $browser) {
}
};

// if the browser does support "input" event, we are fine
// if the browser does support "input" event, we are fine - except on IE9 which doesn't fire the
// input event on backspace, delete or cut
if ($sniffer.hasEvent('input')) {
element.bind('input', listener);
} else {
Expand Down
5 changes: 5 additions & 0 deletions src/ng/sniffer.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@ function $SnifferProvider() {
// IE8 compatible mode lies
(!$window.document.documentMode || $window.document.documentMode > 7),
hasEvent: function(event) {
// IE9 implements 'input' event it's so fubared that we rather pretend that it doesn't have
// it. In particular the event is not fired when backspace or delete key are pressed or
// when cut operation is performed.
if (event == 'input' && msie == 9) return false;

if (isUndefined(eventSupport[event])) {
var divElm = $window.document.createElement('div');
eventSupport[event] = 'on' + event in divElm;
Expand Down
2 changes: 1 addition & 1 deletion test/ng/directive/inputSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,7 @@ describe('ngModel', function() {
expect(element.hasClass('ng-invalid-email')).toBe(true);

element.val('invalid-again');
browserTrigger(element, $sniffer.hasEvent('input') ? 'input' : 'change');
browserTrigger(element, ($sniffer.hasEvent('input')) ? 'input' : 'change');
expect(element).toBeInvalid();
expect(element).toBeDirty();
expect(element.hasClass('ng-valid-email')).toBe(false);
Expand Down
20 changes: 14 additions & 6 deletions test/ng/snifferSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,10 @@ describe('$sniffer', function() {
});


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

expect($sniffer.hasEvent('input')).toBe(true);
expect($sniffer.hasEvent('change')).toBe(true);
});


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

$sniffer.hasEvent('input');
$sniffer.hasEvent('input');
$sniffer.hasEvent('input');
$sniffer.hasEvent('change');
$sniffer.hasEvent('change');
$sniffer.hasEvent('change');

expect(mockDocument.createElement).toHaveBeenCalledOnce();
});


it('should claim that IE9 doesn\'t have support for "oninput"', function() {
// IE9 implementation is fubared, so it's better to pretend that it doesn't have the support
mockDivElement = {oninput: noop};

expect($sniffer.hasEvent('input')).toBe((msie == 9) ? false : true);
});
});
});

0 comments on commit 49dfdf8

Please sign in to comment.