ezw
ezw

Reputation: 430

jQuery Progress Bar PHP Upload not responding correctly

I'm using a progress bar code taken from (http://theonlytutorials.com/jquery-ajax-file-upload-with-percentage-progress-bar/) (Tweaked to meet my needs) and it's not responding correctly. It uploads and includes the data into the database like it should, but the response isn't being sent (or received) at jQuery end.

My Javascript

function addCustomerFile(fileID, filePath, fileName, file)
{
    $("#customerFiles").append('<tr class="border-bottom"><td class="col-1 text-right border-right p-1">' + fileID + '</td><td><a href="' + filePath + '" class="d-block p-1">' + fileName + ' ' + file + '</a></td><td class="col-1 border-left p-1 pr-3"><div class="clearfix no-underline"><div><a href="?m=5&delFile=' + fileID + '" class="removeImg right block-24">&nbsp;</a></div><div><a href="downloads.php?file=' + fileID + '" class="downloadImg right block-24 mr-2">&nbsp;</a></div></div></td></tr>');
}

$(function ()
{
    $('#btn').click(function ()
    {
        $('.myprogress').css('width', '0');
        $('.msg').text('');

        var fileName = $('#fileName').val();
        var customerFile = $('#customerFile').val();
        var customerID = $('#customerID').val();

        if (fileName == '' || customerFile == '')
        {
            alert('Please enter file name and select file');
            return;
        }

        var formData = new FormData();

        formData.append('customerFile', $('#customerFile')[0].files[0]);
        formData.append('fileName', fileName);
        formData.append('customerID', customerID);

        $('#btn').attr('disabled', 'disabled');
        $('.msg').text('Uploading in progress...');

        $.ajax(
        {
            url: 'process/uploadCustomerFile.php',
            data: formData,
            processData: false,
            contentType: false,
            type: 'POST',

            // The progress bar
            xhr: function ()
            {
                var xhr = new window.XMLHttpRequest();

                xhr.upload.addEventListener("progress", function (evt)
                {
                    if (evt.lengthComputable)
                    {
                        $('.progress').removeClass('invisible');

                        var percentComplete = evt.loaded / evt.total;

                        percentComplete = parseInt(percentComplete * 100);

                        $('.myprogress').text(percentComplete + '%');
                        $('.myprogress').css('width', percentComplete + '%');
                    }
                }, false);

                return xhr;
            },

            success: function (data)
            {
                $('.msg').text(data.responseText);
                $('#btn').removeAttr('disabled');

                addCustomerFile(data.fileID, data.filePath, fileName, data.fileNameExt);
            }
        });
    });
});

My HTML

<div class="form-group">
    <div class="progress invisible">
        <div class="progress-bar progress-bar-success myprogress" role="progressbar" style="width:0%">0%</div>
    </div>

    <div class="msg"></div>
</div>
<input type="hidden" id="customerID" value="{{customer.ID}}" />
<div class="form-group">
    <label for="fileName">File name: </label>
    <input type="text" class="form-control" id="fileName" /> 
</div>
<div class="form-group">
    <label>File: </label>
    <input type="file" class="form-control" id="customerFile" />
</div>
<input type="button" id="btn" class="btn btn-info" value="Upload" />

My PHP

<?php
// Security (Making sure we can indirectly access certain components)
define('SIDING', true);
define('ADMIN', true);
define('HELPER', true);

// Including our common component (Needs to be included before any programming)
require '../../components/common.php';

// Making sure the user is allowed to be here, otherwise redirecting the user back to site's homepage
if(!isset($ses->logged->permissions->ADMIN))
{
    // Redirecting the user to
    header("LOCATION: ../index.php");
}

// Maximum file size (15 MB)
$maxSize = 15 * 1024 * 1024;

// File upload path
$path = "../../design/{$tpl->style}/customerFiles/";

// Set the valid file extensions
$validFormats = array("jpg", "png", "gif", "bmp", "jpeg", "GIF", "JPG", "PNG", "doc", "txt", "docx", "pdf", "xls", "xlsx");

// The file's name
$name = $_FILES['customerFile']['name'];

// The file's size
$size = $_FILES['customerFile']['size'];

// Check if the file is selected or cancelled after pressing the browse button.
if(!strlen($name))
{
    die(json_encode(array('responseType' => 0, 'responseText' => "Please select a file...")));
}

// Extract the name and extension of the file
list($txt, $ext) = explode(".", $name);

// If the file is valid go on.
if(!in_array($ext, $validFormats))
{
    die(json_encode(array('responseType' => 0, 'responseText' => "Invalid file format...")));
}

// Check if the file size is more than 2 mb
if($size > $maxSize)
{
    die(json_encode(array('responseText' => "File size max 15 MB")));
}

$fileName = $_POST['fileName'];

$customerID = $_POST['customerID'];

$tmp = $_FILES['customerFile']['tmp_name'];

// The file's name
$fileRealName = $fileName . '_' . $customerID . '.' . $ext;

// The filepath where we are uploading the file
$filePath = $path . $fileRealName;

// Our SQL to check if the file exists in the database
$sql = "SELECT ID FROM " . CUSTFILES_TABLE . " WHERE customerID = :customerID AND fileName = :fileName AND file = :file";

$stmt = $db->prepare($sql);

$stmt->bindParam(":customerID", $customerID, PDO::PARAM_INT);
$stmt->bindParam(":fileName", $fileName, PDO::PARAM_STR);
$stmt->bindParam(":file", $fileRealName, PDO::PARAM_STR);

$stmt->execute();

$selectFile = $stmt->fetch();

// Checking if the file already exists
if(file_exists($filePath) && $selectFile)
{
    die(json_encode(array('responseText' => "This file already exists for the customer")));
}

// Turning off auto-commit
$db->beginTransaction();

// SQL to insert the new uploaded file into the database
$sql = "INSERT INTO " . CUSTFILES_TABLE . " (customerID, fileName, file) VALUES (:customerID, :fileName, :file)";

$stmt = $db->prepare($sql);

$stmt->bindParam(":customerID", $customerID, PDO::PARAM_INT);
$stmt->bindParam(":fileName", $fileName, PDO::PARAM_STR);
$stmt->bindParam(":file", $fileRealName, PDO::PARAM_STR);

// Adding the data to the database
if(!$stmt->execute())
{
    die(json_encode(array('responseText' => "File failed to be added to the database")));
}

// Check if it the file move successfully.
if(!move_uploaded_file($tmp, $filePath))
{
    // Rolling back any changes since there were errors
    $db->rollBack();

    die(json_encode(array('responseText' => "The file failed to be uploaded")));
}

// Committing the changes
$db->commit();

// Getting the ID of the inserted literature
$id = $db->lastInsertId();

// Creating the response for the process
$jsonReply = array(
    'fileID'        => $id,
    'filePath'      => $filePath,
    'fileRealName'  => $fileRealName,
    'responseText'  => "File has being uploaded successfully!"
);

die(json_encode($jsonReply));

When I add the file it uploads and get's added into the database, but my progress bar message still indefinitely says "Uploading in progress..." and the file that is being appended VIA addCustomerFile jQuery function has every field returned from AJAX as undefined. Only the 'fileName' (which is set in jQuery) returns a value.

I've looked for anything off, and nothing seems to be wrong. I don't know javascript. Just enough to guess and check but it doesn't seem to be enough for this case (if the problem is javascript). Any help would be appreciated. Thanks in advance

It doesn't matter what happens. If file exists, it won't upload but still say "Uploading in progress..."... if any error occurs (like bad format or filesize) it still says 'Uploading in progress..." for ever.

The console doesn't show any errors or warnings or any info about my javascript (or anything at all)

Upvotes: 1

Views: 435

Answers (1)

ezw
ezw

Reputation: 430

I solved my issue after an hour of breaking my head over this.

I forgot to put dataType: 'json' to my AJAX call.

url: 'process/uploadCustomerFile.php',
data: formData,
dataType: 'json', // <-- This is what I forgot to add
processData: false,
contentType: false,
type: 'POST',

so the response wasn't treated as JSON

Upvotes: 1

Related Questions