Question

Good Morning,

I searched all over with no luck for the answer to my problem. I would like to use jquery, but have tried with 'regular' Javascript with little success.

Goal
I would like to upload a file (just one) via ajax (asynchronous) to a php server which will consume the file (txt).

Problem
The script will not call the php script, nor will the file upload. There are no javascript errors and it seams that the script runs through just fine. In chrome, process.php does not show up in the network section, so I am not sure if it is from the script or an error within my php.

General Information
Browser: Chrome Version 26.0.1410.64 m
wamp server (php, mysql)
Bootstrap for layout

Code
index:

<div class="span12" id="upload_form_div" style="display: block;">
    <form id="upload_form" enctype="multipart/form-data" class="upload_form">
        <fieldset>
            <legend>
                Please select a file to parse and merge with the database.
            </legend>
            <p>
                <label for="files">File:</label>
                <input type="file" class="text" id="files" name="file">
            </p>
            <p>
                <input type="button" value="Start Parse">
            </p>
        </fieldset>
    </form>
</div>

I am including the jquery.js, app.js (script file for upload), and bootstrap.min.js. Just thought it wasn't necessary to show the full html markup.

Script File:

$(function(){
$("#progressbar").hide();
});


function showProgress(evt) {
if (evt.lengthComputable) {
    var percentComplete = (evt.loaded / evt.total) * 100;
    $('#progressbar').progressbar("option", "value", percentComplete );
}
}

$(':button').click(function(){
var fileIn = $("#files")[0];
//Has any file been selected yet?
if (fileIn.files === undefined || fileIn.files.length == 0) {
    alert("Please select a file");
    return;
}

//We will upload only one file
var file = fileIn.files[0];
console.log(file);
//Show the progress bar
$("#progressbar").show();


$.ajax({
    url: 'process.php',  //server script to process data
    type: 'POST',
    data: file,
    contentType: file.type,
    processData: false,
    success: function(){
        $("#progressbar").hide();
    },
    error: function(){
        $("#progressbar").hide();
        alert("Failed");
        //alert(xhr.responseText);
    },
    xhr: function() {  // custom xhr
        myXhr = $.ajaxSettings.xhr();
        if(myXhr.upload){ // check if upload property exists
            //myXhr.upload.addEventListener('progress',showProgress, false); // for handling the progress of the upload
            //console.log($.ajaxSettings.xhr().upload);
            console.log(myXhr.responseText);
        } else {
            console.log("Upload progress is not supported.");
        }

        return myXhr;
    }
});
});

This is straight copy paste so I commented out some of the trouble shooting lines.

PHP

<?php
set_error_handler("E_ALL");
$upload_directory = "files/";
move_uploaded_file($_FILES['file']['tmp_name'], $upload_directory . $_FILES['file']['name']);
?>

The php file will do more, but I am just trying to get the file to upload at this point.

If anyone needs more information just let me know and I will do my best to supply the information.

Was it helpful?

Solution 2

I know it has been a while, but I have found a solution to my problem. Honestly, I came about this by accident when I used the jQuery form plugin and noticed that the $_FILES[] was actually being sent along with the $_POST[]. It doesn't even need XMLHttpRequest. Below is my code.

Javascript

function saveForm(){
    $("#saveButton").button('loading');
    $("#MyForm").ajaxSubmit({
        url: 'save_script.php',
        type: 'post',
        success: function(responce){
            $("#saveButton").button('reset');
            rebuild_attachments();
        }
    });
};

Some notes, #saveButton is the id of the button I click to save the form, and #MyForm is the id of the form I am submitting. I am also using bootstrap button to change the submit button to a loading state to prevent people from clicking multiple times in the event of a large file upload. The success callback reverts the save button to its original state so they can submit the form again. This also supports multiple files.

The "rebuild_attachments()" is a function that I call which makes another .ajax request to rebuild a div located within the form with the new items, if any. I know there is probably a better way to handle this, such as java script templates, but this method works for me at this time.

OTHER TIPS

Sorry - you cannot upload a file through an ajax request. You'll have to get a little creative and use a hidden iframe with a submit. This usually involves creating a new hidden form, cloning (or moving in the case of IE) the file control into the hidden form, and attaching the new form to a hidden iframe. The post method of the iframe is hooked to the URL of where you want the file sent. You can include variables to go along with the file(s) by creating/cloning text boxes that will be sent to the URL as part of the query string.
On the client side, create a timer event after submitting the form that will check a javascript variable (clear the var before submitting the form). On the server side, send javascript down through the response object to set the client var. This is how you will know the file upload is complete. The process is fairly involved - especially when working with IE where you will need to move the file control back where you moved it from as well as creating a 'dummy' file control to stub it in. You may want to look at some of the jQuery file upload plugins... Here is a bit of code to get you started on the iframe approach:

jQuery('#btn5Submit').click(function() {
    //create a temporary form with the fileboxes on it, then attach to the end of the html form (to avoid nested form tags)
    var wkForm = jQuery('<form id="tmpFileUpload" method="POST" action="filehandler.ashx" encType="multipart/form-data" target="uploadResult" class="ctlHidden"></form>');
    for (var i = 1; i < 4; i++) {
        var wkFile = jQuery('#file5Upload' + i);
        if (wkFile.val() != '' && wkFile.length != 0) {
            jQuery('<img src="Styles/Images/loading.gif" id="' + 'img5File' + i + '" />').insertAfter(wkFile);
            wkForm.append(wkFile);
        }
        else {
            //user did not provide a file, add a dummy file input to the temp form to maintain order
            wkForm.append('<input name="file5TUpload' + i + '" type="file"/>');
        }
    }
    jQuery('body').append(wkForm);
    jQuery('#tmpFileUpload').submit();
});

jQuery('.deleteFile').live('click', function() {
    editRow = jQuery(this).parent();
    var ddlog = jQuery('<div></div>');
    var btns = {};
    var gMsg = 'Are you sure you want to delete this file? (This will allow you to specify a new file, but the server file will not be replaced until "Send Files To Server" is pressed.)';
    ddlog.html(gMsg);
    var button1 = 'Delete File';
    var button2 = 'Cancel Deletion';
    btns[button1] = function() {
        var wkId = jQuery(editRow).attr('id');
        wkId = wkId.charAt(wkId.length - 1);
        jQuery('<input id="file5Upload' + wkId + '" name="file5Upload' + wkId + '" type="file" class="fileUpload" />').insertAfter(editRow);
        jQuery(editRow).remove();
        jQuery(this).dialog('close');
    };
    btns[button2] = function() {
        //Do not save changes, reset section control buttons, reset global var, reset initial_data values (Do not save changes)
        jQuery(this).dialog('close');
    };
    ddlog.dialog({ autoOpen: false, title: 'File Deletion Confirmation', resizable: false, modal: true, buttons: btns });
    ddlog.dialog('open');
});
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top