14

I need to create a form with a few inputs when an event happens. My code is below.

Chrome submits fine - the alert box shows and the page changes.

Firefox does not work - the alert box shows but the page stays the same. How can I get Firefox to submit the form?

var idsInput = document.createElement('input');
idsInput.name = 'itemIds';
idsInput.value = ids;

var quantityInput = document.createElement('input');;
quantityInput.name = 'quantity';
quantityInput.value = 1;

var authTokenInput = document.createElement('input');
authTokenInput.name = 'authenticityToken';
authTokenInput.value = '${session.getAuthenticityToken()}';

var submitInput = document.createElement('input');
submitInput.type = 'submit';
submitInput.value = 'anything';

var form = document.createElement('form');;
form.action = '@{Checkout.setItemsQuantityHandler}';
form.method = 'POST';
form.elements[0] = idsInput;
form.elements[1] = quantityInput;
form.elements[2] = authTokenInput;
form.elements[3] = submitInput;
form.submit();

alert('after submit()'); // for debugging only
Amy B
  • 17,874
  • 12
  • 64
  • 83
  • 2
    Shoot in the dark: set form to `display:none` and add it to an existing element in DOM and then submit it. I'd imagine that FF requires it to be in the DOM already. – BalusC Mar 06 '11 at 02:28
  • @Balus: or even better, delete it after submit? – JCOC611 Mar 06 '11 at 02:29
  • @JCOC: that's a non-concern for this specific issue :) Page will be refreshed anyway since OP doesn't use ajaxical stuff. – BalusC Mar 06 '11 at 02:30
  • Yeah, that would go instead of `display:none` – JCOC611 Mar 06 '11 at 02:31
  • 1
    @Balus - `document.body.appendChild(form);` worked. Thanks! If you want to put that as an answer, I'll accept it. – Amy B Mar 06 '11 at 02:33
  • @JCOC: I'd imagine that the reason of doing this in JS is just to hide the form from the enduser :) There may be some lag before the response returns. Hence the `display:none`. – BalusC Mar 06 '11 at 02:33

2 Answers2

23

FF requires it to be in the DOM already. Set form to display:none and add it to an existing element in DOM and then submit it.

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • Wouldn't this work too? `document.body.appendChild(form);` I'm honestly not too clear on distinct between "DOM" and "page" in this context. Has similar issue where it worked fine in Chrome and failed in IE and FireFox. – ficuscr Aug 19 '15 at 18:42
  • `document` is root node of DOM tree. – BalusC Aug 19 '15 at 18:45
  • Sorry for typos in last comment. Wanted to make clear that while `document.createElement` doesn't add it to the DOM (like I'd assumed) it can still be accomplished programmatically with `appendChild`. That is, it does not require the form be in the HTML markup when instantiated or anything like that. – ficuscr Aug 20 '15 at 00:15
  • Markup (retrieved HTML output) != DOM tree (client side model). – BalusC Aug 20 '15 at 05:42
6

Try This...

var idsInput = document.createElement('input');
idsInput.name = 'itemIds';
idsInput.value = ids;

var quantityInput = document.createElement('input');
quantityInput.name = 'quantity';
quantityInput.value = 1;

var authTokenInput = document.createElement('input');
authTokenInput.name = 'authenticityToken';
authTokenInput.value = '${session.getAuthenticityToken()}';

var submitInput = document.createElement('input');
submitInput.type = 'submit';
submitInput.value = 'anything';

var form = document.createElement('form');
form.action = '@{Checkout.setItemsQuantityHandler}';
form.method = 'POST';
form.elements[0] = idsInput;
form.elements[1] = quantityInput;
form.elements[2] = authTokenInput;
form.elements[3] = submitInput;
document.body.appendChild(form);
form.submit();

rjvilla
  • 61
  • 1
  • 1