I am trying to make file upload field in Advance custom field plugin and I find many reference code on ACF 'https://www.advancedcustomfields.com/resources/file/', stack overflow, stack exchange WordPress development and I also refer WP begginner, kinsta.com but they gave solution for plugin like how to use WP Form plugin. I want it to make it without plugin through custom field. If anyone knows plz give your valuable suggestion.

  • Doesn't the ACF built-in File field type (that you posted the link to) do exactly what you want?
    – Rup
    Commented Oct 28, 2020 at 8:43
  • If not, you'll need to make a field type with the upload input control and then probably wp_handle_upload() on submission, then do whatever you want to with the file data.
    – Rup
    Commented Oct 28, 2020 at 8:46
  • Do you mean to add it through a frontend form that you have custom built? Commented Oct 28, 2020 at 9:25
  • Yes, like I create input field for file in custom field and want to upload file
    – vishal
    Commented Oct 28, 2020 at 9:45
  • Yea this quite a process though. Because you will need to upload the file manually through the form submission or through Ajax. The file needs to be stored in wp-content/uploads and then you can save the URL in the custom field if you like. I have a full example that matches your description. Commented Nov 16, 2020 at 13:02

1 Answer 1


You'll need to add the following in your form, php files and your JS.

Pay close attention to the approach, because it won't suit you. I am storing the file URL in the custom field. Possibly you prefer another way to store your file.

First you need to add two HTML input fields. Add a input type file to your form as well as a hidden field

<input class="input_file" type="file" id="file" name="input_file" />
<input type="hidden" class="hidden-file-field" name="hidden_file_field" />

JS Here we check for file field changes and do a ajax request. Pay attention to the "global" variable name because it's actually set in PHP's localize_script below.

Main strategy here is actually to save the file in a hidden field that is later going to be submitted in the form.

    $imgFile.on('change', function(e) {

        var data = new FormData();

        var files = $('input[name="input_file"]').prop('files')[0];
        data.append('input_file', files);

        data.append('nonce', global.nonce);
        data.append('action', 'media_upload')
        var data_type = 'image';

            url: global.ajax,
            data: data,
            processData: false,
            contentType: false,
            dataType: 'json',
            xhr: function() {
                var myXhr = $.ajaxSettings.xhr();

                if ( myXhr.upload ) {
                    myXhr.upload.addEventListener( 'progress', function(e) {

                    }, false );

                return myXhr;
            type: 'POST',
            beforeSend: function() {
                // handle before send
            success: function(resp) {
                // handle success
                // Save the result the url or attachment ID in a hidden input field and when the overall form is submitted, save it in the custom field.




PHP: We first need to include a nonce for submitting the media field Then we need to have the function that actually uploads the file data and return a url and some other data. This is done with add_action for ajax submissions.

   // Localize script is needed to have the nonce included

            'ajax' => admin_url( 'admin-ajax.php' ),
            'nonce'      => wp_create_nonce('media-form')
add_action( 'wp_ajax_media_upload', 'media_upload' );
add_action( 'wp_ajax_nopriv_media_upload', 'media_upload');

function media_upload(){

    if ( check_ajax_referer( 'media-form', 'nonce', false ) == false ) {
        wp_send_json_error(array('error' => 'nonce failed'));

    require_once(ABSPATH . 'wp-load.php');

    if (isset($_FILES['input_file'] ) && !empty($_FILES['input_file']['name']) )
        $allowedExts = array("doc", "docx", "pdf");

        $temp = explode(".", $_FILES["input_file"]["name"]);
        $extension = end($temp);
        if ( in_array($extension, $allowedExts))
            if ( ($_FILES["input_file"]["error"] > 0) && ($_FILES['input_file']['size'] <= 3145728 ))
                $response = array(
                    "status" => 'error',
                    "message" => 'ERROR Return Code: '. $_FILES["input_file"]["error"],
                $uploadedfile = $_FILES['input_file'];
                $upload_name = $_FILES['input_file']['name'];
                $uploads = wp_upload_dir();
                $filepath = $uploads['path']."/$upload_name";

                if ( ! function_exists( 'wp_handle_upload' ) )
                    require_once( ABSPATH . 'wp-admin/includes/file.php' );
                require_once( ABSPATH . 'wp-admin/includes/image.php' );
                $upload_overrides = array( 'test_form' => false );
                $movefile = wp_handle_upload( $uploadedfile, $upload_overrides );
                if ( $movefile && !isset( $movefile['error'] )  ) {

                    $file = $movefile['file'];
                    $url = $movefile['url'];
                    $type = $movefile['type'];

                    $attachment = array(
                        'post_mime_type' => $type ,
                        'post_title' => $upload_name,
                        'post_content' => 'File '.$upload_name,
                        'post_status' => 'inherit'

                    $attach_id = wp_insert_attachment( $attachment, $file, 0);
                    $attach_data = wp_generate_attachment_metadata( $attach_id, $file );
                    wp_update_attachment_metadata( $attach_id, $attach_data );


                $response = array(
                    "status" => 'success',
                    "url" => $url,
                    "attachment_id" => $attach_id

            $response = array(
                "status" => 'error',
                "message" => 'something went wrong, most likely file is to large for upload. check upload_max_filesize, post_max_size and memory_limit in you php.ini',



In the end, when you submit your form, with AJAX or normal POST, you should use below. Most likely you are going to sanitize the $POST first. I leave that up to you:

update_field('name_of_file_field', $POST['hidden_file_field'] $post_id);

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.