views:

37

answers:

1

Hey guys,

Consider the following code:

index.html

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" 
    "http://www.w3.org/TR/html4/strict.dtd"&gt;
<html>
    <head>
        <script type="text/javascript" src="script.js"></script>
    </head>

    <body>
        <form>
            <button id="getInfoButton1"></button>
            <input type="button" id="getInfoButton2"></input>
        </form>
    </body>
</html>

With the accompanying JavaScript file:

script.js

window.onload = initAll;
var req;

function initAll()
{
    document.getElementById("getInfoButton1").onclick = getInfo;
    document.getElementById("getInfoButton2").onclick = getInfo;
}

function getInfo()
{
    req = new XMLHttpRequest();
    var URL = "index.html";
    req.open("GET", URL, true);
    req.onreadystatechange = whatsTheStatus;
    req.send(null);
}

function whatsTheStatus()
{
    if (req.readyState != 4) { return; }
    alert(req.status);
}

(I've pared down my code a lot, but this example still highlights the error)

The question is this: When you load this, and click both buttons, the first one will display a status of 0, while the second one displays a status of 200.

Of course, I'm expecting both to display 200, and I have no idea why the <button> is behaving differently. It's not a terribly big deal, but I would like to maintain the same use of <button> throughout my site.

I've looked around the web and asked some other developers at my company, and we can't seem to find the answer. Any ideas?

If it helps, I'm testing on Firefox 3.6.8. Also, I'm running it from localhost via WAMPserver 2.0.

+6  A: 

You would need <button type="button"> to reproduce the behaviour of <input type="button">.

If you omit the type on <button> it defaults to submit (except on IE<8 due to a bug; for this reason you should always use a type attribute on <button>). A submit button would cause the form to submit, causing a navigation and cancelling the XMLHttpRequest.

In general you should be trapping onsubmit on the form rather than onclick on a particular button, to ensure you always get informed if the form is submitted by another means such as Enter being pressed. (Consequently you'd use a normal submit button.) Use return false from the event handler to prevent the form submission from going ahead.

bobince
Whoa, well spotted, I even tried running it and didn't notice the page reloading...
Matti Virkkunen
and you you end up using more form controls (text inputs with ENTER key submission) you might want to add an event handler for the onsubmit of the form to return false. (e.g. onsubmit="return false;") - that is, assuming the form will never actually submit...
Dan Heberden
@Dan heh, was just adding in the note about that!
bobince
IIRC pressing enter also generates a click event on the default button of the form, so a `click` event handler on it should also catch it. Using the `submit` event of the form is neater though.
Matti Virkkunen
@Matti – Did you actually test this? That would be very weird…
Marcel Korpel
Well, look at that... adding type="button" works perfectly.Thanks!
tomtheman5
@Marcel: It does so at least in Firefox and Chrome. ...not that I would actually ever use that since I haven't tested it extensively. If it turns out it doesn't work in some browsers let's take this as a lesson to not use weird tricks without testing them properly first.
Matti Virkkunen
@Matti: there are some circumstances where an Enter press does not generate a click event on the first submit button in a form. (In this case the first submit button is also not considered ‘successful’ so does not pass its `name=value` pair in the submission either.) In particular, in IE when there is exactly one text field, pressing Enter in it causes a submit but does not fake the click. There have been some odder historical quirks here too. Avoid the issue: use `onsubmit`.
bobince
@Marcel - leaving out the form element is fine for a pure ajax implementation. For users with javascript turned off, however, it will allow the site to continue to submit the data and operate. Too, if the site is a large application, having different tag names for the dom is faster (a crap load of divs is more to search through for that form than getting all the form elements. @ bobince +1, click on submit can be problematic, particularly when you can attach to the forms submit anyway..
Dan Heberden
@Dan – of course, you're completely right. The question only dealt with an AJAX implementation. Deleted comment.
Marcel Korpel