RSS
 

Fixing the IE7 <Button> Submit Value

12 Mar

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.

That problem is easy enough to fix by making all BUTTON elements trigger form submit, but the second problem which is a tad more difficult to work around is that IE7 will submit the incorrect value of the BUTTON because it uses the innerHTML of the pair of <BUTTON></BUTTON> tags rather than the value=”” attribute. Consider the following form:

<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:

  1. 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.)
  2. 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:

  1. 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).
  2. 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');
  });
});

 
 

75,120 views

Tags: , ,

Leave a Reply

 

 
  1. Jonkemon

    May 25, 2012 at 2:16 am

    Hey there,

    Been very handy dealing with a classic pesky IE7 issue

    Thanks!
    j

     
  2. Dennis

    August 15, 2012 at 12:29 am

    Great fix, thanks!

     
  3. Andy Holland

    September 7, 2012 at 4:22 am

    This is a great workaround for IE7 buggy behaviour.

    I’d suggest that the code should be:

    $(‘form button[type=”submit”]’)

    rather than just $(“form button”), which avoids submitting the form for click buttons and reset buttons.

     
  4. rommel

    September 7, 2012 at 6:57 am

    Nice idea, Andy, however the “type” attribute is optional on the button element and is very often excluded by developers, and by default, every button submits its form.

    However, it might be a good idea to modify it so that if the “type” attribute is specified and it is not “submit” then it should not trigger form submission. I’ll make that change to the code above.

    Thanks!

     
  5. Daniel

    January 25, 2013 at 2:24 pm

    Why not just add a in youtrcode?

     
  6. rommel

    January 25, 2013 at 4:02 pm

    You can’t submit a form using an a tag without JavaScript.

     
  7. Jamie Kitson

    May 8, 2013 at 8:19 am

    You need to add $(this).removeAttr(“name”); immediately before the submit.

     
  8. rommel

    May 8, 2013 at 8:39 am

    Is this because you’re having an issue of the button’s label being submitted as the value for the name? Interesting if so, as I haven’t had that happen.

    Just removing the “name” attribute won’t be a complete fix because then the submission won’t work on a subsequent click. (This could happen if, for example, you canceled the submission after clicking.)

    I’ve implemented a fix in the code above. Thanks!

     
  9. Florian Kammermann

    October 9, 2013 at 3:51 am

    I had to put a “return false” after the submit trigger to avoid a double post:

    $(f).trigger(‘submit’);
    return false;

     
  10. rommel

    October 9, 2013 at 5:00 am

    Hi Florian-

    That makes sense but it’s interesting that I’ve never encountered that issue. I’ve updated the code to include your edit.

    Thanks for reporting this!

     
  11. Charles Lehnert

    February 4, 2014 at 7:32 pm

    Thanks so much for this. I’m not going to change my whole site for IE7. I’d much rather make IE7 comply with my site.

     
  12. Adam

    April 4, 2014 at 6:25 am

    Thanks for this. Ended my squeaky bum moment when testing my new app on ie7 the evening before UAT.
    If only the client had told me of the ie7 requirement at the start of the project……..

    Bum now relaxed

     
  13. Chris Pratt

    February 18, 2015 at 1:24 pm

    You’re only partially correct here. A button will very indeed submit a form in IE7, as long as it has type=”submit”. If you leave this out, then, yes, IE7 won’t do a thing when you click it. However, you should *always* specify the type. Otherwise you’re relying on a browser implementation to decide what happens when the user clicks the button, and while right now most browsers may submit by default, there’s nothing saying that other browsers would choose not to submit, or that this default won’t change. By specifying the type, you, not the particular browser implementation, decide what happens, and that’s the way it should be.

    However, you are correct that the button inner text, and not the value is submitted in IE7. Yet, honestly, I think having a submit button actually contain a form value is kind of a bad design choice in the first place. If you want some implicit value passed on submit, then use a hidden input. That’s what they’re for.

    So, use hidden inputs for implicit values and add type=”submit” to buttons that should submit the form and suddenly you’re 100% cross-browser with no JS hacks needed. Seems much more sane to me.

     
  14. rommel

    February 18, 2015 at 1:43 pm

    Thanks for the reply, Chris. You’re totally right that a BUTTON tag should have type=”submit” included if possible.

    Your hidden input suggestion, however, is not a solution if your intent is to determine which button the user clicked.

    By the way, when is Guardians of the Galaxy 2 coming out? [I can’t imagine how tired you must be of hearing that type of comment, so I apologize. ;-p ]