Catch paste input

JqueryPasteSanitize

Jquery Problem Overview


I'm looking for a way to sanitize input that I paste into the browser, is this possible to do with jQuery?

I've managed to come up with this so far:

$(this).live(pasteEventName, function(e) {
 // this is where i would like to sanitize my input
 return false;
}

Unfortunately my development has come to a screeching hold because of this "minor" issue. I would really make me a happy camper if someone could point me to the right direction.

Jquery Solutions


Solution 1 - Jquery

OK, just bumped into the same issue.. I went around the long way

$('input').on('paste', function () {
  var element = this;
  setTimeout(function () {
    var text = $(element).val();
    // do something with text
  }, 100);
});

Just a small timeout till .val() func can get populated.

E.

Solution 2 - Jquery

You can actually grab the value straight from the event. Its a bit obtuse how to get to it though.

Return false if you don't want it to go through.

$(this).on('paste', function(e) {

  var pasteData = e.originalEvent.clipboardData.getData('text')
  
});

Solution 3 - Jquery

For cross platform compatibility, it should handle oninput and onpropertychange events:

$ (something).bind ("input propertychange", function (e) {
    // check for paste as in example above and
    // do something
})

Solution 4 - Jquery

I sort of fixed it by using the following code:

$("#editor").live('input paste',function(e){
	if(e.target.id == 'editor') {
		$('<textarea></textarea>').attr('id', 'paste').appendTo('#editMode');
		$("#paste").focus();
		setTimeout($(this).paste, 250);
	}
});

Now I just need to store the caret location and append to that position then I'm all set... I think :)

Solution 5 - Jquery

Hmm... I think you can use e.clipboardData to catch the data being pasted. If it doesn't pan out, have a look here.

$(this).live("paste", function(e) {
    alert(e.clipboardData); // [object Clipboard]
});

Solution 6 - Jquery

Listen for the paste event and set a keyup event listener. On keyup, capture the value and remove the keyup event listener.

$('.inputTextArea').bind('paste', function (e){
	$(e.target).keyup(getInput);
});
function getInput(e){
	var inputText = $(e.target).val();
	$(e.target).unbind('keyup');
}

Solution 7 - Jquery

$("#textboxid").on('input propertychange', function () {
    //perform operation
        });

It will work fine.

Solution 8 - Jquery

This is getting closer to what you might want.

function sanitize(s) {
  return s.replace(/\bfoo\b/g, "~"); 
};

$(function() {
 $(":text, textarea").bind("input paste", function(e) {
   try {
     clipboardData.setData("text",
       sanitize(clipboardData.getData("text"))
     );
   } catch (e) {
     $(this).val( sanitize( $(this).val() ) );
   }
 });
});

Please note that when clipboardData object is not found (on browsers other then IE) you are currently getting the element's full value + the clipboard'ed value.

You can probably do some extra steps to dif the two values, before an input & after the input, if you really are only after what data was truly pasted into the element.

Solution 9 - Jquery

 $('').bind('input propertychange', function() {....});                      

This will work for mouse paste event.

Solution 10 - Jquery

How about comparing the original value of the field and the changed value of the field and deducting the difference as the pasted value? This catches the pasted text correctly even if there is existing text in the field.

http://jsfiddle.net/6b7sK/

function text_diff(first, second) {
    var start = 0;
    while (start < first.length && first[start] == second[start]) {
        ++start;
    }
    var end = 0;
    while (first.length - end > start && first[first.length - end - 1] == second[second.length - end - 1]) {
        ++end;
    }
    end = second.length - end;
    return second.substr(start, end - start);
}
$('textarea').bind('paste', function () {
    var self = $(this);
    var orig = self.val();
    setTimeout(function () {
        var pasted = text_diff(orig, $(self).val());
        console.log(pasted);
    });
});

Solution 11 - Jquery

This code is working for me either paste from right click or direct copy paste

   $('.textbox').on('paste input propertychange', function (e) {
		$(this).val( $(this).val().replace(/[^0-9.]/g, '') );
	})

When i paste Section 1: Labour Cost it becomes 1 in text box.

To allow only float value i use this code

 //only decimal
	$('.textbox').keypress(function(e) {
		if(e.which == 46 && $(this).val().indexOf('.') != -1) {
	        e.preventDefault();
	    } 
	   if (e.which == 8 || e.which == 46) {
	        return true;
	   } else if ( e.which < 48 || e.which > 57) {
	    	e.preventDefault();
	  }
	});

Solution 12 - Jquery

See this example: http://www.p2e.dk/diverse/detectPaste.htm

It essentialy tracks every change with oninput event and then checks if it’s a paste by string comparison. Oh, and in IE there’s an onpaste event. So:

$ (something).bind ("input paste", function (e) {
    // check for paste as in example above and
    // do something
})

Solution 13 - Jquery

document.addEventListener('paste', function(e){
    if(e.clipboardData.types.indexOf('text/html') > -1){
        processDataFromClipboard(e.clipboardData.getData('text/html'));
        e.preventDefault();

        ...
    }
});

Further:

Solution 14 - Jquery

This method uses jqueries contents().unwrap().

  1. First, detect the paste event

  2. Add a unique class to the tags that are already in the element into which we are pasting.

  3. After a given timeout scan through all the contents unwrapping tags that don't have the class that you set earlier. Note: This method does not remove self closing tags like
    See an example below.

    //find all children .find('*') and add the class .within .addClass("within") to all tags
    $('#answer_text').find('*').each(function () {
    $(this).addClass("within");
    });
    setTimeout(function() {
    $('#answer_text').find('*').each(function () {
    	//if the current child does not have the specified class unwrap its contents
    	$(this).not(".within").contents().unwrap();
    });
    }, 0);
    

Solution 15 - Jquery

Script to remove special characters from all fields with class portlet-form-input-field:

// Remove special chars from input field on paste
jQuery('.portlet-form-input-field').bind('paste', function(e) {
    var textInput = jQuery(this);
    setTimeout(function() {
        textInput.val(replaceSingleEndOfLineCharactersInString(textInput.val()));
    }, 200);
});

function replaceSingleEndOfLineCharactersInString(value) {
    <%
        // deal with end-of-line characters (\n or \r\n) that will affect string length calculation,
        // also remove all non-printable control characters that can cause XML validation errors
    %>
    if (value != "") {
        value = value.replace(/(\x00|\x01|\x02|\x03|\x04|\x05|\x06|\x07|\x08|\x0B|\x0C|\x0E|\x0F|\x10|\x11|\x12|\x13|\x14|\x15|\x16|\x17|\x18|\x19|\x1A|\x1B|\x1C|\x1D|\x1E|\x1F|\x7F)/gm,'');
        return value = value.replace(/(\r\n|\n|\r)/gm,'##').replace(/(\#\#)/gm,"\r\n");
    }
}


Solution 16 - Jquery

This proved to be quite illusive. The value of the input is not updated prior to the execution of the code inside the paste event function. I tried calling other events from within the paste event function but the input value is still not updated with the pasted text inside the function of any events. That is all events apart from keyup. If you call keyup from within the paste event function you can sanitize the pasted text from within the keyup event function. like so...

$(':input').live
(
    'input paste',
    function(e)
    {
        $(this).keyup();
    }
);

$(':input').live
(
    'keyup',
    function(e)
    {
	    // sanitize pasted text here
    }
);

There is one caveat here. In Firefox, if you reset the input text on every keyup, if the text is longer than the viewable area allowed by the input width, then resetting the value on every keyup breaks the browser functionality that auto scrolls the text to the caret position at the end of the text. Instead the text scrolls back to the beginning leaving the caret out of view.

Solution 17 - Jquery

> There is one caveat here. In Firefox, if you reset the input text on every keyup, if the text is longer than the viewable area allowed by the input width, then resetting the value on every keyup breaks the browser functionality that auto scrolls the text to the caret position at the end of the text. Instead the text scrolls back to the beginning leaving the caret out of view.

function scroll(elementToBeScrolled) 
{
     //this will reset the scroll to the bottom of the viewable area. 
     elementToBeScrolled.topscroll = elementToBeScrolled.scrollheight;
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionChristoffer WinterkvistView Question on Stackoverflow
Solution 1 - JqueryEvgeni DimovView Answer on Stackoverflow
Solution 2 - JqueryCharles HaroView Answer on Stackoverflow
Solution 3 - JqueryXue LiangliangView Answer on Stackoverflow
Solution 4 - JqueryChristoffer WinterkvistView Answer on Stackoverflow
Solution 5 - JquerymoffView Answer on Stackoverflow
Solution 6 - JqueryEricView Answer on Stackoverflow
Solution 7 - JqueryRajat JainView Answer on Stackoverflow
Solution 8 - JqueryMister LuckyView Answer on Stackoverflow
Solution 9 - JqueryAbhiramView Answer on Stackoverflow
Solution 10 - JqueryAlo SarvView Answer on Stackoverflow
Solution 11 - JqueryRN KushwahaView Answer on Stackoverflow
Solution 12 - JqueryIlya BirmanView Answer on Stackoverflow
Solution 13 - JquerydavidcondreyView Answer on Stackoverflow
Solution 14 - JqueryShadrack B. OrinaView Answer on Stackoverflow
Solution 15 - JqueryAlex the cookView Answer on Stackoverflow
Solution 16 - JqueryJames TindallView Answer on Stackoverflow
Solution 17 - JquerylordcheetoView Answer on Stackoverflow