When submitting form data via jQuery and using admin-ajax, including a file attachment was easy:
var data = new FormData($(this)[0]);
How do you include a file attachment when submitting form data to a Rest Controller?
This submits all the form fields, except the file attachment.
var data = $this.serializeArray();
The jQuery:
$('#create-book-form').submit(function (e) {
var $this = $(this);
e.preventDefault();
//var data = new FormData($(this)[0]);
var data = $this.serializeArray();
data.push({name: "rtype", value: "create"});
$.ajax({
url: BOOK_SUBMITTER.root + 'rfp-books/v1/books',
data: $.param(data),
beforeSend: function ( xhr ) {
xhr.setRequestHeader( 'X-WP-Nonce', BOOK_SUBMITTER.nonce );
},
//etc
It all works, except the file is not part of the form data that arrives at the rest controller.
Yes, I have an input called ‘file’ so the user can include a jpg.
I need to send all the form data in a single call.
The post attachment is created right after the post is created in the controller.
So, how do I get the file into the data included in $.param(data)
In the route callback in the REST Controller:
$params = $request->get_params(); write_log( $params );
The log shows all the form data – except the file.
( If I submit the jQuery data as FormData, none of the data is recognized in the controller. )
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
You can really use FormData just like you could use it with the old admin-ajax.php route, but:
-
Set
processDataandcontentTypetofalse. -
Set the
methodtoPOSTand make sure your REST API route supports thePOSTmethod.$('#create-book-form').submit(function (e) { // var $this = $(this); // what's this? e.preventDefault(); var data = new FormData( this ); data.append( 'rtype', 'create' ); // add extra param $.ajax({ url: BOOK_SUBMITTER.root + 'rfp-books/v1/books', data: data, //$.param(data), processData: false, contentType: false, method: 'POST', beforeSend: function ( xhr ) { xhr.setRequestHeader( 'X-WP-Nonce', BOOK_SUBMITTER.nonce ); }, success: function ( data ) { console.log( data ); // I added just for testing purposes. }, }); });
Then in your REST API endpoint callback, just use the $_FILES to get the uploaded file, e.g. $_FILES['file']. For other parameters, you can use $request->get_param(), e.g. $request->get_param( 'rtype' ).
Additionally or to other readers, you should have a file upload input in your form, e.g. <input type="file" name="file" />, but the name can be anything unless if you’re creating an attachment using the default wp/v2/media route.
Method 2
i have used this code which uploads file in an ajax request
<style>
.wbc_form {
width: 500px;
max-width: 100%;
margin: 0 auto;
text-align: center;
}
.image_preview {
width: 500px;
max-width: 100%;
height: 250px;
border: 3px dashed #eee;
display: flex;
align-items: center;
justify-content: center;
}
.image_preview img {
width: 100%;
height: auto;
max-height: 100%;
display: none;
}
</style>
<form class="wbc_form" action="<?php echo esc_url( admin_url( 'admin-ajax.php' ) ) ?>" method="POST"
enctype="multipart/form-data">
<h1>
<?php esc_html_e( 'Upload payment confirmation image', 'wbc' ); ?>
</h1>
<input type="hidden" name="action" value="wbc_bacs_confirm">
<?php wp_nonce_field() ?>
<input type="hidden" name="order_id" id="wbc_order_id" value="<?php echo esc_attr( $order_id ); ?>">
<input type="file" class="wbc_image" name="wbc_image" value="" accept="image/*">
<div class="image_preview">
<img src="" class="img_preview__image" alt="Preview">
<span class="img_preview__default_text"><?php esc_html_e( 'Image Preview', 'wbc' ); ?></span>
</div>
<br>
<button class="go_now button alt" type="submit"><?php esc_html_e( 'Send', 'wbc' ); ?></button>
</form>
<script>
(function ($) {
let input_file = $('.wbc_image'),
preview_image = $('.img_preview__image'),
preview_text = $('.img_preview__default_text');
input_file.on('change', function (e) {
let f = this.files[0];
//here I CHECK if the FILE SIZE is bigger than 2 MB (numbers below are in bytes)
if (f.size > 2097152 || f.fileSize > 2097152) {
//show an alert to the user
alert(wbc_object.max_file_size_msg);
//reset file upload control
this.value = null;
}
let file = e.target.files[0];
if (file) {
let reader = new FileReader();
preview_text.hide();
preview_image.show();
reader.onload = function (event) {
preview_image.attr("src", event.target.result)
};
reader.readAsDataURL(file);
} else {
preview_image.attr('src', '');
preview_image.hide();
preview_text.show();
}
});
$('.wbc_form').on('submit', function (e) {
e.preventDefault();
var formData = new FormData(this);
$.ajax({
url: wbc_object.ajax_url,
type: "POST",
data: formData,
contentType: false,
processData: false,
success: function (response) {
// console.log(response);
if (response.success) {
$('.wbc_form').html(wbc_object.request_received_msg);
} else {
//show the toastr js message
// toastr.error(response.data.msg);
}
}
});
});
})(jQuery);
</script>
then you will receive the file in the request parameters
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0