Forum Moderators: open

Message Too Old, No Replies

onkeypress, arrows and so on

onkeypress, arrows and percent character is that possible?

         

gergoe

11:04 pm on Dec 3, 2007 (gmt 0)

10+ Year Member



Hello,

Does anyone made (complete) success on handling onkeypress events in major browsers?

For example:

  • The onkeypress with the left arrow gives the keycode of 37;
  • The onkeypress with the percent character gives the keycode of 37 - again;

That's ain't nice, but let's handle the situation by checking the state of the shift key:
  • The onkeypress with the left arrow gives the keycode of 37 (modifiers false);
  • The onkeypress with the percent character gives the keycode of 37 (modifiers true);

Great, one could think it is solved, but:
  • The onkeypress with the left arrow selecting the characters to the left (pressing the shift key) gives the keycode of 37 (modifiers true) - again;

All I want to do is actually to make a field only accept numeric values, but the damned firefox cancels anything which is not a numeric character, can't move within the text box, can't switch tabs, can't select contents, ...

Any idea, suggestion?

gergoe

6:09 pm on Dec 6, 2007 (gmt 0)

10+ Year Member



Anyone? Anything? :-)

coopster

4:38 pm on Dec 11, 2007 (gmt 0)

WebmasterWorld Administrator 10+ Year Member



Yes, somewhat. I have been down this road and have been slowly refining my code over the years. Here it is for public review and criticism. Please feel free to post refinements and issues as I'm certain we can improve on it.
/** 
* A helpful link: [quirksmode.org...]
* The event will have two different properties:
* keyCode: the actual keyboard key the user pressed
* charCode: the ASCII value of the resulting character
*
* onkeypress events register in different properties for each of the
* browsers, some in the charCode, others in the keyCode. And some
* will not register keyboard movement keys whatsoever so the
* onkeypress event will not even be fired at all. With onkeydown/up
* the keyCode always holds the key code.
*
// +-----------------------------------------------------------------------+
* For instance, a lower case 'a' and an upper case 'A' have the same
* keyCode because the user presses the same key, but a different charCode
* because the resulting character is different. Explorer and Opera do not
* support charCode. However, they give the character information in the
* keyCode, but only onkeypress. Onkeydown/up keyCode contains the key info.
*
* Some general definitions of onkeypress events:
* ------------------------------------------------
* character: numeric value of keyboard character key (alphanumeric, etc.)
* movement: numeric value of keyboard "movement" key (up, delete, etc.)
*
* The following table shows which event property will be populated for two
* of the major browsers. Windows onkeypress will not register movement
* keys so the event would be undefined.
*
* Event event.charCode event.keyCode
* --------- -------------- -------------
* character Mozilla Windows
* movement Mozilla
*
* character keys:
* -------------------
* 44 Comma
* 46 Period
* 48-57 Digits 0-9

* movement keys:
* -------------------
* 8 Backspace
* 9 Tab
* 32 Space
* 33 Page Up
* 34 Page Down
* 35 End
* 36 Home
* 37 Arrow Left
* 38 Arrow Up
* 39 Arrow Right
* 40 Arrow Down
* 46 Delete
* 48-57 Digits 0-9
*/

function checkMoneyOnlyMillions(elm, desc, msg)
{
desc = (desc)? desc : elm.name
msg = (msg)? false : true
var reMoneyOnly = /^\d{0,9}(\.\d{0,2})?$/
if (elm.value &&!reMoneyOnly.test(elm.value)) {
if (msg) {
alert('The ' + desc + ' accepts monetary values only, up to the millions with two decimal places (123456789.12).')
elm.focus()
elm.select()
}
return false
}
return true
}

function checkNumbersOnly(elm, desc, msg)
{
desc = (desc)? desc : elm.name
msg = (msg)? false : true
var reNumbersOnly = /[^\d]/
if (elm.value &&!reNumbersOnly.test(elm.value)) {
if (msg) {
alert('This field accepts decimal numbers only.')
elm.focus()
}
return false
}
return true
}

function numOnly(evt)
{
evt = (evt)? evt : ((window.event)? window.event : "")
if (evt) {
var charCode = (evt.charCode)? evt.charCode : evt.keyCode
// Backspace (8), tab (9), space (32), page up/down (33-34), end (35), home (36), arrow keys (37-40), delete (Mozilla.event.keyCode=46), digits 0-9 (48-57)
// MSIE movement keys do not register a keyCode event (the evt.which property will be 'undefined'; Mozilla registers 0)
if ((charCode!= 8 && charCode!= 9) && charCode < 33 ¦¦ (charCode > 40 && charCode < 48 && evt.keyCode!= 46) ¦¦ charCode > 57) {
window.status = "This field accepts numbers only."
return false
}
}
window.status = ""
return true
}

function moneyOnly(evt)
{
evt = (evt)? evt : ((window.event)? window.event : "")
if (evt) {
// evt.which and evt.charCode are undefined in Windows, evt.keyCode is the keyboard character value in Windows (keyboard movement keys do not trigger an onkeypress event!)
// evt.which is the keyboard character value in Mozilla, evt.keyCode is the keyboard movement keys in Mozilla
var charCode = (evt.charCode)? evt.charCode : evt.keyCode
if (charCode!= 46 &&!numOnly(evt)) {
window.status = "This field accepts monetary values only."
return false
}
window.status = ""
return true
}
}

gergoe

6:47 pm on Dec 11, 2007 (gmt 0)

10+ Year Member



Nice code, wish one day I'll be so organized that I can create libraries like this. For me reusing code means digging through old projects and hunting for files or code snippets :-)

I'm mainly interested in the numOnly() function, but I already went a bit further than you, but the message to the user in the status bar got my attention, so already built into my function, which I'll post it here:

function numeric_field(obj, evt) { 
if (window.onlyDigitsTimer) window.clearTimeout(window.onlyDigitsTimer);
var keyCode = evt.which?evt.which:evt.keyCode
var keyChar = String.fromCharCode(keyCode);
var numCheck = /\d/;
if (((keyChar=='.')&&(obj.value.indexOf('.')==-1))¦¦(keyCode<32)¦¦numCheck.test(keyChar)¦¦((keyCode>=37)&&(keyCode<=40)&&(!evt.modifiers&&!evt.shiftKey))) {
window.status = '';
return true;
} else {
window.status = "You can only enter numbers into this field!";
window.onlyDigitsTimer = window.setTimeout("if (window.status.length==" + window.status.length + ") window.status = '';", 2500);
return false;
}
}

The approach is the same, I only used slightly different filtering for the keycodes (for example I allow anything below 0x20, as there are no 'genuine' characters), and as regarding to the arrow keys, I only allow them to pass through is the shift key is not pressed. As you explained in the comments, the arrows has the keycode of 37, 38, 39 and 40, but the

%
,
&
,
'
and
(
characters holds these keycodes as well, but i don't want those to happen in the input neither. Additionally I had to make it possible to enter real numbers too, so the function let's one dot character pass through.

It sounds rather complicated after thinking about it (considering its primitive purpose), but I'm still not satisfied as there are many things blocked by this (in Firefox certainly, perhaps in Opera ans Safari too?), for example, you can not select the value entered in the field by holding shift and using the arrows, or you can't use any of the keyboard shortcuts like Ctrl+R, F5, Ctrl+Tab and so on...

Probably the perfect function does not exists, would need to do some kick-ass at W3C and/or the Mozilla developers to make this work properly...