keyboard events and dead letters

J

Joaquín Zuazo

I'm trying to find what character was pressed, using an accent with a
dead letter, e.g an á, on an input box.

I have made an small program to check the keyboard events keydown,
keypress and keyup, and only the
keyup one is fired two times. The first with a 0 keycode and the
characte code just later. No keydown or keypress events, and it is
not enough information to know what character was really pressed.
It happens with Firefox 2.0.0.14 on Linux. Firefox on Windows works
and behaves in a different way.

The input box is properly modified, so, I guess Firefox understands
whatever key sequence is
receiving from the Operating or the X system.

Any suggestion?

Thanks in advance.
 
E

Evertjan.

Joaquín Zuazo wrote on 18 mei 2008 in comp.lang.javascript:
I'm trying to find what character was pressed, using an accent with a
dead letter, e.g an  , on an input box.

I have made an small program to check the keyboard events keydown,
keypress and keyup, and only the
keyup one is fired two times. The first with a 0 keycode and the
characte code just later. No keydown or keypress events, and it is
not enough information to know what character was really pressed.
It happens with Firefox 2.0.0.14 on Linux. Firefox on Windows works
and behaves in a different way.

The input box is properly modified, so, I guess Firefox understands
whatever key sequence is
receiving from the Operating or the X system.

Any suggestion?

Why not compare the whole content on each keyup with the earlier content?
 
T

Thomas 'PointedEars' Lahn

Joaquín Zuazo said:
I'm trying to find what character was pressed, using an accent with a
dead letter, e.g an á, on an input box.

Unless you need to find out whether a dead*key* was used, it does not matter.
I have made an small program to check the keyboard events keydown,
keypress and keyup, and only the
keyup one is fired two times. The first with a 0 keycode and the
characte code just later. No keydown or keypress events, and it is
not enough information to know what character was really pressed.
It happens with Firefox 2.0.0.14 on Linux. Firefox on Windows works
and behaves in a different way.

The input box is properly modified, so, I guess Firefox understands
whatever key sequence is
receiving from the Operating or the X system.

Any suggestion?

Current implementations of keyboard events can be considered a madness
(google for "keyboard events"), but fortunately there appears to be a method
to the madness ;-)

For character input, `keydown' and `keyup' are the wrong events and event
handler attributes to look for; use `keypress'.

For character input, `keyCode' is the wrong property to look for in
Mozilla-based UAs; use `charCode' which yields the Unicode code point
of the character/glyph that is about to be put in:

http://developer.mozilla.org/en/docs/DOM:event.charCode

(BTW: Netscape 4 does not appear to support Unicode character input.)

In MSHTML-based UAs like IE, you have to look for the `keyCode' property
of the `keypress' event object instead.

http://msdn.microsoft.com/en-us/library/ms533927(VS.85).aspx

Opera 9.27 supports MSHTML's keyboard event model. Safari 3.1 supports both.

In order to avoid error-prone UA/DOM sniffing, you may use the following:

// keypress event listener
function(e) {
if (!e) e = window.event;
if (e)
{
var charCode = (typeof e.charCode != "undefined"
? e.charCode
: (typeof e.keyCode != "undefined"
? e.keyCode
: charCode);
if (charCode)
{
// ...
}
}
}

[de] <http://brain4.de/programmierecke/js/tastatur.php> greatly helps to see
the differences between the keyboard event models.


HTH

PointedEars
 
T

Thomas 'PointedEars' Lahn

Thomas said:
var charCode = (typeof e.charCode != "undefined"
? e.charCode
: (typeof e.keyCode != "undefined"
? e.keyCode
: charCode);

: charCode));
 
J

Joaquín Zuazo

: charCode));
This is the html test page:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

<html>
<!-- Keyboard events test program, by Joaquín Zuazo -->
<head>
<title>Testing keyboard events</title>
<meta http-equiv="encoding=UTF-8"></meta>

<script language="javascript" type="text/javascript">
window.onload=testkeys;
var checkinput, out;
var title = "Event\t\tkeyCode\t\twhich\t\tcharCode\tfromCharCode
\tInput Box\n\n";

function testkeys()
{
checkinput = document.getElementById("checkinput");
out = document.getElementById("out");
out.innerHTML = title;
checkinput.onkeydown=check_down;
checkinput.onkeypress=check_press;
checkinput.onkeyup=check_up;
}
function reset_all()
{
out.innerHTML = title;
checkinput.value ="";

}
function output_message(function_name,event)
{
var valid_one = event.keyCode ? event.keyCode : event.which ?
event.which : event.charCode;
var message = function_name + "\t"
+ ( event.keyCode ? event.keyCode : event.keyCode == 0 ?
0 : "undef" )
+ "\t\t"
+ ( event.which ? event.which : event.wich == 0 ?
0 : "undef" )
+ "\t\t"
+ ( event.charCode ? event.charCode : event.charCode == 0 ?
0 :"undef" )
+ "\t\t"
+ ( valid_one >= 32 ? String.fromCharCode ( valid_one ) :
"Ctrl" )
+ "\t\t"
+ checkinput.value
+ "\n";
out.innerHTML += message;
}
function check_press(e)
{
var event = e ? e : window.event;
output_message("keypress",event);
}
function check_up(e)
{
var event = e ? e : window.event;
output_message("keyup ",event);
}
function check_down(e)
{
var event = e ? e : window.event;
output_message("keydown ",event);
}
</script>
</head>

<body>
<h1>Testing keyboard events</h1>
<button onclick="reset_all();">Reset </button>
<input id="checkinput"></input>
<pre id="out"> </pre>
</body>

</html>

This is the return with Firefox 2.0.0.14 with Linux/Fedora
keyup 0 undef 0 Ctrl
keyup 65 65 0 A á
And with Firefox 2.0.0.14 on Windows Xp
keydown
keyup 0 undef 0 Ctrl
keyup 65 65 0 A á
 
J

Joaquín Zuazo

: charCode));
This is the test page

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

<html>
<!-- Keyboard events test program, by Joaquín Zuazo -->
<head>
<title>Testing keyboard events</title>
<meta http-equiv="encoding=UTF-8"></meta>

<script language="javascript" type="text/javascript">
window.onload=testkeys;
var checkinput, out;
var title = "Event\t\tkeyCode\t\twhich\t\tcharCode\tfromCharCode
\tInput Box\n\n";

function testkeys()
{
checkinput = document.getElementById("checkinput");
out = document.getElementById("out");
out.innerHTML = title;
checkinput.onkeydown=check_down;
checkinput.onkeypress=check_press;
checkinput.onkeyup=check_up;
}
function reset_all()
{
out.innerHTML = title;
checkinput.value ="";

}
function output_message(function_name,event)
{
var valid_one = event.keyCode ? event.keyCode : event.which ?
event.which : event.charCode;
var message = function_name + "\t"
+ ( event.keyCode ? event.keyCode : event.keyCode == 0 ?
0 : "undef" )
+ "\t\t"
+ ( event.which ? event.which : event.wich == 0 ?
0 : "undef" )
+ "\t\t"
+ ( event.charCode ? event.charCode : event.charCode == 0 ?
0 :"undef" )
+ "\t\t"
+ ( valid_one >= 32 ? String.fromCharCode ( valid_one ) :
"Ctrl" )
+ "\t\t"
+ checkinput.value
+ "\n";
out.innerHTML += message;
}
function check_press(e)
{
var event = e ? e : window.event;
output_message("keypress",event);
}
function check_up(e)
{
var event = e ? e : window.event;
output_message("keyup ",event);
}
function check_down(e)
{
var event = e ? e : window.event;
output_message("keydown ",event);
}
</script>
</head>

<body>
<h1>Testing keyboard events</h1>
<button onclick="reset_all();">Reset </button>
<input id="checkinput"></input>
<pre id="out"> </pre>
</body>

</html>
This is the result for the key sequence 'a on Linux, Firefox 2.0.0.14
Event keyCode which charCode fromCharCode Input Box

keyup 0 undef 0 Ctrl
keyup 65 65 0 A á

And this is the result with Firefox 2.0.0.14 on Windows Xp
Event keyCode which charCode fromCharCode Input Box

keydown 222 222 0 Þ
keyup 222 222 0 Þ
keydown 65 65 0 A
keypress 0 225 225 á
keyup 65 65 0
A á

Do you think is this a bug of Firefox?
The problem is that the only place where is kept valid information
with the Linux implementation
is inside the input text box, and hacking this is somewhat dirty.
I really thank any suggestion
 
T

Thomas 'PointedEars' Lahn

Joaquín Zuazo said:
This is the html test page:

Why have you not just used my code or the reliable test site I pointed you
to instead of this, sorry, mostly clueless nonsense?
checkinput.onkeydown=check_down;
checkinput.onkeypress=check_press;
checkinput.onkeyup=check_up;

Avoid those proprietary features, use event handler attributes or DOM 2
Event methods when possible.
var valid_one = event.keyCode ? event.keyCode : event.which ?
event.which : event.charCode;

I had chosen the order of evaluation with purpose. Mozilla and MSHTML
support `keyCode' but implement it differently; only Mozilla and Safari
support charCode which is equivalent to MSHTML's keyCode *on keypress*.

If you reverse evaluation order like this, you get misleading results.
Especially, String.fromCharCode(event.keyCode) is not supposed to return
the character that would have been/has been input in all cases.
+ "\t\t"
+ ( event.which ? event.which : event.wich == 0 ?
0 : "undef" )

Here is also a typo.
+ "\t\t"
+ ( valid_one >= 32 ? String.fromCharCode ( valid_one ) :
"Ctrl" )

See above.
[..]
out.innerHTML += message;

There is no need for proprietary error-prone `innerHTML' here.
function check_press(e)
{
var event = e ? e : window.event;

See my code for a more efficient and reliable feature test.
</script>
</head>

<body>
<h1>Testing keyboard events</h1>
<button onclick="reset_all();">Reset </button>

The `button' element should not be used when the `input' element with type
`button' suffices.
<input id="checkinput"></input>

The end tag for the `input' element is forbidden in HTML, per the
Specification's normative prose.
<pre id="out"> </pre>
</body>

</html>

This is the return with Firefox 2.0.0.14 with Linux/Fedora
keyup 0 undef 0 Ctrl
keyup 65 65 0 A á
And with Firefox 2.0.0.14 on Windows Xp
keydown
keyup 0 undef 0 Ctrl
keyup 65 65 0 A á

I don't see `keypress' which my followup was all about. Are you saying
`keypress' never occurs there? (I can confirm the opposite for Fx 2.0.0.14
on Windows XP.) Double-check with fixed test script code, Valid markup and
the `keypress' attribute, or with the test case I pointed you to.


PointedEars
 
J

Joaquín Zuazo

Joaquín Zuazo said:
This is the html test page:

Why have you not just used my code or the reliable test site I pointed you
to instead of this, sorry, mostly clueless nonsense?
checkinput.onkeydown=check_down;
checkinput.onkeypress=check_press;
checkinput.onkeyup=check_up;

Avoid those proprietary features, use event handler attributes or DOM 2
Event methods when possible.
var valid_one = event.keyCode ? event.keyCode : event.which ?
event.which : event.charCode;

I had chosen the order of evaluation with purpose. Mozilla and MSHTML
support `keyCode' but implement it differently; only Mozilla and Safari
support charCode which is equivalent to MSHTML's keyCode *on keypress*.

If you reverse evaluation order like this, you get misleading results.
Especially, String.fromCharCode(event.keyCode) is not supposed to return
the character that would have been/has been input in all cases.
+ "\t\t"
+ ( event.which ? event.which : event.wich == 0 ?
0 : "undef" )

Here is also a typo.
+ "\t\t"
+ ( valid_one >= 32 ? String.fromCharCode ( valid_one ) :
"Ctrl" )

See above.
[..]
out.innerHTML += message;

There is no need for proprietary error-prone `innerHTML' here.
function check_press(e)
{
var event = e ? e : window.event;

See my code for a more efficient and reliable feature test.
</script>
</head>
<body>
<h1>Testing keyboard events</h1>
<button onclick="reset_all();">Reset </button>

The `button' element should not be used when the `input' element with type
`button' suffices.
<input id="checkinput"></input>

The end tag for the `input' element is forbidden in HTML, per the
Specification's normative prose.
<pre id="out"> </pre>
</body>

This is the return with Firefox 2.0.0.14 with Linux/Fedora
keyup 0 undef 0 Ctrl
keyup 65 65 0 A á
And with Firefox 2.0.0.14 on Windows Xp
keydown
keyup 0 undef 0 Ctrl
keyup 65 65 0 A á

I don't see `keypress' which my followup was all about. Are you saying
`keypress' never occurs there? (I can confirm the opposite for Fx 2.0.0.14
on Windows XP.) Double-check with fixed test script code, Valid markup and
the `keypress' attribute, or with the test case I pointed you to.

PointedEars
--
Anyone who slaps a 'this page is best viewed with Browser X' label on
a Web page appears to be yearning for the bad old days, before the Web,
when you had very little chance of reading a document written on another
computer, another word processor, or another network. -- Tim Berners-Lee

Yes no keypress events. Only two keyup events as shown.
 
J

Joaquín Zuazo

Joaquín Zuazo said:
[103 quoted lines]
Yes no keypress events. Only two keyup events as shown.

(sic!)

http://jibbering.com/faq/#FAQ2_3

PointedEars
--
Anyone who slaps a 'this page is best viewed with Browser X' label on
a Web page appears to be yearning for the bad old days, before the Web,
when you had very little chance of reading a document written on another
computer, another word processor, or another network. -- Tim Berners-Lee

There is another place to check keyboard events: http://unixpapa.com/js/testkey.html
that I
have worked before. The result is the same.

Also there is a line I don't understand from your code Is it a typo?
var charCode = (typeof e.charCode != "undefined"
? e.charCode
: (typeof e.keyCode != "undefined"
? e.keyCode
: charCode);
:charCode); <<<<<<<

var charCode = charCode if no other value is available ?

Thanks a lot.
 
T

Thomas 'PointedEars' Lahn

Joaquín Zuazo said:
Joaquín Zuazo said:
[103 quoted lines]
Yes no keypress events. Only two keyup events as shown.
(sic!)
[...]

Could you please trim your quotes?
There is another place to check keyboard events: http://unixpapa.com/js/testkey.html
that I have worked before. The result is the same.

Also there is a line I don't understand from your code Is it a typo?
var charCode = (typeof e.charCode != "undefined"
:charCode); <<<<<<<

Another `)' is missing before the `;'. I had corrected that in a followup
already.
var charCode = charCode if no other value is available ?

Exactly. At this point, the `charCode' variable is already instantiated
(since variable instantiation comes before execution), but not explicitly
initialized yet. So its value is `undefined', the sole value of the
Undefined type. It is a convenient way to avoid reproducing the variable
identifier and to assign `undefined' anyway (i.e. keep the initial
`undefined' value), without having to resort to the `undefined' property of
the Global Object, which is not universally available, or read access to
non-existing properties, which would cause strict script warnings in Geckos.

If you find this too confusing, you may use an explicit universally
available false-value (like `null' or `false') or you can write

var charCode;

if (typeof e.charCode != "undefined")
{
charCode = e.charCode;
}
else if (typeof e.keyCode != "undefined")
{
charCode = e.keyCode;
}

instead.


PointedEars
 
T

Thomas 'PointedEars' Lahn

[snipped attribution novel]

Joaquín Zuazo said:
Thomas said:
Joaquín Zuazo said:
[103 quoted lines]
Yes no keypress events. Only two keyup events as shown.
(sic!)

There is another place to check keyboard events: http://unixpapa.com/js/testkey.html
that I have worked before. The result is the same.

"Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.1.12) Gecko/20080129
Iceweasel/2.0.0.12 (Debian-2.0.0.12-0etch1)":

| keydown keyCode=68 (D) which=68 (D) charCode=0
keyIdentifier=undefined
| keypress keyCode=0 which=100 (d) charCode=100 (d)
keyIdentifier=undefined
| keyup keyCode=68 (D) which=68 (D) charCode=0
keyIdentifier=undefined

So probably it's a bug in the Firefox version of your Linux distribution.

Please trim your quotes to the relevant parts.


PointedEars
 
J

Joaquín Zuazo

[snipped attribution novel]

Joaquín Zuazo said:
Thomas said:
Joaquín Zuazo wrote:
[103 quoted lines]
"Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.1.12) Gecko/20080129
Iceweasel/2.0.0.12 (Debian-2.0.0.12-0etch1)":

| keydown keyCode=68 (D) which=68 (D) charCode=0
keyIdentifier=undefined
| keypress keyCode=0 which=100 (d) charCode=100 (d)
keyIdentifier=undefined
| keyup keyCode=68 (D) which=68 (D) charCode=0
keyIdentifier=undefined

So probably it's a bug in the Firefox version of your Linux distribution.

I guess from your message, that you are pressing the key "d". This
works well with my distribution,
and with the same result you are posting.

The problem comes when I need to identify an "á" or an "ö". For that,
I must press two keys, one for
the accent ( the dead key ) and other for the letter itself with an
spanish keyboard, or an english international
keyboard, that provides dead letters also.

Then, only two keyup events are returned for all the keys pressed.

With windows, you get five keyboard events, and all the information
you need to identify
the key.
Thanks a lot for your help.
 
T

Thomas 'PointedEars' Lahn

Joaquín Zuazo said:
Thomas said:
[snipped attribution novel]
Joaquín Zuazo said:
Thomas 'PointedEars' Lahn wrote:
Joaquín Zuazo wrote:
[103 quoted lines]

"Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.1.12) Gecko/20080129
Iceweasel/2.0.0.12 (Debian-2.0.0.12-0etch1)":

| keydown keyCode=68 (D) which=68 (D) charCode=0
keyIdentifier=undefined
| keypress keyCode=0 which=100 (d) charCode=100 (d)
keyIdentifier=undefined
| keyup keyCode=68 (D) which=68 (D) charCode=0
keyIdentifier=undefined

So probably it's a bug in the Firefox version of your Linux distribution.

I guess from your message, that you are pressing the key "d". This
works well with my distribution, and with the same result you are posting.

The problem comes when I need to identify an "á" or an "ö". For that,
I must press two keys, one for the accent ( the dead key ) and other
for the letter itself with an spanish keyboard, or an english international
keyboard, that provides dead letters also.

Sorry, I missed that this time.
Then, only two keyup events are returned for all the keys pressed.

I am afraid I have to confirm this (with only "keypress" suppressed):

| keyup keyCode=0 which=0 charCode=0
keyIdentifier=undefined
| ókeyup keyCode=79 (O) which=79 (O) charCode=0
keyIdentifier=undefined
With windows, you get five keyboard events, and all the information
you need to identify the key.

Yes, indeed (same character, same settings):

| keydown keyCode=221 which=221 charCode=0
keyIdentifier=undefined
| keyup keyCode=221 which=221 charCode=0
keyIdentifier=undefined
| keydown keyCode=79 (O) which=79 (O) charCode=0
keyIdentifier=undefined
| keypress keyCode=0 which=243 charCode=243
keyIdentifier=undefined
| keyup keyCode=79 (O) which=79 (O) charCode=0
keyIdentifier=undefined

So ISTM for Linux you have to watch for a keyup event for a character key
immediately preceded by a keyup event where keyCode == which == 0.
Unfortunately, `charCode' is not available then, and ISTM keyCode/which
is specific to a keyboard layout. But maybe it suffices here.


PointedEars
 
J

Joaquín Zuazo

So ISTM for Linux you have to watch for a keyup event for a character key
immediately preceded by a keyup event where keyCode == which == 0.
Unfortunately, `charCode' is not available then, and ISTM keyCode/which
is specific to a keyboard layout. But maybe it suffices here.

The problem is than you can not know even what kind of accent was
pressed.
The only place where you can get the information is within the input
box
value.

I think this is a bug of Firefox.
 
T

Thomas 'PointedEars' Lahn

Joaquín Zuazo said:
The problem is than you can not know even what kind of accent was
pressed. The only place where you can get the information is within
the input box value.

Right. So that would mean evaluation after input, using .selectionStart and
..selectionEnd. Not pretty, but works.
I think this is a bug of Firefox.

Or of X? Yes, you should file a bug.


PointedEars
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,989
Messages
2,570,207
Members
46,782
Latest member
ThomasGex

Latest Threads

Top