Single file upload using WordPress Ajax
I recently had to amend an existing form on a website that needed a file input adding to it. The form was already submitting via a wordpress ajax and I found documentation on how to go about it a little sparse and contradictory.
Here is a simplified setup to get you uploading and saving files to the media library using a frontend ajax form…
First we need a form with a file input:
<form action="" enctype="multipart/form-data" id="my_form">
<!-- add a file input -->
<input type="file" name="my_file" />
<!-- set the ajax action to be completed later in PHP -->
<input type="hidden" name="action" value="file_upload_ajax_handler" />
</form>
We now need to set the ajax url for use in a jquery/ajax function. This goes in your functions.php:
<?php
add_action('wp_head', 'add_ajaxurl');
function add_ajaxurl() {
echo '<script type="text/javascript">var ajaxurl = "'.admin_url('admin-ajax.php') . '";</script>';
}
Next we need a jQuery function to handle the submission of the form:
$('#my_form').on('submit', function(e){
e.preventDefault(); // stop the form submitting
var form_data = new FormData(this);
$.ajax({
url: ajaxurl,
type: 'POST',
contentType: false,
cache: false,
processData:false,
data: form_data,
success: function (ajax_response) {
// file was uploaded success fully do something here...
var response = JSON.parse(ajax_response);
console.log(response);
},
error: function (errorThrown) {
console.log(errorThrown);
}
});
});
The jQuery above will send the form data to the WordPress ajax handler and in your functions.php file you need to have a function of the same name we specified in hidden field of the form (file_upload_ajax_handler):
function file_upload_ajax_handler() {
// set up a response array
$response = [];
// you could handle and process other form fields here first like inserting a new post using $_RESPONSE parameters eg. $_RESPONSE['first_name']
// for WordPress to handle the upload and it be accessible in the media library you need to include these files
require_once( ABSPATH . 'wp-admin/includes/image.php' );
require_once( ABSPATH . 'wp-admin/includes/file.php' );
require_once( ABSPATH . 'wp-admin/includes/media.php' );
// handle the upload using the name attribute of the file input 'my_file'.
// the second value 0 can also be a post id to associate the attachment to but by using 0 you are declaring it has no post.
$attachment_id = media_handle_upload('my_file', 0);
// check if we had any errors
if ( is_wp_error( $attachment_id ) ) {
$response['uploaded'] = false;
$response['attachment_id'] = null;
$response['message'] = 'There was an problem uploading your file';
} else {
$response['uploaded'] = true;
$response['attachment_id'] = $attachment_id;
$response['message'] = 'File Uploaded successfully';
}
// return the $response array so you can handle any frontend sucess or failure messages...
return json_encode($response);
// always die or exit an ajax function
wp_die();
}
add_action('wp_ajax_file_upload_ajax_handler', 'file_upload_ajax_handler');
add_action('wp_ajax_nopriv_file_upload_ajax_handler', 'file_upload_ajax_handler');
Just to reiterate, this is a simplified way of getting a file upload working with WordPress ajax but if you know a better or different way to do it then please do leave a comment…