0

I've been trying to create a registration form that requires students to upload documents at the very end. However, after picking up the form values via jQuery, the PHP document can't seem to pick up my uploaded form. Any ideas?

Form:

<form id="joinUs"  enctype="multipart/form-data" method="post">
   <!--various form fields-->
    <input type="file" name="transcript" id="transcript">
    <div class="button" id="submit">Submit!</div>
</form>

jQuery:

$("#submit").click(function(){
    //firstName, lastName, grade, studentID, email, phone are all form values
   var data = "firstName="+firstName+"&lastName="+lastName+"&grade="+grade+"&studentID="+studentID+"&email="+email+"&phone="+phone;
         $.ajax({
                            type: "POST",
                            url: "join_submit.php",
                            data: data,
                            success: function() {                                        
                                   location.href="http://mvcsf.com/new/success.php";

                            }
                    });

join_submit.php

  $allowedExtensions = array("pdf");
$max_filesize = 20000;
$upload_path = "docs/transcripts";
$filename = $_FILES["transcript"]["name"];          
$filesize = $_FILES["transcript"]["size"];
$extension = $_FILES["transcript"]["type"];
 if ($_FILES["transcript"]["error"] > 0) {
        echo "Error: " . $_FILES["transcript"]["error"] . "<br />";
    }
else if((in_array($extension, $allowedExtensions)) && ($filesize < $max_filesize)) {
    move_uploaded_file($_FILES["transcript"]["tmp_name"], $upload_path . $filename);
}

I ran this, and I got no errors. I also tried to print out the file name, except nothing printed out.

Andrew
  • 3,501
  • 8
  • 35
  • 54
  • possible duplicate of [How can I upload files asynchronously with jQuery?](http://stackoverflow.com/questions/166221/how-can-i-upload-files-asynchronously-with-jquery) – hjpotter92 Nov 05 '13 at 04:35
  • 1
    You need to pass the file as FormData(). Else the file wont be obtained at other end – Roy M J Nov 05 '13 at 04:36
  • The only thing(s) that come to mind are, did you test with a file bigger or smaller than `20000`? that's not very big, 20,000 bytes. If so, then that's one thing that will stop from uploading. Second, try adding a forward slash at the end of `$upload_path = "docs/transcripts";` such as `$upload_path = "docs/transcripts/";` and make sure that the folder has write permission, including the sub-folder. – Funk Forty Niner Nov 05 '13 at 04:38
  • @Fred-ii-, I've tried the file upload with a file smaller than 20,000. I've checked the file permissions, it's set to 777. I'll try the forward slash. – Andrew Nov 05 '13 at 04:40
  • @Andrew Folder permissions are usually 755 or 777. My server supports both. – Funk Forty Niner Nov 05 '13 at 04:42
  • @Andrew So, any luck? – Funk Forty Niner Nov 05 '13 at 04:57
  • does your jquery prevent default submit operation – Nabil Nov 05 '13 at 05:13
  • @Fred-ii-, I tried both of them but it doesn't seem to change anything. – Andrew Nov 05 '13 at 05:35
  • why are you ajax-posting a form and then redirecting on success? why not just... _post the form_? don't replicate browser functionality with JS – Eevee Nov 05 '13 at 08:07

3 Answers3

0

First, In your code, you are posting data with $.ajax({...}) and the data sent is

"firstName="+firstName+"&lastName="+lastName+"&grade="+grade+"&studentID="+studentID+"&email="+email+"&phone="+phone;

There is no transcript at all.

Secondly, and most important, you cannot post file with $.ajax({...}) like that, it will not working like that. As @Roy M J says, you should take a look at FormData (for recent browser only), or take a look on the web for an upload jQuery plugin (don't re-invent the whell, some good plugin already exists :))

Take a look here

MatRt
  • 3,494
  • 1
  • 19
  • 14
0

This should do it for you :

$("#submit").click(function () {

        var transcript = $("#transcript").val();

        var data = "firstName=" + firstName + "&lastName=" + lastName + "&grade=" + grade + "&studentID=" + studentID + "&email=" + email + "&phone=" + phone;
        var formData = new FormData();

        formData.append("file", transcript);
        formData.append("data", data);

        $.ajax({
            type: "POST",
            url: "join_submit.php",
            enctype: 'multipart/form-data',//optional
            cache: false,
            contentType: false,
            processData: false,
            data: {
                file: file
                data: data
            },
            success: function () {
                location.href = "http://mvcsf.com/new/success.php";

            }
        });
});

Cheers

Roy M J
  • 6,926
  • 7
  • 51
  • 78
  • Thanks! I'll try this out later and get back to you. Though I have a question - where are you passing formData into the ajax request? (I'm just trying to understand how this works) – Andrew Nov 05 '13 at 05:32
  • no this is basically just sending this out in a particular format. The steps `formData.append("file", transcript);` does this. And in the ajax you are passing it as `data: { file: filename data: data },` . – Roy M J Nov 05 '13 at 05:47
  • for the line that states `file: filename`, is there supposed to be something else there? I ran it, except the form no longer submits – Andrew Nov 05 '13 at 07:52
  • Okay ive changed it. It should be the file field value that is being wrapped in form-data... – Roy M J Nov 05 '13 at 08:05
0

You cannot send a file like you do the values of HTML elements. There are two methods to file upload, the one I've used successfully is the AJAX method using a third-party feature called 'AjaxUploader'.You can download it here via GitHub. Once you've done it, add the ajaxuploader.js file in your 'js' folder (or wherever you've put all of your script files), include the file in the HTML page where you've to use the uploader. Now, uploading is as simple as follows.
HTML:

<input type="file" name="transcriptUploader" id="transcriptUploader" value="Upload" />

jQuery (you need to have the jQuery file included in your page):

            new AjaxUpload('transcriptUploader', { 
            action: "page_to_handle_upload.php", // You need to have either a separate PHP page to handle upload or a separate function. Link to either one of them here
            name: 'file',
            onSubmit: function(file, extension) {
                // This function will execute once a user has submitted the uploaded file. You can use it to display a loader or a message that the file is being uploaded.
            },
            onComplete: function(file, response) {
                // This function will execute once your file has been uploaded successfully.
                var data = $.parseJSON(response); // Parsing the returning response from JSON.
                if(data.error == 0)
                {
                    // If the file uploaded successfully.
                }
                else if(data.error == "size"){
                    // If the response object sent 'size' as the error. It means the file size exceeds the size specified in the code.
                }
                else if(data.error == "type"){
                    // If the response object sent 'type' as the error. It means the file type is not of that specified in the code (in your case, pdf).
                }
                else{
                    // In case the file didn't upload successfully or the code didn't return a usual error code. It is still an error so you need to deal with it appropriately.
                }

            }
        });

Your back-end PHP code that will be doing all the heavy lifting (uploading the file, checking extensions, moving it etc):

if(isset($_FILES)) // Checking if a file is posted.
{
    if ($_FILES['file']['error'] == 0) //Checking if file array contain 0 as an error. It means AJAX had no error posting the file.
    {
        $response = array(); // Initializing a new array.
        $allowedExts = array("pdf"); // Allowable file format.
        $filename = stripslashes($_FILES['file']['name']); // Storing file name.
        //$extension = strtolower(self::_getExtension($filename)); // Fetching file extension.
        // Code block to extract file extension and storing it in a variable called $extraction.
        $i = strrpos($str, ".");
        if (!$i)
        {
            $extension = "";
        }
        $l = strlen($str) - $i;
        $extension = strlower(substr($str, $i + 1, $l));
        $size = $_FILES['file']['size']; // Storing file size (in bytes).
        $fileNameAfterUpload =  md5((time() + microtime())) . '.' . $extension; // Concatinating file name and extension.
        $baseSystemPath = "/var/www/<your_folder_name>/uploaded_transcripts/" // Path on which the file will be uploaded. Need to be relative web path.
        $maxSize = 10*10*1024; // Storing file size. Be advised the file size is in bytes, so this calculation means max file size will be 10 MB.
        $webPath =  "uploaded_transcripts/". $filename; // Creating web path by concatinating base web path (the folder in which you'd be uploading the pdf files to) with file name.


        if (in_array($extension, $allowedExts)) // Checking if file contains allowabale extensions.
        {
            if($size <= $maxSize) // Checking if the size of file is less than and equal to the maximum allowable upload size.
            {
                $moved = move_uploaded_file($_FILES['file']['tmp_name'], $webPath); // Moving the file to the path specified in $webPath variable.
                if($moved == true)
                {
                    $response['error'] = 0; // If moved successfully, storing 0 in the response array.
                    $response['path'] = $webPath; // Storing web path as path in the response array.
                    $response['filename'] = $filename; // Storing file name in the response array.
                }
                else 
             {
                    $response['error'] = 'internal'; // If move isn't successfull, return 'internal' to AJAX.
                }
            }
            else
            {
                 $response['error'] = 'size'; // If file size is too small or large, return 'size' to AJAX.
            }
        }
        else
        {
             $response['error'] = 'type'; // If file type is not that of defined, return 'type' to AJAX.
        }
        echo json_encode($response); // Returning the response in JSON format to AJAX.
    }
}

Do let me know if you need further assistance. P.S: Don't forget to mark it as an answer if it worked.

Basit
  • 1,830
  • 2
  • 31
  • 50