How to Integrate Ajax File Upload in WordPress

Do you want to integrate Ajax file upload in WordPress? Sometimes, you need to perform a task which uploads 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 most obvious reason for using this technique is uploading files through Ajax reduces loads on the server. This process does not require reloading the whole page which 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 a HTML

For getting started, you need a form with the file input. We will give an Ajax call once the user chooses a file on the client-side. This file’s content will be sent to the server. 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 given content in the uploads folder, I’ll use the wp_upload_bits method.

Add the below HTML to your page template or anywhere you want.

<form class="fileUpload" enctype="multipart/form-data">
    <div class="form-group">
        <label>Choose File:</label>
        <input type="file" id="file" accept="image/*" />
    </div>
</form>

I have given the “file” id to execute change events on the file input. The attribute accept=”image/*” will show only images in the file explorer.

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 file will have the JavaScript code to handle

  • Change event on file input
  • Collect the files content
  • Call the Ajax and post files data to the server

The below code will go inside the functions.php file. After adding this, you will see custom.js automatically included 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 elements passed to the custom.js file.

  • ajaxurl : In WordPress, all Ajax requests execute through admin-ajax.php URL. We will call this URL in JavaScript.
  • security : With this variable 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 with files content and give an Ajax call. 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’s content, action, and security arguments to the file object. We proceed with this file content at the server-side to create a 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 WordPress 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 in the functions.php file. To the ‘wp_ajax_’ and ‘wp_ajax_nopriv_’, I appended the action’s value which is ‘file_upload’. The second parameter ‘file_upload_callback’ is the callback method that will have actual code for server-side file uploading. The ‘wp_ajax_{action}’ fires Ajax action.

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.

Go ahead and give it a try. 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.

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 achieve it.

First, add a ‘multiple’ attribute to the file input. This allows a user to select multiple files on file explorer.

<form class="fileUpload" enctype="multipart/form-data">
    <div class="form-group">
        <label>Choose File:</label>
        <input type="file" id="file" accept="image/*" multiple />
    </div>
</form>

On the JavaScript end, we have to pick up 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.

If you liked this article, then please subscribe to our YouTube Channel for video tutorials.

17 thoughts on “How to Integrate Ajax File Upload in WordPress

  1. It worked just fine! But the issue is images are uploading to the current folder but not showing in the media library.

  2. AJAX calls in WP are not working with contentType: false or processData: false. I never managed to get it working like this.

  3. how to upload multiple file

    i’m use

    		  	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];	
    
    		  	}
    

    but not working

  4. 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

    1. 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

Leave a Reply

Your email address will not be published.