Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting correct character on keyboard event

I am making a little word game where I need to get the last char that users enters on their keyboards. I figured two ways to do this.

First one is to get each char by listening on document keyboard event and getting it by keycode. It worked very well until I started writing chars with keyboard dead keys (like Ā). String.fromCharCode(e.keyCode) translates it to A as the keyCode is for the A, but there seems to be nothing on the event regarding dead key or real char that the event produced.

Second one is to keep a hidden input always focused (bad) and on keyboard event getting last char of input's value, but this only works if I write quite slowly. My code looks like this:

function is_char(e){
  return (!e.ctrlKey && !e.altKey && !e.metaKey &&
                        (e.keyCode >= 65 && e.keyCode <= 90) || 
                        (e.keyCode >= 97 && e.keyCode <= 122)
                );
}
$('#fake_input').on('keyup', function(e){
  if (is_char(e)){
    $('#result').append(this.value[this.value.length - 1]);
  }
}).focus();

Here is working example - http://jsfiddle.net/YkaBm/1/ - you should get the same word below the input, but when you write a little faster it turns out wrong.

Do you have some suggestions how to get the real (correct) character on keyboard event or why input keyup event is acting like this?

Update!

As I mentioned in comments semir.babajic answer didn't quite work for my case, but thanks to Semir I found that this silly solution works:

function is_char(e){
  return (!e.ctrlKey && !e.altKey && !e.metaKey &&
                        (e.keyCode >= 65 && e.keyCode <= 90) || 
                        (e.keyCode >= 97 && e.keyCode <= 122)
                );
}
var x = 0;
$('#fake_input').on('keyup', function(e){
  if (e.keyCode === 8){
    x--;
  }
  else if (is_char(e)){
    x++;
    $('#result').append(this.value[x-1]);
  }
}).focus();

I would still love to find a way to get the real character from keyboard event using any of $(document) keyboard events, because keeping input focused doesn't seem as a good solution.

Update 2!

Just in case anyone else is having similar issue, I found this solution the best:

App.insert_char = function(c){
    if (c && c.toUpperCase() != c.toLowerCase()){
        console.log(c);
    }
};

if ('oninput' in $('#fake_input')[0]){
    $('#fake_input').on('input', function(e){
        App.insert_char(this.value[this.value.length - 1]);
    });
}
else if ('onpropertychange' in $('#fake_input')[0]){
    $('#fake_input').on('propertychange', function(e){
        App.insert_char(this.value[this.value.length - 1]);
    });
}
else  if ('ontextInput' in $('#fake_input')[0]){
    $('#fake_input').on('textInput', function(e){
        App.insert_char(this.value[this.value.length - 1]);
    });
}
like image 597
Gints Murans Avatar asked Jan 10 '13 08:01

Gints Murans


1 Answers

This line was causing a "bottleneck": this.value[this.value.length - 1], it was simply slow.

Try this instead:

Updated:

$('#fake_input').keypress(function(e){
    $('#result').append(String.fromCharCode(e.which) + '<br />');
}).focus();

Explanation. I assume you'd want to use keypress instead of keyup to trap characters. Note that keyup does not have nothing to do with characters. It only tells you the keycode of the keyboard signal it received. With keypress, you can determine the case because you get a keycode for character.

http://jsfiddle.net/YkaBm/8/

Regards.

like image 96
semir.babajic Avatar answered Oct 02 '22 19:10

semir.babajic