Form with two submit buttons using HTML5
Let’s say we have a registration form with the choice to join the site, service or whatever as a free or paid member.
We can set up a simple form like so:
<form action="register.php">
<label for="username">Username</label>
<input id="username" type="text" pattern="[A-Za-z]{0,20}[0-9]{0,2}" placeholder="No twitter spamhandles" required>
<label for="password">Password</label>
<input id="password" type="password" required>
<label for="free">Free</label>
<input id="free" type="radio" name="membership" value="free">
<label for="paid">Paid</label>
<input id="paid" type="radio" name="membership" value="paid">
<input type="submit" value="Join">
</form>
All fairly straightforward and some nice new HTML5 attributes to help the user along the way.
We can however help the user even further by removing the click where they select the type of membership they want, and progressively enhancing the form using a second submit button with the formaction
attribute that was introduced with HTML5. The formaction
attribute allows us to override the default action
attribute and submit the form to a different script on the server.
<form>
<!-- form controls -->
<input type="submit" value="Join Free" formaction="free.php">
<input type="submit" value="Join Premium" formaction="premium.php">
</form>
formaction
, leaving non-supporting browsers and non-JavaScript users with the original (perfectly usable) form.
Before we take a look at the JavaScript, a warning: I am crap at JavaScript. Ergo I would appreciate any feedback from folk who know more about it and would advise those who aren’t too sure to read any comments that may be added. So onwards. The first thing we do is a feature detection:
var supportsFormaction = function() {
var input = document.createElement("input"); // create an element in memory
return "formAction" in input; // check if the browser supports the attribute
}
In a production setting it would be better to write a more general supportsAttribute
function and pass in arguments for the element and the attribute, but what we have here will do for this example.
Next it’s a matter of manipulating the DOM to accommodate our new buttons.
if(supportsFormaction()) {
var premium = document.createElement("input"),
free = document.getElementById("submit"),
registration_form = document.getElementById("register");
// set up the premium submit button
premium.setAttribute("formaction","premium.php");
premium.type = "submit";
premium.value = "Join Premium";
registration_form.appendChild(premium); // add the new button to the form
// change the original submit button into a free submit button
free.setAttribute("formaction","free.php");
free.value = "Join Free";
// hide the radio buttons
document.getElementById("membership-type").style.display = "none";
}
There’s a gist on github of the completed example and a working demo on this site.
I tested on all major desktop browsers plus Opera Mini, Opera Mobile, Android, Mobile Safari, Symbian, Blackberry, Fennec and Windows Phone emulator, and didn’t get any false positives on the feature detection. If you find a browser that applies the DOM manipulation but submits to the regular script please let me know in the comments.