Button tag in bloody Internet Explorer

09 August 2005   135 comments   Web development

Mind That Age!

This blog post is 13 years old! Most likely, its content is outdated. Especially if it's technical.

I sincerely hate Internet Explorer sometimes. I never like it. Today it really pissed me off. If you use multiple <button> tags in one form, think again. It doesn't work in IE like it should do [...in Firefox]. If you have a form like this:

<form action="showRequestVariables">
<button type="submit" name="button1">Button1</button>
<button type="submit" name="button2">Button2</button>
</form>

Then, which ever button you press you'll get these request variables if you use Internet Explorer:

button1 = "Button1"
button2 = "Button2"

In Firefox you only get one; the one you pressed. Doesn't that seem logical? The Firfox way I mean.

To solve the problem and tame the IE bastard you'll have to loose the <button> tag and go for a <input> tag instead:

<form action="showRequestVariables">
<input type="submit" name="button1" value="Button1" />
<input type="submit" name="button2" value="Button2" />
</form>

Then you get the more sane behaviour you'd expect from a web browser.

Disclaimer: The spec (is too long to read) could prove me wrong but I feel pretty confident that Firefox has got it more right in this instance.

Comments

quan
well, you might want to try adding a "value" to the button tags you used...or better yet, why not just simply use <input>???????????????????
Peter Bengtsson
The value attribute on the button tag is browser ambigious, meaning that the IE sends a different value than Mozilla. (IE sends the value and the content of the tag)
Anonymous
why not just simply use <input>???????????????????

simple, semantic markup

<button> is much more samentic than <input>

also provides some css benifits
Peter Bencsik
IE makes you suck again. I have the same problem with it. I have a form with multiple <button>some text</button> tags, like this:
In-silico research (<button type="submit" name="removemethod" id="removemethod" value="3">-</button>),...
In Firefox if I press the button, I get these post values:
removemethod=3
In IE:
removemethod=-
So it always send the text between the <button></button> and not the value.
Peter Bengtsson
Exactly. Perhaps it's not IE's fault but the <button> tag's fault. Either way, it can't be used.
Peter Bencsik
Check this:
http://lists.evolt.org/archive/Week-of-Mon-20001002/017911.html

The funny (and most annoying) is that IE always sends the button, even if it was not pressed. In my example, I always gt removemethod=-, even if I press the normal submit button in the form.
BulletProofPoet
Thanks for posting this. I thought I was going mad when I saw this behaviour this afternoon. Unfortunately, it took me a couple of hours to disgnose the problems and find this page though!

There's no way IE should post the button field at all if the button wasn't pressed. Just another reason why IE should be taken out and shot!
AngryWithIE
I was going mad as well. So how am I supposed to get a button with text and an image if I can't use the <button> element?
Peter Bengtsson
You can but not collect the correct value. If you just want a button that submits the form, the <button> will do fine.
Chris Hutchins
They are out to drive me insane - with Moz/NS/Firefox I can get a simple button with an image of my choice (I use it for a photo browsing page). I have yet to come up with even a difficult work-around in IE.
Newbie Cobbler
Anybody know if its the case that Firefox does NOT support button/input border attributes - eg., border-left:5 solid#000099 and border-right:5 solid#000099 and similarly top/bottom - IE supports these OK - is there another way of naming these to get same result in Firefox/Netscape such that It will come up in IE as well?
Solange
you need write
eg. border-left:5px solid #000099;

look "5px" and not "5"
Meyaline
>
> Disclaimer: The spec (is too long to
> read) could prove me wrong but I feel
> pretty confident that Firefox has got
> it more right in this instance.
>

The W3C HTML 4.01 specification (1999) says (http://www.w3.org/TR/html4/interact/forms.html#h-17.13.2): "If a form contains more than one submit button, only the activated submit button is successful." (and by submit button, they mean both "<input type="submit" ... />" and "<button type="submit" ...>...</button>", as said here: http://www.w3.org/TR/html4/interact/forms.html#buttons)

It also is in the working draft of HTML 4 (1997)... (maybe a bit less clear, as they only say so for "<input type="submit" ... />", and say the "button" element works pretty much the same -well, not that unclear, AFAIC)

Anyway, I do wonder how it is of any use, to send the name/value of every submit buttons... Yet another proof that Microsoft just want to screw the world...

Heck, they are members and contributors of the W3C (and took part in the developpment of the HTML specifications), one would expect they at least properly implement such basic rules... well, they don't even do that... (and the worst is that it is purely intented)

Why in the world did I choose to become a webmaster...? :/
Random Penguin
THE SOLUTION TO THE IE BUTTON TAG DISPLAY VALUE/TEXT PROBLEM !!!!

Hi folks,
Here is a solution that works in IE.
I recommend using JavaScript or server-side code to detect the browser, since this code will not work in non-JavaScript browsers, whereas <button> code will.

<input type=submit name="buttonName" value="buttonValue" onclick="this.style='display: hidden';this.value='buttonValue'; this.submit()">
infinite
using that javascript method that "Random Penguin" provided is kinda silly .. buttons disappearing when clicked .. no thanks ..
i had the same problem between IE and FF, <input type=image name=button value=something> FF will sucessfully create a POST variable named 'button' with the value 'something' with 'button.x' and 'buttin.y' while IE only creates the last two ... so i had to switch to the button tag for my image button ... and like mentioned here i had the same probelm .. IE will assume the value of whatever inside the tag and ignore the "value" attribute ... so the simplest solution that comes to mind is setting the text size to 0px using css .. this way both browsers will work and everybody will be happy ... however it's all IE's fault ... i hate that damn thing but as a web developer i have to bend my self in it's favour cuz it's the most used browser out there .. personally i think anybody using it is a damn moron ...
Chris
Another solution is to disable all other submit button in the onClick Event.
But you know, it is all a workaround ...
Chris
For those who are interested:

function disableOtherSubmitButtons(submitButton)
{
if(!submitButton)
{
alert("no object found");
return;
}

if(!submitButton.type)
{
alert("no type attribute");
return;
}

if(submitButton.type != "submit")
{
alert("no submit button");
return;
}

if(!submitButton.form)
{
alert("parentless button (no form)");
return;
}

var formElements = submitButton.form.elements;

for(var i=0; i<formElements.length; i++)
{
//leave the pressed button as is...
if(formElements[i] == submitButton)
continue;

//disable all other submit buttons
if(formElements[i].type == "submit")
{
formElements[i].disabled = "true";
}
}
}

How to use it:
<form action="showRequestVariables">
<button type="submit" name="button1" onClick="disableOtherSubmitButtons(this)">Button1</button>
<button type="submit" name="button2" onClick="disableOtherSubmitButtons(this)">Button2</button>
</form>
Aaron Evans
Yeah, you can disable the other submit buttons, but it still submits the text within the button element, not the text of the value attribute!

This is a real pain because I am trying to determine an "action" based on the value attribute and I might want to reuse the text for different "actions" on different pages but posting to the same "action handler".
Marc Pujol
I've ended using a bunch of tricks wich finally worked pretty well:

1. We will run some javascript only if our browser is IE 5.5>, so we'll add this to header:

<!--[if gte IE 5.5000]>
<script type="text/javascript" src="btnfix.js"></script>
<![endif]-->

2. We'll allways assign the same value to the "class" and "value" tags of the button:

<button name="action" value="add" class="add">
<img src="add.gif" alt="add value" />Add to cart
</button>

3. We'll add this code to the "btnfix.js" file, so that it'll run on window.onload():

window.onload = function() {
var btns = document.getElementsByTagName('button');
for(var i=0;i<btns.length;i++) {
btns[i].onclick = function() {
var bs = document.getElementsByTagName('button');
for (var i=0;i<btns.length;i++) {
if (btns[i] != this)
btns[i].disabled = true;
}
this.innerHTML = this.className;
return true;
}
}
}
Marc Pujol
There's a typo in the script, where line 5 says: "var bs = ..." it should be "var btns = ..."

With all this we end up having fully functional buttons in IE and any other browser (that handles buttons correctly, like all gecko/khtml based ones). The only counterpart (and only in IE) is that our button will "unrender" itself just before sending the form (when our script changes it's innerHTML so it sends the correct value)
Tom
I found another possible solution for the problem:
Encapsulate every button in its own form. So instead of
<form action="showRequestVariables">
<button type="submit" name="button1">Button1</button>
<button type="submit" name="button2">Button2</button>
</form>

you write

<form action="showRequestVariables">
<button type="submit" name="button1">Button1</button>
</form>
<form action="showRequestVariables">
<button type="submit" name="button2">Button2</button>
</form>

IE now posts the correct values (at least that worked for me).
Jon Haugsand
Tom's solution is problematic when you have a table where each row have a submit button, and the other rows may or may not have input fields.

This should be quite common.

- Jon
Chris Doors
Yes this is blooming annoying;
Here's what I did;

I pairred each button tag with a hidden input field in the following way:

<button onClick='buttonTagClicked(this.name)' type='Submit' name='something1~button'>Submit</button>
<input type=hidden id=something1 name=something1 value=0>';

<button onClick='buttonTagClicked(this.name)' type='Submit' name='something2~button'>Submit2</button>
<input type=hidden id=something2 name=something1 value=0>';

And wrote this javascript function:

<script language="JavaScript" type="text/javascript">

function buttonTagClicked(field)
{
var fieldsarray=field.split("~");

document.getElementById(fieldsarray[0]).value=1;
}
</script>

Then when the button is submited it updates the related hidden field to 1. You can then use the hidden field variables to find which button tag was pressed as it will have value of 1.

We should not have to do this but IE is obviously cr*p. Hope this helps
Peter Bengtsson
That's a very complex solution. Is there a reason for this example that you haven't used any of the functionality of <button> tag over a <input type="submit" one?
Chris Doors
I removed all the images and such from between my button tags as would have made comment too large and ugly. If I didn't want all the button tag's functionality then I would have used the input tag as you suggest. Hope my code helps a bit.
Robert Polomsky
Hmm, quite nice, Chris. I will try it.
I had another solution. Better code, but it redraw button for a moment between clicking and disappearing of old page. Maybe somebody could improve it.

function submitForm() {
var e = document.getElementById('btnAction0');
e.value = e.attributes['value'].value;
}

<form method="get" action="login.cgi" onsubmit="submitForm()">
<button type="submit" id="btnAction0" name="action" value="login">Login me</button>
</form>

( be sure you don't use function name: "submit()" )
Chris Doors
I have cleaned up my code in previous example.

This is used if you have multiple button tags submitting the same form, so you can tell which button has submited form.

<form method="POST">
<input type=hidden id="submitbuttonpressedvalue" name="submitbuttonpressedvalue">

<button type="submit" onClick='buttonTagClicked(this.realvalue)' name='continuebutton' realvalue='continue'><img src="whatever.gif"></button>
<button type="submit" onClick='buttonTagClicked(this.realvalue)' name='backbutton' realvalue='back'><img src="whatever.gif"></button>
</form>
<script language="JavaScript" type="text/javascript">

function buttonTagClicked(buttonvalue)
{

document.getElementById('submitbuttonpressedvalue').value=buttonvalue;
}

</script>

Now in the post vars the realvalue of the button pressed should be in the
'submitbuttonpressedvalue' post var.

I think that's correct
FataL
IE 7 beta 2 solved that problem that submit all buttons by pressing one.
BUT there STILL one more poblem: IE 7 beta 2 still submit innerHTML of BUTTON instead of value attribute. :-/ DAMN!
BTW, try Dean's Edwards IE7 lib - it's solve all this issues:
http://dean.edwards.name/IE7/
Rich
I just got bit by this bug today, took me a while to figure out what was going on. I was using <button> for precisely the reason that it lets you set a different label ("Edit Foo") from its value ("edit-<foo's id>").

My solution was this bit of javascript:

function submitAndRedirect(submitButtonID, redirectCode) {
        var submitButton = document.getElementById(submitButtonID);
        var redirectElementID = "input_submit_redirect_" + submitButton.form.id;
        if (document.getElementById(redirectElementID)) {
                document.getElementById(redirectElementID).value = redirectCode;
        } else {
                element = document.createElement("input");
                element.name = "submit_redirect";
                element.id = redirectElementID;
                element.type = "hidden";
                element.value = redirectCode;

                submitButton.form.appendChild(element);
        }
}

Then changed the <button> code to:

<input type="submit" id="button_99_edit" name="submit" value="Edit Foo" onclick="submitAndRedirect('button_99_edit', 'edit-99')"/>

It creates a hidden form item that my server-side code can look for, and gives it the value 'edit-99'.

I *would* add this to my list of items I'm praying Microsoft fixes in IE 7, but I don't think there's room left. It's already so big.
Peter Bengtsson
Shame it doesn't work without javascript though.

You could make it much simpler if you'd just write you input tag like this:

<input type="submit"
name="99"
value="Edit this"
onclick="this.value=this.name;this.name='idvalue'"
/>

...or I just don't understand your particular application problem.
Dromyl
hey guys,
when i use <button> in FF with my ASP.Net App. The page is getting unecessarily refreshed.
where as it works fine with IE.

I have numbers of <button> tag in my page, i mean they are getting created dynamically.

Coz m using the btn tag just 2 call a javascript so i dont want page to be refreshed.

Any Comments/workarounds.
Jyoti
You can add attribute type="button" inside the button tag, then ur problem could be solved.
srbardo
I`m another annoyed web developer who whas about to going mad due to Microsoft incompetents, getting the same problems as you with multiple input and button values submits.

I think i´ll use the id property as it was the value property, plus hidden inputs and JavaScript code.

Thx for the info and up the FireFox!
Joerg
The really annoying this is: Why didn't M$ fix this bug in IE6 two years ago in one of its countless Windows updates?

I "solved" the problem by using simple <input> buttons instead of <button> buttons.
Anonymous
Add me to the list. MS implementation causes the use of button to be useless. Using the button element allows us to have a label independent of the value attribute.

And you can't create standards-compliant table-filled forms with IE's implementation of button.

VERY PO'D
stereopixel
I needed this for image buttons.

My version of it, which I think is simple and effective (thanks to all the previous contributors) but needs javascript:

function imgClick(value)
{
document.getElementById('IEfix').value = value;
}

<form method="post" action="ACTION.PHP">

<input type='hidden' id='IEfix' name='imageButtonIE' value=''>

<input type='image' src='1.jpg' value='IMG1' name='imageButton' onClick='imgClick(this.value)' />
<input type='image' src='2.jpg' value='IMG2' name='imageButton' onClick='imgClick(this.value)' />
<input type='image' src='3.jpg' value='IMG3' name='imageButton' onClick='imgClick(this.value)' />
<input type='image' src='4.jpg' value='IMG4' name='imageButton' onClick='imgClick(this.value)' />
<input type='image' src='5.jpg' value='IMG5' name='imageButton' onClick='imgClick(this.value)' />

</form>

--------------------------

No need to specify a different name for each image, you get 'imageButton' = value on Firefox, and 'imageButton' = "" on IE.

Then if you check 'imageButtonIE' you get the codename value of the clicked image (you can put there the name, or the index...)
snipes
stereopixel's script doesn't work with the <button> tag. If you try to get the set value for the button with 'this.value' IE will still send the innerHTML from the button tag.

I solved it by using the button tags name as the value instead and then accessing the value with 'this.name'. The server then requests the value from a hidden <input> with a specific name...
cresus
After reading all the page, it seems to me it is the best solution to this awful bug...

We only want to bypass a bug from IE, and we surely don't want to overload our codes because of it. stereopixel's solution corrected by snipes is quick and keeps everything relatively simple, clean and tidy.

Thanx everybody for your contribution, it helped me a lot ;-)
Paul
I had this problem today when i was using a php variable as the value using the <input> tag and sending it to another page using GET to be used for a MySQL query. It worked fine in FF but IE didnt want to know.

heres the code...

<input type="image" class="link" src="../viewgallery.gif" name="galname" value="'.$gallery_name.'" />

Thanks to this page giving me some ideas,

All i did was add this line to get it to work in IE...didnt need any javascript!

<input type=hidden id="galname" name="galname" value="'.$gallery_name.'">
</form>
Jesse
I didn't get Pauls solution to work with multiple buttons, but here is my solution without javascript (uses php instead):
<input type='image' alt='img1' src='../images/img1.gif' name='img1' />
<input type='image' alt='img2' src='../images/img2.gif' name='img2' />

and to see which button the user clicked:
if (isset($_POST['img1_x'])) {
unset($_POST['img1_x'],$_POST['img2_y']);
/* do whatever you wan't */
}
else if (isset($_POST['img2_x'])) {
unset($_POST['img2_x'],$_POST['img2_y']);
/* again do whatever you wan't */
}

I have to unset the post values because the user can click first img1 then img2 then again img1 and i just simply sen the whole $_POST array so eventually it would contain both. And still don't get different values, but can play with the different names.

If anyone can make a simpler solution with php i'd be happy to here about it
Keith Lawler
This is terrific! Thank you Jesse! I just used this solution and added the ability to get a value too. What you can do is add the value to the end of the name attribute seperated by a dash. For example if your name is "imagePressed" the new name would be "imagePressed-3". Then call the below function to extract it out.

<input type='image' name='imagePressed-3' src='/btn.gif'>

function getImageButtonValue($formvars, $name) {
// loop through the keys
foreach ($formvars as $key => $value) {
// if key is what you are looking for
if (strstr($key, $name)) {
// extract out the value from the name
$temp = split('-', $key);
// get rid of the _x or _y too
$temp = split('_', $temp[(sizeof($temp)-1)]);
return $temp[0];
}
}
// didn't find anything so return false.
return false;
}

Just becareful if your name attribute or value has dashes or underscores.

Hope this helps!
Rich LaMarche
Here is another variation.

<button type="submit" name="btnContinue" onclick="this.setAttribute('value','continue');"><img src="whatever.gif"></button>
<button type="submit" name="btnBack" onclick="this.setAttribute('value','back');"><img src="whatever.gif"></button>

Doesn't require a hidden field.
Ralph Holz
I find that Rich LaMarche's solution is not yet perfect. E.g. in IE6 - may it burn in hell - it does not work if you want to use two buttons with the same name. Example:

<button name="choice" type="submit" value="submitLogin" onClick="this.setAttribute('value', 'submitLogin');">1</button>

<button name="choice" type="submit" value="submitCancel" onClick="this.setAttribute('value', 'submitCancel');">2</button>

I use a MVC architecture and "choice" is the variable that I use to determine which step to take next. If you try to do it as above, even with Rich's patch, IE6 will still overwrite "choice" with the innerHTML of the second button ("2"), and that will be the value of "choice".

However, the following works: change the name attribute to something else, e.g. "choiceV". Then:

<button name="choiceV" type="submit" value="submitLogin" onClick="this.setAttribute('value', 'submitLogin'); this.setAttribute('name', 'choice');">...</button>

<button name="choiceV" type="submit" value="submitCancel" onClick="this.setAttribute('value', 'submitLogin'); this.setAttribute('name', 'choice');">...</button>

This takes care that only one button will be sent with name "choice", the other one will remain "choiceV", and your controller can use "choice" to properly determine the action to be taken. It does add a short delay to the processing of the page, but does not need JavaScript. Firefox can handle it as well. I dislike such patches immensely, but here I have no choice... but I will add the "Spread Firefox" button to my homepage now.
Arkady Renko
Guys, an enormous thank you for writing about the messed up nature of IE's button support. I spent hours on a problem assuming it was something to do with the way i'd set my sessions.. when it turns out that quite simply IE was sending the wrong value to my session variable. You've just saved me more hours of heartache

Cheers
Anonymous
tada!
this work !!!

button.endsWith("Seguir")

<button type="submit" name="button" value="Seguir"><img src="images2/right-blue.gif"> Seguir</button>
Sina Salek
Hi, thanks for all the solutions,
I like Ralph Holz solution, i think it's useful and easy so i improved it to a general way with no extra code require. only one function which works only in IE. it will change name of the button tags to something unique for preventing duplication. and then adds a js codes to each button onClick attribute. this event function is able to fetch value of button via regex and add hidden field with that value before submitting form.
hope it helps...

<script type="text/javascript">
//--(Begin)-->fetch value of button via outerHTML
function getButtonTagValue(buttonObj) {
var regexObj = /<[^<]*value="([^"'<>]*)"[^>]*>/;
//'
var match = regexObj.exec(buttonObj.outerHTML);
if (match != null && match.length > 1) {
return match[1];
} else {
return '';
}
}
//--(End)-->fetch value of button via outerHTML

function insertHiddenField(parentObj, name, value) {
var hiddenField = document.createElement('input');
hiddenField.type='hidden';
hiddenField.name=name;
hiddenField.value=value;
parentObj.parentNode.appendChild(hiddenField);
}

function fixIeButtonTagBug(formId) {
if (document.all || 1==1) {
var baseObject=document;
var elms;
var custFunc;

if (formId) baseObject=document.getElementById(formId);
elms=baseObject.getElementsByTagName('button');

if (elms) {
for (var x=0; x<elms.length; x++)
if (elms[x].tagName=='BUTTON') {
//this.setAttribute('value', getButtonTagValue(this)); this.setAttribute('name', '"+elms[x].name+"');
custFunc=new Function(
"insertHiddenField(this,'"+elms[x].name+"',getButtonTagValue(this));"+
"return true;"
);

elms[x].onclick=custFunc;
elms[x].name='___fixIeButtonTagBug___';
}
}
}
}

if (window.addEventListener)
window.addEventListener("load", function() {fixIeButtonTagBug();}, false)
else if (window.attachEvent)
window.attachEvent("onload", function() {fixIeButtonTagBug();})
</script>
Abraham J.
This is ever SHIT , but I have nestled a form in a form ... not clean job but it works, and have two working submit buttons.
Works in Windows browser and Firefox
Dan H.
Hello Abraham, you're solution works except in Internet Explorer 5.2 for the Mac.

The site I'm working on only has about 0.11% of sessions using Mac IE. So may not be a big deal. Depends on your site.
minghong
Hi guys, I found that by re-assigning outerHTML of the button element, the value can be fixed automagically.

e.g. forms["form"].onsubmit = function( e )
{
var button = document.activeElement || e.explicitOriginalTarget; // Get the button being pressed (work for IE, Mozilla and Opera only)
alert( button.value ); // The value is wrong
if ( window.ActiveX )
{
button.outerHTML = button.outerHTML;
}
alert( button.value ); // The value is correct
return false; // Just for testing
}
minghong
Typo. Please change "ActiveX" to "ActiveXObject". ;-)

Your email will never ever be published


Related posts

Previous:
Worst album covers (updated) 07 August 2005
Next:
Dream Theater - Octavarium 11 August 2005
Related by Keyword:
Another win for Tracking Protection in Firefox 13 December 2017
Getting uploadify to work 17 July 2009
The importance of checking in Firefox 07 July 2008
Future of Web Apps (quick summary and thoughts) 04 October 2007
Printer usability problem 24 August 2007
Related by Text:
jQuery and Highslide JS 08 January 2008
I'm back! Peterbe.com has been renewed 05 June 2005
Anti-McCain propaganda videos 12 August 2008
I'm Prolog 01 May 2007
Ever wondered how much $87 Billion is? 04 November 2003