55

Is there a way to intercept the paste event in JavaScript and get the raw value, change it, and set the associated DOM element's value to be the modified value?

For instance, I have a user trying to copy and paste a string with spaces in it and the string's length exceeds the max length of my text box. I want to intercept the text, remove the spaces, and then set the text box's value with the change value.

Is this possible?

mikemaccana
  • 81,787
  • 73
  • 317
  • 396
Brandon
  • 9,812
  • 15
  • 59
  • 95
  • 1
    Sure, e.g. http://stackoverflow.com/questions/2242442/to-take-events-on-pasting-some-texts-on-text-area. Or: http://jsfiddle.net/6skZQ/. – pimvdb May 17 '11 at 18:02
  • @pimvdb: Your jsFiddle example doesn't work in Firefox, IE or Opera. – Tim Down May 17 '11 at 23:53
  • @Tim Down: Thanks for noticing, cross-browser clipboard funcionality seems to be a pain. – pimvdb May 19 '11 at 18:33

4 Answers4

82

You can intercept the paste event by attaching an "onpaste" handler and get the pasted text by using "window.clipboardData.getData('Text')" in IE or "event.clipboardData.getData('text/plain')" in other browsers.

For example:

var myElement = document.getElementById('pasteElement');
myElement.onpaste = function(e) {
  var pastedText = undefined;
  if (window.clipboardData && window.clipboardData.getData) { // IE
    pastedText = window.clipboardData.getData('Text');
  } else if (e.clipboardData && e.clipboardData.getData) {
    pastedText = e.clipboardData.getData('text/plain');
  }
  alert(pastedText); // Process and handle text...
  return false; // Prevent the default handler from running.
};

As @pimvdb notes, you will need to use "e.originalEvent.clipboardData" if using jQuery.

maerics
  • 133,300
  • 39
  • 246
  • 273
  • When I do the above code in IE, but do the following: `myElement.Value = pastedText.split(' ').join('');` it sets the value to the originally pasted value. Any ideas? I added this check `alert(myElement.Value);` and am returning true and the value looks correct in my alert, but does not show up correct on my page. – Brandon May 17 '11 at 18:43
  • 1
    By returning "true" you are allowing the default "paste" handler to occur after your own handler, which will just paste the text without any of your custom processing. Returning "false" prevents the default paste handler from running (which is why I did so in my example). – maerics May 17 '11 at 18:54
  • 4
    It looks like [Firefox doesn't allow clipboard operations](http://stackoverflow.com/questions/127040/copy-put-text-on-the-clipboard-with-firefox-safari-and-chrome)... – maerics May 17 '11 at 18:55
  • The question @maerics linked to refers to setting clipboard data which Firefox doesn't allow. Reading clipboard data from a paste event works as shown in the answer, although not in older versions of FF. – Benjineer Mar 31 '15 at 00:46
  • What is the browser support for this? – www139 Oct 10 '15 at 00:25
  • 7
    For those who, like me, were looking for the final piece of the puzzle "set the text box's value with the parsed value.", I used the following to do the final paste "document.execCommand("insertText", false, pastedText);" – Christopher Alun Lewis Nov 17 '16 at 15:42
  • @ChristopherAlunLewis you could also symply `return true` at the end. – Veve Apr 13 '17 at 08:18
  • 2
    @Veve that won't work if you perform any kind of manipulation to `pastedText`. Right? – Claudio Apr 28 '17 at 17:32
3

As it happens, I answered a similar question earlier today. In short, you need a hack to redirect the caret to an off-screen textarea when the paste event fires.

Community
  • 1
  • 1
Tim Down
  • 292,637
  • 67
  • 429
  • 506
1
$(document).ready(function() {
    $("#editor").bind('paste', function (e){
        $(e.target).keyup(getInput);
    });

    function getInput(e){
        var inputText = $(e.target).val();
        alert(inputText);
        $(e.target).unbind('keyup');
    }
});
Cyrus
  • 1,913
  • 2
  • 17
  • 34
1

I needed to implement a "trim" on whatever was pasted (remove all leading and trailing whitespace) while still allowing the use of the spacebar.

For Ctrl+V, Shift+Insert and mouse right-click Paste, here is what I found worked in FF, IE11 and Chrome as of 2017-04-22:

$(document).ready(function() {
    var lastKeyCode = 0;

    $('input[type="text"]').bind('keydown', function(e) {
        lastKeyCode = e.keyCode;
    });
    // Bind on the input having changed.  As long as the previous character
    // was not a space, BS or Del, trim the input.
    $('input[type="text"]').bind('input', function(e) {
        if(lastKeyCode != 32 && lastKeyCode != 8 && lastKeyCode != 46) {
            $(this).val($(this).val().replace(/^\s+|\s+$/g, ''));
        }
    });
});

Two caveats:

  1. If there is already text when the paste occurs, trimming occurs on the entire result, not just what it being pasted.

  2. If the user types space or BS or Del and then pastes, trimming will not occur.

Craig Silver
  • 443
  • 3
  • 22