Paste event not functioning properly in Opera 11 and lower versions - javascript

I am trying out this simple code which is supposed to shift the focus to another text box when a right click is detected on the first, so that any subsequent paste event makes the text to be pasted into the 2nd box:
<!DOCTYPE html>
<html>
<head>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script>
$(document).ready(function() {
$("#real").bind("contextmenu",function() {
$("#paste").focus();
});
});
</script>
</head>
<body>
<input type = 'text' sh = '0' right = '0' id = 'real' />
<input type = 'text' id = 'paste' />
<p>Dummy</p>
</html>
In Opera above versions 12, it is working fine. However, in 11 and below, even though the focus does get shifted to the 2nd text box on right clicking on the first, the paste event pastes the text in the first textbox (with the focus being shifted to the 2nd textbox immediately, on its own). I tried to replace the code by setTimeout(function() { $("#paste").focus(); },0);, still the error persists.
Can anyone tell me how do I fix this, so that the text gets pasted in the 2nd textbox? (Detecting a mouseup, checking whether it's a right click through event.which, if so, shift the focus - yeah, I did that too, same result!)

As an alternative solution...
$("#real").bind("contextmenu",function() {
$("#paste").val($(this).val());
$(this).val('');
});

Related

Javascript CTRL-C is triggered in <textarea>

Sorry, I am not a very best Javascript-programmer, but I am making a homepage for my website ( http://coins.kalf999.com/menu.php) and I was producing some code, but I was suprised it did not work untill....now!
But I still not understand why....
Who can help me..?
I made some small code to show the difference.
In the 1st textarea I can copy some text, press CTRL-C, which hides the textarea and you can test the contents of the clipboard in the 2nd textarea. I use a 1 millescond setTimeout-function, which works !
My old code was the second example:
In the 3rd textarea I can copy some text again, press CTRL-C, which hides the textarea and test the contents of the clipboard in the 4rd textarea.
I not use setTimeout-function, which , obviously, not works !
I can not imagine that a "hidden" object is creating a malfunction for a Copy-command.....
What happens over here...? ;(
I made test-program called tst.html and tst.js
<html>
<head>
<script type="text/javascript" src="tst.js"></script>
</head>
<body>
<div id = "box1"></div>
<div id = "testarea1"></div>
<div id = "box2"></div>
<div id = "testarea2"></div>
<script>
document.getElementById("box1").innerHTML= '<textarea rows="4" onkeypress="CTRLC1(event)">Select some text and copy with CTRL-C.The <textarea> becomes hidden.</textarea>';
document.getElementById("testarea1").innerHTML= '<textarea rows="4" ">Paste text with CTRL-V</textarea>';
document.getElementById("box2").innerHTML= '<textarea rows="4" onkeypress="CTRLC2(event)">Select some text and copy with CTRL-C.The <textarea> becomes hidden.</textarea>';
document.getElementById("testarea2").innerHTML= '<textarea rows="4" ">Paste text with CTRL-V</textarea>';
</script>
</body>
</html>
and the JS-file test.js
function CTRLC1(event) {
if (event.ctrlKey == true){
var x = event.which || event.keyCode;
if (x==99 || x==67){
setTimeout(function(){document.getElementById("box1").style.visibility ="hidden";}, 1);
}
}
}
function CTRLC2(event) {
if (event.ctrlKey == true){
var x = event.which || event.keyCode;
if (x==99 || x==67){
document.getElementById("box2").style.visibility ="hidden";
}
}
}
You should be using onkeydown instead of onkeypress.
In theory, the keydown and keyup events represent keys being pressed or released, while the keypress event represents a character being typed. The implementation of the theory is not same in all browsers. More info: onKeyPress Vs. onKeyUp and onKeyDown
Here is the fiddle: http://jsfiddle.net/lucianmoldovan/g5c0pgwj/3/
Notice that on the second box, though the box gets hidden the text doesn't get copied. I imagine that the element is being hidden before the text gets copied to clipboard. Adding that setTimeout fixes this, even if you set it at 0 milliseconds.

Simulate keypress in Javascript not using jquery

Hi I want to simulate a user clicking on an input box.
script is:
function prepareToScan(){
$("fireRegAdd").focus();
$('fireRegAdd').keypress();
}
and HTML is
<h2>Add a visitor to today's fire register</h2>
<input type="button" onmousedown="prepareToScan()" value="Add Visitor">
<input id="fireRegAdd" name="fireRegAdd">
</div>
I have a barcode scanner which puts the code into the input box but only when it's been "clicked". I've tried .focus() but it needs two scans to get the scan to work. The on focus is not the same as actually clicking in the box. Does any one know how to do that?
thanks
So I've found that if I add in an alert it set it correctly :
function prepareToScan(){
alert("ready to scan");
$("fireRegAdd").focus();
$('fireRegAdd').keypress();
}
but I don't really want an alert box
I've added a demo of the code. When you click on the button I want there to be a blinking cursor in the input box.
function prepareToScan(){
$("#fireRegAdd").focus();
$('#fireRegAdd').click();
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<div>
<h2>Add a visitor to today's fire register</h2>
<input type="button" value ="Add Visitor" onmousedown="prepareToScan()"/>
<input id="fireRegAdd" name="fireRegAdd" value="" />
</div>
I've discovered that it's virtually impossible to focus on an input box so that the curso blinks. I tried everything including manipulating the cursor position and using a click event.
I did however solve my problem. Barcode scanners act like keyboards. So I wrote some code which detects keyboard input. It checks for incoming keys. If it receives more than 3 in 250 ms it assumes that it is coming from the scanner. Works a treat. It'd be easy to modify to adjust for different applications. Here's the javascript code I ended up with. To make it work you need a div with id="barcode" Hope someone finds it useful.
var chars = [];
var pressed = false;
window.addEvent( 'keydown', function( evt ){
//console.log(evt.key);
chars.push(evt.key);
setTimeout(function(){
if (chars.length >= 3) {
var barcode = chars.join("");
$("barcode").value= barcode;
}
chars = [];
pressed = false;
},250);
});

IE issues with 'focus' event

I have an app that must run in IE 7/8(compat). (I know, right?)
The app includes the following functionality....
If I click on a dropdown list, the list checks some values elsewhere and, depending on the number of matches it finds it enables or disables some of the options. I make this happen using the focus event of the dropdown list.
If I run this code in a real browser, it works fine. If I run it in IE7 or 8 with compatibility mode enabled, I have to click the DDL twice; the first time fires my focus event code and the 2nd to get it to drop down.
The markup:
<!DOCTYPE html>
<html>
<head>
<script data-require="jquery#*" data-semver="2.1.1" src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
</head>
<body>
<select id="aa">
<option>A</option>
<option>B</option>
<option>C</option>
<option>D</option>
<option>E</option>
<option>F</option>
<option>G</option>
</select>
<script src="script.js"></script>
</body>
</html>
The JS:
$("#aa").focus(function() {
var countSelectedEvents = 2;
var kids = $("#aa").children("option");
kids.removeAttr("disabled");
kids.removeAttr("title");
if (countSelectedEvents == 0) {
kids.slice(1).attr("disabled", "disabled");
kids.slice(1).attr("title", "This option is only available if one or more Events are selected");
kids.slice(4).attr("title", "This option is only available if exactly ONE Event is selected");
} else if (countSelectedEvents > 1) {
kids.slice(4).attr("disabled", "disabled");
kids.slice(4).attr("title", "This option is only available if exactly ONE Event is selected");
}
return true;
});
For convenience, you can find this code on plnkr. If anyone knows how I can get the DDL to drop open on the first click, I'd love to hear about it.
UPDATE:
This question here on Stack Overflow suggests triggering the focusout event, but that doesn't work either.
UPDATE II
It seems that this is a more generic IE error. It doesn't work in native mod in IE11 either! :-(
You have an extra opening bracket { in your .focus() function event. That's probably breaking your code.
Instead of .focus(function(){{}) , should be .focus(function(){})
(in other words, remove line 2 in your JS example and should be set)

Capture Document-level Paste event without focused Input or Textarea

<!DOCTYPE html>
<html>
<head>
<title>Clipboard Paste Text</title>
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/jqueryui/1.10.3/jquery-ui.min.js"></script>
</head>
<body>
<input type="text" placeholder="paste in here" />
<script type="text/javascript">
/* <![CDATA[ */
$(document, 'input[type="text"]').on('paste', function(event) {
var oEvent = event.originalEvent;
oEvent.preventDefault();
var clipText = '';
if(window.clipboardData){
clipText = window.clipboardData.getData('Text');
}else if(typeof oEvent == 'object' && oEvent.clipboardData){
clipText = oEvent.clipboardData.getData('text/plain');
}
// console.log('Pasted ' + clipText.length + ' characters.');
alert('Pasted ' + clipText.length + ' characters.');
});
/* ]]> */
</script>
</body>
</html>
^ I have this demo code. It binds the paste event on INPUT[TEXT] and DOCUMENT.
In Google Chrome (and Opera 15+), a Ctrl+V with no caret (outside input and textarea) is captured.
In IE and Firefox, a Ctrl+V outside a paste-able object (input and textarea) is not captured.(but binding the document paste event captures paste event for all inputs and textareas.)
Is this proper behavior? Is my JS correct?
I'd like to capture Ctrl+V without a input textbox in all three browsers. I'm using a text input now but I'd like to remove it completely and capture the event at document level, not at input box level. Can it be done?
PS: I need to paste large amounts of text that hog the browser if pasted in a textarea. I'm storing it in a hidden field by capturing the paste event in a inputbox. My current solution works properly but I'm still wondering if I'm missing something or FF and IE will only trigger paste events at input/textarea level.
PPS: I've already used the spellcheck=false and autocomplete=off trick to allow more text pasted... but it still hangs for a bit, and as I don't need it editable, this is a better solution.
PPS: My JS skills are rather rusty (they are more like a JS survival mode) and I have no worries for browser backward compatibility as those who'll use this update often and hard.
Made a jsfiddle: http://jsfiddle.net/ninty9notout/A42UN/
From http://www.w3.org/TR/clipboard-apis/
5.1.3 paste event
The paste event has no default action in a non-editable context, but the event fires regardless.
Chrome uses a lazy paste event, which means that it doesn't check to see if the focused element is an editable content area, which is why the paste event works on the document.
As for firefox and IE, it actually checks the element before letting allowing the paste event to be fired. So basically, you need an content editable element in order for the paste event to work in all browsers.
I played around with using a content editable DIV as the main div on the page and I think it seems to produce the results you are looking for. Forgive me if the answer seems somewhat "hackish".
You can place a contenteditable div as the container div to the rest of your webpage and not allow a user to type into the div by returning false when the user presses a key, unless it's a key for pasting.
Here is a fiddle if you want to see how I did it.
http://jsfiddle.net/NVqQ7/3/
html
<div id="pageDiv" contenteditable><div>other content</div></div>
css
html, body, #pageDiv {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
}
javascript:
$(document).on('paste', function(event){
var oEvent = event.originalEvent;
if (event.preventDefault())
event.preventDefault();
var clipText = '';
if(window.clipboardData){
clipText = window.clipboardData.getData('Text');
}else if(typeof oEvent == 'object' && oEvent.clipboardData){
clipText = oEvent.clipboardData.getData('text/plain');
}
// console.log('Pasted ' + clipText.length + ' characters.');
alert('Pasted ' + clipText.length + ' characters.');
});
$('#pageDiv').keydown(function(e){
if (!event.ctrlKey)
return false;
});
A few notes:
The user still must click on the body of the page in order to activate the paste event. i.e. clicking on the browser by itself may not be enough.
In firfox, you need to set the contenteditable="false" in child divs, otherwise users can add text to those elements.
I had to make the div height and width 100%. If your html and body are not 100% height and width, it will not work in IE.
I had to change the jquery library to a newer version for IE in order for the paste event to work on the document.
Hope this helps

jQuery masked input plugin. select all content when textbox receives focus

This is a followup question to this question:
select all contents of textbox when it receives focus (Javascript or jQuery)
Basically I am using a textbox in conjunction with the jQuery masked input plugin(Edit: Link may no longer point at relevant version)
When the masked input textbox receives focus I want to select all of the contents of that textbox, but it seems as though having this plugin binded to the textbox prevents that. I was just wondering if there was a way around this.
Below is a sample .html page that demonstrates the issue:
<html>
<head>
<title></title>
</head>
<body>
<input id="masktest" type="text" value="01/01/2009" />
<br />
<input id="focustest" type="text" value="on focus will select all contents..." />
<script type="text/javascript" src="http://code.jquery.com/jquery-latest.min.js"></script>
<script type="text/javascript" src="http://jquery-joshbush.googlecode.com/files/jquery.maskedinput-1.2.1.pack.js"></script>
<script type="text/javascript">
$(function() {
$("#masktest").mask("99/99/9999");
// Contents of textboxes will be selected when receiving focus.
$("input[type=text]")
.focus(function() {
$(this).select();
});
});
</script>
</body>
</html>
I'm the author of the Masked Input Plugin for jQuery. I decided that this should be the default behavior for completed masks and I got it into the latest release. You can read the details here
Hey Jon, not too sure about the performance of this, but this should work:
$(function() {
// Contents of textboxes will be selected when receiving focus.
$("input[type=text]")
.focus(function() {
var mask = "99/99/9999";
$(this).unmask(mask).select().mask(mask);
});
});
its working for me in FF3.
$("input[type=text]").focus(function(e) {
var that = this;
setTimeout(function(){$(that).select();},10);
return false;
});
setTimeout will "queue" the select() execution, I was wondering about:
- Ok mask functions do your work THEN I'll select the content. That THEN is where the queue is useful.
Just an idea. I hope it works as expected.
Problem
Defaut value is deleting when focus
Resolve : added little patch code to mask.js file (jquery.maskedinput-1.2.2.min.js)
(function(a){var c=(a.browser.msie?"paste":"input")+".mask";var b=(window.orientation!=undefined);a.mask={definitions:{"9":"[0-9]",a:"[A-Za-z]","*":"[A-Za-z0-9]"}};a.fn.extend({caret:function(e,f){if(this.length==0){return}if(typeof e=="number"){f=(typeof f=="number")?f:e;return this.each(function(){if(this.setSelectionRange){this.focus();this.setSelectionRange(e,f)}else{if(this.createTextRange){var g=this.createTextRange();g.collapse(true);g.moveEnd("character",f);g.moveStart("character",e);g.select()}}})}else{if(this[0].setSelectionRange){e=this[0].selectionStart;f=this[0].selectionEnd}else{if(document.selection&&document.selection.createRange){var d=document.selection.createRange();e=0-d.duplicate().moveStart("character",-100000);f=e+d.text.length}}return{begin:e,end:f}}},unmask:function(){return this.trigger("unmask")},mask:function(j,d){if(!j&&this.length>0){var f=a(this[0]);var g=f.data("tests");return a.map(f.data("buffer"),function(l,m){return g[m]?l:null}).join("")}d=a.extend({placeholder:"_",completed:null},d);var k=a.mask.definitions;var g=[];var e=j.length;var i=null;var h=j.length;a.each(j.split(""),function(m,l){if(l=="?"){h--;e=m}else{if(k[l]){g.push(new RegExp(k[l]));if(i==null){i=g.length-1}}else{g.push(null)}}});return this.each(function(){var ORJ=$(this).val();var r=a(this);var m=a.map(j.split(""),function(x,y){if(x!="?"){return k[x]?d.placeholder:x}});var n=false;var q=r.val();r.data("buffer",m).data("tests",g);function v(x){while(++x<=h&&!g[x]){}return x}function t(x){while(!g[x]&&--x>=0){}for(var y=x;y<h;y++){if(g[y]){m[y]=d.placeholder;var z=v(y);if(z<h&&g[y].test(m[z])){m[y]=m[z]}else{break}}}s();r.caret(Math.max(i,x))}function u(y){for(var A=y,z=d.placeholder;A<h;A++){if(g[A]){var B=v(A);var x=m[A];m[A]=z;if(B<h&&g[B].test(x)){z=x}else{break}}}}function l(y){var x=a(this).caret();var z=y.keyCode;n=(z<16||(z>16&&z<32)||(z>32&&z<41));if((x.begin-x.end)!=0&&(!n||z==8||z==46)){w(x.begin,x.end)}if(z==8||z==46||(b&&z==127)){t(x.begin+(z==46?0:-1));return false}else{if(z==27){r.val(q);r.caret(0,p());return false}}}function o(B){if(n){n=false;return(B.keyCode==8)?false:null}B=B||window.event;var C=B.charCode||B.keyCode||B.which;var z=a(this).caret();if(B.ctrlKey||B.altKey||B.metaKey){return true}else{if((C>=32&&C<=125)||C>186){var x=v(z.begin-1);if(x<h){var A=String.fromCharCode(C);if(g[x].test(A)){u(x);m[x]=A;s();var y=v(x);a(this).caret(y);if(d.completed&&y==h){d.completed.call(r)}}}}}return false}function w(x,y){for(var z=x;z<y&&z<h;z++){if(g[z]){m[z]=d.placeholder}}}function s(){return r.val(m.join("")).val()}function p(y){var z=r.val();var C=-1;for(var B=0,x=0;B<h;B++){if(g[B]){m[B]=d.placeholder;while(x++<z.length){var A=z.charAt(x-1);if(g[B].test(A)){m[B]=A;C=B;break}}if(x>z.length){break}}else{if(m[B]==z[x]&&B!=e){x++;C=B}}}if(!y&&C+1<e){r.val(ORJ);w(ORJ.length,h)}else{if(y||C+1>=e){s();if(!y){r.val(r.val().substring(0,C+1))}}}return(e?B:i)}if(!r.attr("readonly")){r.one("unmask",function(){r.unbind(".mask").removeData("buffer").removeData("tests")}).bind("focus.mask",function(){q=r.val();var x=p();s();setTimeout(function(){if(x==j.length){r.caret(0,x)}else{r.caret(x)}},0)}).bind("blur.mask",function(){p();if(r.val()!=q){r.change()}}).bind("keydown.mask",l).bind("keypress.mask",o).bind(c,function(){setTimeout(function(){r.caret(p(true))},0)})}p()})}})})(jQuery);
if your 'completed' function doesn't work, try to replace this line:
if (settings.completed && next == len)
(this is line number 169 of noncompressed plugin) with that:
if (settings.completed && eval(+next - 1) == len)
While using this plugin with firebug, i've noticed, that 'next' variable jumps up over a symbol when last char of mask entered.
This way should work.
I found a better solution than timeout.
You can view jquery.maskedinput.js:293 there is a function for input focus and it is triggered only on inputs without "readonly" attribute so:
$("input[type=text]").attr("readonly", true).select().removeAttr("readonly");
...just like that. Works like a charm ;)

Categories