-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Description
I struggled getting this to work--but finally came up with a solution. I noticed some others struggling with the same, so I figured I clean my code I used up and put it here to offer you for the website FAQ:
To create a percent complete loading bar for PapaParse, you will need to use a worker. Create a worker file that contains:
worker.js
//****Here you should cut and paste the the PapaParse.min.js file or include it with js. I chose to just cut and paste it.
onmessage = function(file) {
var size = file.data.size;
var percent = 0;
Papa.parse(file.data, {
worker: true,
header: true,
step: function(results, parser) {
var progress = results.meta.cursor;
percent = Math.round(progress / size * 100);
//this posts the percentage to to the corresponding worker function in the main .js file
postMessage(percent);
},
complete: function(results){
//I send a '-1' to signal the main.js worker listener the parsing is complete
postMessage(-1);
}
});
}
After you save that .js file somewhere, then write the main .js file that will be included in the webpage:
main.js
//Note: I am using jQuery / Bootstrap--you can optionally use other methods or plain jscript to accomplish this.
//This is my progress bar div I'm changing
$progressBar = $('#file-read-progress-bar');
//Make sure you include the worker file you made here at the top of the main .js file
var myWorker = new Worker('http://www.yoursite.com/your-worker-file-above.js');
//This function is called by the worker.js file you made and is what asynchronously updates the progress bar
myWorker.onmessage = function (message) {
//I use a -1 to signal the completion of the PapaParse step function
if (message.data == -1){
//update progress bar to completed(Note: These are Bootstrap specific changes-- it may differ for you
$progressBar.removeClass('active progress-bar-striped');
$progressBar.addClass('progress-bar-success');
$progressBar.html = 'Successful Load!';
//If we aren't done loading, update the progress bar here
} else {
//This changes the width of the Bootstrap progress bar according to the provided percentage
$progressBar.css('width', e.data[0]+'%');
}
}
//This function activates when an <input type='file'> element is modified/used on the page
function readCSVFileListener(fileInputEvent) {
//Reset the progress bar: This ensures if the user selects another file, it resets the bar back to zero
$progressBar.addClass('active progress-bar-striped');
$progressBar.removeClass('progress-bar-success');
$progressBar.css('width', '0%');
myWorker.postMessage(fileInputEvent.target.files[0]);//This is a single file input--so we only expect the first file in the array
}
//Set the listener up
document.getElementById('csv').addEventListener('change', readCSVFileListener, false);
Create both these files, import the main.js script on the webpage, and add the worker.js to the new Worker(url-to-worker) line in the main.js code.
Assuming your element ids are setup properly, and your css is setup properly--this should work. I will say it is much slower than normal--but I prefer the user-end experience to be more informed and wait longer than have no feedback on what they're doing.
Let me know what you think!