Search code examples
javascripteventstextareapaste

javascript catch paste event in textarea


I currently have a textarea which I requires control over text that has been pasted in,

essentially I need to be able to take whatever the user wants to paste into a textarea and place it into a variable.

I will then work out the position in which they pasted the text and the size of the string to remove it from the textarea,

Then at the end deal with the text thats is in the variable in my own way.

My question: how would I go about getting a copy of the text in a variable that was just pasted in by the user?

Thanks.


Solution

  • I answered a similar question a few days ago: Detect pasted text with ctrl+v or right click -> paste. This time I've included quite a long function that accurately gets selection boundaries in textarea in IE; the rest is relatively simple.

    You can use the paste event to detect the paste in most browsers (notably not Firefox 2 though). When you handle the paste event, record the current selection, and then set a brief timer that calls a function after the paste has completed. This function can then compare lengths to know where to look for the pasted content. Something like the following:

    function getSelectionBoundary(el, start) {
        var property = start ? "selectionStart" : "selectionEnd";
        var originalValue, textInputRange, precedingRange, pos, bookmark, isAtEnd;
    
        if (typeof el[property] == "number") {
            return el[property];
        } else if (document.selection && document.selection.createRange) {
            el.focus();
    
            var range = document.selection.createRange();
            if (range) {
                // Collapse the selected range if the selection is not a caret
                if (document.selection.type == "Text") {
                    range.collapse(!!start);
                }
    
                originalValue = el.value;
                textInputRange = el.createTextRange();
                precedingRange = el.createTextRange();
                pos = 0;
    
                bookmark = range.getBookmark();
                textInputRange.moveToBookmark(bookmark);
    
                if (/[\r\n]/.test(originalValue)) {
                    // Trickier case where input value contains line breaks
    
                    // Test whether the selection range is at the end of the
                    // text input by moving it on by one character and
                    // checking if it's still within the text input.
                    try {
                        range.move("character", 1);
                        isAtEnd = (range.parentElement() != el);
                    } catch (ex) {
                        log.warn("Error moving range", ex);
                        isAtEnd = true;
                    }
                    range.moveToBookmark(bookmark);
    
                    if (isAtEnd) {
                        pos = originalValue.length;
                    } else {
                        // Insert a character in the text input range and use
                        // that as a marker
                        textInputRange.text = " ";
                        precedingRange.setEndPoint("EndToStart", textInputRange);
                        pos = precedingRange.text.length - 1;
    
                        // Delete the inserted character
                        textInputRange.moveStart("character", -1);
                        textInputRange.text = "";
                    }
                } else {
                    // Easier case where input value contains no line breaks
                    precedingRange.setEndPoint("EndToStart", textInputRange);
                    pos = precedingRange.text.length;
                }
                return pos;
            }
        }
        return 0;
    }
    
    function getTextAreaSelection(textarea) {
        var start = getSelectionBoundary(textarea, true),
            end = getSelectionBoundary(textarea, false);
    
        return {
            start: start,
            end: end,
            length: end - start,
            text: textarea.value.slice(start, end)
        };
    }
    
    function detectPaste(textarea, callback) {
        textarea.onpaste = function() {
            var sel = getTextAreaSelection(textarea);
            var initialLength = textarea.value.length;
            window.setTimeout(function() {
                var val = textarea.value;
                var pastedTextLength = val.length - (initialLength - sel.length);
                var end = sel.start + pastedTextLength;
                callback({
                    start: sel.start,
                    end: end,
                    length: pastedTextLength,
                    text: val.slice(sel.start, end),
                    replacedText: sel.text
                });
            }, 1);
        };
    }
    
    window.onload = function() {
        var textarea = document.getElementById("your_textarea");
        detectPaste(textarea, function(pasteInfo) {
            var val = textarea.value;
    
            // Delete the pasted text and restore any previously selected text
            textarea.value = val.slice(0, pasteInfo.start) +
                pasteInfo.replacedText + val.slice(pasteInfo.end);
    
            alert(pasteInfo.text);
        });
    };