views:

1207

answers:

5

I need to change in a text input the character '.' to ',' while typing. In IE I change the keyCode event property in the keypress event, like this

document.getElementById('mytext').onkeypress = 
 function (evt) {
  var e = evt || window.event;
  if (e.keyCode && e.keyCode==46)
   e.keyCode = 44;
  else if (e.which && e.which==46) {
   e.which = 44;
  }
 };

but it seemes that in Firefox it's impossible to change characters typed in key events. Any suggestions?

+2  A: 

Try this. It works on all browsers:

window.onload = function () {
    var input = document.getElementById("mytext");

    input.onkeypress = function () {
        var evt = arguments[0] || event;
        var char = String.fromCharCode(evt.which || evt.keyCode);

        // Is it a period?
        if (char == ".") {
            // Replace it with a comma
            input.value += ",";

            // Cancel the original event
            evt.cancelBubble = true;
            return false;
        }
    }
};

Update: Pier Luigi pointed out a problem with the above. It doesn't take care of the caret position not being at the end of the text. It will append the command to the end even if you're inserting some text to the value.

The solution would be, instead of appending a comma, to simulate a keypress event for the comma key. Unfortunately the way dispatching of synthetic events work in different browsers seems to show a lot of variety and isn't an easy feat. I'll see if I can find a nice and generic method for it.

Ates Goral
your solution doesn't take care of caret position: if user type "." not at the end of text?
Pier Luigi
@Pier Luigi: Thanks for raising that. I'll update my answer.
Ates Goral
A: 

Technically you just want to replace all dots with commas.

document.getElementById('mytext').onkeyup = function(){
    this.value = this.value.replace('.', ',');
}
pawel
yes it works, but it change caret position!!
Pier Luigi
Capture caret position, replace characters, replace caret position.
eyelidlessness
+2  A: 

Assume that all properties in an Event object are immutable. The DOM spec doesn't address what happens when you change those values manually.

Here's the logic you need: listen for all key events. If it's a period, suppress the event, and manually add the comma at the cursor position. (Here's a code snippet for inserting arbitrary text at the cursor position.)

You'd suppress the event in Firefox by calling event.preventDefault(); this tells the browser not to go ahead with the default action associated with this event (in this case, typing the character). You'd suppress the event in IE by setting event.returnValue to false.

If it's not a period, return early from your handler.

savetheclocktower
thank you, it works! I'll adopt your code snippet, although with a little correction because in Firefox it doesn't restore caret position.
Pier Luigi
A: 

Does this really need to be done on the fly? If you are collecting the information to be posted to a form or submitted to a database, would it not be better to modify the data once it was submitted? That way the user never sees the confusing change.

alexp206
Isn't it more confusing to change something after the fact?
eyelidlessness
+1  A: 

If I look at the official Document Object Model Events document, mouse events fields are defined as read-only. Keyboard events are not defined there, I suppose Mozilla followed this policy for them.

So basically, unless there is some smart trick, you cannot alter an event the way you want. You probably have to intercept the key and insert the char (raw or translated) where the caret is, the way JS HTML editors do.

PhiLho