8

How to execute a function on "Paste" event in input in Angular 1.1.5? I know there is a ng-change directive for input. But it fires each time the input changes, I need only once on initial paste.

Use-case: I have a URL input. I want to execute a function after user pastes the URL. User also can manually enter the URL and execute the function by pressing Enter.

--

Update: Since Angular 1.2.0, ngPaste is a native directive.

Websirnik
  • 1,332
  • 2
  • 21
  • 33
  • why not create a custom directive that listens to when the input gets pasted into? – David Chase Aug 27 '13 at 02:13
  • You can create a directive with some jquery tricks like this http://stackoverflow.com/questions/686995/jquery-catch-paste-input – zs2020 Aug 27 '13 at 04:27

4 Answers4

29

Since Angular 1.2.0 there is an ngPaste directive. Use the following way:

<input type='text' ng-paste='handlePaste($event)'>

To pass the value straightaway, use:

<input type='text' ng-paste='handlePaste($event.clipboardData.getData('text/plain'))'>
balkian
  • 103
  • 3
Websirnik
  • 1,332
  • 2
  • 21
  • 33
10

In function you should use originalEvent

 <input type="text" ng-paste="paste($event)" />

Function:

$scope.paste = function (e) {
    console.log(e.originalEvent.clipboardData.getData('text/plain'));
}
Levsha
  • 374
  • 2
  • 15
5

Wanted to share my solution to support browsers without clipboard API. This should work on any browser that angular supports.

HTML:

<input type="text" ng-paste="copyPasted($event)">

JS:

$scope.copyPasted = function ($event){
    if(typeof $event.originalEvent.clipboardData !== "undefined"){
        $scope.handlePastedData($event.originalEvent.clipboardData.getData('text/plain'));
    } else { // To support browsers without clipboard API (IE and older browsers)
        $timeout(function(){
            $scope.handlePastedData(angular.element($event.currentTarget).val());
        });
    }
};
Firze
  • 3,283
  • 4
  • 41
  • 58
2

I have implemented this solution to sanitize the pasted text with a custom filter with respect of the current input selection (also supported by IE11)

JS:

vm.pasteInput = pasteInput;

function pasteInput(ev){
  var pastedData ='';
  var domElement = ev.currentTarget;

  if(typeof ev.originalEvent.clipboardData !== "undefined"){
    pastedData = ev.originalEvent.clipboardData.getData('text/plain');
  } else if(window.clipboardData){
    pastedData = window.clipboardData.getData('Text');
    ev.returnValue = false;
  }

  pastedData = $filter('inputtext')(pastedData);

  // inject in correct position between selection
  if (document.selection) { // IE11
    domElement.focus();
    var sel = document.selection.createRange();
    sel.text = pastedData;
    domElement.focus();
  } else if (domElement.selectionStart || domElement.selectionStart === 0){
    var startPos = domElement.selectionStart;
    var endPos = domElement.selectionEnd;
    domElement.value = domElement.value.substring(0, startPos) + pastedData + domElement.value.substring(endPos, domElement.value.length);
    domElement.focus();
    domElement.selectionStart = startPos + pastedData.length;
    domElement.selectionEnd = startPos + pastedData.length;
  } else {
    domElement.value += pastedData;
    domElement.focus();
  }

  ev.stopPropagation();
  ev.preventDefault();

  // update model
  vm.input.value = domElement.value;

}

HTML:

<input type="text" ng-model="vm.input.value" ng-paste="vm.pasteInput($event)" />
Ron Jonk
  • 363
  • 2
  • 7