Detecting IME input before enter pressed in Javascript - javascript

I'm not even sure if this is possible, so apologies if it's a stupid question.
I've set up an keyup callback through jQuery to run a function when a user types in an input box. It works fine for English.
However when inputting text in Japanese/Korean/Chinese, the function isn't called until the user confirms their text.
Is it possible to detect that they've started typing, and access their as-yet unfinished text?
I'm thinking maybe it's an OS-level thing so Javascript doesn't have access to it.
Edit: I just realised that this works in Chrome and Safari, but not in Firefox (not had a chance to try it on Windows yet). So Chrome calls keyup and it's possible to get the text. But I'm still having the above problem in Firefox.

The compositionstart, compositionupdate and compositionend events might be helpful.
They help you detect when IME input is being used.
For example, consider using an IME to type か (ka) in Japanese.
The following events (in the order shown) would be fired:
k (IME visible) keydown, compositionstart, compositionupdate, compositionend, input
a (IME visible), compositionstart, compositionupdate, compositionend, input
enter (IME closed) keydown, input
Notice that the compositon events are only fired when the IME is visible (before enter is pressed). Also notice that the keypress event is not fired. This is only fired for non-IME input.
To access the user's unfinished text, you can use the data property of the event.
$('#input').on('compositionupdate', function(e) {
console.log(e.data);
});
For more info see MDN: compositionstart, compositionupdate, compositionend, InputEvent.

This is a known issue in Firefox, and what browsers should be doing isn't clear.
A possible method for working around this problem is demonstrated here, where the text field is polled for changes to the text (rather than relying on events).

Related

JavaScript: block backspace on text input on Android

I'm trying to block all input on an html text field with jQuery. The following solution works on desktop browsers:
that.input.keydown(function (e) {
e.preventDefault();
e.stopPropagation();
e.stopImmediatePropagation();
return false;
});
However, while it blocks regular input it fails to block backspace on Android (Chrome). I've also tried blocking the keyup and keypress events, but that didn't help. I don't want to set the readonly attribute, because I intend to allow the input in certain situations.
Is there any clean solution for this? Thanks in advance!
The reality is that android keyboards are not keyboards. When a text field is opened in android the text-field-owner application and the keyboard application, speaking simply, come to share a resource which is the text field contents. The keyboard app receives the entire contents of the text field and then edits - including deletions - are made locally and pushed to the app via calls like DeleteSurroundingText (for simple deletions of non-text content i.e. whitespace) or setComposingRegion/setComposingText for changes to words. This means that autocorrect can work on already-existing words.
Some android keyboards generate keypress events which reach Chrome, some do not. Sometimes it makes no sense to generate keypress events - if a word is autocorrected what keypresses should be sent?
As you are looking for the keyboard and cursor to be displayed but the field to remain uneditable until later I would suggest you implement some sort of onChange/Revert loop.
Detect all changes to a <input type="text"> (immediately) using JQuery
Apparently android keyboards have a strange bug with the keyboard so instead of attaching to the keydown event maybe try the oninput event.
I found more info on this issue here Capture keys typed on android virtual keyboard using javascript

Listen for deletion of input value

One of the most recommended ways to listen for a change of a input text field is to bind that field to a key up event. That works fine in most cases. But there are cases where this is not working. In Firefox for example one has the option, when text is already selected, to delete it by using the context menu. And this doesn't fire a key up event. I haven't found any event that is fired for that text field when doing this.
Any suggestions how I can react on this (in pure Javascript or jQuery)?
See the oninput event, and my write up about it here.
oninput fires for all forms of text input - including cut, paste, undo, redo, clear, drag and drop and spelling corrections. It's a HTML 5 event which isn't supported in Internet Explorer 8 and lower (but it is in the latest IE 9 preview). However, Internet Explorer supports a proprietary event on all DOM objects - onpropertychange. This fires whenever the value of an input element changes.
I didn't notice you'd tagged with jquery — since you did, it's probably worth mentioning that I wrote a plugin to implement the oninput event cross browser. You can find it here.
The best way is to store the value on a focus event and recheck the value on a blur event. Listening to key events fires a lot of usually redundant processes. Most of the time, you are only interrested in a field value when the user is done inputting (or deleting) it.
This works cross browser, though delegating focus/blur can be an issue in some browsers. The easiest way is to apply blur/focus listeners to the element directly.
Only exceptions are implementations like autosuggest/complete and even then you might want to debounce key input so it only fires when the user idles for a few hundred miliseconds.

IE, textarea value is not changed when pressing buttons

I have a really nasty problem with focus in Internet Explorer.
I have a textarea for inputting text. This textarea is not visible for the user and is only used to provide robust text input for a more advanced view.
As the textarea isn't visible and shouldn't be I use textarea.focus() in the JavaScript to activate text-input. This has worked fine until now where I get really weird results.
For the textinput I basically use this event plus an exact copy for onkeypress.
textarea.onkeyup = function (e) {
//textarea.value contains the full text
//Update the view with this value
};
The problem is that sometimes textarea.value is not updated. I can even see the button in e.keyCode on the keyup event above but the value isn't changed.
This seems to happen after I have clicked somewhere on the page, but this does not trigger a blur-event. I'm logging the onfocus- and onblur-events so I can see when the textarea loses focus but it doesn't. And i still receive the keyup/press/down events.
If I try to refocus the textarea with textarea.focus() the problem remains. A workaround I found though is to focus the window with window.focus() and right after call textarea.focus().
The problem with this is that focus is a really expensive operation in IE (no kidding) and since I cannot detect when this problem will happen I have to keep doing it with certain interval which seriously affects the performance of my application (involves animation etc).
I use the exact same code for other browsers and do not have this problem there.
Change the identifier to something less generic like "textAreaAdv", IE sometimes get confused with this word.

How can a javascript function be fired when a user types text into an input field or pastes text into it?

$(document).ready(function() {
$("input[id^='question']").live('keyup',function(ev){
id=this.id.substr(8);
if (ajaxCallTimeoutID != null)
clearTimeout(ajaxCallTimeoutID);
ajaxCallTimeoutID = setTimeout(function(){subjectivecheck(id)}, 1000);
});
});
There is a problem. When a user pastes text into an input field, the function above can not be fired. How to solve this problem?
The onchange event is what you want here. It fires when the textbox loses focus (blur) and has had its value changed since it received focus. It takes care of the paste problem.
So instead of .live('keyup', use live('change'.
This is as good as it gets, without using some ridiculous interval polling. And just for the purpose of context, be aware that any user can disable Javascript in the browser whenever they feel like it.
The Paste (onpaste) event is not standard - it is AFAIK supported only in Internet Explorer (see: http://msdn.microsoft.com/en-us/library/ms536955(VS.85).aspx)
The change (onchange handlder) event is standard - but that will only fire if the value of the textbox changed in the time between gaining and losing focus - i.o.w. detecting change requires the textbox to lose focus.
What you could do, is use setInterval() (http://www.w3schools.com/jsref/met_win_setinterval.asp) to poll the value of the textbox, and compare it with the previous value.
At the onfocus event on the field, you can start a timer to check if the field value has changed.
And at onblur, clear that timer.
The paste with ctrl+v is ok with onkeyup, but not with the mouse right click or with a browser undo.
That's not the only problem. Even if you could catch cut and paste reliably on all browsers, which you can't, there are still more ways of putting content in a form field. For example on some platforms dragging a file to an input will put the pathname in, with no event for you to catch. Or a user might do right-click-Undo to change the contents. Or Delete. Or select some text from the input or another input and drag-and-drop it in. And probably many more I haven't thought of.
If you want to be informed of all changes to a form field more quickly than onchange, I'm afraid there is no alternative but to constantly monitor the value of the element in a polling setInterval.

IE7+ does not execute events if control does not lose focus

I have a input control (a Text Box) which has some javascript events associated with it (change, keypress, select, click). The first time my page is executed, I type some value in this input control and then click on my button. This button executes some ajax code, send some info to a application server and it is OK. Also, the Text Box related events are executed properly (these events runs some code that checks which controls have its values changed, so these changes can be sent to the server).
The 2nd time I type some value in this input control, the associated events are not executed properly, except if I first click outside the control and click inside the control again, so I can type some value and then then associated TextBox events are executed.
It only happens on IE7+, works fine on other browsers, like FF, Safari, Opera and Chrome. It seems that IE does not change the focus from the TextBox when I press my button and for some unknown reason, IE "forgets" about those events.
Just to clarify, my page consists of some HTML/JavaScript/AJAX code that communicates with a Application Server written in Delphi.
Please let me know if I was not clear enought and thanks for your time.
--
Jackson Gomes
I added a function that set the focus on the next element of the form in the onBlur event of my input element as a hack to my problem and it solves it (IE seems to re-recoginize the events if the focus moves to another control).
Now if I explicity set the focus on the input element again (even with the function call I described above), the problem appears.
I really do not understand why it happens and if it is a IE7+ bug or not.
The hack works, but if I want the focus on the input element, it does not.
:-(
--
Jackson Gomes
How about moving the focus and then moving it back? Kinda like a blink...

Categories

Resources