IE sends inner HTML when clicking on a button elem

2019-03-19 22:31发布

I have the following html in my webpage (simplified).

<button type="submit" name="action" value="ButtonA">Click Here</button>

In Firefox, it submits "ButtonA" as the value for the "action" form value. However, in IE7, it submits "Click Here". Is there any way to resolve this? I don't want to use input tags, because I need to be able to customize the text without affecting the values sent back to the form (localization). Basically, I want to be able to have multiple buttons with the same name, and depending on their value, do a different action when submitted. Is there any easy with to get IE to act correctly in this case?

[MORE]

Maybe I should be more clear, but I can't use

<input type="submit" name="Action" value="ButtonA">

because I need to be able to change the text displayed for localization rules, without affecting the actual value of the button that's submitted with the form.

[MORE]

To elaborate even more, Basically, I want the button to be able to say "Save" or "Sauver" depending on the language, but not have the value submitted to the server change. I also want to have multiple buttons with the same name, and depending on the value, do something, rather than depending on the button name, and testing if there is a value for that button. The code is already written from that perspective, and I just want to be able to change the displayed text in the values, without existing server side processing code.

Here is a link with a very good explanation of the problem, with some possible work arounds.

12条回答
乱世女痞
2楼-- · 2019-03-19 23:11

As Eduardo mentions, JavaScript sounds like your best option. However, you'll need to somehow consider the fact that if a user has JavaScript disabled, you will not receive the appropriate value.

查看更多
Luminary・发光体
3楼-- · 2019-03-19 23:12

Good news: Microsoft fixed this in IE8 (standards mode only)

Bad news: It is still in beta

This jQuery fix works alright or you can hack your own JS to handle IE.

As for those suggesting input over button, that's fine, but if you want graphics or different styles on your button, then button is the only way to go.

查看更多
乱世女痞
4楼-- · 2019-03-19 23:12

Use <input> instead of <button>. Otherwise, here's a description of a nice jQuery-based hack.

查看更多
祖国的老花朵
5楼-- · 2019-03-19 23:14

One solution is to use Javascript and a hidden field

   <input type="hidden" name="actionparam" value="DoNothing">
   <input type="button" onclick="OnSubmitForm('ActionA')" Value="Click Here for A" />
   <input type="button" onclick="OnSubmitForm('ActionB')" Value="Click Here for B" />


   function OnSubmitForm(actionname) {
    var f = document.frm;
    f.actionparam.value = actionname;
    f.submit();
 }

This works as a hidden CATPCHA also, and you can add some client validation in the javascript function

Edit:

Since you say you want to degrade to non-javascript browsers, you can use this version, that allow only one default action to the people with no javascript

The extra buttons are disabled in HTML but then re-enabled with javascript.
Tested code:

<html>
<head>
    <script type="text/javascript">
    <!--
    function OnSubmitForm(actionname) {
            var f = document.frm;
            f.actionparam.value = actionname;
            f.submit();
    }
    //-->
    </SCRIPT>
</head>
<body>
   <noscript>
        <div style="background-color: yellow; margin: 20px;" >
            You are using a limited version of the site because you don't have Javascript enabled
        </div>
    </noscript>


   <h1>form</h1>
    <form name="frm" method="post">
    <input type="hidden" name="actionparam" value="DefaultAction" />
    <button name="defaultbutton" type="submit">default action</button>
    <button name="extrabutton1" disabled onclick="OnSubmitForm('ExtraAction1')">Extra action 1</button>
    <button name="extrabutton2" disabled onclick="OnSubmitForm('ExtraAction2')">Extra action 2</button>
    </form>


   <h1>Results</h1>
   <h2>forms collection</h2>
   <ol>
   <%
   For x = 1 To Request.Form.count()
      Response.Write("<li>" + Request.Form.key(x) + "=" + Request.Form.item(x) + "</li>")
   Next
   %>
   </ol>


    <script type="text/javascript">
    <!--
    document.frm.extrabutton1.disabled = false;
    document.frm.extrabutton2.disabled = false;
    //-->
    </SCRIPT>

</body>
</html>
查看更多
别忘想泡老子
6楼-- · 2019-03-19 23:18

Just had to deal with IE6's wonderful implementation of button elements. This solution does rely on Javascript but some may find it useful.

It's particularly annoying when using the AbstractWizardController in the Spring framework as the button element is the ideal solution for the "Next", "Back" and "Finish" buttons of the wizard but don't work in IE6.

So, I ended up writing a small jQuery based fix (though it's quite trivial to convert it so that you don't have to use the jQuery library).

$(function(){
if((window.XMLHttpRequest == undefined) && (ActiveXObject != undefined)) {
    $('button').click( function(event) {
        var rx = /\bvalue ?= ?(".*?"|'.*?')/i;
        var matches = $(this)[0].outerHTML.match( rx );
        if( matches != null )
            $(this).attr( 'value', matches[1].substring( 1, matches[1].length - 1 ) );
        $('button').not( $(this) ).attr('disabled','disabled');
    });
}
}); 

This will add an onclick event to all button elements. When a button is clicked it will grab the outerHTML of the button, e.g.:

<button name="playerId" value="34">Walter Payton</button>

and parse out the value attribute. Seems a lot of trouble to go in order to get the value but I found that getAttributeNode('value').value returned the innerHTML rather than the specified value attribute so wasn't very helpful. We then set the submatch of the regex as the value of the button. It should match it if you use either double or single quotes as delimiters but you do have to use some form of delimiter.

The upshot of this is that instead of "Walter Payton" being posted it will actually post "34" instead. The downside is that the button's appearance on the page will also change to "34" just before the form is submitted.

Finally the script will find all button elements except the clicked one and set their disabled attribute to be disabled. This ensures they aren't included in the POST and you don't get false positives.

查看更多
仙女界的扛把子
7楼-- · 2019-03-19 23:18

I don't know any way of making it work in IE7 (or IE6) without the need for JavaScript (or strange multi-form constructions).

Isn't that localized accessible to the back-end somehow either? Say, is the text coming from a database or will that just be inline in the local templates or so? You should be able to retrieve the localized version of the label both on printing and on validating the form on the back-end, shouldn't you (as much as you'd rather just use the unchanging value as you should really be able to do)?

There's always the JavaScript solution...

The following is more of a proof-of-concept that'll need some tweaking than a ready-made jQuery one-liner, but it should work without the need to change any of the HTML:

<!doctype html>
<html>

<head>

<title>Fix Buttons in IE6</title>

<script type="text/javascript">
function fixButtons() {
    var btns = document.getElementsByTagName('button');

    for (var i = 0; i < btns.length; i++) {
        btns[i].onclick = fixValue;
    }
}

function fixValue() {
    var btns = document.getElementsByTagName('button');

    for (var j = 0; j < btns.length; j++) {
        if (this == btns[j]) {
            this.value = this.getAttributeNode('value').value;
        }
        else {
            btns[j].parentNode.removeChild(btns[j--]);
        }
    }
}
</script>

</head>

<body onload="fixButtons()">

<form action="" method="get">
    <button type="submit" name="action1" value="value1">Do Action 1</button>
    <button type="submit" name="action2" value="value2">Do Action 2a</button>
    <button type="submit" name="action2" value="value3">Do Action 2b</button>
</form>

</body>

</html>

If it only needs to work in IE7, and not in IE6, the fiXValue() function can be reduced to just:

this.value = this.getAttributeNode('value').value
查看更多
登录 后发表回答