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...
Related
I have a canvas app where I handle window's keyup and other events. This works fine. However, now I've created a popup div with a textarea in it, and I don't want my keyup handling to be active when the textarea is focused (or when the popup is visible).
I could set a bool isPopupVisible and check for that in my keyup handling, but it strikes me that much more elegant would be to just use the standard focus management of HTML. So I tried handling the canvas's keyup event rather than the window's, but now the problem is that the canvas never receives focus (not even if I click on it) so it doesn't receive any key events. Apparently most HTML elements can't receive focus.
What would be a good way to resolve this?
Edit: It now occurs to me that what I want is in effect a modal dialog box, which HTML doesn't natively support. To support this modality, it's normal to implement it manually with a bool as I initially planned. Standard HTML focus doesn't provide for that, even if I could get the canvas to receive focus. Because the user can switch focus back to the canvas by clicking on it even when the popup is still visible (undesirable).
So I guess I withdraw my question.
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).
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.
HTML5 gives us some new input elements to play with, such as <input type=number>. This renders (in Chrome) as a textbox with two cycle buttons inside the textbox, for incrementing and decrementing the numeric value inside the box.
For a personal hobby project, I'm using this control. However, I'm stuck with one issue:
Is there a way to detect the value being changed using a javascript event? I had expected the onChange event to fire, but no such luck. Also, onClick only triggers when the textbox content is clicked, not when the cycle buttons are clicked.
Any ideas? (apart from: hey, it's HTML5 Forms, don't expect anything to work yet!)
Edit: As mikerobi points out below, the onChange event does fire as soon as the element loses focus. Still not quite what I'm looking for, so other comments and suggestions are welcome!
Result of the bugreport: Won't Fix, because the input event is fired when those buttons are pressed. It's part of the HTML5 spec. So problem solved, thanks to mikerobi's sugestion to file the report.
The onChange event gets fired when when the box loses focus, but you probably already know that.
The HTML5 specifies that a number input should be a text box or spinner control, but the spec does not appear to have any guidelines for how a spinner should look or behave, leaving those decisions up to the browser vendors.
It appears that in the Mac Safari, the spin buttons do respond to click events, you might want to file a Chrome bug report, I suspect it was just an oversight.
$.click() works fine. If you click and hold, it doesn't until you release.
When it comes to navigating through an HTML form by hitting the TAB key, Internet Explorer 7 treats an INPUT element with TYPE=FILE as two controls (see MSDN for details). The first time you hit TAB it focusses on the text field, and the second time it focuesses on the Browse button. This is invisible to JavaScript.
The problem is I want to use Ajax Upload or something similar to allow the user to click what looks like a button and see the File chooser appear. This works by placing an invisible file-input element under the mouse. I have managed to change the script to allow you to TAB to the hidden file-input element and for this to trigger a CSS change so the fake button looks like it has focus, the upshot being that, on browsers other than IE7, it looks to the user as if you can tab to the button and activate it as you would expect.
This cannot work on IE7 because the first TAB takes it to the invisible text field; pressing SPACE adds a space to the invisible file name instead of activating the file picker. I have tried adding an event handler for keypress that calls the click event, but when I do this the change event I am depending on seems not to be fired.
I am beginning to think the only accessible solution on IE7 (and, I assume, IE8) will be to replace the whole dialogue with a two part form -- the first part with a (visible) file-input element and Upload button, the second part with all the other form items. This is unfortunate because (a) IE7 get a less slick user experience, and (b) I have to add all sorts of extra server-side code to allow the form to be submitted in two parts.
So I would be interested to know if anyone has a way to make IE7's file-input element behave like a single control, or, alternatively, to allow JavaScript to access both controls of the element (something the DOM was not designed for!).
This a bit complicated to do but here's how:
Create a new button to use as your "fake" input control (you have this as the visible element). This element needs to be a button or a link for it to be able to get tab focus (I suggest button so that it works better on Safari).
Remove the file input from the tabbing order by setting it's .tabIndex to -1. It should now be hidden from sight and tabbing order.
Assign events to the file input so that on activity then the focus is moved back to the fake button, values are copied from it, and so forth.
Assign a click event to the fake button that calls .click on the file input element. This will only work for IE. It will also very likely break in a future release.
For mozilla style browsers you can move the focus from the fake button to the file input on keydown, the keypress event will the occur on the file control and you can then move the focus back to fake button on change. This should also give you del/backspace functionality (clear field).
Clearing the field in IE can only be done by rebuilding a new file input control.
As should be obvious from my other answer, I have managed to build this widget with full keyboard accessibility.
My sincere advice is to drop this pursuit. It is a maintenance nightmare. You are exploiting security holes in the browser to make this work and it is only a matter of time before vendors close something that you rely on.
You could also check out swfupload, as it may provide what you're going for and more.