Typically when you have a HTML form, the objective is to send data to a seperate page to handle the form contents. By default, you’ll get redirected to the destination page which isn’t always helpful. Analytics tracking or file uploads may wish to occur in the background without redirecting the user. We can have this behaviour with some help from JavaScript!
Setting up a form:
When you set up a form, you’ll probably have something which looks a bit like this:
<form action="/action_page.php">
<label for="fname">First name:</label><br>
<input type="text" id="fname" name="fname" value="John"><br>
<label for="lname">Last name:</label><br>
<input type="text" id="lname" name="lname" value="Doe"><br><br>
<input type="submit" value="Submit">
</form>
(This was taken from w3schools here)
By default, the user will get taken to the page action_page.php as this is the form action for when the user clicks the submit button. Make note of this, it’s important for later.
We’ll get around this behaviour later by tweaking our form but for now, let’s set up some JavaScript.
The JavaScript
Want just the full code? Skip to: ### Adding the form data to our request
Want to know how it works? Keep reading …
By this point you need to know where you wish to send your formdata, like another page on your which will handle this at /formresponder. Look at the bottom of this post for Security considerations if you plan to send form data to a completely different website.
The first thing we need to do is create our JavaScript file. I like to write individual JavaScript files which contain functions and then load them into my HTML. You can just put everything within <script> HTML tags but it leads to base HTML getting messy and increases the chance you’ll make mistakes.
We need to create an empty JavaScript file and open it. I will call mine form_submit.js
Function creation
The end goal here is that we’ll modify our HTML form to run a function on click, overriding the default form action going to action_page.php
To create our function, we simply need something like this in our new JavaScript file:
function sumbit_my_form() {
// your future code will go here...
}
Setting up our transport
This makes the assumption that you’ll use a HTTP POST method to send data to your receiver. Therefore, we need to setup a new HTTP request handler and tell it we’re going to use POST as the HTTP method.
Make note at this point to use the second argument in request.open as the destination for you’re going to send your form!
function sumbit_my_form() {
// your future code will go here...
var request = new XMLHttpRequest();
request.open("POST", "<INSERT YOUR POST ADDRESS HERE>");
}
Next, we’re going to tell our JavaScript how to handle the request’s response before we even send the HTML Request. We can do that like this:
function sumbit_my_form() {
// your future code will go here...
var request = new XMLHttpRequest();
request.open("POST", "<INSERT YOUR POST ADDRESS HERE>");
request.onreadystatechange = function () {
// when somethhing happens with the request, this code will get evaluated
}
}
}
Now when the state of our request changes, we can start evaluating it with the below:
function sumbit_my_form() {
// your future code will go here...
var request = new XMLHttpRequest();
request.open("POST", "<INSERT YOUR POST ADDRESS HERE>");
request.onreadystatechange = function () {
// when somethhing happens with the request, this code will get evaluated
if (request.readyState === 4 && request.status === 200) {
// we got a response back.
console.log("form sent!")
}
}
}
The above code now adds the following steps when our request changes states
- Determines the request ready state. In this case we’re checking if it’s
4. According the Mozilla docks, this meansThe operation is completeLink - Then we check if the request HTTP code is 200 (‘OK’)
Adding the form data to our request
At this point we’ve setup the request handler but we haven’t actually sent any data. We’re going to make some assumption we know the HTML id for our form (we can add that later)
We’re going to create a new form object in JavaScript and then assign it the data from our form. We’re going to do this before we setup our HTML request:
formupload = document.getElementById('uploadform');
var formData = new FormData(formupload);
Now we’ve got everything we need, so we can build this all together and specify our form data to be in the post request we’ve already set up. This is easy to do with request.send(formData);. This means our resulting JavaScript function should look like this:
function sumbit_my_form() {
formupload = document.getElementById('myform');
var formData = new FormData(formupload);
// your future code will go here...
var request = new XMLHttpRequest();
request.open("POST", "<INSERT YOUR POST ADDRESS HERE>");
request.onreadystatechange = function () {
// when somethhing happens with the request, this code will get evaluated
if (request.readyState === 4 && request.status === 200) {
// we got a response back.
console.log("form sent!")
}
}
//send the data
request.send(formData);
}
Fixing our HTML
You may have noticed that the way JavaScript reads data from our form is by looking for an element on the page named myform. We need to fix our HTML to reflect this.
As mentioned earlier, we also need to change how our form behaves. We’re going to do this by changing the submit button and instead replace it with a hyperlink that will run our function.
We also need to import our JavaScript function into the HTML.
All the above can be achieved by adding some extra lines:
<script src="form_submit.js"></script>
<form id="myform" action="/action_page.php">
<label for="fname">First name:</label><br>
<input type="text" id="fname" name="fname" value="John"><br>
<label for="lname">Last name:</label><br>
<input type="text" id="lname" name="lname" value="Doe"><br><br>
<!--<input type="submit" value="Submit">*/-->
<a id=uploadbttn style="margin-left:10px;margin-top:0px" onclick="sumbit_my_form()">Upload</a>
</form>
I’ve left the input button in the HTML by commenting it out but you could remove it with no harm.
Voila!
With the above you can now send a form the background without redirecting the user. You can test for a successful form post by opening dev tools and looking for messages printed to the console. If sent successfully you should see form sent! printed.
Security Consideration
If your destination page to handle your form isn’t on the same website, ie specifies a full URL away from your website such as ‘https://myformresponder.com" you must make sure you have set correct origin policies on ‘https://myformresponder.com". By default, modern browsers will not read a response from ‘https://myformresponder.com" if it doesn’t have a valid Access-Control-Allow-Origin' header on the destination site
Improving on this:
At the moment our function isn’t very portable. If you wanted to, you could add parameters to our JavaScript function which take the form id from there. This would result in something like "sumbit_my_form(id="myformid")" when the function is called.
The if statement to check if the form posting was successful is achieved by exclusively looking for a status code of 200. Anything else won’t print a message. The if statement located in the onreadystatechange function could be adapted for other status codes (typically > 200 but < 300 indicates some kind of success). You could also print a message indicating failure if you don’t get the desired scenario.
EOF