Javascript CTRL-C is triggered in <textarea> - javascript

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.

Related

Javascript: how to trigger a backspace keypress when pressing enter key in conteditable div?

Due to some complicated reason, When user press enter key in contenteditable div, I have to hard code to imitate the normal behavior of changing lines, my attempt was that when enter key is pressed, first, two br tags then created (works fine)and then second, delete last br by imitating user's pressing on backspace (works not fine).
My attempt is below, which fails to imitate user's backspace keypress at the caret position.
html:
<div id="hithere" style="border:1px solid black" contenteditable="true" autocomplete="off" spellcheck="false"></div>
Javascript:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.2/jquery.min.js"></script>
<script>
$('div[contenteditable]').keydown(function(e) {
if (e.keyCode === 13) {
document.execCommand('insertHTML', false, ' <br><br>');
$(function() {
var bre = $.Event('keypress');
bre.keyCode= 8; // enter
document.trigger(bre);
});
}
// // prevent the default behaviour of return key pressed
return false;
});
</script>
I saw the problem which you probably ran into but didn't write about:
The <br /> is inserted, but when the user continues typing, the text gets inserted above the break.
You can insert the break as Text instead, using the two components \r and \n (Carriage Return and New Line)
document.execCommand('insertText', false, '\r\n');
See here:
https://jsfiddle.net/svArtist/6o5ao1bm/1/

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);
});

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

how to predict if DOM keydown will cause a character input

Given a keydown event in the browser, how can I predict whether that key event will result in character input? For example, hitting the left arrow doesn't input characters but hitting the a key inputs an A (unless ctrl or alt is down).
I don't need to know what character will be input, just whether the key event will result in an input.
I'm targeting Chrome. Bonus points if your solution works in an IME.
Note: I'm asking about the keydown event, not a downstream event like keypress or oninput.
There's an HTML 5 event: input. MDN: https://developer.mozilla.org/en-US/docs/Web/Reference/Events/input. Other than that there's no proper solution.
Ok, I think I have a solution. I don't know how good it is but it works. Have a look: http://jsfiddle.net/tLPsL/
It's basically saving the value of the input onkeydown and checking it in onkeyup.
$('#sattar').keydown(function() {
window.SATTAR = $(this).val();
});
$('#sattar').keyup(function() {
if(window.SATTAR !== $(this).val()) {
alert("changed");
}
});
[updated]
use this
$(document).keydown(function(event){
console.log(event.which);
});
and filter the value of the event.which according to your needs using the ascii values and exclude the numbers that appear with unwanted buttons
for example (this example demonstrates accepting small letters only):
$(document).keydown(function(event){
var x = event.which;
if (x <= 90 && x >=65) console.log('accepted');
else console.log('not accepted');
});
JSFiddle
[update] :
If you don't like this method you can use another that detects an input to any textfield or textarea :
$('input,textarea').change(function(){
console.log('input detected!');
});
$(document).keyup(function(event){
var x = $(event.target);
if (x[0].nodeName == 'INPUT' || x[0].nodeName == 'TEXTAREA'){ //you can filter the backspace if you don't want to consider it a change on the input by anding it with the whole argument here using the key number explained above
x.blur().focus();
}
});
DEMO
note: The first method works for all languages as the same keyboard keys are used for inputs of different characters but they still can type.
Sources && tips:
I saw the characters keydata list in this site.
-To make it crossplatform and crossbrowser, I suggest you to watch this site
-You can test the keydown event here.
-Jquery also suggest to use key which because it normalizes keycode and charcode (i think this can be usefull for the crossbrowser part but I didn't find a table like the one I posted before for keycode), see details here.
To the end, a personal thought: I wouldn't appear rude by telling this so please, try to understand, you had 3 clear and working answer, should be your interest to improve details to make it working as you need, especially because, for many reason, (like time, hardware disponibility, no one pay us, freelancer site is elsewhere, etc etc), who are helping you, maybe, can't do your entirely work.
EDIT
Considering your needs, I wrote this code, keeps in mind that combination key are hard to handle, so, you should test this example before to re-use it. fiddle
<!DOCTYPE html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="http://code.jquery.com/jquery-1.9.1.js"></script>
<script>
$(document).keydown(
function(event){
if(event.target!='[object HTMLBodyElement]'){//Are we in an input?
if(!event.ctrlKey && !event.altKey){//Are we using a combo ctrl or alt?
if(event.keyCode==13 || event.keyCode==8 || event.keyCode==32 || (event.keyCode>45 && event.keyCode<91) || event.keyCode==188 || (event.keyCode>189 && event.keyCode<193) || (event.keyCode>218 && event.keyCode<222)){
//It is a char?
document.getElementById('valid').innerHTML+=event.keyCode+' ';
document.getElementById('idlast').innerHTML=event.target.id;
}
}
}
}
);
</script>
</head>
<body>
<input id="a" type="text"></input>
<textarea id="b">a</textarea>
<div id="c" contenteditable="true">a</div>
<div id="d" style="width:200px;height:200px;background-color:red">a</div>
last keydown in: <span id="idlast"></span><br>
for keypress in input:<span id="valid"></span><br>
</body>
</html>
END EDIT
For first if the focus is on an object that is not an input(textarea,contenteditable...) you are targeting the body. So if the target is the body, for sure you are not writing somewhere.
Then I suggest you to see this example, keypress is probably usefull for your aim, because it seems to don't register keys that aren't an input.
<!DOCTYPE html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="http://code.jquery.com/jquery-1.9.1.js"></script>
<script>
$(document).keypress(
function(event){
if(event.target!='[object HTMLBodyElement]'){
document.getElementById('valid').innerHTML=document.getElementById('valid').innerHTML+event.keyCode+' ';
document.getElementById('idlast').innerHTML=event.target.id;
}else{
document.getElementById('out').innerHTML=document.getElementById('out').innerHTML+event.keyCode+' ';
}
}
);
$(document).keydown(function(e){document.getElementById('down').innerHTML=document.getElementById('down').innerHTML+e.keyCode+' ';});
</script>
</head>
<body>
<input id="a" type="text"></input>
<textarea id="b">a</textarea>
<div id="c" contenteditable="true">a</div>
<div id="d" style="width:200px;height:200px;background-color:red">a</div>
last keypress input id: <span id="idlast"></span><br>
for keypress in input:<span id="valid"></span><br>
for keypress out:<span id="out"></span><br>
for keydown:<span id="down"></span><br>
</body>
</html>

Paste event not functioning properly in Opera 11 and lower versions

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('');
});

Categories