Written on 11/20/2014 in Web development
I've been busy on a personal project2 and got stuck on a trivial issue. This will be a short post for an even smaller, possibly dirty fix. I didn't find a lot of good answers on this particular issue so I'm self-documenting it for later.
Required behaviour
I have a website that has a page with only a single text-input and a submit button. I use the autofocus attribute to make sure it gets focused on page load. When the user presses the 'Enter' key, or presses a submit button, the filled in value will be sent to an API using an HTTP post call. Since there are no other text-inputs on the page, I want it to always keep the focus.
The problem
The problem is that browsers might remove this focus, by design, and that's logical in most cases.
Firefox 33:
- On 'Enter': Keeps the focus => Expected behaviour
- On 'Submit': Removes the focus => Expected behaviour
Chrome 38:
- On 'Enter': Removes the focus => Unexpected behaviour?
- On 'Submit': Removes the focus => Expected behaviour
Internet explorer 10 (still chewing glue, the page uses flexbox and works fine in other browsers but is completely wrong in internet explorer):
- On 'Enter': Removes the focus => Unexpected behaviour?
- On 'Submit': Removes the focus => Expected behaviour
Now, this is entirely subjective. This might be expected behaviour for reasons I don't know. When I navigate a form, fill in some values and press enter, I'm probably only using my keyboard. And I'd value it, if the cursor or focus stayed in the form, so I can easily continue inputting values. I tested this with and without a form/submit. So I don't really know why the focus was always lost whenever I did the HTTP call.3 This was the raw problem. I had guessed the solution was easy0.
The solution
I just return the focus to the text-input when the HTTP call returns. This fixes all the issues.
I applied this solution using the Vanilla JavaScript 'focus' function on the element. I tested Firefox and the input always kept focus4. Then I tested Chrome and was surprised that it wasn't working. The element did not get focus.1 I looked on the interwebz for a solution or source for this problem and haven't found any clean answers. I might be overlooking some very simple solution here, I hope I do. But long story short, I got to this solution:
Not working:
document.getElementById("ConsoleInput").focus();
Working:
setTimeout(function () {
document.getElementById("ConsoleInput").focus();
}, 1);
Using the time-out, it suddenly started working on Chrome (and kept working on Firefox). Personal opinion: this a dirty solution. I don't like to use a time-out for something like this, but it works. I hope to release the project into the wild internet sometime soon. Until then!