268

How do you tell if caps lock is on using JavaScript?

One caveat though: I did google it and the best solution I could find was to attach an onkeypress event to every input, then check each time if the letter pressed was uppercase, and if it was, then check if shift was also held down. If it wasn't, therefore caps lock must be on. This feels really dirty and just... wasteful - surely there's a better way than this?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
nickf
  • 537,072
  • 198
  • 649
  • 721
  • 1
    Just out of curiosity, why do you want to detect Caps Lock in a web app? – Chetan S May 22 '09 at 06:14
  • 219
    BECAUSE WAY TOO MANY OF MY USERS FILL IN THEIR FORMS LIKE THIS. – nickf May 22 '09 at 08:40
  • 7
    @nicf: If that's the reason, why don't you run a regexp on the input and ask them to stop shouting if there are too many upper case letters? – some Sep 28 '10 at 20:08
  • 167
    There's a much better reason to do this. If a user is entering a password, it would be very useful to warn them if their capslock is on. – T Nguyen Jun 11 '11 at 08:14
  • 1
    i gave up trying to get users to enter lowercase data, and always display text using Title Case, lower case, or sentence case, as appropriate. Note that country codes (`US`), postal codes (`M5W 1E6`), and telephone numbers (`KL5-0912`) should display as uppercase even if they were entered as lowercase. **Edit** *"Just dial diamond, `D`-`I`-`A`-`M`-`O`-`N`-`D`."* – Ian Boyd Apr 25 '12 at 15:00
  • 27
    Seems like browsers should implement a "caps lock is on" warning when users type into `input type=password` fields (similar to email address validation for `input type=email` in chrome, etc.) – nothingisnecessary Sep 02 '14 at 19:59
  • 8
    Excellent question, but the accepted answer is 8 years old. The better response is [here](https://stackoverflow.com/a/34277417/2158270) – Mac Apr 06 '17 at 16:09
  • @Mac Further down Ryan Marin posted an updated (as of September 2018) method which worked great for me. See [his reply here](https://stackoverflow.com/a/52418434/10063563). Cheers! – Cameron C Sep 20 '18 at 07:15
  • 1
    @Sirtastic: Yup, both of 'em check for `event.getModifierState( 'CapsLock' )`. Awesome! – Mac Sep 20 '18 at 18:47
  • Thanks for your comments, because I was thinking... Why the accepted answer is the thing that the questioner didn't want to do? – Tupac May 02 '20 at 02:44

31 Answers31

133

You can use a KeyboardEvent to detect numerous keys including the caps lock on most recent browsers.

The getModifierState function will provide the state for:

  • Alt
  • AltGraph
  • CapsLock
  • Control
  • Fn (Android)
  • Meta
  • NumLock
  • OS (Windows & Linux)
  • ScrollLock
  • Shift

This demo works in all major browsers including mobile (caniuse).

passwordField.addEventListener( 'keydown', function( event ) {
  var caps = event.getModifierState && event.getModifierState( 'CapsLock' );
  console.log( caps ); // true when you press the keyboard CapsLock key
});
isherwood
  • 58,414
  • 16
  • 114
  • 157
Mottie
  • 84,355
  • 30
  • 126
  • 241
  • 9
    I answered this on a dupe/similar question and was updated by another user that this now has Chrome support. I confirmed this, so now works across all major browsers - and should be the best solution to this question – Ian Clark Aug 26 '16 at 07:49
  • http://caniuse.com/#search=getModifierState says it's currently not supported on Safari (yet?). So across all major browsers may not be the case just yet. – Jens Kooij Sep 12 '16 at 10:37
  • 3
    It's supported in Safari now. – Mottie Mar 31 '17 at 12:52
  • 4
    And yet it detects the capslock press and can't get the general capslock state when user enters the form... – SparK Nov 07 '18 at 13:17
  • 3
    This seems to work except when pressing the caps lock key into the *off* position. It doesn't pick up that input until the next key press. This was on Chrome for OS X. Not sure if this is something that spans across browsers and OSs. – Ashraf Slamang Dec 04 '18 at 07:59
  • @Mottie: Doesn't work on the actual android device on mobile browser! – Aniruddha Shevle Mar 15 '21 at 06:24
  • Can I add the eventListener in some other element but the input field? Like the body tag perhaps? – ed1nh0 Feb 25 '22 at 17:26
129

In jQuery,

$('#example').keypress(function(e) { 
    var s = String.fromCharCode( e.which );
    if ( s.toUpperCase() === s && s.toLowerCase() !== s && !e.shiftKey ) {
        alert('caps is on');
    }
});

Avoid the mistake, like the backspace key, s.toLowerCase() !== s is needed.

Arthur P
  • 1,050
  • 9
  • 16
user110902
  • 1,347
  • 2
  • 8
  • 2
  • 5
    actually... fromCharCode eliminated the need for me to even check. however it should be noted that keydown and keypress give different charcodes, which was where I went wrong in the first place. – Shea Nov 07 '11 at 21:24
  • 5
    -1 bc this ONLY works if they have not pressed shift while CAPS is on. –  Jan 15 '14 at 20:36
  • 1
    If anyone want to see a live example with bootstrap so you can view here http://www.bootply.com/91792 – Govinda Rajbhar Jan 22 '16 at 13:28
  • This answer was useful for me. I improved the conditional in [this answer](https://stackoverflow.com/a/51384804/3692177), due to the flaw mentioned by @D_N, that it doesn't work while pressing shift. – SebasSBM Jul 17 '18 at 15:15
  • but what if it is only on on document load? – TAHA SULTAN TEMURI Jan 20 '21 at 17:58
96

You can give it a try.. Added a working example. When focus is on input, turning on caps lock makes the led go red otherwise green. (Haven't tested on mac/linux)

NOTE: Both versions are working for me. Thanks for constructive inputs in the comments.

OLD VERSION: https://jsbin.com/mahenes/edit?js,output

Also, here is a modified version (can someone test on mac and confirm)

NEW VERSION: https://jsbin.com/xiconuv/edit?js,output

NEW VERSION:

function isCapslock(e) {
  const IS_MAC = /Mac/.test(navigator.platform);

  const charCode = e.charCode;
  const shiftKey = e.shiftKey;

  if (charCode >= 97 && charCode <= 122) {
    capsLock = shiftKey;
  } else if (charCode >= 65 && charCode <= 90
    && !(shiftKey && IS_MAC)) {
    capsLock = !shiftKey;
  }

  return capsLock;
}

OLD VERSION:

function isCapslock(e) {
  e = (e) ? e : window.event;

  var charCode = false;
  if (e.which) {
    charCode = e.which;
  } else if (e.keyCode) {
    charCode = e.keyCode;
  }

  var shifton = false;
  if (e.shiftKey) {
    shifton = e.shiftKey;
  } else if (e.modifiers) {
    shifton = !!(e.modifiers & 4);
  }

  if (charCode >= 97 && charCode <= 122 && shifton) {
    return true;
  }

  if (charCode >= 65 && charCode <= 90 && !shifton) {
    return true;
  }

  return false;
}

For international characters, additional check can be added for the following keys as needed. You have to get the keycode range for characters you are interested in, may be by using a keymapping array which will hold all the valid use case keys you are addressing...

uppercase A-Z or 'Ä', 'Ö', 'Ü', lowercase a-Z or 0-9 or 'ä', 'ö', 'ü'

The above keys are just sample representation.

Mario Petrovic
  • 7,500
  • 14
  • 42
  • 62
rajesh pillai
  • 8,102
  • 7
  • 43
  • 60
  • 1
    It's possibly not the best implementation but when I wrote it I was trying to keep it simple. I think the only way you can really do it with the nastyness you need to cover for different browsers. –  Dec 10 '09 at 10:29
  • 2
    I've found that using this with keydown (in chrome) causes all the codes to be picked up as caps. If I use keypress it works. – Tim Mar 26 '14 at 12:25
  • 2
    Finding each possible character combination for all international characters is doomed to miss out some cases. Use toUpper/Lower case methods instead to check casing. – awe Jun 11 '15 at 09:54
  • 4
    Suprising that an answer completely false -confusing charcodes and ascii (!!!)- can get that much upvote. Nobody has ever checked ??? – GameAlchemist Nov 03 '15 at 20:55
  • @GameAlchemist that code only works in a `keypress` event when the `charCode` value *does* match ASCII values. – Mottie Dec 14 '15 at 22:08
  • 1
    Note that [according to Mozilla](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/which), event.which has been removed from the Web standards. – verism Feb 18 '16 at 10:03
  • Response bellow from Diego Vieira should be the accepted answer nowadays. This one is very old and contains deprecated code – chezwhite May 09 '18 at 11:32
  • @chezwhite, and others Yes, the response is very old and strangely just came across this again after 6 years of posting. But also e.which is used, only if supported, otherwise it will fallback to e.keyCode. So, technically this will still work, but I will also post an update. Thanks. – rajesh pillai Dec 21 '19 at 06:32
  • @rajeshpillai: Doesn't work on the actual android device on mobile browser! – Aniruddha Shevle Mar 15 '21 at 06:27
24

You can detect caps lock using "is letter uppercase and no shift pressed" using a keypress capture on the document. But then you better be sure that no other keypress handler pops the event bubble before it gets to the handler on the document.

document.onkeypress = function ( e ) {
  e = e || window.event;
  var s = String.fromCharCode( e.keyCode || e.which );
  if ( (s.toUpperCase() === s) !== e.shiftKey ) {
    // alert('caps is on')
  }
}

You could grab the event during the capturing phase in browsers that support that, but it seems somewhat pointless to as it won't work on all browsers.

I can't think of any other way of actually detecting caps lock status. The check is simple anyway and if non detectable characters were typed, well... then detecting wasn't necessary.

There was an article on 24 ways on this last year. Quite good, but lacks international character support (use toUpperCase() to get around that).

SparK
  • 5,181
  • 2
  • 23
  • 32
Borgar
  • 37,817
  • 5
  • 41
  • 42
13

Many existing answers will check for caps lock on when shift is not pressed but will not check for it if you press shift and get lowercase, or will check for that but will not also check for caps lock being off, or will check for that but will consider non-alpha keys as 'off'. Here is an adapted jQuery solution that will show a warning if an alpha key is pressed with caps (shift or no shift), will turn off the warning if an alpha key is pressed without caps, but will not turn the warning off or on when numbers or other keys are pressed.

$("#password").keypress(function(e) { 
    var s = String.fromCharCode( e.which );
    if ((s.toUpperCase() === s && s.toLowerCase() !== s && !e.shiftKey)|| //caps is on
      (s.toUpperCase() !== s && s.toLowerCase() === s && e.shiftKey)) {
        $("#CapsWarn").show();
    } else if ((s.toLowerCase() === s && s.toUpperCase() !== s && !e.shiftKey)||
      (s.toLowerCase() !== s && s.toUpperCase() === s && e.shiftKey)) { //caps is off
        $("#CapsWarn").hide();
    } //else upper and lower are both same (i.e. not alpha key - so do not hide message if already on but do not turn on if alpha keys not hit yet)
  });
joshuahedlund
  • 1,722
  • 2
  • 20
  • 25
12

In JQuery. This covers the event handling in Firefox and will check for both unexpected uppercase and lowercase characters. This presupposes an <input id="password" type="password" name="whatever"/>element and a separate element with id 'capsLockWarning' that has the warning we want to show (but is hidden otherwise).

$('#password').keypress(function(e) {
    e = e || window.event;

    // An empty field resets the visibility.
    if (this.value === '') {
        $('#capsLockWarning').hide();
        return;
    }

    // We need alphabetic characters to make a match.
    var character = String.fromCharCode(e.keyCode || e.which);
    if (character.toUpperCase() === character.toLowerCase()) {
        return;
    }

    // SHIFT doesn't usually give us a lowercase character. Check for this
    // and for when we get a lowercase character when SHIFT is enabled. 
    if ((e.shiftKey && character.toLowerCase() === character) ||
        (!e.shiftKey && character.toUpperCase() === character)) {
        $('#capsLockWarning').show();
    } else {
        $('#capsLockWarning').hide();
    }
});
Joe Liversedge
  • 4,124
  • 26
  • 19
  • I'm not sure why, but this method does not work on the first keypress (tested only on Chrome). –  Jan 15 '14 at 10:19
  • Could it be the empty field hiding issue? I could not get that to work correctly, at least in Chrome. It automatically happens in many other browsers (at least in my version, below) because backspaces count and blank out the mssg. –  Jan 15 '14 at 23:13
  • **Note**: as you correctly utilized here, you need to use the `keypress` event to make use of different casings on input, because both [`keydown` and `keyup` will always return uppercase](https://stackoverflow.com/a/14944501/1366033). Consequently, this will not [fire the capslock key](https://stackoverflow.com/a/39716260/1366033) ...if you intended to combine with `e.originalEvent.getModifierState('CapsLock')` – KyleMit Feb 20 '18 at 20:54
6

The top answers here didn't work for me for a couple of reasons (un-commented code with a dead link and an incomplete solution). So I spent a few hours trying everyone's out and getting the best I could: here's mine, including jQuery and non-jQuery.

jQuery

Note that jQuery normalizes the event object so some checks are missing. I've also narrowed it to all password fields (since that's the biggest reason to need it) and added a warning message. This has been tested in Chrome, Mozilla, Opera, and IE6-8. Stable and catches all capslock states EXCEPT when numbers or spaces are pressed.

/* check for CAPS LOCK on all password fields */
$("input[type='password']").keypress(function(e) {

    var $warn = $(this).next(".capsWarn"); // handle the warning mssg
    var kc = e.which; //get keycode
    var isUp = (kc >= 65 && kc <= 90) ? true : false; // uppercase
    var isLow = (kc >= 97 && kc <= 122) ? true : false; // lowercase
    // event.shiftKey does not seem to be normalized by jQuery(?) for IE8-
    var isShift = ( e.shiftKey ) ? e.shiftKey : ( (kc == 16) ? true : false ); // shift is pressed

    // uppercase w/out shift or lowercase with shift == caps lock
    if ( (isUp && !isShift) || (isLow && isShift) ) {
        $warn.show();
    } else {
        $warn.hide();
    }

}).after("<span class='capsWarn error' style='display:none;'>Is your CAPSLOCK on?</span>");

Without jQuery

Some of the other jQuery-less solutions lacked IE fallbacks. @Zappa patched it.

document.onkeypress = function ( e ) {
    e = (e) ? e : window.event;

    var kc = ( e.keyCode ) ? e.keyCode : e.which; // get keycode
    var isUp = (kc >= 65 && kc <= 90) ? true : false; // uppercase
    var isLow = (kc >= 97 && kc <= 122) ? true : false; // lowercase
    var isShift = ( e.shiftKey ) ? e.shiftKey : ( (kc == 16) ? true : false ); // shift is pressed -- works for IE8-

    // uppercase w/out shift or lowercase with shift == caps lock
    if ( (isUp && !isShift) || (isLow && isShift) ) {
        alert("CAPSLOCK is on."); // do your thing here
    } else {
        // no CAPSLOCK to speak of
    }

}

Note: Check out the solutions of @Borgar, @Joe Liversedge, and @Zappa, and the plugin developed by @Pavel Azanov, which I have not tried but is a good idea. If someone knows a way to expand the scope beyond A-Za-z, please edit away. Also, jQuery versions of this question are closed as duplicate, so that's why I'm posting both here.

  • 5
    A good solution should always include support for letters outside the English letters A-Z. Any other solution is an insult to almost all non-english languages. – awe Feb 10 '14 at 12:34
  • Doesn't work on the actual android device on mobile browser! – Aniruddha Shevle Mar 22 '21 at 04:59
6

We use getModifierState to check for caps lock, it's only a member of a mouse or keyboard event so we cannot use an onfocus. The most common two ways that the password field will gain focus is with a click in or a tab. We use onclick to check for a mouse click within the input, and we use onkeyup to detect a tab from the previous input field. If the password field is the only field on the page and is auto-focused then the event will not happen until the first key is released, which is ok but not ideal, you really want caps lock tool tips to display once the password field gains focus, but for most cases this solution works like a charm.

HTML

<input type="password" id="password" onclick="checkCapsLock(event)" onkeyup="checkCapsLock(event)" />

JS

function checkCapsLock(e) {
  if (e.getModifierState("CapsLock")) {
    console.log("Caps");
  }
}

https://codepen.io/anon/pen/KxJwjq

Ryan Marin
  • 94
  • 1
  • 5
  • Superb! Simple, concise, and flawless in my implementation. – Cameron C Sep 20 '18 at 07:12
  • 1
    @Ryan: Thanks for the contribution! It's a good, clean example of code, though I'd like to point out your answer is basically the same as [Mottie's reply](https://stackoverflow.com/a/34277417/2158270) from 2015, where you both employ `event.getModifierState("CapsLock").` – Mac Sep 20 '18 at 19:01
  • @Ryan: Doesn't work on the actual android device on mobile browser! – Aniruddha Shevle Mar 15 '21 at 06:22
5

This is a solution that, in addition to checking state when writing, also toggles the warning message each time the Caps Lock key is pressed (with some limitations).

It also supports non-english letters outside the A-Z range, as it checks the string character against toUpperCase() and toLowerCase() instead of checking against character range.

$(function(){
  //Initialize to hide caps-lock-warning
  $('.caps-lock-warning').hide();

  //Sniff for Caps-Lock state
  $("#password").keypress(function(e) {
    var s = String.fromCharCode( e.which );
    if((s.toUpperCase() === s && s.toLowerCase() !== s && !e.shiftKey)||
       (s.toUpperCase() !== s && s.toLowerCase() === s && e.shiftKey)) {
      this.caps = true; // Enables to do something on Caps-Lock keypress
      $(this).next('.caps-lock-warning').show();
    } else if((s.toLowerCase() === s && s.toUpperCase() !== s && !e.shiftKey)||
              (s.toLowerCase() !== s && s.toUpperCase() === s && e.shiftKey)) {
      this.caps = false; // Enables to do something on Caps-Lock keypress
      $(this).next('.caps-lock-warning').hide();
    }//else else do nothing if not a letter we can use to differentiate
  });

  //Toggle warning message on Caps-Lock toggle (with some limitation)
  $(document).keydown(function(e){
    if(e.which==20){ // Caps-Lock keypress
      var pass = document.getElementById("password");
      if(typeof(pass.caps) === 'boolean'){
        //State has been set to a known value by keypress
        pass.caps = !pass.caps;
        $(pass).next('.caps-lock-warning').toggle(pass.caps);
      }
    }
  });

  //Disable on window lost focus (because we loose track of state)
  $(window).blur(function(e){
    // If window is inactive, we have no control on the caps lock toggling
    // so better to re-set state
    var pass = document.getElementById("password");
    if(typeof(pass.caps) === 'boolean'){
      pass.caps = null;
      $(pass).next('.caps-lock-warning').hide();
    }
  });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="password" id="password" />
<span class="caps-lock-warning" title="Caps lock is on!">CAPS</span>

Note that observing caps lock toggling is only useful if we know the state of the caps lock before the Caps Lock key is pressed. The current caps lock state is kept with a caps JavaScript property on the password element. This is set the first time we have a validation of the caps lock state when the user presses a letter that can be upper or lower case. If the window loses focus, we can no longer observe caps lock toggling, so we need to reset to an unknown state.

awe
  • 21,938
  • 6
  • 78
  • 91
  • 2
    Good idea. If you're going to show a warning to the user that caps lock is on it's probably a good idea to turn that warning off immediately when the caps lock is disabled, otherwise you might confuse the user. – Ajedi32 Jun 10 '15 at 14:22
5

I know this is an old topic but thought I would feed back in case it helps others. None of the answers to the question seem to work in IE8. I did however find this code that works in IE8. (Havent tested anything below IE8 yet). This can be easily modified for jQuery if required.

function capsCheck(e,obj){ 
    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('#'+obj.id).style.visibility = 'visible';
    } 
    else document.getElementById('#'+obj.id).style.visibility = 'hidden';
}

And the function is called through the onkeypress event like this:

<input type="password" name="txtPassword" onkeypress="capsCheck(event,this);" />
<div id="capsWarningDiv" style="visibility:hidden">Caps Lock is on.</div> 
Zappa
  • 453
  • 1
  • 5
  • 14
  • Thanks for the IE8- fix. Incorporated it in my reworked answer (below). This is solid, though. –  Jan 15 '14 at 23:14
3

Recently there was a similar question on hashcode.com, and I created a jQuery plugin to deal with it. It also supports the recognition of caps lock on numbers. (On the standard German keyboard layout caps lock has effect on numbers).

You can check the latest version here: jquery.capsChecker

Community
  • 1
  • 1
Pavel Azanov
  • 188
  • 1
  • 11
3

For jQuery with twitter bootstrap

Check caps locked for the following characters:

uppercase A-Z or 'Ä', 'Ö', 'Ü', '!', '"', '§', '$', '%', '&', '/', '(', ')', '=', ':', ';', '*', '''

lowercase a-Z or 0-9 or 'ä', 'ö', 'ü', '.', ',', '+', '#'

/* check for CAPS LOCK on all password fields */
$("input[type='password']").keypress(function(e) {
    var kc = e.which; // get keycode

    var isUpperCase = ((kc >= 65 && kc <= 90) || (kc >= 33 && kc <= 34) || (kc >= 36 && kc <= 39) || (kc >= 40 && kc <= 42) || kc == 47 || (kc >= 58 && kc <= 59) || kc == 61 || kc == 63 || kc == 167 || kc == 196 || kc == 214 || kc == 220) ? true : false; // uppercase A-Z or 'Ä', 'Ö', 'Ü', '!', '"', '§', '$', '%', '&', '/', '(', ')', '=', ':', ';'
    var isLowerCase = ((kc >= 97 && kc <= 122) || (kc >= 48 && kc <= 57) || kc == 35 || (kc >= 43 && kc <= 44) || kc == 46 || kc == 228 || kc == 223 || kc == 246 || kc == 252) ? true : false; // lowercase a-Z or 0-9 or 'ä', 'ö', 'ü', '.', ','

    // event.shiftKey does not seem to be normalized by jQuery(?) for IE8-
    var isShift = (e.shiftKey) ? e.shiftKey : ((kc == 16) ? true : false); // shift is pressed

    // uppercase w/out shift or lowercase with shift == caps lock
    if ((isUpperCase && !isShift) || (isLowerCase && isShift)) {
        $(this).next('.form-control-feedback').show().parent().addClass('has-warning has-feedback').next(".capsWarn").show();
    } else {
        $(this).next('.form-control-feedback').hide().parent().removeClass('has-warning has-feedback').next(".capsWarn").hide();
    }
}).after('<span class="glyphicon glyphicon-warning-sign form-control-feedback" style="display:none;"></span>').parent().after("<span class='capsWarn text-danger' style='display:none;'>Is your CAPSLOCK on?</span>");

live demo on jsfiddle

Community
  • 1
  • 1
ramiz4
  • 81
  • 3
3

A variable that shows caps lock state:

let isCapsLockOn = false;

document.addEventListener( 'keydown', function( event ) {
  var caps = event.getModifierState && event.getModifierState( 'CapsLock' );
  if(isCapsLockOn !== caps) isCapsLockOn = caps;
});

document.addEventListener( 'keyup', function( event ) {
  var caps = event.getModifierState && event.getModifierState( 'CapsLock' );
  if(isCapsLockOn !== caps) isCapsLockOn = caps;
});

works on all browsers => canIUse

Alice Rocheman
  • 939
  • 1
  • 7
  • 7
  • 1
    Upvoted for giving an up-to-date answer to an old question. You might want to add something like a headline saying something like "For modern browsers (2017->) try this" or "Update for 2017" – eon Jan 09 '18 at 21:43
3

This jQuery-based answer posted by @user110902 was useful for me. However, I improved it a little to prevent a flaw mentioned in @B_N 's comment: it failed detecting CapsLock while you press Shift:

$('#example').keypress(function(e) { 
    var s = String.fromCharCode( e.which );
    if (( s.toUpperCase() === s && s.toLowerCase() !== s && !e.shiftKey )
    ||  ( s.toLowerCase() === s && s.toUpperCase() !== s && e.shiftKey )) {
        alert('caps is on');
    }
});

Like this, it will work even while pressing Shift.

SebasSBM
  • 860
  • 2
  • 8
  • 32
2

This code detects caps lock no matter the case or if the shift key is pressed:

$('#password').keypress(function(e) { 
    var s = String.fromCharCode( e.which );
    if ( (s.toUpperCase() === s && !e.shiftKey) || 
             (s.toLowerCase() === s && e.shiftKey) ) {
        alert('caps is on');
    }
});
formixian
  • 1,549
  • 16
  • 25
2

I wrote a library called capsLock which does exactly what you want it to do.

Just include it on your web pages:

<script src="https://rawgit.com/aaditmshah/capsLock/master/capsLock.js"></script>

Then use it as follows:

alert(capsLock.status);

capsLock.observe(function (status) {
    alert(status);
});

See the demo: http://jsfiddle.net/3EXMd/

The status is updated when you press the Caps Lock key. It only uses the Shift key hack to determine the correct status of the Caps Lock key. Initially the status is false. So beware.

Aadit M Shah
  • 72,912
  • 30
  • 168
  • 299
  • This is a really ingenious solution. But it has the bug that if the Caps Lock is on when the page gains focus, the "capslock" object starts with the incorrect state (off). – Ric Aug 12 '14 at 08:43
  • Indeed it starts with an incorrect state. However when you press any key it automatically corrects its state. If you can figure out a way to set it to the correct state when the page gains focus then I would be more than happy to merge your code. – Aadit M Shah Aug 12 '14 at 10:19
2

Yet another version, clear and simple, handles shifted capsLock, and not constrained to ascii I think:

document.onkeypress = function (e)
{
    e = e || window.event;
    if (e.charCode === 0 || e.ctrlKey || document.onkeypress.punctuation.indexOf(e.charCode) >= 0)
        return;
    var s = String.fromCharCode(e.charCode); // or e.keyCode for compatibility, but then have to handle MORE non-character keys
    var s2 = e.shiftKey ? s.toUpperCase() : s.toLowerCase();
    var capsLockOn = (s2 !== s);
    document.getElementById('capslockWarning').style.display = capsLockOn ? '' : 'none';
}
document.onkeypress.punctuation = [33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,91,92,93,94,95,96,123,124,125,126];

Edit: Sense of capsLockOn was reversed, doh, fixed.

Edit #2: After checking this out some more, I've made a few changes, a bit more detailed code unfortunately, but it handles more actions appropriately.

  • Using e.charCode instead of e.keyCode and checking for 0 values skips a lot of non-character keypresses, without coding anything specific to a given language or charset. From my understanding, it's slightly less compatible, so older, non-mainstream, or mobile browsers may not behave as this code expects, but it's worth it, for my situation anyway.

  • Checking against a list of known punctuation codes prevents them from being seen as false negatives, since they're not affected by caps lock. Without this, the caps lock indicator gets hidden when you type any of those punctuation characters. By specifying an excluded set, rather than an included one, it should be more compatible with extended characters. This is the ugliest, special-casiest bit, and there's some chance that non-Western languages have different enough punctuation and/or punctuation codes to be a problem, but again it's worth it IMO, at least for my situation.

enigment
  • 3,316
  • 7
  • 30
  • 35
2

React

onKeyPress(event) { 
        let self = this;
        self.setState({
            capsLock: isCapsLockOn(self, event)
        });
    }

    onKeyUp(event) { 
        let self = this;
        let key = event.key;
        if( key === 'Shift') {
            self.shift = false;
        }
    }

    <div>
     <input name={this.props.name} onKeyDown={(e)=>this.onKeyPress(e)} onKeyUp={(e)=>this.onKeyUp(e)} onChange={this.props.onChange}/>
                {this.capsLockAlert()}
</div>

function isCapsLockOn(component, event) {
        let key = event.key;
        let keyCode = event.keyCode;

        component.lastKeyPressed = key;

        if( key === 'Shift') {
            component.shift = true;
        } 

        if (key === 'CapsLock') {
            let newCapsLockState = !component.state.capsLock;
            component.caps = newCapsLockState;
            return newCapsLockState;
        } else {
            if ((component.lastKeyPressed !== 'Shift' && (key === key.toUpperCase() && (keyCode >= 65 && keyCode <= 90)) && !component.shift) || component.caps ) {
                component.caps = true;
                return true;
            } else {
                component.caps = false;
                return false;
            }
        }
    }
José Araújo
  • 69
  • 1
  • 5
1

Based on answer of @joshuahedlund since it worked fine for me.

I made the code a function so it can be reused, and linked it to the body in my case. It can be linked to the password field only if you prefer.

<html>
<head>
<script language="javascript" type="text/javascript" >
function checkCapsLock(e, divId) { 
    if(e){
        e = e;
    } else {
        e = window.event;
    }
    var s = String.fromCharCode( e.which );
    if ((s.toUpperCase() === s && s.toLowerCase() !== s && !e.shiftKey)|| //caps is on
      (s.toUpperCase() !== s && s.toLowerCase() === s && e.shiftKey)) {
        $(divId).style.display='block';
    } else if ((s.toLowerCase() === s && s.toUpperCase() !== s && !e.shiftKey)||
      (s.toLowerCase() !== s && s.toUpperCase() === s && e.shiftKey)) { //caps is off
        $(divId).style.display='none';
   } //else upper and lower are both same (i.e. not alpha key - so do not hide message if already on but do not turn on if alpha keys not hit yet)
 }
</script>
<style>    
.errorDiv {
    display: none;
    font-size: 12px;
    color: red;
    word-wrap: break-word;
    text-overflow: clip;
    max-width: 200px;
    font-weight: normal;
}
</style>
</head>
<body  onkeypress="checkCapsLock(event, 'CapsWarn');" >
...
<input name="password" id="password" type="password" autocomplete="off">
<div id="CapsWarn" class="errorDiv">Capslock is ON !</div>
...
</body>
</html>
Cedric Simon
  • 4,571
  • 4
  • 40
  • 52
1

Mottie's and Diego Vieira's response above is what we ended up using and should be the accepted answer now. However, before I noticed it, I wrote this little javascript function that doesn't rely on character codes...

var capsLockIsOnKeyDown = {shiftWasDownDuringLastChar: false,
  capsLockIsOnKeyDown: function(event) {
    var eventWasShiftKeyDown = event.which === 16;
    var capsLockIsOn = false;
    var shifton = false;
    if (event.shiftKey) {
        shifton = event.shiftKey;
    } else if (event.modifiers) {
        shifton = !!(event.modifiers & 4);
    }

    if (event.target.value.length > 0 && !eventWasShiftKeyDown) {
      var lastChar = event.target.value[event.target.value.length-1];
      var isAlpha = /^[a-zA-Z]/.test(lastChar);

      if (isAlpha) {
        if (lastChar.toUpperCase() === lastChar && lastChar.toLowerCase() !== lastChar
          && !event.shiftKey && !capsLockIsOnKeyDown.shiftWasDownDuringLastChar) {
          capsLockIsOn =  true;
        }
      }
    }
    capsLockIsOnKeyDown.shiftWasDownDuringLastChar = shifton;
    return capsLockIsOn;
  }
}

Then call it in an event handler like so capsLockIsOnKeyDown.capsLockIsOnKeyDown(event)

But again, we ended up just using @Mottie s and @Diego Vieira s response

Chris
  • 425
  • 3
  • 12
1

How about using getModifierState()

The getModifierState() method returns true if the specified modifier key was pressed, or activated.

You can use it like:

function checkIfCapsLockIsOn(event) {
  var capsLockIsOn = event.getModifierState("CapsLock");
  console.log("Caps Lock activated: " + capsLockIsOn);
}

This will simply check if CapsLock is ON or OFF and show it in console. You can change the way the function you want to work.

And then use this function on keydown or keyup for example.

<input type="text" onkeydown="checkIfCapsLockIsOn(event)">
Alireza
  • 100,211
  • 27
  • 269
  • 172
0

try this out simple code in easy to understand

This is the Script

 <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('divMayus').style.visibility = 'visible';
 else
   document.getElementById('divMayus').style.visibility = 'hidden';
}
</script>

And the Html

<input type="password" name="txtPassword" onkeypress="capLock(event)" />
 <div id="divMayus" style="visibility:hidden">Caps Lock is on.</div> 
sourabh kasliwal
  • 947
  • 3
  • 8
  • 21
0

try to use this code.

$('selectorOnTheInputTextBox').keypress(function (e) {
        var charCode = e.target.value.charCodeAt(e.target.value.length - 1)
        var capsOn = 
            e.keyCode && 
            !e.shiftKey &&
            !e.ctrlKey &&
            charCode >= 65 && 
            charCode <= 90;

            if (capsOn) 
               //action if true
            else
               //action if false
});

Good Luck :)

Oday Fraiwan
  • 1,147
  • 1
  • 9
  • 21
0

Here is a custom jquery plugin, using jquery ui, made up of all the good ideas on this page and leverages the tooltip widget. The caps lock message is auto applied all password boxes and requires no changes to your current html.

Custom plug in code...

(function ($) {
    $.fn.capsLockAlert = function () {
        return this.each(function () {
            var capsLockOn = false;
            var t = $(this);
            var updateStatus = function () {
                if (capsLockOn) {
                    t.tooltip('open');
                } else {
                    t.tooltip('close');
                }
            }
            t.tooltip({
                items: "input",
                position: { my: "left top", at: "left bottom+10" },
                open: function (event, ui) {
                    ui.tooltip.css({ "min-width": "100px", "white-space": "nowrap" }).addClass('ui-state-error');
                    if (!capsLockOn) t.tooltip('close');
                },
                content: function () {
                    return $('<p style="white-space: nowrap;"/>')
                        .append($('<span class="ui-icon ui-icon-alert" style="display: inline-block; margin-right: 5px; vertical-align: text-top;" />'))
                        .append('Caps Lock On');
                }
            })
            .off("mouseover mouseout")
            .keydown(function (e) {
                if (e.keyCode !== 20) return;
                capsLockOn = !capsLockOn;
                updateStatus();
            })
            .keypress(function (e) {
                var kc = e.which; //get keycode

                var isUp = (kc >= 65 && kc <= 90) ? true : false; // uppercase
                var isLow = (kc >= 97 && kc <= 122) ? true : false; // lowercase
                if (!isUp && !isLow) return; //This isn't a character effected by caps lock

                // event.shiftKey does not seem to be normalized by jQuery(?) for IE8-
                var isShift = (e.shiftKey) ? e.shiftKey : ((kc === 16) ? true : false); // shift is pressed

                // uppercase w/out shift or lowercase with shift == caps lock
                if ((isUp && !isShift) || (isLow && isShift)) {
                    capsLockOn = true;
                } else {
                    capsLockOn = false;
                }
                updateStatus();
            });
        });
    };
})(jQuery);

Apply to all password elements...

$(function () {
    $(":password").capsLockAlert();
});
Ben Gripka
  • 16,012
  • 6
  • 45
  • 41
0

Javascript Code

<script type="text/javascript">
   function isCapLockOn(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('alert').style.visibility = 'visible';
   else
       document.getElementById('alert').style.visibility = 'hidden';
   }
</script>

We now need to associate this script using Html

<input type="password" name="txtPassword" onkeypress="isCapLockOn(event)" />
<div id="alert" style="visibility:hidden">Caps Lock is on.</div> 
M Arfan
  • 4,384
  • 4
  • 29
  • 46
0

In this below code it will be show alert when Caps lock on and they press key using shift.

if we return false; then current char will not append to text page.

$('#password').keypress(function(e) { 
    // e.keyCode is not work in FF, SO, it will
    // automatically get the value of e.which.  
    var s = String.fromCharCode( e.keyCode || e.which );
    if ( s.toUpperCase() === s && s.toLowerCase() !== s && !e.shiftKey ) {
            alert('caps is on');
            return false;
    }
else  if ( s.toUpperCase() !== s) {
            alert('caps is on and Shiftkey pressed');
            return false;
    }
});
nickf
  • 537,072
  • 198
  • 649
  • 721
Naga Harish M
  • 2,779
  • 2
  • 31
  • 45
0

it is late i know but, this can be helpfull someone else.

so here is my simpliest solution (with Turkish chars);

function (s,e)
{
    var key = e.htmlEvent.key;

    var upperCases = 'ABCÇDEFGĞHIİJKLMNOÖPRSŞTUÜVYZXWQ';
    var lowerCases = 'abcçdefgğhıijklmnoöprsştuüvyzxwq';
    var digits = '0123456789';

    if (upperCases.includes(key))
    {
        document.getElementById('spanLetterCase').innerText = '[A]';
    }

    else if (lowerCases.includes(key))
    {
        document.getElementById('spanLetterCase').innerText = '[a]';
    }

    else if (digits.includes(key))
    {
        document.getElementById('spanLetterCase').innerText = '[1]';
    }

    else
    {
        document.getElementById('spanLetterCase').innerText = '';
    }
}
nadir
  • 63
  • 1
  • 11
0

So I found this page and didn't really like the solutions I found so I figured one out and am offering it up to all of you. For me, it only matters if the caps lock is on if I'm typing letters. This code solved the problem for me. Its quick and easy and gives you a capsIsOn variable to reference whenever you need it.

let capsIsOn=false;
let capsChecked=false;

let capsCheck=(e)=>{
    let letter=e.key;
    if(letter.length===1 && letter.match(/[A-Za-z]/)){
        if(letter!==letter.toLowerCase()){
          capsIsOn=true;
          console.log('caps is on');
        }else{
          console.log('caps is off');
        }
        capsChecked=true;
        window.removeEventListener("keyup",capsCheck);
    }else{
      console.log("not a letter, not capsCheck was performed");
    }

}

window.addEventListener("keyup",capsCheck);

window.addEventListener("keyup",(e)=>{
  if(capsChecked && e.keyCode===20){
    capsIsOn=!capsIsOn;
  }
});
Mike Sraj
  • 81
  • 1
  • 4
-1

There is a much simpler solution for detecting caps-lock:

function isCapsLockOn(event) {
    var s = String.fromCharCode(event.which);
    if (s.toUpperCase() === s && s.toLowerCase() !== s && !event.shiftKey) {
        return true;
    }
}
ron tornambe
  • 10,452
  • 7
  • 33
  • 60
-1

When you type, if caplock is on, it could automatically convert the current char to lowercase. That way even if caplocks is on, it will not behave like it is on the current page. To inform your users you could display a text saying that caplocks is on, but that the form entries are converted.

Frederik.L
  • 5,522
  • 2
  • 29
  • 41
  • Yes, but then you'd still need to detect caps lock. Plus, this means that you're disallowing uppercases in passwords, which is sub-optimal. – Dave Liepmann Apr 20 '12 at 14:49
  • to detect if caps lock is on, you have to check if the lowercase version of the char you sent is different from it, if it is --> caps lock, then «Warning : you are using caps lock but our system is converting in lower case», I guess javascript isn't meant to detect caps lock after all (checkings caps lock need a system access), you must find the way around that best fits your need – Frederik.L Oct 22 '12 at 17:53
-8

In jQuery:

$('some_element').keypress(function(e){
       if(e.keyCode == 20){
             //caps lock was pressed
       }
});

This jQuery plugin (code) implements the same idea as in Rajesh's answer a bit more succinctly.

Community
  • 1
  • 1
rz.
  • 19,861
  • 10
  • 54
  • 47
  • 11
    that'll detect if you press caps lock (even if you're turning it off), not whether or not it is on. – nickf Dec 08 '08 at 06:37
  • correct. i'm still trying to figure out if there is a cleaner way to do this than what is in the blogpost linked above. – rz. Dec 08 '08 at 06:48
  • It seems like this could be used to check cap and shift, and would be a bit less wasteful, since it is bound to a single element, like a password field... – Eli Dec 09 '08 at 00:42