1

Given a keydown event in the browser, how can I predict whether that key event will result in character input? For example, hitting the left arrow doesn't input characters but hitting the a key inputs an A (unless ctrl or alt is down).

I don't need to know what character will be input, just whether the key event will result in an input.

I'm targeting Chrome. Bonus points if your solution works in an IME.

Note: I'm asking about the keydown event, not a downstream event like keypress or oninput.

amwinter
  • 3,121
  • 2
  • 27
  • 25
  • have a look at this post very much like you're looking for: http://stackoverflow.com/questions/7590011/get-val-on-keydown-not-keyup – Roshan Jun 15 '13 at 14:30
  • @RoshanJha similar, but the answer there is to use keypress or oninput. I'm wondering if there's a way to do it earlier in the pipeline. Also, the accepted answer to that question is a broken link. – amwinter Jun 15 '13 at 14:36
  • possible duplicate of [Translate Javascript keyCode into charCode for non-U.S. keyboard layout (i.e. azerty)](http://stackoverflow.com/questions/5306132/translate-javascript-keycode-into-charcode-for-non-u-s-keyboard-layout-i-e-az) – amwinter Jun 17 '13 at 19:37

3 Answers3

0

There's an HTML 5 event: input. MDN: https://developer.mozilla.org/en-US/docs/Web/Reference/Events/input. Other than that there's no proper solution.

Ok, I think I have a solution. I don't know how good it is but it works. Have a look: http://jsfiddle.net/tLPsL/

It's basically saving the value of the input onkeydown and checking it in onkeyup.

$('#sattar').keydown(function() {
    window.SATTAR = $(this).val();
});

$('#sattar').keyup(function() {
    if(window.SATTAR !== $(this).val()) {
        alert("changed");
    }
});
Abdulsattar Mohammed
  • 10,154
  • 13
  • 52
  • 66
0

[updated]

use this

$(document).keydown(function(event){
    console.log(event.which);
});

and filter the value of the event.which according to your needs using the ascii values and exclude the numbers that appear with unwanted buttons

for example (this example demonstrates accepting small letters only):

$(document).keydown(function(event){
    var x = event.which;
    if (x <= 90 && x >=65) console.log('accepted');
    else console.log('not accepted');
});

JSFiddle

[update] :

If you don't like this method you can use another that detects an input to any textfield or textarea :

$('input,textarea').change(function(){
    console.log('input detected!');
});
$(document).keyup(function(event){
    var x = $(event.target);
    if (x[0].nodeName == 'INPUT' || x[0].nodeName == 'TEXTAREA'){ //you can filter the backspace if you don't want to consider it a change on the input by anding it with the whole argument here using the key number explained above
        x.blur().focus();
    }
});

DEMO

note: The first method works for all languages as the same keyboard keys are used for inputs of different characters but they still can type.

Community
  • 1
  • 1
CME64
  • 1,673
  • 13
  • 24
  • ok, but is there a reliable way to do this that doesn't choke on international keyboard layouts? I don't want to have unspecified behavior in my app every time someone types an international character. – amwinter Jun 16 '13 at 23:55
  • Converting key codes to character codes is normally a feature the platform provides. I'm uncomfortable implementing the 'filter' you're talking because when I get it wrong my app will get weird and buggy. I'd feel better about a well-tested library, or at least a normative doc of the browser's key translation logic. – amwinter Jun 17 '13 at 00:02
  • here you go .. tell me if that's what you wanted – CME64 Jun 17 '13 at 01:27
  • `change` and `keyup` are too far downstream for me. I'd like to do this in the `keydown` event. – amwinter Jun 17 '13 at 02:16
  • @amwinter you can use keydown instead but it won't perform as well as keyup .. why do you have to use keydown? and why are those downstream for you?, please explain your reasons – CME64 Jun 17 '13 at 02:20
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/31842/discussion-between-amwinter-and-cme64) – amwinter Jun 17 '13 at 02:24
-1

Sources && tips:

I saw the characters keydata list in this site.
-To make it crossplatform and crossbrowser, I suggest you to watch this site
-You can test the keydown event here.
-Jquery also suggest to use key which because it normalizes keycode and charcode (i think this can be usefull for the crossbrowser part but I didn't find a table like the one I posted before for keycode), see details here.


To the end, a personal thought: I wouldn't appear rude by telling this so please, try to understand, you had 3 clear and working answer, should be your interest to improve details to make it working as you need, especially because, for many reason, (like time, hardware disponibility, no one pay us, freelancer site is elsewhere, etc etc), who are helping you, maybe, can't do your entirely work.


EDIT

Considering your needs, I wrote this code, keeps in mind that combination key are hard to handle, so, you should test this example before to re-use it. fiddle

<!DOCTYPE html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="http://code.jquery.com/jquery-1.9.1.js"></script>
<script>
$(document).keydown(
    function(event){
        if(event.target!='[object HTMLBodyElement]'){//Are we in an input?
            if(!event.ctrlKey && !event.altKey){//Are we using a combo ctrl or alt?
                if(event.keyCode==13 || event.keyCode==8 || event.keyCode==32 || (event.keyCode>45 && event.keyCode<91) || event.keyCode==188 || (event.keyCode>189 && event.keyCode<193) || (event.keyCode>218 && event.keyCode<222)){
                    //It is a char?
                    document.getElementById('valid').innerHTML+=event.keyCode+' ';
                    document.getElementById('idlast').innerHTML=event.target.id; 
                }
            }
        }
    }
);
</script>
</head>
<body>
<input id="a" type="text"></input>
<textarea id="b">a</textarea>
<div id="c" contenteditable="true">a</div>
<div id="d" style="width:200px;height:200px;background-color:red">a</div>
last keydown in: <span id="idlast"></span><br>
for keypress in input:<span id="valid"></span><br>
</body>
</html> 

END EDIT

For first if the focus is on an object that is not an input(textarea,contenteditable...) you are targeting the body. So if the target is the body, for sure you are not writing somewhere.

Then I suggest you to see this example, keypress is probably usefull for your aim, because it seems to don't register keys that aren't an input.

    <!DOCTYPE html>
    <head>

    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
    <script src="http://code.jquery.com/jquery-1.9.1.js"></script>
    <script>
$(document).keypress(
    function(event){
        if(event.target!='[object HTMLBodyElement]'){
            document.getElementById('valid').innerHTML=document.getElementById('valid').innerHTML+event.keyCode+' ';
            document.getElementById('idlast').innerHTML=event.target.id;            
        }else{
            document.getElementById('out').innerHTML=document.getElementById('out').innerHTML+event.keyCode+' ';
        }
    }
);

$(document).keydown(function(e){document.getElementById('down').innerHTML=document.getElementById('down').innerHTML+e.keyCode+' ';});
    </script>
    </head>
    <body>
    <input id="a" type="text"></input>
<textarea id="b">a</textarea>
<div id="c" contenteditable="true">a</div>
<div id="d" style="width:200px;height:200px;background-color:red">a</div>
last keypress input id: <span id="idlast"></span><br>
for keypress in input:<span id="valid"></span><br>
for keypress out:<span id="out"></span><br>
for keydown:<span id="down"></span><br>
    </body>
    </html>
  • thanks, but I'm specifically looking for a way to do this in `keydown` -- all of my arrow-key logic is in `keydown` and I'd rather not handle another event. – amwinter Jun 16 '13 at 23:51
  • Thanks, but how did you get that particular combination of keycodes? Are you sure it works on different platforms and different keyboards? – amwinter Jun 17 '13 at 19:20
  • @amwinter I added some rows at the beginning of the answer – Alessandro Gabrielli Jun 17 '13 at 21:29
  • Sorry, didn't mean to waste your time or make you write any more code. All I meant was that I'm not an expert on keyboard input and international layouts. If I made a list of key codes, I couldn't guarantee that list is correct. I would only trust a keycode filter if it was part of a widely-used and widely-tested library. – amwinter Jun 17 '13 at 23:03
  • @amwinter Well, I'm not wasting time, I just listed some of the reasons which could stop a person to helps, but, if I reply, I choose to spend time here and I try to give complete answer. As you can't test this solution in different operative systems, a solution to this could be a virtual machine from where to load and test differents os (thing impossible for me, because i'm running win xp with low resources). If you are interested in a library I can suggest you to read this http://stackoverflow.com/questions/2353417/which-is-the-best-javascript-keyboard-event-library-hotkeys-shortcuts – Alessandro Gabrielli Jun 17 '13 at 23:33
  • I'll check out the libraries. Thanks for your help. – amwinter Jun 17 '13 at 23:58