Do you want to integrate Ajax file upload in WordPress? Sometimes, you need to perform the task of uploading a file through Ajax. In this article, we study how to upload files with jQuery and Ajax in WordPress. I’ll cover uploading both single and multiple files.
The main reason for uploading files through Ajax is it reduces loads on the server. This process does not require reloading the whole page which as a result saves extra calls to a server. Eventually, it saves the server bandwidth. This approach also gives a better user experience on your WordPress website.
Create HTML
For getting started, you need a form with the file input. Once the user browses a file on the client side, we will send the content of a file to the server side. On the server side, we collect the content of a file and store its copy under the wp-content/uploads
directory. To create a file with the given content, I’ll use the wp_upload_bits method.
Having said that, let’s add the below HTML to your page template or anywhere you want.
<form enctype="multipart/form-data">
<label>Choose File:</label>
<input type="file" id="file" accept="image/*" />
</form>
I have given the id file
on the file input to execute change events. The attribute accept=”image/*” will show only images in the file explorer. If you are looking for files other than images then remove this attribute.
Include JS File in WordPress Environment
To send the file on the server side, it is required to write JavaScript code. For this, I am going to create a custom.js
into the theme directory and include it in the WordPress environment. This JavaScript file will handle:
- Change event on file input
- Collect the content of the file
- Call the Ajax and post files data to the server
Write the below code inside the functions.php
file which will include custom.js
automatically on the front end.
function blog_scripts() {
// Register the script
wp_register_script( 'custom-script', get_stylesheet_directory_uri(). '/js/custom.js', array('jquery'), false, true );
// Localize the script with new data
$script_data_array = array(
'ajaxurl' => admin_url( 'admin-ajax.php' ),
'security' => wp_create_nonce( 'file_upload' ),
);
wp_localize_script( 'custom-script', 'blog', $script_data_array );
// Enqueued script with localized data.
wp_enqueue_script( 'custom-script' );
}
add_action('wp_enqueue_scripts', 'blog_scripts');
Look at the above code and you will notice 2 parameters passed to the custom.js
file.
ajaxurl
: In WordPress, all Ajax requests execute through the admin-ajax.php URL. Using our parameter, we are passing this URL to the JavaScript file.security
: With this parameter, I am passing a WordPress nonce to avoid CSRF attacks.
Write a JavaScript to Upload a File
We are ready with the HTML form and JS file. Now, we have to catch the change event, build the file object, and give an Ajax call. To achieve this, add the following code to the custom.js
file.
jQuery(function($) {
$('body').on('change', '#file', function() {
$this = $(this);
file_data = $(this).prop('files')[0];
form_data = new FormData();
form_data.append('file', file_data);
form_data.append('action', 'file_upload');
form_data.append('security', blog.security);
$.ajax({
url: blog.ajaxurl,
type: 'POST',
contentType: false,
processData: false,
data: form_data,
success: function (response) {
$this.val('');
alert('File uploaded successfully.');
}
});
});
});
Here, I am appending the file, action, and security arguments to the file object. We proceed with this file content on the server side to create a new file out of it. The values of action
and security
will be handled in the next step.
Upload File on Server
The value of the action
argument is used to call the server-side PHP function. We need to pass this value to the wp_ajax
actions as follows.
add_action('wp_ajax_file_upload', 'file_upload_callback');
add_action('wp_ajax_nopriv_file_upload', 'file_upload_callback');
You should add the above code to the functions.php
file. To the wp_ajax
and wp_ajax_nopriv
, I appended the action’s value which is file_upload
. The wp_ajax_{action}
fires Ajax action. The second parameter file_upload_callback
is the callback method which will have actual code for server-side file uploading.
Note: You don’t need to write the wp_ajax_nopriv
action if you are adding this functionality on the backend. This action is required only for front-end users.
function file_upload_callback() {
check_ajax_referer('file_upload', 'security');
$arr_img_ext = array('image/png', 'image/jpeg', 'image/jpg', 'image/gif');
if (in_array($_FILES['file']['type'], $arr_img_ext)) {
$upload = wp_upload_bits($_FILES["file"]["name"], null, file_get_contents($_FILES["file"]["tmp_name"]));
//$upload['url'] will gives you uploaded file path
}
wp_die();
}
The very first statement checks for security nonce and executes a code only if the nonce is valid. When you run this code, your file should be uploaded to the wp-content/uploads/
folder. You will find your file in the current month folder of the uploads directory.
Note: If you want to move your files to a custom directory then refer to our article – uploading files programmatically in WordPress.
Upload Multiple Files
Similar to a single file you would like to upload multiple files through Ajax. With a few changes in the previous code, you can easily achieve it.
First, add multiple
attribute to the file input. This allows the user to browse multiple files at a time.
<form enctype="multipart/form-data">
<label>Choose File:</label>
<input type="file" id="file" accept="image/*" multiple />
</form>
On the JavaScript end, we will access these multiple files, loop through them, and build a final file object.
custom.js
jQuery(function($) {
$('body').on('change', '#file', function() {
$this = $(this);
file_obj = $this.prop('files');
form_data = new FormData();
for(i=0; i<file_obj.length; i++) {
form_data.append('file[]', file_obj[i]);
}
form_data.append('action', 'file_upload');
form_data.append('security', blog.security);
$.ajax({
url: blog.ajaxurl,
type: 'POST',
contentType: false,
processData: false,
data: form_data,
success: function (response) {
$this.val('');
alert('File(s) uploaded successfully.');
}
});
});
});
Finally, in the Ajax callback function, loop through the file array and upload each file on a server.
function file_upload_callback() {
check_ajax_referer('file_upload', 'security');
$arr_img_ext = array('image/png', 'image/jpeg', 'image/jpg', 'image/gif');
for($i = 0; $i < count($_FILES['file']['name']); $i++) {
if (in_array($_FILES['file']['type'][$i], $arr_img_ext)) {
$upload = wp_upload_bits($_FILES['file']['name'][$i], null, file_get_contents($_FILES['file']['tmp_name'][$i]));
//$upload['url'] will gives you uploaded file path
}
}
wp_die();
}
I hope you understand the Ajax file upload in WordPress. This tutorial mainly focuses on uploading images. However, by removing references to images, you can upload any other file formats through this code.
Related Articles
- How to Load WordPress Posts With Ajax
- How to Use jQuery Ajax in WordPress
- Load Dynamic Content on Bootstrap Modal in WordPress
If you liked this article, then please subscribe to our YouTube Channel for video tutorials.
How can upload another type of files, for example, .csv?
Refer to our article https://artisansweb.net/upload-files-programmatically-wordpress
See the section Upload file in the Custom Directory.
Scripts works well!!
Do you know how to handle duplicate file upload? How to create a unique name before it uploaded?
I was thinking to use wp_unique_filename but cannot get the file path before the file is uploaded.
Append a unique string next to the file name. Something like uniqid().’_’.$_FILES[‘file’][‘name’]
That worked so well !! thanks for the help
You’re welcome, Vivek.
It worked just fine! But the issue is images are uploading to the current folder but not showing in the media library.
You’re right. The purpose of this tutorial is to show how to upload images in a custom directory. If you want images in the media library then you need to tweak a code. Refer my tutorial where I set images in media library
https://artisansweb.net/set-featured-image-programmatically-wordpress/
Hello,
Thanks for the tutorial. It works fine. Is there a way to get the uploaded file name with path?
$upload['url']
gives a file path.worked perfectly! Now to add a progress bar?
AJAX calls in WP are not working with contentType: false or processData: false. I never managed to get it working like this.
Function name error!
function file_upload()_callBack <<–Errada
function file_upload() <<– Correta
how to upload multiple file
i’m use
[code]
var number = document.getElementById(‘file’);
for (var i = 0; i < number; i++) {
//var ‘file_data_’+i = $(this).prop(‘files’)[i];
//window[‘file_data_’ + i ] = $(this).prop(‘files’)[i];
var file_data = $(‘#file’).prop(‘files’)[0];
}
[/code]
but not working
You can take reference from our article https://artisansweb.net/drag-and-drop-multiple-file-upload-using-javascript-and-php Basically we create an array of all files and then send to Ajax.
I updated the article. It now includes a code for uploading multiple files using Ajax in WordPress.
Any advice on how to integrate a upload progress indicator?
Finally, someone that understands the special nuances of WP and AJAX! I was so close before this article, but couldn’t figure out how to pass my ‘action’… Didn’t think to put it inside the FormData… This line was the winner: form_data.append(‘action’, ‘file_upload’); THANK YOU
Thanks. I am glad it solved your problem.
Another way to do this is via HTML: input name=”action” type=”hidden” value=”action_name”
which will include the action in the form data
Simple short and awesome script!