If you’ve ever used <BUTTON>
tags in your HTML forms, you’ve probably noticed that there are a couple of problems with them in IE7 and older.
For starters, clicking a BUTTON does not cause its form to be submitted. This means that a user will never be able to submit the form by clicking it. Furthermore, if you are using JavaScript including jQuery to trigger a callback upon form submit, that callback will never be fired.
<form method="post" action=""> <!-- ... your form fields go here ... --> <button name="proceed" value="save">Update Record</button> <button name="proceed" value="undo">Cancel</button> </form>
The easiest fix, which might be your best option, would be to simply replace those BUTTON elements with INPUT elements:
<input type="submit" name="proceed" value="Update Record"/> <input type="submit" name="proceed" value="Cancel"/>
Again, this is a simple fix, and if it satisfies your requirements, you should definitely stick with it. The problems with this, however, are:
- You may be dealing with legacy or third-party code and you don’t want to go fumbling through thousands of lines of someone else’s code to change their HTML. (This could also break other parts of the system that make assumptions about the fields being of type BUTTON or having a specific value attribute.)
- The other issue is that you cannot specify an arbitrary value for the fields because the value attribute also doubles as the user-friendly display value.
So, to tackle both of our issues, we’ll need to bind a click handler to every BUTTON on a page contained within a FORM element. We can do this with jQuery by using the following code:
$(document).ready(function(){ // use live() to handle dynamically added buttons (pre jQuery v1.7) $("form button").live('click',function(){ var f = $(this).get(0).form; if (typeof(f) !== 'undefined') { if (this.type && this.type != 'submit') return; if (this.name) { this.trueName = this.name; this.name = ''; } $("input[type='hidden'][name='"+this.trueName+"']", f).remove(); if (typeof(this.attributes.value) !== 'undefined') $(f) .append(''); $(f).trigger('submit'); return false; } }); }); /* Note: As of jQuery v1.7, live() has been deprecated. You can replace that line above with the following if you're using the latest jQuery: $("form").on("click", "button", function(){ */
Note that we don’t want this code to be executed in other browsers than IE7 and older, so you should put it into a file, let’s call it ie7.js, and use Microsoft’s conditional comments in your HTML file to import it only if the user is using a version of Internet Explorer before version 8:
<!--[if lt IE 8]> <script type="text/javascript" src="ie7.js"></script> <![endif]-->
Now, if you’re interested, let’s consider how that code works. It will cause any click of a BUTTON element contained within a FORM element to trigger the callback we defined. The callback does two important things:
- It appends a hidden INPUT element to the FORM using the name of the clicked BUTTON and its real value attribute (rather than the display label).
- It triggers the submit event on the FORM element, so any callbacks you’ve bound on form submission will get executed.
Side note: Fetching the actual “value” attribute can seem a tricky thing to figure out. If you’re just trying to use $button.attr(‘value’) you’ll always get the button label. Instead, we use the “attributes” value of the element.
That should be all you need to get your BUTTON elements working properly in IE7.
As an added bonus, you may want to add a handler to submit your form when the user presses enter while focused on an entry field. To do so, you can use this to trigger the click event on the first non-disabled button in the form:
$(document).ready(function(){ $("form").on("keypress", "input,select", function(e){ if (e.keyCode == 13) $("button:not(disabled):first", this.form).trigger('click'); }); });