views:

182

answers:

5

Is there a way to submit an HTML form using JavaScript that is guaranteed to work in all situations?

I elaborate. The common approach seems to be:

formElement.submit()

That is all good and well except for one thing. Fields of a form are available as attributes of formElement, so if there is a field with name or id "text1", it can be accessed as formElement.text1.

This means that if an elements is called "submit" (be it its name or its id), then formElement.submit() will not work. This is because formElement.submit won't be a method of the form, but the field with that name. Unfortunately, it's fairly common that submit buttons have a "submit" name or id.

Two examples to illustrate my point. First, the following will NOT work, because an element of the form has name "submit":

<form name="example" id="example" action="/">
  <button type="button" name="submit" onclick="document.example.submit(); return false;">Submit</button>
</form>

The following will work though. The only difference is that I have removed the name "submit" from the form:

<form name="example" id="example" action="/">
  <button type="button" onclick="document.example.submit(); return false;">Submit</button>
</form>

So, is there any other way to submit an HTML form using JavaScript?

A: 

So, is there any other way to submit an HTML form using JavaScript?

Update: Take the advice of Jerome (elsewhere in this thread). I'll leave this answer up for historical interest, but it isn't as nice or reliable as Jerome's solution.

The following approach is ugly, but works.

    var x = document.forms.example;
    var f = document.createElement('form');
    f.action = x.action;
    f.method = x.method;
    f.enctype = x.enctype;
    for (var i = 0; i < x.elements.length; i++) {
        var el = x.elements[i];
        if (el.name !== "submit") {
            f.appendChild(el);
        }
    }
    x.parentNode.replaceChild(f,x);
    f.submit();
David Dorward
+14  A: 

Create another form in JavaScript, and apply its submit() function on your form:

<html>
    <script>
        function hack() {
            var form = document.createElement("form");
            var myForm = document.example;
            form.submit.apply(myForm);
        }
    </script>

    <form name="example" id="example" method="get" action="">
        <input type="hidden" value="43" name="hid">
        <button 
          type="button" 
          name="submit" 
          onclick="hack();return false;"
        >Submit</button>
    </form>
</html>
Jerome
That's really rather clever. +1.
David Dorward
+1 clever indeed
Pablo Fernandez
I've never run into apply ... +1!
Sean Vieira
Great use of apply! Blows my mind. +1
pablobm
Pleased to help you, that was a fun challenge. If this answer was helpful, please accept it by clicking on the green check on the left. Thank you!
Jerome
Don't worry, I just wanted to wait in case somebody came up with a solution that wasn't a hack, although yours was beautiful anyway. I hereby declare ye winner! ;-)
pablobm
Thank you pablobm :)
Jerome
A: 

In Firefox

formElement.constructor

returns "HTMLFormElement". So you can submit the form by using:

HTMLFormElement.prototype.submit.call(formElement)

You can extend this to other browsers as well:

formElement.constructor.prototype.submit.call(formElement)
Alsciende
However, not all browsers expose `constructor` on form elements (or any other host object, for that matter).
kangax
Obviously this is not cross browser
Pablo Fernandez
A: 

The best idea is to not name a submit button 'submit', but you can get around it-

function reallysubmitform(n){
 n= n || 0;
 var f= document.forms[n];
 f.onsubmit= function(){
  return true
 };
 var sub= f.elements['submit'];
 if(sub && sub.type== 'submit') sub.click();
 else f.submit();
}

reallysubmitform()

kennebec
A: 

Submiting a form using JavaScript cannot by design be safe.

Your users can browse your web site on their phone, have disabled JavaScript, tweaked the source of your page, or using Lynx.

In any case, for accessibility purposes, you will need the good old HTML submit button and some input checks on the server side.

Benoit Vidis
Of course, but sensible enhancements can still be added that make use of these features. As for "safety", I wasn't asking for it: it was reliability that I wanted, in the form of a stable interface
pablobm