views:

536

answers:

3

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!).

+2  A: 

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.

Borgar
On most browsers I use focus events on the invisible file input to control the appearance of the (fake) button, because calling the click method does not work -- it's only logical I should need to do the exact opposite on IE. Sigh.
pdc
Heh, yeah. This is one of those things that simply cannot be written without a mountain of complicated code. I've happily thrown my implementation away and moved on to the next nightmare. :-)
Borgar
+1  A: 

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.

Borgar
I totally agree -- It was intricate enough before IE 7 made things even more complicated! Obviously the question will be whether I can replace it with something my customer will accept. :-)
pdc
A: 

You could also check out swfupload, as it may provide what you're going for and more.

Mikko Tapionlinna