5

I've written the following code that writes to the console "true" if the [Shift] was pressed on a keyup even and "false" otherwise.

<script>
    var el = document.getElementById("myInput");
    el.addEventListener("keyup", function (e) {            
        console.log(e.shiftKey);            
    });
</script>

For some reason, this code doesn't work when the event is triggered by pressing a number on the 10-key. If I hold Shift and press Numpad5, it logs false. I see the same behavior in Chrome, Firefox, and IE.

I need to be able to detect if the user is holding [Shift] when a number on the 10-key is pressed.

Edit: In response to @sagar's comment, I tested specifically with the keys 1-10 because that is what I expect my user's to press. Other keys will be ignored for the time being. I want to be able to tell when the user presses a key for a digit 1-10 and whether or not [Shift] was pressed.

Vivian River
  • 31,198
  • 62
  • 198
  • 313
  • with other keys (instead of num) code works properly? – sagar Jul 29 '19 at 17:55
  • 1
    When testing your code it worked as you desired. Perhaps there is a difference in how your keyboard is responding? Is it a laptop with a function key lock or something else interfering? Try using a different keyboard? – BA_Webimax Jul 29 '19 at 18:15
  • @BA_Webimax I guess you're right, on my keyboard it didn't even log anything since there's no "Shift-based" key on the numpad (Or that's what I think at least) – Mahmoud Atwa Jul 29 '19 at 18:19
  • I think there is some kind of flag turning ON /OFF while num lock is ON/OFF. That generates unexpected behaviour. As I tested this over my laptop turning on/off num lock in both cases result changes. If Num Lock off it logs true otherwise false – sagar Jul 29 '19 at 18:22
  • 1
    Moreover, on analysing logs I found if you turn on the num lock and press shift + num pad (numbers only) there will be two events. One for shift key and another for number key. Possibly it is OS-level interpretation of num lock, num pad and shift key. – sagar Jul 29 '19 at 18:33

4 Answers4

1

you can base your condition on e.getModifierState("NumLock") status if it's ON or OFF because when it's ON your e.shiftKey is false and if it's off your e.shiftKey is true

press on the Num lock to test

var el = document.getElementById("myInput");
el.addEventListener("keyup", function(e) {

  console.log(e.getModifierState("NumLock"))
});
<input type="text" id="myInput" />
Aziz.G
  • 3,599
  • 2
  • 17
  • 35
  • 1
    It hadn't occurred to me that NumLock has anything to do with it. However, I still need to know if [Shift] is pressed. Is there a way to do this? – Vivian River Jul 29 '19 at 18:19
  • yes you're right, I spend some time with that and i figure out that when numbers lock is active the `e.codeKey` between 95 and 105 returns always false even with `e.shiftKey` sorry i didn't find something works – Aziz.G Jul 29 '19 at 21:19
1

Create an object with the key numbers that the user must press to perform this action:

const KeysEnum = {
        "ENTER": 16,
        "SHIFT": 13,
}

let keysPressed = {
};

const handleEventShiftAndEnterPress = () => {
      console.log ('User Press Shift Enter');
}

window.document.addEventListener ('keydown', function (event) {
    keysPressed[event.keyCode.toString()] = true;
    if (keysPressed [KeysEnum.SHIFT] && keysPressed [KeysEnum.ENTER]) {
       handleEventShiftAndEnterPress ();
       keysPressed [KeysEnum.SHIFT] = false; 
    keysPressed [KeysEnum.ENTER] = false;
    }
});

as long as you control the keystroke object, you can do and know the state of each key whenever you like, so it's easy to do what you need :)

  • It had occurred to me to try something like this. It sounds like a lot of extra work and it would break if the user shifted the focus away with the mouse while holding down keys. – Vivian River Jul 29 '19 at 18:29
  • I didn't understand the problem of using keyCode to detect SHIFT instead of using e.shiftKey. I use it for shortcut keys with an Enum and a keystroke object. Works great :) What is your intention in using shiftKey? Can you detail what you want to do? – Nathan Nacimento Jul 29 '19 at 21:44
  • My intention is straightforward: I want the program to listen for keystrokes on the numpad and perform one action when a key is pressed if [Shift] is held and a different action otherwise. – Vivian River Jul 30 '19 at 16:27
0

Unfortunately, it looks like this is somehow a limitation of the Windows operating system and I have no idea why this limitation exists. I've seen examples on StackOverflow of developers encountering this same issue in other contexts.

For now, here's a solution that seems to work. I don't like it and I think I shouldn't have to do this, but this is the best thing I could find.

I've discovered that when NumLock is on, if I hold [Shift] and press [Num5], there is a keyup event from [Shift] fired immediately before the keydown event for [Num5]. On my workstation, if I grab timestamps of these two events, they will be 5 ms or less part. I simply wrote code that checks these two timestamps and if they are 10 ms apart or less, my application responds to the input considering that the user was holding [Shift] and pressing [Num5].

Since this code runs in a browser, I presume that other platforms will not have this limitation and it still does check for the event to indicate that [Shift] was pressed.

Vivian River
  • 31,198
  • 62
  • 198
  • 313
-1

This is a little bit of a special case, special key + numbers.

The key event contains an entry shiftKey (ctrlKey as well).

To handle numbers from both the right num pad and the top numbers keys, we can test to see if event.code contains a number.

document.addEventListener ('keydown', function (e) {
    /* If shift key is down */
    if (e.shiftKey) {
         /* Test if e.code contains numbers */
         if (/\d/.test(e.code)){
               console.log("SHIFTKEY + NUMBER");
         }  
    }
},false)

This is for the detection, now the goal is to extract the number from that string:

let keys = []
document.addEventListener ('keydown', function (e) {
    if (e.shiftKey) {
         if (/\d/.test(e.code)){
               hasInt(e.code)
               console.log("SHIFTKEY + NUMBER " + keys[keys.length-1])
               console.log(keys)
         }
         
    }
},false)

/* Extract numbers from string */
/* https://stackoverflow.com/a/56510812/2494754 */
function hasInt(me){
  let i = 1,a = me.split(""),b = "",c = "";
  a.forEach(function(e){
   if (!isNaN(e)){
     c += e
     i++
   } else {b += e}
 })
 keys.push(+c)
}
Hold SHIFT + any numbers
NVRM
  • 11,480
  • 1
  • 88
  • 87
  • This is not the answer. In my question, I already showed that I was looking at the value of e.shiftKey and it reads as false even when [Shift] is pressed. It looks like this has something to do with NumLock. – Vivian River Jul 29 '19 at 20:21
  • This is not the answer but a working solution to your problem. – NVRM Jul 29 '19 at 20:38
  • It is not a working solution to my problem because it depends on the value of e.shiftKey being true when the [Shift] key is pressed and false otherwise. When NumLock is on and the num pad keys are pressed, e.shiftKey is always false. – Vivian River Jul 29 '19 at 20:41