« 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