Window.open and pass parameters by post method - javascript

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?

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.

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();

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);
}

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 :)

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.

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);

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!

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()
}

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 :)

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
}

Related

How to replace hidden input with global variable to hold data

Currently I save data in input type="hidden" and access them from any JS script using getDocumentById("sourceJson"). For example:
<input type="hidden" id="sourceJson" name="sourceJson" >
var val = document.getElementById("sourceJson").value
But it forces me to scatter many hidden inputs in the HTML file. What is good replacement to hold data and have access to it from all scripts? Some kind of global variables that can also be submitted to the server.
If you declare a variable in any normal script it should be available from any other script.
<html><body>
<script>
var varOne = "Hello ..";
</script>
<script>
var varTwo = ".. world";
</script>
<script>
alert(varOne + varTwo);
</script>
</body></html>
Update
To Store array data we can use localStorage.setItem("data", JSON.stringify(data));
const data = localStorage.getItem("data")? JSON.parse(localStorage.getItem("data")):[];
function setData(name, value){
data.push({"name":name, "value":value});
localStorage.setItem("data", JSON.stringify(data));
}
function getData(name){
var ret = undefined;
for(var x = 0; x < data.length; x++){
if(data[x].name == name){
ret = data[x].value;
}
}
return ret;
}

How do I get the id of a element in a form?

I need to get the id of an element within a form so I can tag the element as "false" or "true". Or, alternately, I need a way to associate a name with an element that can I pull in javascipt so I can change the associated value.
var form = document.getElementById("myForm");
form.elements[i].value
Those lines of code is what I tried but it doesn't seem to work.
Edit:
function initial(){
if (localStorage.getItem("run") === null) {
var form = document.getElementById("myForm").elements;
for(var i = 0; i < 1 ; i++){
var id = form.elements[i].id;
sessionStorage.setItem(id,"false");
}
localStorage.setItem("run", true);
}
}
So basically when I run the page, I want a localStorage item attached to all the buttons on the screen. I want this to run once so I can set all the items to false. Problem is I don't know how to get the ids so I have a value to attach to the button. Any idea of how to accomplish a task like this.
Edit2:
function initial(){
if (localStorage.getItem("run") === null) {
var form = document.getElementById("myForm");
var tot = document.getElementById("myForm").length;
for(var i = 0; i < tot ; i++){
sessionStorage.setItem(form.elements[i].id,"false");
}
localStorage.setItem("run", true);
}
}
This is the new code. It mostly seems to work but for some reason only the first value is getting set to false. Or maybe it has to do with this function, I'm not sure.
function loader(){
var form = document.getElementById("myForm");
var tot = 5;
for(var i = 0; i < 5 ; i++){
if(sessionStorage.getItem(form.elements[i].id) === "true"){
document.getElementById(form.elements[i].id).style.backgroundColor = "green";
return ;
}else{
document.getElementById(form.elements[i].id).style.backgroundColor = "red";
return false;
}
}
}
Anyways, I'm running both of these at the same time when the page is executed so they are all set to false and turn red. But when a button is properly completed, the color of the button turns green.
It's available via the id property on the element:
var id = form.elements[i].id;
More on MDN and in the spec.
Live Example:
var form = document.getElementById("myForm");
console.log("The id is: " + form.elements[0].id);
<form id="myForm">
<input type="text" id="theText">
</form>
You're already storing all the elements in the form so it must be :
var form = document.getElementById("myForm").elements;
var id = form[i].id;
Or remove the elements part from the form variable like :
var form = document.getElementById("myForm");
var id = form.elements[i].id;

Get data sent from form in popup

I need to Get data sent from form in popup but the problem that in the form there is many checkboxes with same name like name='list[]' :
JS :
function showPopup(){
var user = document.getElementById("check").value;
var popup = window.open("milestone.php?a="+user,"hhhhhh","width=440,height=300,top=100,left=‌​300,location=1,status=1,scrollbars=1,resizable=1") ;
}
html :
<input type='checkbox' name="approve[]" value="get from Mysql">
<input type='checkbox' name="approve[]" value="get from Mysql">
<input type='checkbox' name="approve[]" value="get from Mysql">
var user = document.getElementById("check").value;
That won't work because:
You need to get multiple values
You need to get the values only of checkboxes that have been checked
You don't have an element with that id (but an id has to be unique anyway)
The fields all have the same name. Use the name.
var inputs = document.getElementsByName("approve[]")
Then you need to generate your form data from it, filtering out the ones which are not checked:
var form_data = [];
for (var i = 0; i < inputs.length; i++) {
var input = inputs[i];
if (input.checked) {
form_data.push(encodeURIComponent(input.name) + "=" + encodeURIComponent(input.value));
}
}
Then put all the form data together:
var form_data_query_string = form_data.join("&");
Then put it in your URL:
var url = "milestone.php" + "?" + form_data_query_string;
Then open the new window:
var popup = window.open(url,"hhhhhh","width=440,height=300,top=100,left=‌​300,location=1,status=1,scrollbars=1,resizable=1") ;
If you want to pass the array via get you should loop through all the checked checkboxes and store the value of everyone in array then convert them to Json using JSON.stringify so you can passe them in url :
function showPopup(){
var approve_array=[];
var checked_checkboxes = document.querySelectorAll('input[type="checkbox"]:checked');
for(var i=0;i<all_checkboxes.length;i++){
approve_array[i] = checked_checkboxes[i].value;
}
var url = "milestone.php?approve="+JSON.stringify(approve_array);
var popup = window.open(url,"hhhhhh","width=440,height=300,top=100,left=‌​300,location=1,status=1,scrollbars=1,resizable=1") ;
}
In you php page you could get the array passed as Json using json_decode :
$array_of_approves = json_decode($_GET['approve']);
Hope this helps.
You can access the value as:
$approveList= $_POST['approve'];
and can be iterated as
foreach ($approveList as $approve){
echo $approve."<br />";
}

Multiple files upload in onedrive (skydrive)?

It is possible to upload multiple files in onedrive(skydrive) using WL.upload ? I tried something but I always get an error like "element must be an html input element" or something like this. I use onedrive sdk 5.6 and the application is build in ASP.NET MVC 5. The problem is that I created an input of type="file" with the attribute multiple set so I can select multiple files from my computer but the upload method from WL api ask for an element property that is actual an id to an input element of type="file". Because my input is set on multiple I tried to iterate through the files that contains and to create an input element to pass to the method, but it's doesn't work because due to security reasons I can set a value of an input element.
So, does anybody knows how I can do this ? Thanks
This is what I have tried:
<div id="save-to-skydrive-dialog-content-multiple">
<p>select a file</p>
<form enctype='multipart/form-data' method='POST'>
<input id="save-to-skydrive-file-input-multiple" type="file" name="files[]" multiple />
</form>
<p>upload file</p>
<button id="save-to-skydrive-upload-multiple-button">upload multiple</button>
</div>
function saveMultipleToSkyDrive() {
WL.fileDialog({
mode: 'save'
}).then(function (response) {
var folder = response.data.folders[0];
var elements = document.getElementById("save-to-skydrive-file-input-multiple").files;
for (var i = 0; i < elements.length; i++) {
var htmlInPutElement = document.createElement('input');
htmlInPutElement.setAttribute('type', 'file');
htmlInPutElement.value = elements.item(i);
WL.api({
})
WL.upload({
path: folder.id,
element: htmlInPutElement,
overwrite: 'rename'
}).then(function (response) {
log("You save to" + response.source + ". " + "Below is the result of the upload");
log("");
log(JSON.stringify(response));
},
function (errorResponse) {
log("WL.upload errorResponse = " + JSON.stringify(errorResponse));
},
function (progress) {
});
}
}, function (errorResponse) {
log("WL.upload errorResponse = " + JSON.stringify(errorResponse));
}
);
Thanks.
From what I remember of messing with the input[file] element, you can't set the value of an input[file] like that, for security reasons.
var htmlInPutElement = document.createElement('input');
htmlInPutElement.setAttribute('type', 'file');
htmlInPutElement.value = elements.item(i);
A solution would be to post the files to an interim action on your controller, and then do the OneDrive API stuff in that action method instead. You can iterate through Request.Files (although it can be tricky with the multiple property, I learned the hard way - see this post for more info
I find the answer, but not in javascript, in c# code.
Html input:
<p>Upload Files</p>
<div id="save-to-skydrive-dialog-content">
#using (Html.BeginForm("UploadFiles", "Auth", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
<input type="file" name="file" multiple />
<input type="submit" value="Upload File"/>
}
</div>
C# method:
[HttpPost]
public async Task<ActionResult> UploadFiles()
{
var files = Request.Files;
if (Request.Files.Count > 0)
{
LiveLoginResult loginStatus = await authClient.InitializeWebSessionAsync(HttpContext);
if (loginStatus.Status == LiveConnectSessionStatus.Connected)
{
connectedClient = new LiveConnectClient(this.authClient.Session);
LiveOperationResult result = await connectedClient.GetAsync("me/skydrive");
string folderId = (string)result.Result["id"];
for (var i = 0; i < Request.Files.Count; i++)
{
var fileName = Request.Files[i].FileName;
var fileStream = Request.Files[i].InputStream;
LiveOperationResult uploadResult = await connectedClient.UploadAsync(folderId, fileName, fileStream, OverwriteOption.Overwrite);
}
}
}
return View("~/Views/Home/Index.cshtml");
}

Submit form without reloading page [duplicate]

This question already has answers here:
Submit form without page reloading
(19 answers)
Closed 9 years ago.
I have a function built in JavaScript that I want to be executed after a form submit is hit. It basically changes the look of the page completely. But I need a variable from the search box to still go through to the JavaScript. At the moment it flashes and resets what was there because it reloads the page.
So I set up a return false in my function which keeps it from doing that but the variable I want doesn't get submitted through the form. Any ideas on what I should do to get it? It's okay for the page to refresh as long as the updateTable() function works and isn't reset by the page reset.
<form action="" method="get" onsubmit="return updateTable();">
<input name="search" type="text">
<input type="submit" value="Search" >
</form>
This is the updateTable function:
function updateTable() {
var photoViewer = document.getElementById('photoViewer');
var photo = document.getElementById('photo1').href;
var numOfPics = 5;
var columns = 3;
var rows = Math.ceil(numOfPics/columns);
var content="";
var count=0;
content = "<table class='photoViewer' id='photoViewer'>";
for (r = 0; r < rows; r++) {
content +="<tr>";
for (c = 0; c < columns; c++) {
count++;
if(count == numOfPics) break; // check if number of cells is equal number of pictures to stop
content +="<td><a href='"+photo+"' id='photo1'><img class='photo' src='"+photo+"' alt='Photo'></a><p>City View</p></td>";
}
content +="</tr>";
}
content += "</table>";
photoViewer.innerHTML = content;
}
You can't do this using forms the normal way. Instead, you want to use AJAX.
A sample function that will submit the data and alert the page response.
function submitForm() {
var http = new XMLHttpRequest();
http.open("POST", "<<whereverTheFormIsGoing>>", true);
http.setRequestHeader("Content-type","application/x-www-form-urlencoded");
var params = "search=" + <<get search value>>; // probably use document.getElementById(...).value
http.send(params);
http.onload = function() {
alert(http.responseText);
}
}
You can use jQuery serialize function along with get/post as follows:
$.get('server.php?' + $('#theForm').serialize())
$.post('server.php', $('#theform').serialize())
jQuery Serialize Documentation: http://api.jquery.com/serialize/
Simple AJAX submit using jQuery:
// this is the id of the submit button
$("#submitButtonId").click(function() {
var url = "path/to/your/script.php"; // the script where you handle the form input.
$.ajax({
type: "POST",
url: url,
data: $("#idForm").serialize(), // serializes the form's elements.
success: function(data)
{
alert(data); // show response from the php script.
}
});
return false; // avoid to execute the actual submit of the form.
});
I guess this is what you need. Try this .
<form action="" method="get">
<input name="search" type="text">
<input type="button" value="Search" onclick="return updateTable();">
</form>
and your javascript code is the same
function updateTable()
{
var photoViewer = document.getElementById('photoViewer');
var photo = document.getElementById('photo1').href;
var numOfPics = 5;
var columns = 3;
var rows = Math.ceil(numOfPics/columns);
var content="";
var count=0;
content = "<table class='photoViewer' id='photoViewer'>";
for (r = 0; r < rows; r++) {
content +="<tr>";
for (c = 0; c < columns; c++) {
count++;
if(count == numOfPics)break; // here is check if number of cells equal Number of Pictures to stop
content +="<td><a href='"+photo+"' id='photo1'><img class='photo' src='"+photo+"' alt='Photo'></a><p>City View</p></td>";
}
content +="</tr>";
}
content += "</table>";
photoViewer.innerHTML = content;
}
I did it a different way to what I was wanting to do...gave me the result I needed. I chose not to submit the form, rather just get the value of the text field and use it in the javascript and then reset the text field. Sorry if I bothered anyone with this question.
Basically just did this:
var search = document.getElementById('search').value;
document.getElementById('search').value = "";

Categories

Resources