Most browsers have a bug that isn’t really a bug. In fact it was purposely put there to make your simpler, but if you (or someone else writing the HTML code) do something in the right (read “WRONG!”) way, it could completely blow up. Specifically, if you assign your input
tags a name
or id
attribute of “action” or “submit”, you can cause some very well hidden bugs.
Introduction to the “Bug”
Last year I read through Secrets of the JavaScript Ninja by John Resig and Bear Bibeault. It’s an absolutely great book if you’re planning on writing a lot of vanilla JavaScript, by the way. Anyway, in Chapter 11, something was brought to my attention. As the result of a feature they referred to as “greedy IDs”, if you have an input
element with an id
and/or name
attribute within a form
, you will be able to reference that input
directly as a property of the form.
1 | <form id="form" action="url"> |
1 | // Grab the form |
This is a pretty cool idea, except it’s not all that necessary since getting elements by their id
or name
is fairly simple. Also, take note of 1 very important thing: if the form already has a property with the same key as the input
‘s id
/name
, that property will be overridden by a reference to the input
element.
This becomes especially painful if you have input
s named “action” or “submit” and you’re trying to control submissions with JavaScript. Now, if you need to know the URL it will submit to (via form.action
), or if you just want to submit the form programmatically (via form.submit
), you’ll either get a very wrong value or an error, respectively.
The Workaround
I never thought I’d run into this issue personally, but I actually did at one point. Probably the simplest way to fix the issue is to rename your input
s, but sadly I didn’t have access to the HTML, and sometimes you won’t either. There’s also the chance that other code relies on that id
/name
for other purposes. Well, if there’s no way for you to fix the HTML, there is another way around it.
This fix only works for properties of the form that are functions. Any properties that aren’t functions will be stuck, even if you try to change the name
/id
of the input
element dynamically with JavaScript. Anyway, to work around functions (like submit
) being overridden, you can grab the function off of the prototype, and call it with a context of the form
you want to use.
1 | <form id="form" action="url"> |
1 | // Grab the form |
I haven’t tried this out in older browsers, but it should work in any browser that supports good old HTML4 since HTMLFormElement
was initially specified in the DOM Level 1 Specification.
The folks at Webucator went ahead and created a video that talks about this issue and demonstrates the workarounds I pointed out.
Webucator also has several JavaScript Courses that you may wish to check out.
Conclusion
I’m a little surprised that a workaround was never suggested in the book. They kinda just blew it off saying that we should avoid the use of these name
s/id
s:
Luckily, we can avoid this problem in our own markup by avoiding simple id values that can conflict with standard property names, and we can encourage others to do the same. The value submit is especially to be avoided for id and name values, as it’s a common source of frustrating and perplexing buggy behavior.
While that’s definitely sound advice, hence the title of this post, it’s not always avoidable, so it’s nice to have a simple way of getting around some of the issues. In any case, I hope you never need to use this workaround. God bless and happy coding!