129

With window.open method I open new site with parameters, which I have to pass by post method.I've found solution, but unfortunately it doesn't work. This is my code:

<script  type="text/javascript">    
function openWindowWithPost(url,name,keys,values)
{
    var newWindow = window.open(url, name);

    if (!newWindow) return false;

    var html = "";
    html += "<html><head></head><body><form id='formid' method='post' action='" + url +"'>";

    if (keys && values && (keys.length == values.length))
        for (var i=0; i < keys.length; i++)
            html += "<input type='hidden' name='" + keys[i] + "' value='" + values[i] + "'/>";

    html += "</form><script type='text/javascript'>document.getElementById(\"formid\").submit()</sc"+"ript></body></html>";

    newWindow.document.write(html);
    return newWindow;
}
</script>  

Next, I create arrays:

<script type="text/javascript">    
var values= new Array("value1", "value2", "value3") 
var keys= new Array("a","b","c") 
</script>  

And call function by:

<input id="Button1" type="button" value="Pass values" onclick="openWindowWithPost('test.asp','',keys,values)" />   

But, when I click on this button, the site test.asp is empty (of course I try get pass values - Request.Form("b")).

How could I solve this problem, why I can't get pass values?

Abbas
  • 14,186
  • 6
  • 41
  • 72
luk4443
  • 2,709
  • 5
  • 23
  • 20
  • 2
    What's not working? I saved a copy at http://jsfiddle.net/TZMMF/ and it functions as expected. – PleaseStand Oct 17 '10 at 02:51
  • Thanks for reply. Yes, sorry - above code works. But I test this function with array of keys: I get value by Request.Form("2") In IE and Firefox I get empty page. – luk4443 Oct 17 '10 at 11:04

10 Answers10

141

Instead of writing a form into the new window (which is tricky to get correct, with encoding of values in the HTML code), just open an empty window and post a form to it.

Example:

<form id="TheForm" method="post" action="test.asp" target="TheWindow">
<input type="hidden" name="something" value="something" />
<input type="hidden" name="more" value="something" />
<input type="hidden" name="other" value="something" />
</form>

<script type="text/javascript">
window.open('', 'TheWindow');
document.getElementById('TheForm').submit();
</script>

Edit:

To set the values in the form dynamically, you can do like this:

function openWindowWithPost(something, additional, misc) {
  var f = document.getElementById('TheForm');
  f.something.value = something;
  f.more.value = additional;
  f.other.value = misc;
  window.open('', 'TheWindow');
  f.submit();
}

To post the form you call the function with the values, like openWindowWithPost('a','b','c');.

Note: I varied the parameter names in relation to the form names to show that they don't have to be the same. Usually you would keep them similar to each other to make it simpler to track the values.

Guffa
  • 687,336
  • 108
  • 737
  • 1,005
  • That's exactly what I was thinking. The original code posted did seem to work though...except on IE. – PleaseStand Oct 17 '10 at 03:37
  • Thanks for reply. But I have a table, where in column are buttons. When I click this button, I open new page and pass some parameters. So I have to write function, and for each button call it and pass fixed arguments. My question, how could I rewrite Your above code to function? – luk4443 Oct 17 '10 at 12:08
  • @luk4443: I added a function example above. – Guffa Oct 17 '10 at 14:35
  • Thanks, but I have still problem :( I'd like open new page test.asp, after click button. I've written Your code and I call function: I try add adress test.asp to window.open('test.asp', 'TheWindow'); but it still doesn't work. – luk4443 Oct 17 '10 at 15:28
  • 1
    @luk4443: If you use the URL when you open the window, the page will just be replaced when you post the form. Put the URL in the `action` property of the form. – Guffa Oct 17 '10 at 20:01
  • @Guffa the `f.more = additional` part did not work for me. I had to change this to: `f.more.value = additional`. Using Chrome 16. – qdii Jan 20 '12 at 14:47
  • @victor: Yes, of course you should set the `value` property. I corrected the code. – Guffa Jan 20 '12 at 15:34
  • 1
    @Guffa any way to also simulate the behavior of `target="_blank"`? – everton Jan 15 '14 at 20:31
  • 2
    @EvertonAgner: Use a unique name for the window, and it will work as `_blank`. – Guffa Apr 28 '15 at 15:55
  • how to pass whole object instead of setting single variables – vignesh selvarathinam Sep 22 '17 at 10:33
77

Since you wanted the whole form inside the javascript, instead of writing it in tags, you can do this:

let windowName = 'w_' + Date.now() + Math.floor(Math.random() * 100000).toString();
var form = document.createElement("form");
form.setAttribute("method", "post");
form.setAttribute("action", "openData.do");

form.setAttribute("target", windowName);

var hiddenField = document.createElement("input"); 
hiddenField.setAttribute("type", "hidden");
hiddenField.setAttribute("name", "message");
hiddenField.setAttribute("value", "val");
form.appendChild(hiddenField);
document.body.appendChild(form);

window.open('', windowName);

form.submit();
Ωmega
  • 42,614
  • 34
  • 134
  • 203
Mercenary
  • 2,106
  • 6
  • 34
  • 43
  • 7
    No jQuery and Pure JavaScript based implementation. Thanks. – Pawan Pillai Sep 01 '14 at 10:19
  • 2
    @Mercenary page is open in new tab here, can I open the page in new popup window? – Yaje Nov 29 '14 at 06:46
  • 1
    Should not be there some cleanup after the `form.submit()`, to remove the `form` from the `document.body` ? – Ωmega Feb 21 '21 at 23:53
  • @Yaje - Just add `"resizable"`or `"resizable=1"` or `"resizable=yes"` as the third parameter in the `window.open()`call and the browser will open a new window instead of a new tab. – Ωmega Feb 22 '21 at 00:10
  • how to make sure the form and it's inputs are attached to the newly opened window? I added an Id attribute to the input before submitting and trying to read the input `document.getElementById('id')` in the new window, but it returns nothing. – Thulasi Sep 22 '22 at 21:18
34

I completely agree with mercenary's answer posted above and created this function for me which works for me. It's not an answer, it's a comment on above post by mercenary

function openWindowWithPostRequest() {
  var winName='MyWindow';
  var winURL='search.action';
  var windowoption='resizable=yes,height=600,width=800,location=0,menubar=0,scrollbars=1';
  var params = { 'param1' : '1','param2' :'2'};         
  var form = document.createElement("form");
  form.setAttribute("method", "post");
  form.setAttribute("action", winURL);
  form.setAttribute("target",winName);  
  for (var i in params) {
    if (params.hasOwnProperty(i)) {
      var input = document.createElement('input');
      input.type = 'hidden';
      input.name = i;
      input.value = params[i];
      form.appendChild(input);
    }
  }              
  document.body.appendChild(form);                       
  window.open('', winName,windowoption);
  form.target = winName;
  form.submit();                 
  document.body.removeChild(form);           
}
Community
  • 1
  • 1
Youdhveer
  • 529
  • 5
  • 10
30

Even though I am 3 years late, but to simplify Guffa's example, you don't even need to have the form on the page at all:

$('<form method="post" action="test.asp" target="TheWindow">
       <input type="hidden" name="something" value="something">
       ...
   </form>').submit();

Edited:

$('<form method="post" action="test.asp" target="TheWindow">
       <input type="hidden" name="something" value="something">
       ...
   </form>').appendTo('body').submit().remove();

Maybe a helpful tip for someone :)

Imran Qamer
  • 2,253
  • 3
  • 29
  • 52
Andrius Naruševičius
  • 8,348
  • 7
  • 49
  • 78
  • 7
    This solution is incomplete. It should first add this form the body and then submit it. So where it says .submit(); it should say .appendTo('body').submit(); – Jonathan van de Veen Nov 10 '14 at 11:34
  • 2
    Without this part `$("body").append(form);` it won't work – Axel Sep 10 '15 at 20:47
  • 5
    If you add a `.remove()` after Jonathan's suggested `.appendTo('body').submit()`, you'll even clean up after yourself and not clutter the current page with form objects. – Simon Mar 08 '16 at 10:57
13

You could simply use target="_blank" on the form.

<form action="action.php" method="post" target="_blank">
    <input type="hidden" name="something" value="some value">
</form>

Add hidden inputs in the way you prefer, and then simply submit the form with JS.

Pier
  • 10,298
  • 17
  • 67
  • 113
  • Furthermore since `window.open` would be blocked as a popup, when not called inside a `click` handler (or any user fired event like that) – Xenos Oct 26 '18 at 14:38
6

I created a function to generate a form, based on url, target and an object as the POST/GET data and submit method. It supports nested and mixed types within that object, so it can fully replicate any structure you feed it: PHP automatically parses it and returns it as a nested array. However, there is a single restriction: the brackets [ and ] must not be part of any key in the object (like {"this [key] is problematic" : "hello world"}). If someone knows how to escape it properly, please do tell!

Without further ado, here is the source:

function getForm(url, target, values, method) {
  function grabValues(x) {
    var path = [];
    var depth = 0;
    var results = [];

    function iterate(x) {
      switch (typeof x) {
        case 'function':
        case 'undefined':
        case 'null':
          break;
        case 'object':
          if (Array.isArray(x))
            for (var i = 0; i < x.length; i++) {
              path[depth++] = i;
              iterate(x[i]);
            }
          else
            for (var i in x) {
              path[depth++] = i;
              iterate(x[i]);
            }
          break;
        default:
          results.push({
            path: path.slice(0),
            value: x
          })
          break;
      }
      path.splice(--depth);
    }
    iterate(x);
    return results;
  }
  var form = document.createElement("form");
  form.method = method;
  form.action = url;
  form.target = target;

  var values = grabValues(values);

  for (var j = 0; j < values.length; j++) {
    var input = document.createElement("input");
    input.type = "hidden";
    input.value = values[j].value;
    input.name = values[j].path[0];
    for (var k = 1; k < values[j].path.length; k++) {
      input.name += "[" + values[j].path[k] + "]";
    }
    form.appendChild(input);
  }
  return form;
}

Usage example:

var obj = {
  "a": [1, 2, [3, 4]],
  "b": "a",
  "c": {
    "x": [1],
    "y": [2, 3],
    "z": [{
      "a": "Hello",
      "b": "World"
    }, {
      "a": "Hallo",
      "b": "Welt"
    }]
  }
};

var form = getForm("http://example.com", "_blank", obj, "post");

document.body.appendChild(form);
form.submit();
form.parentNode.removeChild(form);
Ceremony
  • 198
  • 2
  • 13
3

I found a better way to pass parameters to the popup window and even to retrieve parameters from it :

In the main page :

var popupwindow;
var sharedObject = {};

function openPopupWindow()
{
   // Define the datas you want to pass
   sharedObject.var1 = 
   sharedObject.var2 = 
   ...

   // Open the popup window
   window.open(URL_OF_POPUP_WINDOW, NAME_OF_POPUP_WINDOW, POPUP_WINDOW_STYLE_PROPERTIES);
   if (window.focus) { popupwindow.focus(); }
}

function closePopupWindow()
{
    popupwindow.close();

    // Retrieve the datas from the popup window
    = sharedObject.var1;
    = sharedObject.var2;
    ...
}

In the popup window :

var sharedObject = window.opener.sharedObject;

// function you have to to call to close the popup window
function myclose()
{
    //Define the parameters you want to pass to the main calling window
    sharedObject.var1 = 
    sharedObject.var2 = 
    ...
    window.opener.closePopupWindow();
}

That's it !

And this is very convenient because:

  • You have not to set parameters in the URL of the popup window.
  • No form to define
  • You can use illimited parameters even objects.
  • Bi-directionnal : you can pass parameters AND, if you want you, can retreive new parameters.
  • Very easy to implement.

Have Fun!

BlueMan
  • 121
  • 2
  • 2
  • note: `window.opener` is not supported from all browsers. – Raptor Apr 08 '16 at 08:29
  • This only works if windows/tabs are of the same origin. Otherwise you will get accessing a cross-origin frame. Another solutions would be to use postMessage. – ScottyG Oct 19 '22 at 21:05
2

I wanted to do this in React using plain Js and the fetch polyfill. OP didn't say he specifically wanted to create a form and invoke the submit method on it, so I have done it by posting the form values as json:

examplePostData = {
    method: 'POST',
    headers: {
       'Content-type' : 'application/json',
       'Accept' : 'text/html'
    },
    body: JSON.stringify({
        someList: [1,2,3,4],
        someProperty: 'something',
        someObject: {some: 'object'}
    })
}

asyncPostPopup = () => {

    //open a new window and set some text until the fetch completes
    let win=window.open('about:blank')
    writeToWindow(win,'Loading...')

    //async load the data into the window
    fetch('../postUrl', this.examplePostData)
    .then((response) => response.text())
    .then((text) => writeToWindow(win,text))
    .catch((error) => console.log(error))
}

writeToWindow = (win,text) => {
    win.document.open()
    win.document.write(text)
    win.document.close()
}
0

The default submit Action is Ext.form.action.Submit, which uses an Ajax request to submit the form's values to a configured URL. To enable normal browser submission of an Ext form, use the standardSubmit config option.

Link: http://docs.sencha.com/extjs/4.2.1/#!/api/Ext.form.Basic-cfg-standardSubmit

solution: put standardSubmit :true in your config. Hope that this will help you :)

0

I've used this in the past, since we typically use razor syntax for coding

@using (Html.BeginForm("actionName", "controllerName", FormMethod.Post, new { target = "_blank" }))

{

// add hidden and form filed here

}

ransems
  • 641
  • 7
  • 19