Fixing the Internet Explorer BUTTON form submission bug

Internet Explorer 6/7 incorrectly handle a form submission with the <button/> element.

Consider <button name="action" value="next">Go to step 3</button> <button name="action" value="back">Back to step 1</button>

What should happen is the value of the button used clicked by the user should be posted with the action parameter.

IE however posts the inner HTML of the button. In the case of IE6 it posts ALL of the button parameters – even less helpful!

If you get a reference to the DOM element, and call the button.getAttribute('value') will still return the inner HTML of the button. Basically, IE is completely mangled.

I use the following function to fix IE, note it relies on the jQuery library.

/**
 * fix the HTML BUTTON submission bug.
 * 
 * Problem: IE6/7 ignore the value attribute of button elements and
 * instead submit the innerHTML of the button. Even using the JavaScript
 * getAttribute('value') method will return the incorrent value in IE6.
 * 
 * To fix this issue, add the BUTTON.id property to the below map, with
 * the desired value propery.
 * 
 * The script will automatically execute on DOM READY and search for any
 * BUTTON elements within a web form. If found, it will:
 * 
 * 1. Rename the name property so 'foo' becomes '_foo' (this workarounds
 *    the IE6 issue of submitting all of the BUTTON elements
 * 2. Add a click listener to inctercept the click.
 * 3. Look up the value of the element ID in the map object
 * 4. Set the dynamically generated hidden field VALUE to the desired
 *    value
 * 5. Submit the form.
 * 
 * @param {String} name - The name property of the buttons to process
 */
 
function fixButtonSubmit(name)
{
	var map = {
		buttonSubmit: 'next',
		buttonBack: 'back'
	};
 
	// fix the button submission bug
	$('form').each(function () {
		var that = this,
			fixSubmit = false;
 
		// prepend button names
		$(this).find('button[name='+name+']').each(function () {
			this.name = '_'+name;
			fixSubmit = true;
 
			// intercept click handler
			$(this).click(function () {
				// set the hidden input to value specified in the map
				$('input#'+name).val(map[this.id]); 
				that.submit();
				return false;
			});
		});
 
		// add hidden field to the form
		if (fixSubmit) {
			$(this).append($('<input id="'+name+'" type="hidden" name="'+name+'" value="" />'));
		}
	});
}
 
$(function () {
 
	// return if not IE
	if (!$.browser.msie) {
		return;
	}
 
	// set browser version
	var isIE6 = false,
	    isIE7 = false,
	    isIE8 = false;
 
	switch ($.browser.version)
	{
	case '6.0':
		isIE6 = true;
		break;
	case '7.0':
		isIE7 = true;
		break;
	case '8.0':
		isIE8 = true;
		break;
	}
 
	if (isIE6 || isIE7)
	{
		fixButtonSubmit('action');
	}
});

An alternative non-javascript Solution would be to replace any BUTTON elements with INPUT submit elements. You only need to apply this to IE6/7, which you can target with IE conditional comments. See my post on targeting non-IE browsers with IE conditional comments.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>