More button woes

The HTML button element has given me trouble in the past. My conclusion was to not use the button element except to progressively enhance the look of buttons. This means the button would initially be an input of type button and JavaScript, if enabled, would change it to a button element.

Well at work I’m working on an app that requires JavaScript and all form submissions are done with JavaScript already so I thought it would be safe to switch over to <button>. The server never uses the button names or values (all needed information is in other inputs – hidden or otherwise) so the IE bugs should not be an issue.

This time the problems I found were exposed with Firefox but the real problem was in the web app code even if the browser behavior was surprising.

The app is doing two interesting things with buttons. It disables the buttons before it submits a form and it has some buttons that work like a link by setting location.href. My goal was to simply change the button style and not other functionality so I just changed <input type=’button’…> to <button …>.

Here is a reproducer that captures the essence of what the app is doing. The actual app uses the post method and does useful stuff.


...
<p>Doesn't work on Firefox 2</p>
<form id="f1" method="get"
  action="http://hardlikesoftware.com/weblog/">
    <label for="someinput">Label:</label>
    <input type="text" value="foo" id="someinput">
    <button id="b1" 
      onclick="this.disabled=true;document.forms.f1.submit();">
        Disable and Submit
    </button>
</form>
<p>Doesn't work on Firefox 3 - here the button works like a link</p>
<form id="f2" method="get"
  action="http://hardlikesoftware.com/weblog/">
    <label for="someinput2">Label:</label>
    <input type="text" value="bar" id="someinput2">
    <button id="b2" 
      onclick="this.disabled=true;self.location.href='http://www.google.com'">
        Goto
    </button>
</form>
...

The expected behavior is that the “Disable and Submit” button will take you to the HardLikeSoftware main page and the “Goto” button will take you to google. On Firefox 2 the first button gets disabled and no request of any kind is sent. The second button works fine. On Firefox 3 the first button works as desired but the second button submits the form and you end up at the HLS main page. The problem goes away if you use IE7, Opera, or Safari (I suspect IE6 also works), or change the button elements to input buttons, or move the buttons outside of the form. If you don’t disable the buttons then the first button works in both Firefox 2 and 3 but the second button doesn’t work in either.

When I first noticed the behavior I thought I was going crazy. The first step in figuring it out was isolating the problem to something like the simple reproducer above. I also used Firebug to step through the JavaScript and used the Live HTTP Headers plug-in to verify that no request was being sent in the first case.

It was the behavior of the second button that finally tipped me off when I realized that it was actually submitting the form. Noticing this was more difficult with the actual app simply because of the way it works.

The code had been getting away with not returning true or false from the click handler for a long time. Simply adding “return false; to the event handlers solves all the problems and continues to work in the other browsers. Returning false from the click event means don’t take the default action. For a submit button the default action is to submit the form.

Another aspect to this issue is that when you use the input element to create a button you make a conscious choice between a submit button and a regular button. But when you use the button element it is a submit button by default. Thanks to IE the default isn’t a very useful default because you can’t use it this way.

The moral of the story is always return an appropriate value from an event handler. Also it may not be a bad idea to be specific about they type of button. Although it looks redundant <button type=’button’> may be the way to go.

2 thoughts on “More button woes

Comments are closed.