I have a form that looks like this
<form action="receiver.pl" method="post">
<input name="signed" type="checkbox">
<input value="Save" type="submit">
</form>
and I would like to stay on the same page, when Submit is clicked, but still have receiver.pl executed.
How should that be done?
99% of the time I would use XMLHttpRequest or fetch for something like this. However, there's an alternative solution which doesn't require javascript...
You could include a hidden iframe on your page and set the target attribute of your form to point to that iframe.
<style>
.hide { position:absolute; top:-1px; left:-1px; width:1px; height:1px; }
</style>
<iframe name="hiddenFrame" class="hide"></iframe>
<form action="receiver.pl" method="post" target="hiddenFrame">
<input name="signed" type="checkbox">
<input value="Save" type="submit">
</form>
There are very few scenarios where I would choose this route. Generally handling it with javascript is better because, with javascript you can...
gracefully handle errors (e.g. retry)
provide UI indicators (e.g. loading, processing, success, failure)
run logic before the request is sent, or run logic after the response is received.
The easiest answer: jQuery. Do something like this:
$(document).ready(function(){
var $form = $('form');
$form.submit(function(){
$.post($(this).attr('action'), $(this).serialize(), function(response){
// do something here on success
},'json');
return false;
});
});
If you want to add content dynamically and still need it to work, and also with more than one form, you can do this:
$('form').live('submit', function(){
$.post($(this).attr('action'), $(this).serialize(), function(response){
// do something here on success
},'json');
return false;
});
The HTTP/CGI way to do this would be for your program to return an HTTP status code of 204 (No Content).
When you hit on the submit button, the page is sent to the server.
If you want to send it async, you can do it with ajax.
Use XMLHttpRequest
var xhr = new XMLHttpRequest();
xhr.open("POST", '/server', true);
//Send the proper header information along with the request
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xhr.onreadystatechange = function() { // Call a function when the state changes.
if (this.readyState === XMLHttpRequest.DONE && this.status === 200) {
// Request finished. Do processing here.
}
}
xhr.send("foo=bar&lorem=ipsum");
// xhr.send(new Int8Array());
// xhr.send(document);
Related
I'm trying to send some data to a web service on page load and then allow the page to continue to work as usual. The idea is to grab some data from the client just when the page loads without user interaction and then let the user continue with the page normally.
I'm using XMLHttpRequest, when I wanted to do the POST to the web service without refreshing the page, I don't know if that's the best method. Here is my current test html:
<html>
<body>
<form name="myform2" method="post" action="./login.asp">
First Name: <input type="text" name="fname" /><br><br>
Last Name : <input type="text" name="lname" />
<input type="submit" value="Submit" />
</form>
<form action="" id="myform">
<input type="submit" value="send-info"/>
</form>
<script src="https://code.jquery.com/jquery-2.2.1.min.js"></script>
<script type="text/JavaScript">
$(document).ready(function() {
$(document).on('submit', '#myform', function() {
var http = new XMLHttpRequest();
var params = ("myvar=somedata");
http.open("POST", "http://127.0.0.1:3000", true);
http.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
http.send(params);
return false;
});
});
</script>
</body>
</html>
Right now the data is sent when I click the send-info button but I need to send it without user interaction, without refreshing the page and allowing whatever additional logic is needed after that. I have tried with window.onload without success.
Please excuse my poor programming skills, I'm not that versed on Javascript.
You should just be able to remove the "on submit" so your code runs when the "document ready" event is called. Also if you are using jquery you can use its ajax function to simplify the http call:
$(document).ready(function() {
$.ajax({
type: "POST",
url: "http://127.0.0.1:3000",
data: { "myvar" : "somedata" }
});
});
Right now you are sending data on submit form. So you need to use ajax call right after your $(document).ready(function() Here is a sample
$(document).ready(function()({
myvar = somedata;
$.ajax({
url: "test.html",
type: "Post",
data: {myvar : myvar},
success: function(response){
//do anything here
}
});
});
I am trying to submit a form via ajax using the post method and a FormData object.
Here is a simplified version of the JavaScript:
var form=…; // form element
var url=…; // action
form['update'].onclick=function(event) { // button name="update"
var xhr=new XMLHttpRequest();
xhr.open('post',url,true);
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
var formData=new FormData(form);
formData.append('update', true); // makes no difference
xhr.send(formData);
xhr.onload=function() {
alert(this.response);
};
};
The form has:
a button (type="button" name="update") to run the script
no action and method="get"
My PHP script has the following:
if(isset($_POST['update'])) {
print_r($_POST);
exit;
}
// more stuff
print 'other stuff';
When I try it, the PHP falls through to the rest of the code, and I get the other output, rather than what I expect from the print_r statement.
I have tried the following variations:
new FormData() (without the form). This does work if I add the update data manually.
new FormData(form). This does not work, whether I add the update manually or not.
changing the form method to post.
Firefox, Safari & Chrome on MacOS; all current versions.
The from itself looks something like this:
<form id="edit" method="post" action="">
<p><label for="edit-summary">Summary</label><input id="edit-summary" name="summary" type="text"></p>
<p><label for="edit-description">Description</label><input id="edit-description" name="description" type="text"></p>
<p><label for="edit-ref">Reference</label><input id="edit-ref" name="ref" type="text"></p>
<p><label for="edit-location">Location</label><input id="edit-location" name="location" type="text"></p>
<p><button type="button" name="update">OK</button></p>
</form>
What should I do to submit the get this to work?
No jQuery, please.
The content type when sending a FormData object is multipart/form-data not url encoded.
Further more the proper boundary must be set for the request, which the user is unable to do. For this XMLHttpRequest sets the correct content type with the required boundary.
So all you have to do is not set the content type and it'll work.
var xhr=new XMLHttpRequest();
xhr.open('post',url,true);
//xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded");<--don't do this
var formData=new FormData(form);
formData.append('update', true); // makes no difference
xhr.send(formData);
xhr.onload=function() {
alert(this.response);
};
Change the name of the button to something other than "update" (and change it in your form['update'].onclick... as well). I think its clashing with the value you are trying to set on the FormData to trigger the PHP code.
I have a website that manages where people are and what they are doing at work and if they need help or not.
I am using phone gap in order to make my application and I was wondering if it is possible to take a button on the phone gap and have javascript fill out a form on my webpage and then submit it so I can then process that data?
The form that I am trying to connect to is. I process this form in python through flask:
<form action="" method="POST" id = "stuff">
<dl>
<dt>
<input type=text name=gc>
<input type=text name=cursquad>
<input type=text name=trap>
<input type=text name=scrtkey>
<input type="submit">
</form>
You could use an AJAX post request with jquery, but then you'll need jquery in your phonegap, which might be quite overkill only for this.
Therefor I'd recommend this approach:
<script>
function loadXMLDoc() {
var url = "http://example.com";
var parameters = "foo=bar&bar=baz"; // Construct you form values like field=value&field2=value2&...
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
var response = xmlhttp.responseText;
}
}
xmlhttp.open("POST", url, true);
xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xmlhttp.setRequestHeader("Content-length", parameters.length);
xmlhttp.setRequestHeader("Connection", "close");
xmlhttp.send(parameters);
}
</script>
This will POST all the data you put into parameters to the url you give. If you point it to your form page it should work.
If it doesn't, (jquery approach doesn't work out of the box), you might have to add some headers to the receiving page to allow it to receive data from external pages. The Access-Control-Allow-Origin header is needed here, where you can provide a list of safe domains. Since your application is not on a domain though, you could add this to your receiving page (Assuming you are running php):
header('Access-Control-Allow-Origin: *');
Try running it without first though, as it opens your form for everyone.
I want to have a callback after my form has successfully been submitted. This form does not reload the page and the ajax alternative is not available to us because of "cross origin" issues.
What I have now is:
$('#uploadform form').on('submit', function(){
// DO STUFF HERE
});
But this is firing as soon as submit event is triggered and not as a callback. Without using ajax, how do I make code run after and only after the response is received (and get the response to do stuff with)? Is this even possible?
It is through AWS's S3 file hosting and cannot use JSONP.
I would rather not use an iframe if I don't have to for simplicity's sake.
EDIT
It doesn't reload the page just like a file download link doesn't reload the page. Otherwise it's exactly like any other form. It's not submitted inside of an iframe. It's a normal form, but the headers involved don't require the page to reload.
A solution has come to me that will allow me to submit my form without reloading the page, not use an iframe or JSONP, and while it probably technically counts as AJAX, it does not have this same "cross origin" issue.
function uploadFile() {
var file = document.getElementById('file').files[0];
var fd = new FormData();
fd.append('key', "${filename}");
fd.append("file",file);
xhr = new XMLHttpRequest();
xhr.upload.addEventListener("progress", uploadProgress, false);
xhr.addEventListener("load", uploadComplete, false);
xhr.addEventListener("error", uploadFailed, false);
xhr.addEventListener("abort", uploadCanceled, false);
xhr.open('POST', 'http://fake-bucket-name.s3-us-west-1.amazonaws.com/', true); //MUST BE LAST LINE BEFORE YOU SEND
xhr.send(fd);
}
function uploadProgress(evt) {
if (evt.lengthComputable) {
var percentComplete = Math.round(evt.loaded * 100 / evt.total);
document.getElementById('progressNumber').innerHTML = percentComplete.toString() + '%';
}
else {
document.getElementById('progressNumber').innerHTML = 'unable to compute';
}
}
function uploadComplete(evt) {
/* This event is raised when the server send back a response */
alert("Done - " + evt.target.responseText );
}
function uploadFailed(evt) {
alert("There was an error attempting to upload the file." + evt);
}
function uploadCanceled(evt) {
alert("The upload has been canceled by the user or the browser dropped the connection.");
}
With a simple form like this:
<form id="form1" enctype="multipart/form-data" method="post">
<div class="row">
<label for="file">Select a File to Upload</label><br>
<input type="file" name="file" id="file">
</div>
<div id="fileName"></div>
<div id="fileSize"></div>
<div id="fileType"></div>
<div class="row">
<input type="button" onclick="uploadFile()" value="Upload">
</div>
<div id="progressNumber"></div>
</form>
The uploadComplete(evt) function being the callback. As you can see, it also gives you the percentage complete you can show your users.
Note: To do this you have to set the correct upload policy and CORS
policy in your S3 account.
– RonSper
You will run into 'cross origin' issues with ajax and iframes equally if you need access to the response.
JSONP is the only way around your 'cross-origin' issues. It is what is used by all JSON APIs that are hosted on a different domain, unless you try to use CORS which isn't supported in legacy IE versions.
If you can control the server where the form is submitted you should be able to make it return a JSONP compatible response. If not, you are kind of out of luck.
I have a form that when submitted, goes to blah.php. The problem is, blah.php goes off site to another domain. JQuery sees that and gives a 302 Object Moved error. So I had to use JSON and AJAX to send the form. Comment details are within the Jquery code below.
The flow should be click button, check server side, if not 'ok' response, output response in status div and stop everything server side on that page. If 'ok' was the response let form continue on its way
Quick mock up of my code
<form id="ppform" method="post" action"blah.php">
<input id="someid" type="text" />
<button id="sendbutton">Send</button>
<div id="status"></div>
</form>
$(document).ready(function(){
$(document).on('click', '#sendbutton', function(){
$('#status').empty();
$.ajax({
type: "POST",
url: "blah.php",
data: reqBody,
dataType: "json",
success:function(data,textStatus){
// here I want the div to return data if the response isn't 'ok'
if(data!='ok'){
$('#status').append(data);
}else{
// response was 'ok' so empty div,
// show loading gif and submit the form
$('#status').empty().html('<div id="proc">Processing</div><img src="loading.gif" />');
if (data.redirect){
window.location.href = data.redirect;
} else {
$("#ppform").replaceWith(data.form);
}
}
}
});
});
});
I think, it is a browser security issue, that you can't send ajax request on different domain.
If you're using jQuery to do the ajax requests you could change the datatype to JSONP
to do cross domain json calls.
more information here:
jQuery AJAX cross domain