Thursday, October 14, 2004

MSIE and the <button> tag

MSIE doesn't really support the <button> as defined in the HTML 4 specification. Sure it does render a button, and something happens when you push on it. But it doesn't work as specified.

Why use <button> instead of a <input type="submit" ... />?

Simple, <button> gives you more power. For example, with the <button> tag the text on the button is different that the value submitted when the button is clicked. this is very usefull when you want to use a nicer description and don't want to use ugly value checks in your backend script.
<input type="submit" name="mybutton" value="add this new entry" /> displays:

When submitted the following details will be received by the back end script: mybutton = "add this new entry"
Sure it works when you only have only one button. But what if you have two buttons:

Now you will have to check the value of the action variable. It would be much nicer in the code if that value would be addChild or addSibling (also better for localization). But this is not possible with the <input> element.
That's where the <button> tag is usefull:
<button name="action" value="addChild" />add as child<button></button name="action" value="addSibling" />add as sibling</button> produces:

Depending on which button is pressed the value of action would be either addChild or addSibling while the text on the button is descriptive.
Another thing about the <button> is, that it's easier to use for style sheets, you don't have to set a special CSS class for all buttons (since not all Browsers support Input[type="submit"] elements in CSS).

But MSIE is broken

The <button> in MSIE doesn't work as it should. Instead of sending the value of the value property, it will send the value of the innerText (note: this is documented on MSDN), in other words, it will just behave like a normal <input> .
Another thing is that MSIE will include all <button> elements in the submit data, not just the one of the pressed button. So you would get something like: ?action=addChild&action=addSibling. This makes the button element complete useless since you don't know what button was pressed. This incorrect behavior isn't even documented on the MSDN.

A ugly workaround

I came up with an ugly workaround for just MSIE. It uses some javascript. Instead of creating a submit button I will create a normal button: <button type="button" onclick="onButtonClick(this, 'action', 'addChild')">Add as a child
Note, no value and no name have been set, this is very important. When this button is clicked it will call the following JavaScript code:
function onButtonClick(btn, name, value)
{
 btn.name = name;
 btn.value = value;
 btn.form.submit();
}
This will simply set the name of the button pressed to the desired name and set the value. After which it will submit the form.
Now when the button is pressed the text on the button will change to the desired value (yep, that's also incorrect behavior). But the form is submitted at once so it doesn't hurt a lot.
This bug exists in all MSIE versions that support the <button> tag, up to MSIE 6 sp2.
If everybody would switch to browsers that did support the standards as defined (like Mozilla, Firefox, or Opera) it wouldn't be a problem.