How to write a good Caps Lock detection solution in JavaScript? - 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 :)

Related

Javascript disable spacebar scrolling [duplicate]

This question already has answers here:
Pressing spacebar scrolls page down?
(3 answers)
Closed 2 years ago.
I am working on a WebGL application and I use the spacebar for movement of the camera. The problem is, when I press the spacebar the website also scrolls down. Is there a way to disable this feature?
None of the answers so far works reliably. They work for about a second, then the site scrolls down for a tiny amount of time and then the cycle repeats.
This is my code for the keypresses:
window.addEventListener("keydown", (e) => {
if(e.repeat) { return; }
if(e.which == 27 || e.which == 9) {
document.exitPointerLock();
checkMouse = false;
}
if(checkMouse) {
if(e.which == 87) { forwardPressed = true; }
if(e.which == 83) { backwardPressed = true; }
if(e.which == 65) { leftPressed = true; }
if(e.which == 68) { rightPressed = true; }
if(e.which == 32) { upPressed = true; event.stopPropagation(); event.preventDefault(); }
if(e.which == 16) { downPressed = true; }
}
});
As you can see, for the space key there already is one solution implemented but both types of answers I have gotten so far don't work.
You can do it something like this
$(document).keypress(function(event){
var keycode = (event.keyCode ? event.keyCode : event.which);
if(keycode == '32') {
event.preventDefault();
}
});
Add this to your javascript:
let checkMouse = true
window.addEventListener("keydown", (e) => {
if(e.repeat) {
return;
}
if(e.which == 27 || e.which == 9) {
document.exitPointerLock();
checkMouse = false;
}
if(checkMouse) {
if(e.which == 87) { forwardPressed = true; }
if(e.which == 83) { backwardPressed = true; }
if(e.which == 65) { leftPressed = true; }
if(e.which == 68) { rightPressed = true; }
if(e.which == 32) { upPressed = true; event.stopPropagation(); event.preventDefault(); }
if(e.which == 16) { downPressed = true; }
}
if (e.which == 32) {
return !(e.keyCode == 32);
}
});
checkMouse wasn't initialised before. It's working fine here.

Modify Arrow Key Navigation to support Mobile Swipe

I currently use the code below to navigate to the next and previous pages by allowing the user to use the left and right buttons. How would I integrate the code for swiping on the mobile phone for navigation?
var browser = navigator.appName;
if (browser == "Microsoft Internet Explorer") {
document.onkeydown=keydownie;
} else {
document.onkeydown=keydown;
}
function keydownie(e) {
if (!e) var e = window.event;
if (e.keyCode) {
keycode = e.keyCode;
if ((keycode == 39) || (keycode == 37)) {
window.event.keyCode = 0;
}
} else {
keycode = e.which;
}
if (keycode == 37) {
img = document.querySelector("img[src='http://www.example.com/arrowleft.jpg'],img[src='http://www.example.com/images/left.png']");
window.location = img.parentElement.href;
return false;
} else if (keycode == 39) {
img = document.querySelector("img[src='http://www.example.com/arrowright.jpg'],img[src='http://www.example.com/images/right.png']");
window.location = img.parentElement.href;
return false;
}
}
function keydown(e) {
if (e.which) {
keycode = e.which;
} else {
keycode = e.keyCode;
}
if (keycode == 37) {
img = document.querySelector("img[src='http://www.example.com/arrowleft.jpg'],img[src='http://www.example.com/images/left.png']");
window.location = img.parentElement.href;
return false;
} else if (keycode == 39) {
img = document.querySelector("img[src='http://www.example.com/arrowright.jpg'],img[src='http://www.example.com/images/right.png']");
window.location = img.parentElement.href;
return false;
}
}

jquery elastic textarea issue

i am using this plugin :http://www.unwrongest.com/projects/elastic/ and this is my code :
$(document).ready(function () {
$("#<%=Message_txt.ClientID %>").elastic();
var keyPressCount = 0;
$(window).keyup(function (e) {
if (keyPressCount++ % 10 == 0) {
chat.server.onuserTyping(ToClient, fromClient);
}
var enterkey = e.which == 13 || e.KeyCode == 13 || e.charCode == 13 ? true : false;
if (enterkey) {
var Msgtxt = $("#<%=Message_txt.ClientID %>").val().trim();
if (Msgtxt == null) return false;
$("#<%=Send_btn.ClientID %>").trigger("click");
}
});
});
as you can see when the enter key is pressed i am triggering the send_btn click the problem is after the button is triggered the textarea loose the elastic functionality and i don't know why

Event is not defined error in javascript only Firefox

I use the following script to validate the text box to enter only numbers and (.) which means it is decimal textbox validation. It was work fine in Internet Explorer and Google Chrome. If I execute the function in FireFox I get the following Error:
Event Is not Defined.
How to solve this?
function abc(event) {
if (event.keyCode > 47 && event.keyCode < 58) {
return true;
}
if (event.keyCode == 8 || event.keyCode == 46)
{
return true;
}
return false;
}
I call this function like this:
$('.decimalValidate').live('keypress',function(){
var decimalid=$(this).attr("id");
var decimalval=$('#'+decimalid).val();
var decimalvalidate=abc(decimalval);
if(decimalvalidate == false)
return false;
});
I assign this validation for text box like this:
input type="text" id="Total" class="abc"
Try this
function abc(event) {
if(!event)
event= window.event;
if (event.keyCode > 47 && event.keyCode < 58) {
return true;
}
if (event.keyCode == 8 || event.keyCode == 46)
{
return true;
}
return false;
}
and
$('.decimalValidate').live('keypress',function(e){
var decimalid=$(this).attr("id");
var decimalval=$('#'+decimalid).val();
var decimalvalidate=abc(evt); //keypress event
if(decimalvalidate == false)
return false;
});
decimalval is not an Event object, and you have to pass it to the abc function in ordert to find out which key you pressed:
$('.decimalValidate').live('keypress',function(ev){
var decimalid=$(this).attr("id");
var decimalval=$('#'+decimalid).val();
var decimalvalidate=abc(ev);
if(decimalvalidate == false)
return false;
});
$('.decimalValidate').live('keypress',function(e){
var decimalvalidate=abc(e); //this will point to the event of the keypress.
if(decimalvalidate == false)
return false;
});
I am not sure why you did all of the decimalid and decimalval operations, but if you want the event, do as I wrote in the edited code above.
Good luck.
$('.decimalValidate').on('keypress',function(event){
var decimalid = $(this).attr("id");
var decimalval = $('#'+decimalid).val();
var decimalvalidate = abc(event);
if(decimalvalidate == false)
return false;
});
function abc(event) {
if (event.keyCode > 47 && event.keyCode < 58) {
return true;
}
if (event.keyCode == 8 || event.keyCode == 46)
{
return true;
}
return false;
}
It helps you..

Javascript/jQuery: Convert key combo to string?

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/

Categories

Resources