18

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?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
pablobm
  • 2,026
  • 2
  • 20
  • 30
  • pretty annoying... I had the same issue with the "length" property of the form (number of controls) being replaced with the value of a control named "length". In the end I changed the name of the control. – Eric Bréchemier Jan 04 '10 at 14:43
  • See http://stackoverflow.com/questions/876243/why-does-naming-your-html-form-submit-button-submit-break-things – Darin Dimitrov Jan 04 '10 at 14:50
  • Am I stupid if I would suggest to give it just another name..? E.g. `"action"` or `"run"`. – BalusC Jan 04 '10 at 15:12
  • @BalusC: for a single script in a specific site, changing the name will suffice indeed. However, if you want to build a library to use in multiple sites, you need to provide for the most general case. Changing the name is not an option there. – pablobm Jan 04 '10 at 15:35
  • Great explanation of why form.submit() may not work; solved my problem! – Steve Jun 16 '11 at 19:49

7 Answers7

32

Create another form in JavaScript, and apply its submit() method on your original 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>

form.submit is the reference to a fresh and clean submit method, and then you use apply(myForm) to execute it with the original form.

Echilon
  • 10,064
  • 33
  • 131
  • 217
Jerome
  • 8,427
  • 2
  • 32
  • 41
2

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();
Quentin
  • 914,110
  • 126
  • 1,211
  • 1,335
1

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)
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Alsciende
  • 26,583
  • 9
  • 51
  • 67
1

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
  • 102,654
  • 32
  • 106
  • 127
  • It really solved one of my issues, where I cant change the name of the submit button even though I have the form HTML in my file, as I have to submit on external server and they had a check on if the form submitted is having a SUBMIT element or not. – Aamir Mahmood Jul 12 '12 at 11:20
0

For a form named submit just calling its buttons click function works for me.

document.forms[0].submit.click();  //where submit here is just the name of the button/input tied to the form.
Jonathon
  • 2,571
  • 5
  • 28
  • 49
  • 1
    When I originally asked the question, I was developing a JS library. I had to assume as little as possible about the environment. Therefore, this solution would not have worked for me, as I would have had to assume that users would use the correct markup. – pablobm Sep 23 '13 at 14:28
0

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.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Benoît Vidis
  • 3,908
  • 2
  • 23
  • 24
  • 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 Jan 04 '10 at 23:05
0

Just use onsubmit ...

<form name="example" id="example" action="/" onsubmit="document.example.submit();">
  <button type="submit" name="submit" onclick="document.example.submit(); return false;">Submit</button>
</form>
Zigri2612
  • 2,279
  • 21
  • 33