POST Form without a redirect - javascript

I would like to post a form's data to the page where the database-query will be made.
But I don't want like in normal cases where a new page opens up, or the site gets redirected. It should be something like a "hidden" post.
I tried to use a xmlhttp-request (GET) with a URL, but since there are a lot of form-fields where you can enter a few sentences of text, the URL gets super long.
I also heard about the "POST" xmlhttp-request, but I haven't found a good tutorial with a working example.
I don't want to use jQuery or anything like that.
Does anybody know how to do this, or how xmlhttp post works?
Here is the code I used for GET: (BUT I would like to not do the var ID1 = ... part. I want to just get the values by $_POST like a regular submit.
function doGET() {
var ID1 = document.getElementByID("Textfield1").value;
var ID2 = document.getElementByID("Textfield2").value;
var ID3 = document.getElementByID("Checkbox1").value;
if (window.XMLHttpRequest) {
xmlhttp = new XMLHttpRequest();
} else {
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystate = function() { alert(msg); }
xmlhttp.open("GET", "insert.php?ID1=" + ID1 + "&ID2" + ID2 + "&ID3=" + ID3, true);
xmlhttp.send();
}
HTML
<div>
<p> TEXT1 </p>
<Input type="TextBox" id="Textfiel1">
<br>
<p> TEXT2 </p>
<Input type="TextBox" id="Textfield2">
<br>
<p> Checkbox 1</p>
<Input type="Checkbox" id="checkbox1">
<br>
<Label onclick="doGET()"> Click </Label>
</div>

Sending a POST request is not much different than sending a GET. There are two key differences, though, that I will point out below:
Since you didn't supply an HTML form to work with, I made the following below:
<form id="myForm">
<input type="text" id="Textfield1" name="Textfield1" />
<input type="text" id="Textfield2" name="Textfield2" />
<input type="checkbox" id="Checkbox1" name="Checkbox1" />
<select id="Select1" name="Select1">
<option value="1">Option 1</option>
<option value="2" selected>Option 2</option>
</select>
</form>
I also refactored your doGET method, renaming it postForm which accepts a form element as an argument.
function postForm(form) {
var xmlhttp = null,
data = '';
for (var i = 0; i < form.elements.length; i++) {
data += '&' + encodeURIComponent(form.elements[i].id) + '=' + encodeURIComponent(form.elements[i].value);
}
data = data.substr(1); //Get rid of the first character.
if (window.XMLHttpRequest) {
xmlhttp = new XMLHttpRequest();
} else {
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystate = function() { alert(msg); }
xmlhttp.open("POST", "insert.php", true);
xmlhttp.send(data); //Send your data in the send method.
}
postForm(document.getElementById('myForm'));
We use POST instead of GET in the xmlhttp.open method.
We send the parameters just like you did in the GET, but I have automated the serialization of the form with a loop.

This is actually quite easy, you simply need an iframe in the document with a name attribute, and then you can set the target on your form to the same value.
When you submit the form, it will then target the iframe.
If you want the form to return something, it can return javascript that accesses the parent using parent.doSomething (as long as these are on the same domain).

Related

How to send in a form AJAX request to a c++ cgi? [duplicate]

I’m sending a POST request via XMLHttpRequest with data entered into an HTML form. The form without interference of JavaScript would submit its data encoded as application/x-www-form-urlencoded.
With the XMLHttpRequest, I wanted to send the data with via the FormData API which does not work since it treats the data as if it were encoded as multipart/form-data. Therefor I need to write the data as a query string, properly escaped, into the send method of the XMLHttpRequest.
addEntryForm.addEventListener('submit', function(event) {
// Gather form data
var formData = new FormData(this);
// Array to store the stringified and encoded key-value-pairs.
var parameters = []
for (var pair of formData.entries()) {
parameters.push(
encodeURIComponent(pair[0]) + '=' +
encodeURIComponent(pair[1])
);
}
var httpRequest = new XMLHttpRequest();
httpRequest.open(form.method, form.action);
httpRequest.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
httpRequest.onreadystatechange = function() {
if (httpRequest.readyState === XMLHttpRequest.DONE) {
if (httpRequest.status === 200) {
console.log('Successfully submitted the request');
} else {
console.log('Error while submitting the request');
}
}
};
httpRequest.send(parameters.join('&'));
// Prevent submitting the form via regular request
event.preventDefault();
});
Now this whole thing with the for ... of loop, etc. seems a bit convoluted. Is there a simpler way to transform FormData into a query string? Or can I somehow send FormData with a different encoding?
You could use URLSearchParams
const queryString = new URLSearchParams(new FormData(myForm)).toString()
You've asked for a simpler solution...
A for loop is the simplest way to traverse over a collection - imho.
But there is a shorter version if you use the spread operator/syntax (...)
The spread syntax allows an expression to be expanded in places where
multiple arguments (for function calls) or multiple elements (for
array literals) or multiple variables (for destructuring assignment)
are expected.
Your for...of loop can then be replaced with:
let parameters = [...formData.entries()] // expand the elements from the .entries() iterator into an actual array
.map(e => encodeURIComponent(e[0]) + "=" + encodeURIComponent(e[1])) // transform the elements into encoded key-value-pairs
If you could use JQuery, you'll simply call .serialize() function on your form object, like follow:
function getQueryString() {
var str = $( "form" ).serialize();
console.log(str);
}
$( "#cmdTest" ).on( "click", getQueryString );
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form>
<select name="list1">
<option>opt1</option>
<option>opt2</option>
</select>
<br>
<input type="text" name="txt1" value="valWith%Special&Char$">
<br>
<input type="checkbox" name="check" value="check1" id="ch1">
<label for="ch1">check1</label>
<input type="checkbox" name="check" value="check2" checked="checked" id="ch2">
<label for="ch2">check2</label>
<br>
<input type="radio" name="radio" value="radio1" checked="checked" id="r1">
<label for="r1">radio1</label>
<input type="radio" name="radio" value="radio2" id="r2">
<label for="r2">radio2</label>
</form>
<button id="cmdTest">Get queryString</button>
Note: It also encode data for use it in url request
I hope it helps you, bye.

It seems I can't get my FormData object through to my PHP script

I'm working on a small homemade CMS/portfolio-type thing, using HTML, PHP and Javascript (I'm trying not to use jQuery, or node.js), and I can't seem to make my FromData() object reach my php script...
I want to, when a form (used to create a new project page) is submitted, pass it through a small piece of js, and then send it to a php script that will write what needs to be written down in the database, create the files, etc...
In order to achieve this, I'm trying to use a FormData() object. I used to do it with a full on url-style request (and it did work!) but I want to add the option to upload images.
The form is declared a enctype="multipart/form-data", and the POST request also, but then, nothing seems to touch the php script...
Here's the code (I'm french, hence some of the variable names...):
<form method="post" id="add_form" enctype="multipart/form-data">
<fieldset>
<legend>Infos:</legend><br />
<label for="add_cat">Catégory:</label>
<select name="add_cat" id="add_cat">
<?php
$USR_CATS = $bdd->query('SELECT * FROM cats');
while($cat = $USR_CATS->fetch()){
?>
<option <?php echo 'value="'.$cat['cat'].'"'; ?> <?php if($cat['id'] == 1){echo 'selected';}?> ><?php echo $cat['cat'] ?></option>
<?php
}
$USR_CATS->closeCursor();
?>
</select><br />
<input type="button" id="add_newCat" name="add_newCat" value="Ajouter une catégorie"><br />
<label for="add_titre">Title:</label>
<input type="text" id="add_titre" name="add_titre" required><br />
<label for="add_support">Support:</label>
<input type="text" id="add_support" name="add_support" required><br />
<label for="add_com">Commentaire du projet:</label>
<textarea id="add_com" name="add_com" required></textarea><br />
</fieldset>
<fieldset id="add_infosFieldset">
<legend>Infos Techniques:</legend><br />
<input type="text" class="add_infos" placeholder="ex: Format: 65x84 cm" style="display:block">
<input type="button" id="add_newInfos" name="add_newInfos" value="Ajouter une information"><br />
</fieldset>
<fieldset id="add_imagesFieldset">
<legend>Images:</legend>
<input type="file" class="add_images" style="display:block">
<input type="button" id="add_newImagesBouton" name="add_newImagesBouton" value="Ajouter une image"><br />
</fieldset>
<input type="submit">
</form>
When submitted, the results of this form goes through js:
var add_form = document.getElementById("add_form");
add_form.addEventListener("submit", function(e){
e.preventDefault();
add_formData = new FormData();
//Basic infos
add_formData.append("add_prjt", true);
add_formData.append("add_cat", document.getElementById("add_cat").value);
add_formData.append("add_titre", document.getElementById("add_titre").value);
add_formData.append("add_support", document.getElementById("add_support").value);
add_formData.append("add_com", document.getElementById("add_com").value);
//I had, for that, to make a loop because I want the user to be able to create and fill as many fields as he/she wants
var infos = document.getElementsByClassName("add_infos");
var infosCh = ""; //So I'm creating a string which will contain them all
for(var i = 0; i < infos.length; i ++){
infosCh += infos[i].value + "<br />"; //Concatening everything so that the different infos are separated by <br />
}
add_formData.append("add_infos", infosCh);
//And then a bunch of shenaningans regarding the number of images people want to upload, so that there can be as much upload buttons as they want, each of them containing several images
if(add_nbreBoutonsImages > 0){
add_formData.append("add_nbreBoutonsImages", add_nbreBoutonsImages);
var add_nbreImages = 0;
for(var j = 1; j < add_nbreBoutonsImages; j++){
var nbreImagesUpload = document.getElementById("add_newImages"+j).files.length; //On regarde combien d'images y a été sélectionné
for(var x = 0; x < nbreImagesUpload; x++){ //Et pour chacune d'entres elles
add_nbreImages++;
add_formData.append("add_image"+add_nbreImages, document.getElementById("add_newImages"+j).files[x], "add_image"+add_nbreImages);
}
}
}
//add_formData.contentType = false;
//add_formData.processData =false;
//I tried with and without those, but they doesn't seem to work without jQuery
//The problem must come from here...
var req = new XMLHttpRequest();
req.open("POST", "add.php", true);
req.setRequestHeader("Content-Type", "multipart/form-data");
req.send(add_formData);
});
I had a more advanced version of the request/sending step, but I tried keeping it as simple as possible first, trying to make it work
And then the php
if(isset($_POST['add_titre'])){
$fichierFichier = fopen('fichier.txt', 'a+');
fputs($fichierFichier, 'ça a marché...');
}
For now I'm just trying to see if PHP gets anything at all... But even those simple instructions doesn't get executed... As if PHP is not getting the variables?
I don't get it... And the frustrating part is that nothing appears to be not working, no error message, nothing... Just the big white blank
Anyway, thanks for your time!
Quick update on the situation:
The problem comes as soon as I'm trying to send something to PHP using ajax with the encapuslation "multipart/data-form".
I realised that even another script from the same project stopped working as soon as I modified my ajaxPost script (which I use to send things via POST through ajax, original name), it looks like this:
function ajaxPost(url, data, callback, isData){
var req = new XMLHttpRequest();
req.open("POST", url);
req.addEventListener("load", function(){
if(req.status >= 200 || req.status < 400){
callback(req.responseText);
}
else{
console.error(req.status + " " + req.statusText + " " + url);
}
});
req.addEventListener("error",function(){
console.error("Erreur réseau avec l'url: " + url);
});
//Ajout pour contrôler ou non si on envoie au format JSON
if(isData){
req.setRequestHeader("Content-Type", "multipart/form-data");
}
else{
req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
}
req.send(data);
}
As long as I'm calling it and specifiying I want a "application/x-www-form-urlencoded", it goes okay. But when I try the other option, it stops working, either sending a formData or a simple string.
I've checked my php.ini config file, and the file_upload is on. And when the form is itself a enctype=multipart/form-data, and I bypass the javascript step, it works...
Tricky thing is, I need all the informations at once, so that everytinhg can be placed properly, the images in the folder named after the project of which the page is being created, etc...
So, basically still at the same spot, but with a clearer understanding...
Is there anyway my php might be configured to block such cross-langage thing? Maybe I'm not understanding correctly the FormData, and not setting it up properly?

How to concatenate url with a variable everytime a login is made

The Wordpress site I'm working on:
http://www.careersroadmap.com/
After submission of a registration form, I have to redirect to this URL:
http://careertest.edumilestones.com/access-login-api.php?
However, during the redirect, I have to pass this variable to the URL:
category=2123&channel_id=371&cd=89&age=371&access_code=accesscodehere
So the final destination URL will be:
http://careertest.edumilestones.com/access-login-api.php?category=2123&channel_id=371&cd=89&age=371&access_code=accesscodehere
The access_code variable will change for each user that logs in.
I tried an AJAX call using the code below:
<script>
var startButton = document.getElementById("startButton");
startButton.addEventListener("click", getApiFunction());
function getApiFunction(){
var myRequest = new XMLHttpRequest();
myRequest.open('GET', 'http://careertest.edumilestones.com/access-login-api.php?category=2123&channel_id=371&cd=89&age=371&access_code=accesscodehere');
myRequest.onload= function(){
var myData = JSON.parse(this.response);
};
myRequest.send();
};
</script>
After trying the above code, I got the CORS policy error.
How do I accomplish this with Javascript or PHP??
I suppose you could add hidden inputs to the registration form.
Something along those lines:
<form action="http://careertest.edumilestones.com/access-login-api.php" method="GET">
<input type="hidden" name="category" value="2123">
<input type="hidden" name="channel_id" value="371">
<input type="hidden" name="cd" value="89">
<input type="hidden" name="age" value="371">
<input type="hidden" name="access_code" value="democodesjam12474">
</form>
A hidden field lets web developers include data that cannot be seen or modified by users when a form is submitted.
Read more about it here: https://www.w3schools.com/tags/att_input_type_hidden.asp

Append user entered data into redirect url

I had a question about trying to append user entered data into a redirect url. I use a online database/fundraising company (Salsa) for supporter sign ups. I want to have a form where people can enter just their email and zip, have that submit to be saved into the database (so onsubmit redirect) and then another form will come up if that person wants to fill out more information they can but they don't have to. The 2nd form should have prefilled their email and zip so they don't have to (to link it back to database)
What I tried to use is Salsa url that autofills the signup page provided it has the field names
example http://wfc2.wiredforchange.com/o/8564/p/salsa/web/common/public/signup?signup_page_KEY=7145&Email=testing#test.tes&Zip=12345
so http://wfc2.wiredforchange.com/o/8564/p/salsa/web/common/public/signup?signup_page_KEY=7145&Email=[email]&Zip=[zip]
The only problem is that I don't know how to pull form the form the user email and zip and append it to the url. I figure I need to use javascript but I am not very good with it.
Any help with this would be great and very appreciated. Even other ideas that I might try.
Edit:
I was able to figure some out on my own but could still use some help.
​function URL() {
var email = document.getElementById("email").value;
window.location = "http://wfc2.wiredforchange.com/o/8564/p/salsa/web/common/public/signup?signup_page_KEY=7145&Email=" + email;
}​
I used
onsubmit="URL(); return false;" in
So...
<form action="org2.salsalabs.com/save" ; method="POST" name="data" onsubmit="genURL(); false" >
<input type="text" id="user" />
<input type="submit" value="Submit" />
Something like that, except it won't submit the data to the database first, it just redirects me to the 2nd form. I am guessing it has something to do with onsumbit. Is there a way to have the data be submitted to the database first then redirect to the other form?
I would first have an XmlHttpRequest to your database with the information and then do the window.location redirect that you have already figured out when the request is complete. This is what it would look like in code.
HTML:
<form id="myForm">
Email: <input id="email" type="text" name="Email" /><br />
Zip: <input id="zip" type="text" name="Zip" /><br />
<input type="hidden" name="sign_up_page_KEY" value="7145" />
<input type="button" onclick="saveData()" value="Submit" />
</form>
JavaScript:
function saveData() {
var xmlhttp;
if (window.XMLHttpRequest) { // code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp = new XMLHttpRequest();
} else { // code for IE6, IE5
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange = function() {
if(xmlhttp.readyState == 4) { // Triggered when the information is done saving to your database
var email = document.getElementById("email").value;
var zip = document.getElementById("zip").value;
window.location = "http://wfc2.wiredforchange.com/o/8564/p/salsa/web/common/public/signup?signup_page_KEY=7145&Email=" + email + "&Zip=" + zip;
}
}
xmlhttp.open("POST", "org2.salsalabs.com/save", false);
xmlhttp.send(new FormData(document.getElementById("myForm"))); // Sends a post request to org2.salsalabs.com/save with all the data from the form with id="myForm"
}

How to know which <input> is submited when several ones are defined within a <form>?

I want to implement the below simple JavaScript function submitForm() based on XMLHttpRequest and FormData. This functions works well on the first <form> but fails on the second one: the function should use input.formaction instead of form.action.
How to detect the pressed <input> and retrieve the corresponding formaction?
( Most of SO answers advise to use a framework (as jquery) for such processing. But I think learning solely pure JavaScript is easier than learning also JS frameworks. If you are convinced that this snippet can be written simpler using a framework, please propose your version. Please explain also why your advised framework is pertinent/relevant/suitable in this case. I may decide to learn your favorite JS framework... EDIT: I have found this similar question: JQuery get formaction and formmethod )
<!DOCTYPE html>
<html>
<head>
<script>
function submitForm(form)
{
var xhr = new XMLHttpRequest();
xhr.onload = function() { alert (xhr.responseText); }
xhr.open ("post", form.action, true);
xhr.send (new FormData (form));
return false;
}
</script>
</head>
<body>
<form action="first.php" onsubmit="submitForm(this);">
<fieldset>
<legend>First</legend>
<input type="text" name="data" />
<input type="submit" />
</fieldset>
</form>
<form onsubmit="submitForm(this);">
<fieldset>
<legend>Second</legend>
<input type="text" name="data" />
<input type="submit" value="A" formaction="second-A.php" />
<input type="submit" value="B" formaction="second-B.php" />
</fieldset>
</form>
</body>
</html>
( I have implemented this snippet after reading XMLHttpRequest to Post HTML Form, Sending POST data with a XMLHttpRequest and the excellent MDN documentation. )
I'd propose to set the event listener in JavaScript, so you can access the Event object.
function submitForm(e) {
// Get the DOM element that submitted the form
var caller = e.target || e.srcElement;
// Set the action to 'formaction' attribute of the caller if it exists, otherwise use the action of the form the caller is in
var action = caller.getAttribute("formaction") || caller.form.action;
// This is your code, I just changed the variable name for the action to 'action'.
var xhr = new XMLHttpRequest();
xhr.onload = function() { alert (xhr.responseText); }
xhr.open ("post", action, true);
xhr.send (new FormData (form));
}
// Get all forms
var forms = document.querySelectorAll("form");
// Iterate over the forms
for (var i = 0; i < forms.length; ++i) {
// Set the event listener
forms.item(i).onsubmit = submitForm;
}
The 11684's answer is a good start point, but does not work for me...
I have finally fixed it (successfully tested on Firefox 25, does not work on IE9)
Therefore I provide my version if this can help someone else:
<!DOCTYPE html><html>
<head>
<script>
function submitForm(e)
{
var form = e.target;
var input = e.explicitOriginalTarget;
var action = input.formAction || form.action;
var xhr = new XMLHttpRequest();
xhr.onload = function() { alert (xhr.responseText); }
xhr.open ("post", action, true);
xhr.send (new FormData (form));
return false; //avoid following the link
}
</script>
</head>
<body onload="var forms = document.querySelectorAll('form');
for (var i = 0; i < forms.length; ++i)
forms.item(i).onsubmit = submitForm;">
<form id="first" action="first.php">
<fieldset>
<legend>First</legend>
<input type="text" name="data" />
<input type="submit" />
</fieldset>
</form>
<form id="second" >
<fieldset>
<legend>Second</legend>
<input type="text" name="data" />
<input type="submit" value="A" formaction="second-A.php" />
<input type="submit" value="B" formaction="second-B.php" />
</fieldset>
</form>
</body>
</html>

Categories