How to manipulate clipboard data using jquery in chrome, IE 8&9? - javascript

This is my jquery code that I am using to truncate the pasted text, so that it doesn't exceed the maxlength of an element. The default behaviour on Chrome is to check this automatically but in IE 8 and 9 it pastes the whole text and doesn't check the maxLength of an element. Please help me to do this. This is my first time asking a question here, so please let me know if I need to provide some more details. Thanks.
<script type="text/javascript">
//var lenGlobal;
var maxLength;
function doKeypress(control) {
maxLength = control.attributes["maxLength"].value;
value = control.value;
if (maxLength && value.length > maxLength - 1) {
event.returnValue = false;
maxLength = parseInt(maxLength);
}
}
//function doBeforePaste(control) {
//maxLength = control.attributes["maxLength"].value;
//if (maxLength) {
// event.returnValue = false;
//var v = control.value;
//lenGlobal = v.length;
// }
// }
$(document).on("focus","input[type=text],textarea",function(e){
var t = e.target;
maxLength = parseInt($(this).attr('maxLength'));
if(!$(t).data("EventListenerSet")){
//get length of field before paste
var keyup = function(){
$(this).data("lastLength",$(this).val().length);
};
$(t).data("lastLength", $(t).val().length);
//catch paste event
var paste = function(){
$(this).data("paste",1);//Opera 11.11+
};
//process modified data, if paste occured
var func = function(){
if($(this).data("paste")){
var dat = this.value.substr($(this).data("lastLength"));
//alert(this.value.substr($(this).data("lastLength")));
// alert(dat.substr(0,4));
$(this).data("paste",0);
//this.value = this.value.substr(0,$(this).data("lastLength"));
$(t).data("lastLength", $(t).val().length);
if (dat == ""){
this.value = $(t).val();
}
else
{
this.value = dat.substr(0,maxLength);
}
}
};
if(window.addEventListener) {
t.addEventListener('keyup', keyup, false);
t.addEventListener('paste', paste, false);
t.addEventListener('input', func, false);
} else{//IE
t.attachEvent('onkeyup', function() {keyup.call(t);});
t.attachEvent('onpaste', function() {paste.call(t);});
t.attachEvent('onpropertychange', function() {func.call(t);});
}
$(t).data("EventListenerSet",1);
}
});
</script>

You could do something like this, mind you this was done in YUI but something simlar can be done for jquery. All you need to do is get the length of the comment that was entered and then truncate the text down the the desired length which in the case of this example is 2000 characters.
comment_text_box.on('valuechange', function(e) {
//Get the comment the user input
var comment_text = e.currentTarget.get('value');
//Get the comment length
var comment_length = comment_text.length;
if(comment_length > 2000){
alert('The comment entered is ' + comment_length + ' characters long and will be truncated to 2000 characters.');
//Truncate the comment
var new_comment = comment_text.substring(0, 2000);
//Set the value of the textarea to truncated comment
e.currentTarget.set('value', new_comment);
}
});

You're putting too much effort into something that is apparently a browser quirk and is mostly beyond your control and could change in the future. In fact, I can't recreate this in IE10 - it behaves just like Chrome for me.
Make sure you are validating the length on the server-side, since it's still possible to get around a field's maxlength when submitting the form input to the server (see this somewhat similar question). That's not to say you shouldn't have some client-side logic to validate the length of the input to enforce the maxlength constraint - I just think you don't need to go to the length you are attempting here to essentially intercept a paste command. Keep it simple - having a basic length validation check in your JavaScript is going to be a lot less messy than what you have here.
Perhaps consider a bit of jQuery like this:
$("#myTextControl").change(function() {
if ($(this).val().length > $(this).attr('maxlength')) {
DisplayLengthError();
}
});
(where DisplayLengthError() is an arbitrary function that triggers some kind of feedback to the user that they have exceeded the maxlength constraint of the field, be it an error label, and alert box, etc.)

Related

jQuery method that disallows input of certain chars

I'm trying to make a jQuery method that would delete wanted chars from selected elements.
For example:
$("input").disallowChars(/\D/g);// should disallow input of all non-digit elements in input elements
This is how I thought to do it, but it doesn't seem to work:
$.fn.disallowChars = function(regexp){
this.keyup(function(){
var value = $(this).val();
value.replace(regexp, "");
$(this).val(value);
});
return this;
};
$("input").disallowChars(/\D/g);
I'm a total newbie at this, how can I make it work.
Thanks
You could use String.fromCharCode() and keypress event instead:
$.fn.disallowChars = function(regexp){
return this.keypress(function(e){
if(String.fromCharCode(e.which).match(regexp)) return false;
});
};
DEMO
BUT doesn't disable any characters to be paste in input using mouse or paste keyboard shortcut.
On modern browsers, you could use input event, or change keyup paste mouseup (ya mouseup, to handle dropped text too):
$.fn.disallowChars = function(regexp){
return this.on('input', function(){
this.value = this.value.replace(regexp, '');
});
};
BUT then once input value is replaced, text carret is put in end (or start depending browser behaviour) of string input.
DEMO
heres a handy routine I use to sanitize some input fields in a current project:
// REPLACE SELECTOR WITH YOUR ID(S) OR SELECTORS...
$('input').bind("change keyup", function() {
var val = $.trim($(this).val());
// READ UP ON REGEX TO UNDERSTAND WHATS GOING ON HERE... ADD CHARACTERS YOU WANT TO ELIMINATE...
var regex = /[":'/\+;<>&\\/\n]/g;
if (val.match(regex)) {
val = val.replace(regex, "");
$(this).val($.trim(val));
}
});
Heres another version I used recently:
$("#myField").on("keypress", function(event) {
// THIS ONLY ALLOWS A-Z, A-Z, 0-9 AND THE # SYMBOL... just change stuffToAllow to suit your needs
var stuffToAllow = /[A-Za-z0-9# ]/g;
var key = String.fromCharCode(event.which);
if (event.keyCode == 8 || event.keyCode == 37 || event.keyCode == 39 || stuffToAllow.test(key)) {
return true;
}
alert( key + ' character not allowed!');
return false;
});

Sliding down label depending on time difference

So I have two time fields, timeFrom and timeTo. What I want to do is get a label sliding down if the time difference is equal or greater than 2. But I can't figure out what I'm doing wrong here. Here's my code:
$(document).ready(function() {
$("#timeTo").change(function()) {
var timeTo = $("#timeTo").val();
var timeFrom = $("#timeFrom").val();
var diff = timeTo - timeFrom;
if (diff >= 2){
$("#cost_label").slideDown();
}
else{
$("#cost_label").slideUp();
}
});
$("#cost_label").hide();
$("#timeTo").trigger("change");
});
Try
$(document).ready(function () {
$("#timeTo").on('input', function () {
var timeTo = $("#timeTo").val();
var timeFrom = $("#timeFrom").val();
var diff = parseFloat(timeTo) - parseFloat(timeFrom);
alert(diff);
if (diff >= 2) {
$("#cost_label").slideDown({
complete: function () {
$("#cost_label").hide();
}
});
} else {
$("#cost_label").slideUp({
complete: function () {
$("#cost_label").hide();
}
});
}
});
});
Your label is to hide when the animation completes so it doesn't hide immediately
Strings read as integers, because you can't subtract Strings
on('input') instead of on(change), this is the right way to detect textfield changes
Removed parenthesis after anonymous function declaration, that was a syntax error ;)
You can always debug your problems and use logic to fix these issues.
Somewhat-working Demo
You may not need the + to typecast values and may not need to Math.abs if you're using type="number" inputs with sensible min/max limits.
The 'keyup' event will fire when a key goes from down to up position, so you will not need to unfocus (click or tab away from) the input box. You can also use 'keydown' too, if you're too eager to wait, and don't mind events that fire every 14 milliseconds when the user falls asleep on the keyboard.
Use the $.on instead of the event-named methods so that you can listen for multiple events (as a space separated list) and listen for the event on both inputs (selectors need comma separated list).
$(function(){
$('#cost_label').hide();
$('#timeFrom,#timeTo').on('keyup change', timeChange);
function timeChange(){
var from = +$('#timeFrom').val();
var to = +$('#timeTo').val();
if(Math.abs(to - from) >= 2)
$('#cost_label').slideDown();
else $('#cost_label').slideUp();
}
timeChange();
});
http://jsfiddle.net/LDB5X/ using input type="text"
http://jsfiddle.net/6M5V6/ using input type="number" (might not work in all browsers)
What is this 'input' event? I can't find it in the jquery docs

autosuggestion box, set focus

Been knocking up a simple suggestion box on an input field.. all working as it should so far except for two issues I can't seem to resolve:
1) when onkeypress event fires, the value of the input box is not correct - it misses off the last character! So for e.g. if you enter 3 chars only first two get carried through. so sometimes suggestions aren't totally accurate!
2) I need to watch out for users pressing the arrow down key, and then set focus to the first list item in the suggestion box! Can't seem to get this working though!
Have included code for you to look at! Any suggestions welcomed.. However I don't really want to use a plugin seeing as I have this 95% done already..
Here is the jsfiddle link!
http://jsfiddle.net/beardedSi/kr4Cq/
Note - I just noticed that in the fiddle verison as I have put dummy array in the code it is no longer matching suggestions - but this doesn't matter, it works fine in my working code!
work = true;
function finish() {
work = true;
}
var autoComp = $('.autoComp');
var skillInput = $('.new-skills input');
$('.new-skills input').keypress(function (e) {
var param = $(skillInput).val();
if (param.length > 0) {
$.getJSON('/recruiter/home/GetAutocompleteSkills?term=' + param, function (data) {
$(autoComp).slideDown().empty();
var items = [];
$.each(data, function (key, val) {
items.push('<li>' + val + '</li>');
});
$(autoComp).append(items.join(''));
$('.base-wrapper a').not('.button').click(function (e) {
work = false;
e.preventDefault();
$(skillInput).val($(this).text());
$(autoComp).empty().slideUp(500, finish);
});
});
}
});
$(skillInput).keydown(function (e) {
if (e.keyCode == 40) {
console.log("down");
$('.autoComp li:first:child').focus();
}
});
$('.new-skills input').blur(function () {
if (work == true)
$(autoComp).slideUp();
});

Invoke a function after right click paste in jQuery

I know we can use bind paste event as below:
$('#id').bind('paste', function(e) {
alert('pasting!')
});
But the problem is, that it will call before the pasted text paste. I want a function to be triggered after the right click -> paste text pasted on the input field, so that I can access the pasted value inside the event handler function.
.change() event also doesn't help. Currently I use .keyup() event, because I need to show the remaining characters count while typing in that input field.
Kind of a hack, but:
$("#id").bind('paste', function(e) {
var ctl = $(this);
setTimeout(function() {
//Do whatever you want to $(ctl) here....
}, 100);
});
Why not use the "input" event?
$("#id").bind('input', function(e) {
var $this = $(this);
console.log($this.val());
});
This will stop user from any pasting, coping or cutting with the keyboard:
$("#myField").keydown(function(event) {
var forbiddenKeys = new Array('c', 'x', 'v');
var keyCode = (event.keyCode) ? event.keyCode : event.which;
var isCtrl;
isCtrl = event.ctrlKey
if (isCtrl) {
for (i = 0; i < forbiddenKeys.length; i++) {
if (forbiddenKeys[i] == String.fromCharCode(keyCode).toLowerCase()) {
return false;
}
}
}
return true;
});
This one will do the same for the mouse events:
$("#myField").bind("cut copy paste",function(event) {
event.preventDefault();
});
Even though the above one will not prevent right clicks, the user will not be able to paste, cut or copy from that field.
To use it after the event, like you wondered on your question, you must use JavaScript Timing Event
setTimeout(function() {
// your code goes here
}, 10);
I had the same issue, I opted to replicate the paste action through javascript and use that output instead:
var getPostPasteText = function (element, pastedData) {
// get the highlighted text (if any) from the element
var selection = getSelection(element);
var selectionStart = selection.start;
var selectionEnd = selection.end;
// figure out what text is to the left and right of the highlighted text (if any)
var oldText = $(element).val();
var leftPiece = oldText.substr(0, selectionStart);
var rightPiece = oldText.substr(selectionEnd, oldText.length);
// compute what the new value of the element will be after the paste
// note behavior of paste is to REPLACE any highlighted text
return leftPiece + pastedData + rightPiece;
};
See IE's document.selection.createRange doesn't include leading or trailing blank lines for source of the getSelection function.
No need to bind :
$(document).on('keyup input', '#myID', function () {
//Do something
});

JS filter textbox input

I hope this isn't a daft question. I expected google to be promising but I failed today.
I have a textbox <input type="text" id="input1" /> that I only want to accept the input /^\d+(\.\d{1,2})?$/. I want to bind something to the keydown event and ignore invalid keys but charCode isn't robust enough. Is there a good jQuery plugin that does this?
The affect I want to achieve is for some one to type 'hello world! 12.345' and want all characters to be ignored except '12.34' and the textbox to read '12.34'. Hope this is clear.
Thanks.
I don't think you need a plugin to do this; you could easily attach an event and write a simple callback to do it yourself like so:
$('#input1').keyup(function()
{
// If this.value hits a match with your regex, replace the current
// value with a sanitized value
});
try this:
$('#input1').change(function(){
if($(this).data('prevText') == undefined){
$(this).data('prevText', '');
}
if(!isNaN($(this).val())){
$(this).val($(this).data('prevText'))
}
else {
//now do your regex to check the number settings
$(this).data('prevText', $(this).val());
}
})
the isNAN function checks to make sure the value is a number
$('#input1').bind('keyup', function() {
var val = $(this).val();
if(!val)
return;
var match = val.match(/^\d+(\.\d{1,2})?$/);
if(!match)
return;
//replace the value of the box, or do whatever you want to do with it
$(this).val(match[0]);
});
jQuery Keyfilter
Usage:
$('#ggg').keyfilter(/[\dA-F]/);
It also supports some pre-made filters that you can assign as a css class.
You should look at jQuery validation. You can define your own checking methods like this here.
$('input1').keyup(function(){
var val = $(this).val().match(/\d+([.]\d{1,2})?/);
val = val == null || val.length == 0 ? "" : val[0];
$(this).val(val);
});
I found the solution.
Cache the last valid input on keydown event
Rollback to last valid input on keyup event if invalid input detected
Thus:
var cache = {};
$(function() {
$("input[regex]").bind("keydown", function() {
var regex = new RegExp($(this).attr("regex"));
if (regex.test($(this).val())) {
cache[$(this).attr("id")] = $(this).val();
}
});
$("input[regex]").bind("keyup", function() {
var regex = new RegExp($(this).attr("regex"));
if (!regex.test($(this).val())) {
$(this).val(cache[$(this).attr("id")]);
}
});
});

Categories

Resources