Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

I keep running into an issue getting the file(s) added/switched to ajax so that the server ajax handler can deal with the rest. How can I get the $_FILES to be passed the same as with the default action (built into form elements)?

Updated

I was originally sending a mixed object, but modified it to use the FormData Object only. Using FormData Objects is a solution for uploading files instead of being dependent on JS/jQuery plugins to accomplish the task.

HTML Form

<form id="frmImport" name="frmImport" method="post" enctype="multipart/form-data" >
    <input id="fileImportData" name="importData" type="file" />
    <br/>
    <button id="btnImport" type="submit" >Import</button>
</form>

JavaScript

jQuery(document).ready(function($){
    //This is already setup and sent from the server side, and is
    // is used to prevent unauthorized users from uploading data.
    var importnonce = "3x4mpl3f4k3n0nc3"; 

    $('#frmImport').submit(function(e)
    {
        e.preventDefault();
        //CHECK ERRORS ON USER SIDE, IF TRUE, END OPERATIONS.
        if (import_errors())
        {
            return false;
        }
        import_db();
        return false;
    });

    function import_errors()
    {
        if ($('#fileImportData').val() == '')
        {
            alert('No file(s) selected. Please choose a JSON file to upload.');
            return true;
        }
        if ($('#fileImportData').val() != '')
        {
            var ext = $('#fileImportData').val().split('.').pop().toLowerCase();
            if($.inArray(ext, ['json']) == -1) 
            {
                alert('Invalid file type. Please choose a JSON file to upload.');
                return true;
            }
        }
        return false;
    }

    function import_db()
    {
        //REMOVED - Everything was switched over to be added to the FormData Objects
        //var ajaxData = { 
        //    action : 'ajax_handler_import',
        //    _ajax_nonce : importNonce
        //};

        //This is where issues occurred, I couldn't get the file added to ajax
        // and preserved in $_FILE, and this isn't the only method I've tried 
        // to add data. However, this was the most promising.

        //MODIFIED - Everything is appended to the FormData Object instead.
        //ajaxData.formD = new FormData();
        //jQuery.each($('#fileImportData')[0].files, function(i, file) {
        //    ajaxData.formD.append('file-'+i, file);
        //});

        var formData = new FormData();
        jQuery.each($('#fileImportData')[0].files, function(i, file) {
            formData.append('uploadFile-'+i, file);
        });
        formData.append('action', 'ajax_handler_import');
        formData.append('_ajax_nonce', importNonce);

        jQuery.ajax({
            url: ajaxurl,
            type: 'POST',
            cache: false,
            contentType: false,
            processData: false,

            //MODIFIED - From ajaxData to formData
            data: formData,

            beforeSend: function(jqXHR, settings){
                console.log("Haven't entered server side yet.");
            },
            dataFilter: function(data, type){
                //May need/want to create a function to parse the data. Which includes
                // PHP Errors that would normally break the AJAX function with a JS 
                // Error with no sign of the PHP Error message. Normally want to 
                // try/catch php errors.
                console.log("JSON string echoed back from server side.");
            },
            success: function(data, textStatus, jqXHR){
                console.log("Back from server-side!");
                //Checking errors that may have been caught on the server side that
                // normally wouldn't display in the error Ajax function.
                if (data.msg != 'success')
                {
                    alert(data.error);
                }
            },
            error: function(jqXHR, textStatus, errorThrown){
                console.log("A JS error has occurred.");
            },
            complete: function(jqXHR, textStatus){
                console.log("Ajax is finished.");
            }
        });  
    }
});

PHP Server/Handler

<?php
class server
{
    function ajax_import_handler()
    {
        check_ajax_referer("ajax_handler_import");

        $rtnData = new stdClass();
        $rtnData->msg = 'success'; //For signifying Server errors
        $rtnData->error = ''; //For displaying custom error messages or using the try/catch method

        //Do Stuff
        foreach ($_FILES as $key => $value)
        {
            //GET FILE CONTENT
            $file_array[$key] = json_decode(file_get_contents($value['tmp_name']));
        }
        //Do More Stuff

        //Add Stuff to $rtnData

        echo json_encode($rtnData);
    }
}
?>
share|improve this question
add comment

2 Answers

up vote 1 down vote accepted

I haven't tried but i think you need to add FormData object directly as data parameter. Something like this

    var ajaxData = new FormData();

    ajaxData.append( 'action', 'ajax_handler_import' );
    ajaxData.append( '_ajax_nonce', importNonce );
    // or maybe skip the nonce for now

    jQuery.each($('#fileImportData')[0].files, function(i, file) {
        ajaxData.append('file-'+i, file);
    });

The rest of your code goes as it is

share|improve this answer
    
Sorry I haven't replied sooner...I was trying to finish out a project, and figured I'd come back when I have more knowledge on the subject. Thanks for providing the solution, I didn't know adding the FormData object to an object would mess it up, and I was running out of ideas. Figures it would be a simple problem xP. The lesson learned here: stay away from mixed objects. –  EkoJr Dec 1 '12 at 9:44
add comment

Ajax in the traditional sense is XMLHttpRequest, which does not allow you encode and send local files to a server.

The common ways of doing uploading through "ajax" means, is to either use a Flash swf to handle the uploading on the same page, or to use a form that has a target of an invisible 1x1 iframe.

Here is a very similar question with a good answer to see how you can do that

share|improve this answer
    
Yea, I was going through that Q/A recently. Unfortunately, I'm not familiar with flash, and I've been trying to avoid adding plugins if at all possible. I've mainly been trying to follow WordPress Ajax method, but by what I've found, just passing it to ajax is restricted/limited by the browsers. Mainly refering to this Q/A led me to FormData Objects which says is possible if the browser used has it. –  EkoJr Nov 2 '12 at 8:45
    
It turns out that you can use your own methods for passing file data over to an AJAX function instead of relying on a JS plugin. For the most part, FormData Objects (as mentioned above), handles this with XMLHttpRequest Level 2 operations (as I currently understand it), and is supported by all major browsers now. I figured it would be a matter of time after HTML5 came out. However, using plUpload is a possible recommendation for large file data. –  EkoJr Dec 1 '12 at 9:54
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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