how make file upload field through custom field

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) {
    
        e.preventDefault();

        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";

        jQuery.ajax({
            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.

                $('.hidden-file-field').val(resp.url)



            }
        });

    })

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
   wp_localize_script(

        'jsfilename',
        'global',
        array(
            '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"],
                );
            }
            else
            {
                $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
                );

            }
        }
        else
        {
            $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',
            );
        }
    }

        wp_send_json_success($response);


}

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