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 paste/cut events in IE to support context menu
Browse files Browse the repository at this point in the history
In IE the model is not updated when the input value is modified using the context
menu, e.g. pasting from the clipboard, or cutting all or part of the current value.
To capture these changes, we bind to the proprietary 'paste' and 'cut' events.

Closes #1462
  • Loading branch information
markdalgleish authored and petebacondarwin committed Apr 17, 2013
1 parent c4d5631 commit 363e4cb
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 8 deletions.
21 changes: 15 additions & 6 deletions src/ng/directive/input.js
Original file line number Diff line number Diff line change
Expand Up @@ -413,23 +413,32 @@ function textInputType(scope, element, attr, ctrl, $sniffer, $browser) {
} else {
var timeout;

var deferListener = function() {
if (!timeout) {
timeout = $browser.defer(function() {
listener();
timeout = null;
});
}
};

element.bind('keydown', function(event) {
var key = event.keyCode;

// ignore
// command modifiers arrows
if (key === 91 || (15 < key && key < 19) || (37 <= key && key <= 40)) return;

if (!timeout) {
timeout = $browser.defer(function() {
listener();
timeout = null;
});
}
deferListener();
});

// if user paste into input using mouse, we need "change" event to catch it
element.bind('change', listener);

// if user modifies input value using context menu in IE, we need "paste" and "cut" events to catch it
if ($sniffer.hasEvent('paste')) {
element.bind('paste cut', deferListener);
}
}


Expand Down
34 changes: 32 additions & 2 deletions test/ng/directive/inputSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -309,7 +309,7 @@ describe('ngModel', function() {


describe('input', function() {
var formElm, inputElm, scope, $compile, changeInputValueTo;
var formElm, inputElm, scope, $compile, $sniffer, $browser, changeInputValueTo;

function compileInput(inputHtml) {
inputElm = jqLite(inputHtml);
Expand All @@ -318,7 +318,9 @@ describe('input', function() {
$compile(formElm)(scope);
}

beforeEach(inject(function($injector, $sniffer) {
beforeEach(inject(function($injector, _$sniffer_, _$browser_) {
$sniffer = _$sniffer_;
$browser = _$browser_;
$compile = $injector.get('$compile');
scope = $injector.get('$rootScope');

Expand Down Expand Up @@ -385,6 +387,34 @@ describe('input', function() {
expect(scope.name).toEqual('adam');
});

describe('"paste" and "cut" events', function() {
beforeEach(function() {
// Force browser to report a lack of an 'input' event
$sniffer.hasEvent = function(eventName) {
return eventName !== 'input';
};
});

it('should update the model on "paste" event', function() {
compileInput('<input type="text" ng-model="name" name="alias" ng-change="change()" />');

inputElm.val('mark');
browserTrigger(inputElm, 'paste');
$browser.defer.flush();
expect(scope.name).toEqual('mark');
});

it('should update the model on "cut" event', function() {
compileInput('<input type="text" ng-model="name" name="alias" ng-change="change()" />');

inputElm.val('john');
browserTrigger(inputElm, 'cut');
$browser.defer.flush();
expect(scope.name).toEqual('john');
});

});


it('should update the model and trim the value', function() {
compileInput('<input type="text" ng-model="name" name="alias" ng-change="change()" />');
Expand Down

0 comments on commit 363e4cb

Please sign in to comment.