First of all you need to create three variables that hold references to the <form>
, <input>
, and <button>
elements in your HTML markup.
var form = document.getElementById('file-form');
var fileSelect = document.getElementById('file-select');
var uploadButton = document.getElementById('upload-button');
Next you need to attach an event listener to the form’s onsubmit event.
form.onsubmit = function(event) {
event.preventDefault();
// Update button text.
uploadButton.innerHTML = 'Uploading...';
// The rest of the code will go here...
}
Inside the event listener you start by calling preventDefault() on the event object passed into the handler. This will prevent the browser from submitting the form, allowing us to handle the file upload using AJAX instead.
Next you update the innerHTML property on the uploadButton to Uploading.... This just provides a bit of feedback to the user so they know the files are uploading.
Your next job is to retrieve the FileList from the <input>
element and store this in a variable. You can do this by accessing the files property.
// Get the selected files from the input.
var files = fileSelect.files;
You then create a new FormData object. This is used to construct the key/value pairs which form the data payload for the AJAX request.
// Create a new FormData object.
var formData = new FormData();
Your next job is to loop through each of the files in the files array and add them to the formData object you just created. You’ll also want to check that the user has selected the type of file you’re expecting.
// Loop through each of the selected files.
for (var i = 0; i < files.length; i++) {
var file = files[i];
// Check the file type.
if (!file.type.match('image.*')) {
continue;
}
// Add the file to the request.
formData.append('photos[]', file, file.name);
}
Here you’re first fetching the current file from the files array and then checking to make sure it’s an image. The file’s type property will return the file type as a string. You can therefore use the JavaScript match() method to ensure that this string matches the desired type. If the file type does not match, you skip the file by calling continue.
You then use the append method on the formData object to add this file to the data payload.
The FormData.append()
method is used to handle Files, Blobs, or Strings.
// Files
formData.append(name, file, filename);
// Blobs
formData.append(name, blob, filename);
// Strings
formData.append(name, value);
Next you need to set up the XMLHttpRequest
that is responsible for communicating with the server. To do this you first need to create a new XMLHttpRequest
object.
// Set up the request.
var xhr = new XMLHttpRequest();
You now need to create a new connection to the server. You do this using the open method. This method takes three parameters. The HTTP method, the url that will handle the request, and a boolean value that determines whether the request should be dealt with asynchronously.
// Open the connection.
xhr.open('POST', 'handler.php', true);
Next you need to set up an event listener that will be triggered when the onload event is fired. Examining the status property of the xhr object will tell you if the request completed successfully.
// Set up a handler for when the request finishes.
xhr.onload = function () {
if (xhr.status === 200) {
// File(s) uploaded.
uploadButton.innerHTML = 'Upload';
} else {
alert('An error occurred!');
}
};
All that’s left to do now is send the request. Pass the formData object to the send method which is available on the xhr object.
// Send the Data.
xhr.send(formData);