TransWikia.com

How to include file attachment in ajax submission via the rest_api?

WordPress Development Asked by shanebp on October 30, 2021

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

2 Answers

You can really use FormData just like you could use it with the old admin-ajax.php route, but:

  1. Set processData and contentType to false.

  2. Set the method to POST and make sure your REST API route supports the POST method.

    $('#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.

Answered by Sally CJ on October 30, 2021

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

Answered by Ahmad Wael on October 30, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP