8

So I've been researching solutions for Caps Lock detection for a form, using JavaScript/jQuery. There is a huge thread on stackoverflow offering many solutions. But the only problem is they don't check whether Caps Lock is pressed directly per se. They detect whether a capital letter has been entered and that the shift key has not been depressed. The drawbacks of this is that my Caps Lock warning message will not toggle on/off until the user starts typing into the form, which is hardly optimal. Here is my code.

document.onkeypress = function(e){
    e = e || window.event;
    var s = String.fromCharCode(e.keyCode || e.which);
    if (s.toUpperCase() === s && !e shiftKey) {
        capsWarning.style.visibility = 'visible';
    } else {
        capsWarning.style.visibility = 'hidden';
    }
}

Is there a better way, that I can trigger a caps lock message, with JavaScript when I press the Caps Lock key? That is, not delay toggling message until I start typing?

Preferably I'd prefer a pure JavaScript solution to JQuery. Although if you think jQuery would be really really really good here say why and I could pressure my colleague to let me include it here ;o

Bakudan
  • 19,134
  • 9
  • 53
  • 73
  • 1
    There's some scenario's that are not covered: what if caps-lock is active before the page is loaded? AFAIK it is not possible to get keyboard statuses until a key is pressed. – Kenney Aug 03 '15 at 16:24
  • What I mean is, I want JavaScript to detect whether Caps Lock is on before I start typing a password in an input field. So yes, a key has to be pressed. Right now the user will only know if Caps Lock is on or not after he/she starts typing login details. This is not optimal. Sorry for confusion. –  Aug 03 '15 at 16:29
  • 2
    Modern browsers have [`getModifierState()`](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/getModifierState) method in event object. You can use that if you don't have to support older browsers. Though this also needs an event, but you might get that working by triggering an event yourself? – Teemu Aug 03 '15 at 16:31
  • Could you give a more detailed example of using getModifierState() Teemu? –  Aug 03 '15 at 16:32
  • 3
    @Gaweyne [Here's a fiddle](http://jsfiddle.net/cvg3bnzf/1/). Unfortenately it seems, that only MouseEvents and KeyboardEvents have getModifierState method. A good event for your task would be `onfocus`, but its event object doesn't have the said method. Also it looks like that if you'd trigger a keydown method by JS, you'd get always `false` from getModifierState() (see the first version of the linked fiddle). – Teemu Aug 03 '15 at 17:20
  • This is closer to what I wanted, and thank you for trying. But you probably already see why this would be less than ideal. It's an improvement in so far as when the user clicks on the input field and hits caps lock the alert message flashes. But the user can still have caps lock on, and continue typing, and the message will not alert him/her that the caps key is still on. –  Aug 04 '15 at 08:39
  • In IE 11 the input with type password has automatic notification for Caps Lock. – Bakudan Aug 09 '15 at 11:50

4 Answers4

0

I've used this piece of code and to try dispatch an event. The getModifierState MSDN, MDN won't return other than false. With this actually you will send a character as it is - "a" or "A". Either case it will be hard coded.

getModifierState will return true only in the case of real keypress.

But there is an automatic CapsLock detection in IE 11 ( for <input type="password" /> )

            var eventType = "keypress";
            window.addEventListener ( eventType, function(e){
                var msg = "Key Pressed: " + String.fromCharCode(e.charCode) + "\n" + "charCode: " + e.charCode + "\n" + e.getModifierState ( "CapsLock" );
                console.log ( msg );
            }, false );

            function simulateKeyEvent() {
                var evt = document.createEvent("KeyboardEvent");
                var initMethod = typeof evt.initKeyboardEvent !== 'undefined' ? "initKeyboardEvent" : "initKeyEvent";

                evt[initMethod](
                    "keypress",         // type,
                    true,               // bubbles,
                    true,               // cancelable,
                    window,             // viewArg, 
                    0,                  // ctrlKeyArg,
                    0,                  // altKeyArg,
                    0,                  // shiftKeyArg,
                    0,                  // metaKeyArg, 
                    /* lower a */ 97,   //  keyCodeArg,
                    /* lower a */ 97    //  charCodeArg
                );
                window.dispatchEvent(evt);
            }
            simulateKeyEvent();
Bakudan
  • 19,134
  • 9
  • 53
  • 73
0

I tested this in chrome and it worked, put this JavaScript in tag

function  loadcaps ( e ) {
     e = e || window.event;
     var s = String.fromCharCode( e.keyCode || e.which );
     if ( s.toUpperCase() === s && !e.shiftKey ) {            
          capsWarning.style.visibility = 'visible';
     } else {
          capsWarning.style.visibility = 'hidden';
     }
  }

and put that on your tag

<body onload="loadcaps()">

let me know if it works for you.

Deivi
  • 197
  • 2
  • 12
0

Use below mention code:

<script language="Javascript">
    function capLock(e){
     kc = e.keyCode?e.keyCode:e.which;
     sk = e.shiftKey?e.shiftKey:((kc == 16)?true:false);
     if(((kc >= 65 && kc <= 90) && !sk)||((kc >= 97 && kc <= 122) && sk)){
      document.getElementById('divon').style.visibility = 'visible';
       document.getElementById('divoff').style.visibility = 'hidden';
     }else{
      document.getElementById('divon').style.visibility = 'hidden';
       document.getElementById('divoff').style.visibility = 'visible';
    }
    }
    </script>
    <input type="text" name="trackcaps" onkeypress="capLock(event)" />
    <div id="divon" style="visibility:hidden">Caps Lock is on.</div>`enter code here`
    <div id="divoff" style="visibility:hidden">Caps Lock is off.</div>
Pankaj Chauhan
  • 1,623
  • 14
  • 12
-4

Use the onkeydown handler:

document.onkeypress=function(){console.log(arguments);}
Kenney
  • 9,003
  • 15
  • 21
  • Please reread the question. It is asking how to do it without waiting for a keypress. – Quentin Aug 03 '15 at 16:23
  • I replaced onkeypress with onkeydown. My caps lock message appears when I press the caps key, before typing anything. But when I press caps again, turning it off, the message is still there ;o –  Aug 03 '15 at 16:24
  • @Quentin That's impossible. I was addressing this part of the question: `Is there a better way, that I can trigger a caps lock message, with JavaScript when I press the Caps Lock key?` – Kenney Aug 03 '15 at 16:25
  • lel. Actually, now the caps lock message displays no matter what key I press :s –  Aug 03 '15 at 16:26
  • @Quentin. No Kenney is right. At least Caps Lock has to be pressed. I want to know if JavaScript can detect that without having to type inside an input field. "Is there a better way, that I can trigger a caps lock message, with JavaScript when I press the Caps Lock key? That is, not delay toggling message until I start typing [that is, typing a password for example]" Sorry if unclear. –  Aug 03 '15 at 16:27