Page 1 of 1

upload file to server

Posted: Thu Mar 13, 2025 10:18 am
by johan
I am having a problem uploading files.
I am using the code below and it works when adding 1 attachment. But as soon as I want to add a 2nd attachment, I get error message, namely that the first document already exists.
Any idea how I could refine the code?

Code: Select all

var idRowFileName;
var idRowFileId;

function uploadFile(event) {
    var td = $(event.target);
    var t = td.attr('data-nu-prefix');

    idRowFileName = t + idFileName;
    idRowFileId = t + idFileId;

   $("#fileToUpload").click();

}
Johan

Re: upload file to server

Posted: Thu Mar 13, 2025 10:25 am
by kev1n
Hi Johan,

It looks like your code performs an action when "fileToUpload" is clicked, but you haven't provided the part where the files are actually processed and uploaded. The problem you're having (the first document already exists when you add a second) suggests that your upload logic may not be handling multiple files correctly.

Re: upload file to server

Posted: Thu Mar 13, 2025 10:50 am
by johan
Kev1n

Do you mean this part?

Code: Select all

<script type="text/javascript">

function setUploadStatus(id, classname, icon, status) {

    var msg = '<div class="' + classname + '"><i class="' + icon + '"></i>' + status + '</div>';
    $('#' + id).html(msg);

}

function setSubGridFileInfo(filename, fileid) {
     $('#' + idRowFileName).val(filename).change();
     $('#' + idRowFileId).val(fileid).change();  
}


$(document).ready(function(e) {

    $('#fileToUpload').on('change', function(event) {

        var file = $(this)[0].files[0];

        var formdata = new FormData();
        formdata.append('file', file);
        formdata.append('record_id', nuCurrentProperties().record_id);

        setUploadStatus('sample_msg', 'alert alert-info', 'fa fa-spin fa-spinner', nuTranslate('Uploading...'));

        $.ajax({
            type: "POST",
            url: "libs/upload.php",
            data: formdata,
            contentType: false,
            cache: false,
            processData: false,
            success: function(data) {

                var result = JSON.parse(data);
                if (result.error !== '') {
                    var err = "";
                    switch (result.error) {
                        case "INVALID_FILE_TYPE":
                            err = "The file type is not allowed.";
                            break;
                        case "ERROR_MOVING_FILE":
                            err = "The file cannot be moved to the destination directory.";
                            break;
                        case "FILE_TOO_LARGE":
                            err = "Error: File size is larger than the allowed limit.";
                            break;
                        default:
                            err = result.error;
                    }
                    setUploadStatus('sample_msg', 'alert alert-info', 'fa fa-exclamation-triangle', nuTranslate("Upload Failed:") + ' ' + nuTranslate(err));

                } else {

                        setSubGridFileInfo(result.file_name, result.file_id);
                        createDownloadLink(idRowFileName, uploadFolder, result.file_id, result.file_name);
                        setUploadStatus('sample_msg', 'alert alert-success', 'fa fa-thumbs-up', nuTranslate('File uploaded successfully.'));

                }
                $("#upload-form")[0].reset();

            },
            error: function(data) {
                setUploadStatus('sample_msg', 'alert alert-info', 'fa fa-exclamation-triangle', nuTranslate('Upload failed.'));
            }
        });
    });
});

</script>

<form id="upload-form" action="libs/upload.php" method="post" enctype="multipart/form-data">   
    <input type="file" name="fileToUpload" id="fileToUpload">
    <input type="submit" name="submit" value="Upload">
</form>


Re: upload file to server

Posted: Thu Mar 13, 2025 11:45 am
by kev1n
It's a bit tricky to pinpoint the issue, especially without knowing the exact implementation.
I asked ChatGPT and got the following response (though I haven't verified its accuracy).

Your current issue seems to stem from how you handle file inputs. When you upload a second file, the browser might still be holding onto the first file in the `<input type="file">` field. Some common problems and their solutions:

Possible Issues & Fixes:

1. Reset File Input After Upload:
- You need to clear the file input after every successful upload. Right now, your reset line:

Code: Select all

     $("#upload-form")[0].reset();
     
is inside `success`, but sometimes file inputs don't clear as expected. Try explicitly clearing it:

Code: Select all

     $('#fileToUpload').val('');
     
Add this right after `$("#upload-form")[0].reset();`.

2. Ensure `FormData` Contains All Files When Uploading Multiple Files
- Your current approach only supports one file at a time since you're appending just `files[0]`:

Code: Select all

     var file = $(this)[0].files[0];
     
If you're trying to upload multiple files, modify it:

Code: Select all

     var files = $(this)[0].files;
     var formdata = new FormData();
     for (var i = 0; i < files.length; i++) {
         formdata.append('files[]', files[i]);  // Use an array
     }
     
Then, adjust your PHP backend (`upload.php`) to handle multiple files.

3. Avoid Overwriting Variables (`idRowFileName`, `idRowFileId`)
- If multiple files are being processed simultaneously, they could override each other.
- Instead of using global variables:

Code: Select all

     var idRowFileName;
     var idRowFileId;
     
Store values locally:

Code: Select all

     function uploadFile(event) {
         let td = $(event.target);
         let t = td.attr('data-nu-prefix');

         let idRowFileName = t + idFileName;
         let idRowFileId = t + idFileId;

         $("#fileToUpload").data('fileNameField', idRowFileName);
         $("#fileToUpload").data('fileIdField', idRowFileId);

         $("#fileToUpload").click();
     }
     
Then retrieve them before setting values:

Code: Select all

     let idRowFileName = $('#fileToUpload').data('fileNameField');
     let idRowFileId = $('#fileToUpload').data('fileIdField');
     
### Updated Code (Fixing Multi-File Upload)

Code: Select all

$(document).ready(function(e) {
    $('#fileToUpload').on('change', function(event) {
        var files = $(this)[0].files;
        var formdata = new FormData();
        var recordId = nuCurrentProperties().record_id;

        for (var i = 0; i < files.length; i++) {
            formdata.append('files[]', files[i]);  // Store as array
        }
        formdata.append('record_id', recordId);

        setUploadStatus('sample_msg', 'alert alert-info', 'fa fa-spin fa-spinner', nuTranslate('Uploading...'));

        $.ajax({
            type: "POST",
            url: "libs/upload.php",
            data: formdata,
            contentType: false,
            cache: false,
            processData: false,
            success: function(data) {
                var result = JSON.parse(data);
                if (result.error !== '') {
                    var errMsg = {
                        "INVALID_FILE_TYPE": "The file type is not allowed.",
                        "ERROR_MOVING_FILE": "The file cannot be moved to the destination directory.",
                        "FILE_TOO_LARGE": "Error: File size is larger than the allowed limit."
                    };
                    setUploadStatus('sample_msg', 'alert alert-info', 'fa fa-exclamation-triangle', nuTranslate("Upload Failed:") + ' ' + nuTranslate(errMsg[result.error] || result.error));
                } else {
                    // Handle multiple files properly
                    result.files.forEach(function(file) {
                        let idRowFileName = $('#fileToUpload').data('fileNameField');
                        let idRowFileId = $('#fileToUpload').data('fileIdField');

                        setSubGridFileInfo(file.file_name, file.file_id);
                        createDownloadLink(idRowFileName, uploadFolder, file.file_id, file.file_name);
                    });

                    setUploadStatus('sample_msg', 'alert alert-success', 'fa fa-thumbs-up', nuTranslate('Files uploaded successfully.'));
                }

                // Clear file input
                $("#upload-form")[0].reset();
                $('#fileToUpload').val('');
            },
            error: function() {
                setUploadStatus('sample_msg', 'alert alert-info', 'fa fa-exclamation-triangle', nuTranslate('Upload failed.'));
            }
        });
    });
});
### Backend (upload.php) Update
Ensure your PHP backend can handle multiple files:

Code: Select all

php
<?php
if (!empty($_FILES['files']['name'][0])) {
    $uploadDir = "uploads/";
    $uploadedFiles = [];
    
    foreach ($_FILES['files']['name'] as $key => $name) {
        $tmpName = $_FILES['files']['tmp_name'][$key];
        $newFileName = uniqid() . "_" . basename($name);
        $filePath = $uploadDir . $newFileName;

        if (move_uploaded_file($tmpName, $filePath)) {
            $uploadedFiles[] = ["file_name" => $newFileName, "file_id" => $key]; 
        }
    }

    echo json_encode(["error" => "", "files" => $uploadedFiles]);
} else {
    echo json_encode(["error" => "NO_FILES"]);
}
?>
Final Fix Summary
- Reset the file input after each upload (`$('#fileToUpload').val('')`)
- Modify JS to support multiple file uploads
- Store dynamic field IDs per upload to avoid overwriting
- Update `upload.php` to handle multiple files at once

Re: upload file to server

Posted: Mon Mar 17, 2025 11:34 am
by johan
Kev1n

I discovered that the problem was in the validation (no duplicate) of the upload.
I changed this to no validation, which solved the problem.
Thanks for your help.
Johan