0

I'm new to Dropzone Js and i want to upload a file, process data to json then upload to my Flask server. i appreciate any kind of help, thanks.

var id = '#kt_dropzone_4';
// set the preview element template
var previewNode = $(id + " .dropzone-item");
previewNode.id = "";
var previewTemplate = previewNode.parent('.dropzone-items').html();
previewNode.remove();

var myDropzone4 = new Dropzone(id, { // Make the whole body a dropzone
  url: "/Upload", // Set the url for your upload script location
  headers: {
    'x-csrftoken': $('#csrf_Upload').val()
  },
  method: "post",
  parallelUploads: 5,
  acceptedFiles: ".xls, .xlsx, .csv",
  previewTemplate: previewTemplate,
  maxFilesize: 2, // Max filesize in MB
  autoQueue: false, // Make sure the files aren't queued until manually added
  previewsContainer: id + " .dropzone-items", // Define the container to display the previews
  clickable: id +
    " .dropzone-select" // Define the element that should be used as click trigger to select files.
});

myDropzone4.on("addedfile", function (file) {
  // Hookup the start button
  file.previewElement.querySelector(id + " .dropzone-start").onclick = function () {
    myDropzone4.enqueueFile(file);
  };
  $(document).find(id + ' .dropzone-item').css('display', '');
  $(id + " .dropzone-upload, " + id + " .dropzone-remove-all").css('display', 'inline-block');

  //remove duplicates
  if (this.files.length) {
    var i, len;
    for (i = 0, len = this.files.length; i < len - 1; i++) // -1 to exclude current file
    {
      if (this.files[i].name === file.name && this.files[i].size === file.size && this.files[i]
        .lastModifiedDate.toString() === file.lastModifiedDate.toString()) {
        this.removeFile(file);
        $('#muted-span').text('Duplicates are not allowed').attr('class', 'kt-font-danger kt-font-bold').hide()
          .fadeIn(1000)
        setTimeout(function () {
          $('#muted-span').hide().text('Only Excel and csv files are allowed for upload')
            .removeClass('kt-font-danger kt-font-bold').fadeIn(500);
        }, 2500);

      }
    }
  }
});

// Update the total progress bar
myDropzone4.on("totaluploadprogress", function (progress) {
  $(this).find(id + " .progress-bar").css('width', progress + "%");
});

myDropzone4.on("sending", function (file, response) {
  console.log(file)
  console.log(response)

  // Show the total progress bar when upload starts
  $(id + " .progress-bar").css('opacity', '1');
  // And disable the start button
  file.previewElement.querySelector(id + " .dropzone-start").setAttribute("disabled", "disabled");
});

// Hide the total progress bar when nothing's uploading anymore
myDropzone4.on("complete", function (progress) {
  var thisProgressBar = id + " .dz-complete";
  setTimeout(function () {
    $(thisProgressBar + " .progress-bar, " + thisProgressBar + " .progress, " + thisProgressBar +
      " .dropzone-start").css('opacity', '0');
  }, 300)

});

// Setup the buttons for all transfers
document.querySelector(id + " .dropzone-upload").onclick = function () {
  myDropzone4.enqueueFiles(myDropzone4.getFilesWithStatus(Dropzone.ADDED));
};

// Setup the button for remove all files
document.querySelector(id + " .dropzone-remove-all").onclick = function () {
  $(id + " .dropzone-upload, " + id + " .dropzone-remove-all").css('display', 'none');
  myDropzone4.removeAllFiles(true);
};

// On all files completed upload
myDropzone4.on("queuecomplete", function (progress) {
  $(id + " .dropzone-upload").css('display', 'none');
});

// On all files removed
myDropzone4.on("removedfile", function (file) {
  if (myDropzone4.files.length < 1) {
    $(id + " .dropzone-upload, " + id + " .dropzone-remove-all").css('display', 'none');
  }
});

I have not found yet a way to get the uploaded data from dropzonejs. I tried to read the file with FileReader but it's not a binary data (correct me if i'm wrong).

I need to process data on myDropzone4.on("addedfile", function (file){}) and return it as a json format if possible.

  • Any documented research effort? – Pochmurnik Mar 11 '20 at 12:16
  • Why not upload the CSV or XLS file, then process the file on the server side? – v25 Mar 11 '20 at 13:48
  • I know it's a possible way but i find it a bit hard to process data without saving it in a directory or reading it directly for file in request.files.getlist("file"): filename = file.filename data=file.readlines() on the server side i can read csv files directly but excel files seems to be encrypted or something when i print result – Louaie Rbiha Mar 11 '20 at 14:10
  • For excel you probably need to use a library like `xlrd` maybe see [this thread](https://stackoverflow.com/questions/22169325/read-excel-file-in-python). – v25 Mar 11 '20 at 14:38
  • Thanks for the help i'll keep trying on the client side, when i hit a dead wall i'll probably switch to that. – Louaie Rbiha Mar 11 '20 at 14:42

1 Answers1

0

I found an answer for it, I just needed to find the input type file.when using dropzone.js either you find the input type file in the html page or in their javascript file, where i found that the input type file was being created with a class to hide this element :

var setupHiddenFileInput = function setupHiddenFileInput() {
                if (_this3.hiddenFileInput) {
                    _this3.hiddenFileInput.parentNode.removeChild(_this3.hiddenFileInput);
                }
                _this3.hiddenFileInput = document.createElement("input");
                _this3.hiddenFileInput.setAttribute("type", "file");
                _this3.hiddenFileInput.setAttribute("id", "123");
                if (_this3.options.maxFiles === null || _this3.options.maxFiles > 1) {
                    _this3.hiddenFileInput.setAttribute("multiple", "multiple");
                }


                // _this3.hiddenFileInput.className = "dz-hidden-input";
}

so i gave it an id and bind an event to the input then i read the file with two functions depends on the format of the file uploaded, for csv files to json :

    function getText(fileToRead) {
    var reader = new FileReader();
    reader.readAsText(fileToRead);
    reader.onload = loadHandler;
    reader.onerror = errorHandler;
}

function loadHandler(event) {
    var csv = event.target.result;
    process(csv);
}

function process(csv) {
    // Newline split
    var lines = csv.split("\n");
    result = [];
    var headers = lines[0].split(",");
    for (var i = 1; i < lines.length - 1; i++) {
        var obj = {};
        //Comma split
        var currentline = lines[i].split(",");
        for (var j = 0; j < headers.length; j++) {
            obj[headers[j]] = currentline[j];
        }
        result.push(obj);
    }
    console.log(result);
}

function errorHandler(evt) {
    if (evt.target.error.name == "NotReadableError") {
        alert("Canno't read file !");
    }
}

Read excel files (xls,xlsx) format to json format:

    var ExcelToJSON = function () {
    this.parseExcel = function (file) {
        var reader = new FileReader();

        reader.onload = function (e) {
            var data = e.target.result;
            var workbook = XLSX.read(data, {
                type: 'binary'
            });
            workbook.SheetNames.forEach(function (sheetName) {
                // Here is your object
                var XL_row_object = XLSX.utils.sheet_to_row_object_array(workbook.Sheets[
                    sheetName]);
                var json_object = JSON.stringify(XL_row_object);
                console.log(JSON.parse(json_object));
                jQuery('#xlx_json').val(json_object);
            })
        };

        reader.onerror = function (ex) {
            console.log(ex);
        };

        reader.readAsBinaryString(file);
    };
};

the event that will detect change on the input, detect file format then use one of those to get the result in a JSON format:

$(document).ready(function () {
    $('input[type="file"]').on('change', function (e) {
        // EXCEL TO JSON
        var files = e.target.files;
        console.log(files)
        var xl2json = new ExcelToJSON();
        xl2json.parseExcel(files[0]);

        var fileName = e.target.files[0].name;
        console.log('The file "' + fileName + '" has been selected.');


        // CSV TO JSON
        var files = e.target.files;
        if (window.FileReader) {
            getText(files[0]);
        } else {
            alert('FileReader are not supported in this browser.');
        }
    });
});

I hope this helps i'm using dropzonejs with keenthemes implementation.