views:

5179

answers:

3

I would like to have an input element (type=text) or textarea element that validates dynamically by triggering specific keystrokes. This will be used for Chinese pinyin input, so for example:

The user types "ma2" into an input element. The keydown event triggers for every keystroke, and the 2 never appears. Instead, when the user presses "2" the "a" will receive a tone mark, like this: "á". In the end, the user will have typed: "má".

This can be accomplished by reading and changing the entire input value using $(element).val() however, when an input element has focus and it's value is set by calling .val("something"), the cursor moves to the end of the text. This works fine in most situations because a user just continues typing at the end of the field, but I want this to work in all situations.

...another solution to this problem would be to get/set the location of a cursor within an input or textarea element. I don't think this is possible in javascript, however.

+5  A: 

You may not have much luck triggering keypress - I'm fairly sure that unless the keypress is trusted (i.e. originates from the browser), it won't be picked up.

However, you can do text replacement and insert the carat back where it was - instead of shooting it to the end of the string. You need to use setSelectionRange and createTextRange (for IE).

I've put together a little demo - the replacements you'll see don't match real words, but it shows how it works:

http://jsbin.com/emudi/ (to edit the source http://jsbin.com/emudi/edit)

The trick is to take note of where the carat is, replace the found word using substr (rather than regex to avoid replacing the wrong matches) and then re-placing the carat at the end of the new word.

The replacement is triggered on the space press or blurring the away. A note on this - you could trigger the replacement on a specific character (i.e. the '2') - but I wouldn't recommend searching for replacements on every keypress.

Remy Sharp
A: 

So, Remy was on the right track for sure. Triggering keypresses wouldn't allow me to input special characters without a lot of hassle anyways. Instead, I catch the keydown event and set the value of the input/textarea, and then move the caret.

I haven't found anything good for caret getting/setting in jQuery, but the following really broke that problem down for me. I'll post a link to my final pinyin input code when it's stable. It's pretty close now.

http://blog.vishalon.net/Post/57.aspx http://demo.vishalon.net/getset.htm

A: 

Also, for simple code controlling the "caret" in a cross-browser way this could be useful:

http://javascript.nwbox.com/cursor_position/

a bit late with the answer but I am sure you will still find this old stuff useful.

Diego Perini