Javascript/jQuery: Convert key combo to string? - javascript

I'm looking for an existing Javascript library, or even better, a jQuery plugin, which detects a key combo and outputs the corresponding string (for example, "ctrl+shift+f"). This is to allow a user to configure a key combo for a Google Chrome plugin. The preferences behavior for BetterTouchTool ( http://www.boastr.de/ ) is a good example of what I'm talking about. Has anyone come across something like this?

I think something of this kind might help:
document.onkeydown = KeyDownHandler;
document.onkeyup = KeyUpHandler;
var CTRL = false;
var SHIFT = false;
var ALT = false;
var CHAR_CODE = -1;
function KeyDownHandler(e) {
var x = '';
if (document.all) {
var evnt = window.event;
x = evnt.keyCode;
}
else {
x = e.keyCode;
}
DetectKeys(x, true);
DoSometing();
}
function KeyUpHandler(e) {
var x = '';
if (document.all) {
var evnt = window.event;
x = evnt.keyCode;
}
else {
x = e.keyCode;
}
DetectKeys(x, false);
DoSometing();
}
function DetectKeys(KeyCode, IsKeyDown) {
if (KeyCode == '16') {
SHIFT = IsKeyDown;
}
else if (KeyCode == '17') {
CTRL = IsKeyDown;
}
else if (KeyCode == '18') {
ALT = IsKeyDown;
}
else {
if(IsKeyDown)
CHAR_CODE = KeyCode;
else
CHAR_CODE = -1;
}
}
function DoSometing() {
//check for keys here
}
I hope it'll be useful

$(document).keypress(function(e) {
alert(
(e.ctrlKey ? 'ctrl+' : '') +
(e.altKey ? 'alt+' : '') +
(e.shiftKey ? 'shift+' : '') +
String.fromCharCode(e.which).toLowerCase()
);
});
This will register the keys; not sure how you're going to block the ctrl/alt keys from getting interpreted though.
browser support: http://www.quirksmode.org/js/keys.html

I forgot I even asked this question! After many months, I've written a plugin myself that does exactly this =)
http://suan.github.com/jquery-keycombinator/

Related

How to write a good Caps Lock detection solution in JavaScript?

Found this Caps Lock detection solution. Fiddle here: https://jsfiddle.net/07ugkacn/11/ (Thank you Armfoot). JS/jQuery code here:
$(function () {
var isShiftPressed = false;
var isCapsOn = null;
$("#txtName").bind("keydown", function (e) {
var keyCode = e.keyCode ? e.keyCode : e.which;
if (keyCode == 16) {
isShiftPressed = true;
}
});
$("#txtName").bind("keyup", function (e) {
var keyCode = e.keyCode ? e.keyCode : e.which;
if (keyCode == 16) {
isShiftPressed = false;
}
if (keyCode == 20) {
if (isCapsOn == true) {
isCapsOn = false;
$("#error").hide();
} else if (isCapsOn == false) {
isCapsOn = true;
$("#error").show();
}
}
});
$("#txtName").bind("keypress", function (e) {
var keyCode = e.keyCode ? e.keyCode : e.which;
if (keyCode >= 65 && keyCode <= 90 && !isShiftPressed) {
isCapsOn = true;
$("#error").show();
} else {
$("#error").hide();
}
});
});
Works perfectly for my needs. I'm trying to rewrite it in JavaScript though, with no jQuery. How do I rewrite the bind methods without the jQuery? I've tried storing the input fields in a variable and writing
passwordInput.onkeyup = function(e) { ... }
... For example. But to no avail. Think this is what's stopping this solution from working.
Help pls thx.
EDIT: Figured it out on my own
For whom it may concern, a solution for caps detection in vanilla JavaScript. The problem with most of the solutions floating around on the internet is they only show/hide an alert/popup when the user starts typing in the input field. This is not optimal because the "Caps Lock is on" notification is still visible after the user has turned Caps Lock off, and remains so until they resume typing. This is long and unwieldy, and I still don't quite understand it myself. But I recommend it all the same.
function capsDetect() {
var body = document.getElementsByTagName('body')[0];
var isShiftPressed = false;
var isCapsOn = null;
var capsWarning = document.getElementById('caps-lock-warning');
body.addEventListener('keydown', function(e) {
var keyCode = e.keyCode ? e.keyCode : e.which;
if (keyCode = 16){
isShiftPressed = true;
}
});
body.addEventListener('keyup', function(e) {
var keyCode = e.keyCode ? e.keyCode : e.which;
if(keyCode == 16) {
isShiftPressed = false;
}
if(keyCode == 20) {
if(isCapsOn == true) {
isCapsOn = false;
capsWarning.style.visibility = 'hidden';
} else if (isCapsOn == false) {
isCapsOn = true;
capsWarning.style.visibility = 'visible';
}
}
});
body.addEventListener('keypress', function(e) {
var keyCode = e.keyCode ? e.keyCode : e.which;
if(keyCode >= 65 && keyCode <= 90 && !isShiftPressed) {
isCapsOn = true;
capsWarning.style.visibility = 'visible';
} else {
capsWarning.style.visibility = 'hidden';
}
});
}
shiftCaps();
Gaweyne, nicely done! I tested your pure JS code and there are some things that I modified which you may find interesting:
ignored control characters while typing (<= 40), such as directional and removal keys;
replaced if (keyCode = 16){ to if (keyCode === 16){ and other == in the same way;
used display property instead of visibility (CSS);
considered isCapsOn as a boolean, always;
called capsDetected instead of shiftCaps.
You can run the snippet below to check it out:
function capsDetect() {
var body = document.getElementsByTagName('body')[0];
var isShiftPressed = false;
var isCapsOn = false;
var capsWarning = document.getElementById('error');
body.addEventListener('keydown', function(e) {
var keyCode = e.keyCode ? e.keyCode : e.which;
if (keyCode === 16) {
isShiftPressed = true;
}
});
body.addEventListener('keyup', function(e) {
var keyCode = e.keyCode ? e.keyCode : e.which;
if (keyCode === 16) {
isShiftPressed = false;
}
if (keyCode === 20) {
if (isCapsOn) {
isCapsOn = false;
capsWarning.style.display = 'none';
} else {
isCapsOn = true;
capsWarning.style.display = 'inline-block';
}
}
});
body.addEventListener('keypress', function(e) {
var keyCode = e.keyCode ? e.keyCode : e.which;
if (keyCode <= 40)
return;
if (keyCode >= 65 && keyCode <= 90 && !isShiftPressed) {
isCapsOn = true;
capsWarning.style.display = 'inline-block';
} else {
capsWarning.style.display = 'none';
}
});
}
capsDetect();
body {
font-family: Arial;
font-size: 10pt;
}
#error {
border: 1px solid #FFFF66;
background-color: #FFFFCC;
display: inline-block;
margin-left: 10px;
padding: 3px;
display: none;
}
<form action="">
<input id="txtName" type="text" /><span id="error">Caps Lock is ON.</span>
</form>
Maybe some more tweaking will make it perfect... There is still the CAPS LOCK detection on page load: maybe by simulating user input in the background will let us know, but right now I haven't completely figured it out yet.
Btw, I never thought of doing this before, but it is clear that it helps users, specially in passwords fields. In fact, I may personally use it! So I really appreciate your time for posting this up :)

JavaScript How to allow only one symbol at the begining of string

I would like to allow the users to put only one kind of symbol (character) in input and only at the beginning of string.
Of course on keyDown/keyUp event. I'm looking-for the fastest solution.
Supposing you have an input like
<input type="text" id="text">
you can use the following code
$(function(){
var alreadyIn = 0;
var chars = [33, 64, 35]; // Place here the codes for accepted chars (!##$ etc)
$("#text").on('keypress', function(e) {
var code = (e.keyCode ? e.keyCode : e.which);
if(chars.indexOf(code) != -1) {
if($(this).caret() != 0){return false;}
if(alreadyIn){return false;}
alreadyIn++
} else {
if(alreadyIn && $(this).caret() == 0){return false;}
}
return true;
}).on('keyup', function(e){ // Keyup event to catch backspace and delete
var code = (e.keyCode ? e.keyCode : e.which);
if(code == 8 || code == 46) {
var current = $(this).val();
var instances = 0;
chars.forEach(function(char) {
if(current.search(String.fromCharCode(char)) > -1){instances++;}
});
alreadyIn = instances == 0 ? 0 : 1;
}
}).bind("cut copy paste", function(e) { // Do not allow cut copy paste in field
e.preventDefault();
});
});
EDIT
I've updated the answer. You have to include jquery caret plugin also. You can find it here

Not all code paths return a value (JavaScript)

document.getElementById('search_field').onkeypress = function(e) {
if (!e) e = window.event;
var keyCode = e.keyCode || e.which;
if (keyCode == '13') {
window.location.href = '/search/?s=' + $('#search_field').val();
return false;
}
};
The last bracket show me an error, not all code paths return a value, what seems to be problem here ?
Thanks
Try this :
document.getElementById('search_field').onkeypress = function(e) {
if (!e) {
e = window.event;
}
var keyCode = e.keyCode || e.which;
if (keyCode == '13') {
window.location.href = '/search/?s=' + $('#search_field').val();
return false;
}
return true;
};
More... I think that you may not use both pure javascript and jquery
So you'd rather choose between
JAVASCRIPT :
document.getElementById('search_field').onkeypress = function(e) {
if (!e) e = window.event;
var keyCode = e.keyCode || e.which;
if (keyCode == '13') {
window.location.href = '/search/?s=' + document.getElementById('search_field').value;
return false;
}
return true;
};
JQUERY
$( "#search_field" ).keypress(function( event ) {
if ( event.which == 13 ) {
event.preventDefault();
window.location.href = '/search/?s=' + $(this).val();
return false;
}
return true;
});
End your function with return true.
If any other key then 13 is pressed the flow should just continue normally.
Ignore your tool. Event handlers do not have to return a value in every occasion, it is fine if only a particular path does return false.

Keylistener in Javascript

I'm looking for a KeyListener for a game I'm developing in JavaScript. I have no idea how this would work in real code but it would be something like this:
if(keyPress == upKey)
{
playerSpriteX += 10;
}
else if(keyPress == downKey)
{
playerSpriteY -= 10;
}
etc...
I searched it up, and Google came up with things that involved AJAX which I don't understand yet. Is there a built in function in JavaScript that does this?
Here's an update for modern browsers in 2019
let playerSpriteX = 0;
document.addEventListener('keyup', (e) => {
if (e.code === "ArrowUp") playerSpriteX += 10
else if (e.code === "ArrowDown") playerSpriteX -= 10
document.getElementById('test').innerHTML = 'playerSpriteX = ' + playerSpriteX;
});
Click on this window to focus it, and hit keys up and down
<br><br><br>
<div id="test">playerSpriteX = 0</div>
Original answer from 2013
window.onkeyup = function(e) {
var key = e.keyCode ? e.keyCode : e.which;
if (key == 38) {
playerSpriteX += 10;
}else if (key == 40) {
playerSpriteX -= 10;
}
}
FIDDLE
The code is
document.addEventListener('keydown', function(event){
alert(event.keyCode);
} );
This return the ascii code of the key. If you need the key representation, use event.key (This will return 'a', 'o', 'Alt'...)
JSFIDDLE DEMO
If you don't want the event to be continuous (if you want the user to have to release the key each time), change onkeydown to onkeyup
window.onkeydown = function (e) {
var code = e.keyCode ? e.keyCode : e.which;
if (code === 38) { //up key
alert('up');
} else if (code === 40) { //down key
alert('down');
}
};
Did you check the small Mousetrap library?
Mousetrap is a simple library for handling keyboard shortcuts in JavaScript.
A bit more readable comparing is done by casting event.key to upper case (I used onkeyup - needed the event to fire once upon each key tap):
window.onkeyup = function(event) {
let key = event.key.toUpperCase();
if ( key == 'W' ) {
// 'W' key is pressed
} else if ( key == 'D' ) {
// 'D' key is pressed
}
}
Each key has it's own code, get it out by outputting value of "key" variable (eg for arrow up key it will be 'ARROWUP' - (casted to uppercase))

Javascript on second keypress

I've been wondering if there was a simple way to detect if a user presses the same character on the keyboard twice within one second. I've written some code that kind of works but it's unreliable.
var escapeCount = 0;
function reset() {
escapeCount = 0;
setTimeout('reset();', 1000);
}
window.onload = function() {
reset();
};
document.onkeyup = function(e) {
if (!e) var e = window.event;
var code = e.keyCode ? e.keyCode : e.which;
if (code == 27) escapeCount +=1;
if (escapeCount == 2) {
// stuff on second escape
}
};
Is there a better way to do this? Thanks
It would make sense to reset after 1 second has passed since the last character was pressed. Example:
var lastChar = -1;
document.onkeyup = function(e) {
if (!e) var e = window.event;
var code = e.keyCode ? e.keyCode : e.which;
if (lastChar == code) {
// Same key was pressed twice in a row within 1 second.
} else {
lastChar = code;
setTimeout(function() {lastChar = -1;}, 1000);
}
};
Your timer resets every second, so you not only have to press Escape again within a second of the last Escape, but that also has to have no timeout in between the presses.
It's probably easier to forget the timeout and just remember the time of the last keypress instead:
var lastescapetime= null;
document.onkeyup= function(event) {
if (event===undefined) event= window.event;
if (event.keyCode===27) {
var now= new Date().getTime();
if (lastescapetime!==null && now<lastescapetime+1000) {
alert('You double-escaped!');
lastescapetime= null;
} else {
lastescapetime= now;
}
} else {
lastescapetime= null;
}
};

Categories

Resources