« Reading List: The Penguin Dictionary of Curious and Interesting Geometry | Main | Reading List: American Theocracy »

Friday, March 30, 2007

Button, button: Microsoft Internet Explorer sends form button content, not value

Microsoft's lame attempt at a Web browser, “Internet Exploder”, seems to take every possible opportunity to misinterpret and mal-implement even the simplest of Web standards. Consider the humble “<button>” tag, introduced in HTML 4.0 and part of the current HTML 4.01 and XHTML 1.0 standards. Unlike the original “<input type="submit">” button, in which both the label of the button and the text submitted with the form when it is clicked are identical (and hence the button's label cannot contain HTML mark-up or style specifications—just the plain text permissible in an attribute value), the “<button>” control decoupled these; the value submitted with the form remains specified by the value= attribute, but the label on the button is given by the content of the tag, for example:
    <button type="submit" name="action" value="detonate">
    <b>Ka-<em>BOOM!</em></b>
    </button>
Even Web designers uninterested in fancy text in buttons find the “<button>” tag attractive, because it provides a simple way to include multiple buttons in a single form which send different codes when pressed, independent of their labels. A common example is a form which lists a number of items as rows in a table and, for each item, includes action buttons which operate upon it, for example “Edit” and “Delete”. The buttons in each row have the same label, but are distinguished by their value fields, for example:
    <button type="submit" name="edit" value="row12">Edit</button>
    <button type="submit" name="delete" value="row12">Delete</button>
When one of these buttons is clicked, it informs the application of both the operation requested and the row of the table operated upon. The “<button>” tag is useful in any situation where you wish to send different text to the server than is displayed as the label on the button, which is why the keepers of the HTML standard incorporated it back in 1998.

Well, it would be useful, if the idiots at Microsoft, who retain a dismaying large share of the Web browser market, had implemented it correctly. Unlike every other competently-implemented browser, which sends the name and value fields to the server as CGI arguments, Internet Exploder, even the much-vaunted version 7, sends the name with the content of the button tag instead of the value.

In the first example, the server would see an argument named “action” with a value of “<b>Ka-<em>BOOM!</em></b>”, and in the second, if the user pressed the “Edit” button, the server would receive “edit=Edit”, providing no indication whatsoever of the table row upon which the user wished to operate. As a final kick in the face of the developer trying to build an application on top of that rickety platform, Exploder renders buttons defined with the <button> and <input type="submit"> tags at different vertical positions, so if you combine a number of them on the same line, it looks like they weren't securely glued to the page and shook loose as they travelled over the Internet.

There are several discussions of this outrage on various Web sites, and many suggestions of work-arounds, the vast majority of which use JavaScript. Now, I'm a fan of JavaScript, which, used appropriately, can make pages more responsive and interactive, but I dislike making pages that depend upon it for correct operation; some users block JavaScript as a matter of security (or are behind firewalls which do so), and many text-only browsers and screen reader programs used by blind users do not support JavaScript. Disenfranchising these individuals from using a Web application just to work around Microsoft incompetence is unacceptable.

Here is the solution I have settled on. This is implemented in the context of a Perl CGI application which uses the Perl CGI package with extensions of my own devising to parse form arguments into a hash named %CGIargs. Rather than use a button declared as:

    <button type="submit" name="edit" value="row12">Edit</button>
I declare it as:
    <input type="submit" name="edit=row12" value="Edit" />
and then use the following Perl code to parse any CGI arguments with name fields containing an equal sign into name and value pairs, which are assigned to new values in the CGI arguments hash. (If for some bizarre reason you require CGI argument names containing equal signs for some other purpose, simply pick a different delimiter.)
    for my $qk (keys(%CGIargs)) {
        if ($qk =  m/^(\w+)=(.*)$/) {
             $CGIargs{$1} = $2;
        }
    }
This solves the problem of multiple buttons per form with the same value. If you require buttons with HTML content, you can use the same trick in the name= field of a <button> tag. However, if your users are using Exploder 6, you still cannot use multiple <button> tags in a single form because it moronically sends all buttons in the form, not just the one which was pressed! (Note that this doesn't happen with multiple <input type="submit"> buttons—that would be too consistent for Microsoft.) This has been fixed in Exploder 7, but unless you don't care about users who have yet to “upgrade” to that piece of…software, you're going to have to stay away from <button> entirely.

Posted at March 30, 2007 22:45