Upload progress bar inside modal not working when ajax call - javascript

I have page where drag and drop upload works , When drag and dropped it opens a modal which has progress bar. The drag and drop functionality works well. When the file is dropped the modal is opened but the progress bar doesn't seem to increase at all. Even after the success response of the ajax call the the progress bar is still the same.
<div class="modal-body">
<div class="progress">
<div class="bar"></div >
<div class="percent">0%</div >
</div>
<div id="status"></div>
</div>
Here is my Jquery
$("html").on("drop", function(e) {
e.preventDefault();
e.stopPropagation();
$('#myModal').modal('show');
var dt = e.dataTransfer || (e.originalEvent && e.originalEvent.dataTransfer);
var files = e.target.files || (dt && dt.files);
if (files) {
for(var i = 0; i<e.originalEvent.dataTransfer.files.length;i++){
var file_ext = e.originalEvent.dataTransfer.files[i].name.split('.').pop();
console.log(file_ext);
if ((file_ext == 'pdf') || (file_ext == 'docx') || (file_ext == 'txt')) {
console.log('right file');
var resume = e.originalEvent.dataTransfer.files[i];
var resume_name = resume.name;
console.log(resume_name);
var form_data = new FormData();
form_data.append("resume",resume);
var bar = $('.bar');
var percent = $('.percent');
var status = $('#status');
$.ajax({
url : '/resume_upload',
type : 'POST',
headers: {'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')},
mimeType: "multipart/form-data",
data : form_data,
beforeSend: function() {
$('#myModal').modal('show');
status.empty();
var percentVal = '0%';
bar.width(percentVal);
percent.html(percentVal);
},
uploadProgress: function(event, position, total, percentComplete) {
var percentVal = percentComplete + '%';
bar.width(percentVal);
percent.html(percentVal);
},
success : function(data) {
$('#myModal').modal('hide');
console.log(data.msg);
//alert(data.msg);
},
processData : false,
contentType : false,
error : function(xhr ,status ,error){
console.log(xhr);
alert(xhr);
}
});
}
And how do i create multiple progress divs when more than one file is dropped.

Related

Progress Bar in ajax while uploading 2 files or more

Hi Im trying to upload a 2 file or more, my problem is my progress bar will say 100% because of the small file being uploaded first, then its going back to the percent of the large file.. My question is how can I have a same progress if i have many files being uploaded?
$('body').on('change', 'input:file.gallery_images', function(event)
{
event.preventDefault();
var data = new FormData();
data.append('id', $("#id").val());
var count = $(this)[0].files.length;
$.each($(this)[0].files, function(i, file)
{
data.append('userfile', file);
$.ajax(
{
type: "POST",
url: href+path+"/imagens/store",
data: data,
mimeType: 'multipart/form-data',
contentType: false,
cache: false,
processData: false,
dataType: "json",
xhr: function()
{
var _xhr = $.ajaxSettings.xhr();
_xhr.addEventListener('progress', function (event) { }, false);
if (_xhr.upload)
{
_xhr.upload.onprogress = function(event)
{
var percent = 0;
if (event.lengthComputable)
{
var position = event.position || event.loaded;
var total = event.totalSize || event.total;
percent = Math.ceil(position / total * 100);
}
$("#progress-bar").width(percent + '%');
};
}
return _xhr;
},
beforeSend: function()
{
$("#progress").fadeIn('slow');
$("#progress-bar").width('0%');
},
success: function(data)
{
if(data.gallery)
{
if($(".alert").length > 0)
{
$(".alert").hide('slow').remove();
$("#droppable").show('slow');
}
$('.gallery').fadeTo('300', '0.5', function () {
$(this).html($(this).html() + data.gallery).fadeTo('300', '1');
});
}
$("#progress").fadeOut('slow');
}
});
});
});
Ok, first thing I noticed is that you're adding the file to the 'data' variable inside your $.each... but that means the first POST contains the first image, the second POST contains the first and the second, and so on. I think you should this part inside your $.each:
var data = new FormData();
data.append('id', $("#id").val());
Ok, so, to solve your problem: Before sending anything, go through them and sum their size. You'll also need to store the progress for each file individually, so start it as zero:
var sumTotal = 0;
var loaded = [];
for (var i = 0, list = $(this)[0].files; i < list.length; i++) {
sumTotal += list[i].size;
loaded[i] = 0;
}
Inside your onprogress, instead of comparing the event.position with the event.totalSize, you'll store this position on your 'loaded' array, sum all your array, and then compare it to your sumTotal.
loaded[i] = event.position || event.loaded;
var sumLoaded = 0;
for (var j = 0; j < loaded.length; j++) sumLoaded += loaded[j];
percent = Math.ceil(sumLoaded * 100/sumTotal);
;)

jQuery detect refreshing of the page when ajax is in progress and stop reload

I have a script ajax which is launched every 32 seconds sending an ajax request :
setInterval(function() {
var dt = new Date();
var time = dt.getHours() + ":" + dt.getMinutes() + ":" + dt.getSeconds();
console.time("debut ajax");
$.getJSON('http://127.0.0.1:<?php echo $_SERVER['SERVER_PORT']; ?>/order/get_orders', function(data) {
//console.log(data);
if(jQuery.type(data) === "array") {
var id = data[0].id; var starter = data[0].starter; var meal = data[0].meal; var dessert = data[0].dessert; var expenses = data[0].expenses;
var iduser = data[0].log_by; var date = data[0].date;
var server= "<?php echo $this->config->item('server_url'); ?>index.php/account/updateExternal?";
$.ajax({
url: server+"&callback=?",
data: "balance="+expenses+"&starter="+starter+"&meal="+meal+"&dessert="+dessert+"&date="+date+"&id_user="+iduser+"&place=client2",
type: 'POST',
success: function (resp) {
var myObj = $.parseJSON(resp);
$.getJSON("http://127.0.0.1:<?php echo $_SERVER['SERVER_PORT']; ?>/order/update_log?id="+id+"&balance="+myObj.expenses+"&starter="+myObj.starter+"&meal="+myObj.meal+"&dessert="+myObj.dessert+"&id_user="+myObj.id_user, function(data) {
});
},
error: function(e) {
//alert('Error: '+e);
}
});
}
});
console.timeEnd("fin ajax");
}, 32 * 1000);
During this ajax request I need to prevent or stop the page from refreshing. How to do it ?
// Reload the page if the input is onfocusout for some reasons
$(document).ready(function(){
$(function(){
$("#barcode").focus();
$('#mtsg').html('Staff Canteen Software<br />Veuillez placer votre badge pour identification');
});
$( "#barcode" ).focusout(function() {
$(location).attr('href', "http://127.0.0.1:<?php echo $_SERVER['SERVER_PORT']; ?>/");
});
});
///

how to run the following function jquery with a button?

The truth is that very little jquery, and I have the following jquery code with django and what it does is this.
to select the file:
<input id="chunked_upload" type="file" name="the_file">
the following jquery code is automatically executed
<script type="text/javascript">
var md5 = "",
csrf = $("input[name='csrfmiddlewaretoken']")[0].value,
form_data = [{"name": "csrfmiddlewaretoken", "value": csrf}];
function calculate_md5(file, chunk_size) {
var slice = File.prototype.slice || File.prototype.mozSlice || File.prototype.webkitSlice,
chunks = chunks = Math.ceil(file.size / chunk_size),
current_chunk = 0,
spark = new SparkMD5.ArrayBuffer();
function onload(e) {
spark.append(e.target.result); // append chunk
current_chunk++;
if (current_chunk < chunks) {
read_next_chunk();
} else {
md5 = spark.end();
}
};
function read_next_chunk() {
var reader = new FileReader();
reader.onload = onload;
var start = current_chunk * chunk_size,
end = Math.min(start + chunk_size, file.size);
reader.readAsArrayBuffer(slice.call(file, start, end));
};
read_next_chunk();
}
$("#chunked_upload").fileupload({
url: "{% url 'api_chunked_upload' %}",
dataType: "json",
maxChunkSize: 100000, // Chunks of 100 kB
formData: form_data,
add: function(e, data) { // Called before starting upload
$("#messages").empty();
// If this is the second file you're uploading we need to remove the
// old upload_id and just keep the csrftoken (which is always first).
form_data.splice(1);
calculate_md5(data.files[0], 100000); // Again, chunks of 100 kB
data.submit();
},
chunkdone: function (e, data) { // Called after uploading each chunk
if (form_data.length < 2) {
form_data.push(
{"name": "upload_id", "value": data.result.upload_id}
);
}
$("#messages").append($('<p>').text(JSON.stringify(data.result)));
var progress = parseInt(data.loaded / data.total * 100.0, 10);
/*$("#progress").text(Array(progress).join("=") + "> " + progress + "%");*/
$('#progress .progress-bar').css('width',progress + '%');
$('#progress .progress-bar').css('aria-valuenow',progress + '%');
},
done: function (e, data) { // Called when the file has completely uploaded
$.ajax({
type: "POST",
url: "{% url 'api_chunked_upload_complete' %}",
data: {
csrfmiddlewaretoken: csrf,
upload_id: data.result.upload_id,
md5: md5
},
dataType: "json",
success: function(data) {
$("#messages").append($('<p>').text(JSON.stringify(data)));
}
});
},
});
</script>
this code upload the file into several pieces with a progress bar. The problem is that I want the code to run only if I click a button to load and not how.
I tried as follows:
<input id="chunked_upload" type="file" name="the_file">
<button id="enviar">Enviar</button>
<script type="text/javascript">
var md5 = "",
csrf = $("input[name='csrfmiddlewaretoken']")[0].value,
form_data = [{"name": "csrfmiddlewaretoken", "value": csrf}];
function calculate_md5(file, chunk_size) {
var slice = File.prototype.slice || File.prototype.mozSlice || File.prototype.webkitSlice,
chunks = chunks = Math.ceil(file.size / chunk_size),
current_chunk = 0,
spark = new SparkMD5.ArrayBuffer();
function onload(e) {
spark.append(e.target.result); // append chunk
current_chunk++;
if (current_chunk < chunks) {
read_next_chunk();
} else {
md5 = spark.end();
}
};
function read_next_chunk() {
var reader = new FileReader();
reader.onload = onload;
var start = current_chunk * chunk_size,
end = Math.min(start + chunk_size, file.size);
reader.readAsArrayBuffer(slice.call(file, start, end));
};
read_next_chunk();
}
$('button#enviar').click(function(){
$("#chunked_upload").fileupload({
url: "{% url 'api_chunked_upload' %}",
dataType: "json",
maxChunkSize: 100000, // Chunks of 100 kB
formData: form_data,
add: function(e, data) { // Called before starting upload
$("#messages").empty();
// If this is the second file you're uploading we need to remove the
// old upload_id and just keep the csrftoken (which is always first).
form_data.splice(1);
calculate_md5(data.files[0], 100000); // Again, chunks of 100 kB
data.submit();
},
chunkdone: function (e, data) { // Called after uploading each chunk
if (form_data.length < 2) {
form_data.push(
{"name": "upload_id", "value": data.result.upload_id}
);
}
$("#messages").append($('<p>').text(JSON.stringify(data.result)));
var progress = parseInt(data.loaded / data.total * 100.0, 10);
/*$("#progress").text(Array(progress).join("=") + "> " + progress + "%");*/
$('#progress .progress-bar').css('width',progress + '%');
$('#progress .progress-bar').css('aria-valuenow',progress + '%');
},
done: function (e, data) { // Called when the file has completely uploaded
$.ajax({
type: "POST",
url: "{% url 'api_chunked_upload_complete' %}",
data: {
csrfmiddlewaretoken: csrf,
upload_id: data.result.upload_id,
md5: md5
},
dataType: "json",
success: function(data) {
$("#messages").append($('<p>').text(JSON.stringify(data)));
}
});
},
});
})
The problem I have to do with this method is that:
I must first click and then I select the file.
and should be reversed where must first select the file and then click to work.
need councils how to do it please
Create a Button into your template and replace:
data.submit();
by:
$("#SubmitButtonid").off('click').on('click', function () {
data.submit();
});

AJAX drag and drop

I have created an AJAX drag and drop file upload form. But when the upload is complete it shows file upload done. But I want it to be redirected to another page. How can I do this?
This is my code
function sendFileToServer(formData,status)
{
var uploadURL ="upload.php"; //Upload URL
var extraData ={}; //Extra Data.
var jqXHR=$.ajax({
xhr: function()
{
var xhrobj = $.ajaxSettings.xhr();
if (xhrobj.upload)
{
xhrobj.upload.addEventListener('progress', function(event)
{
var percent = 0;
var position = event.loaded || event.position;
var total = event.total;
if (event.lengthComputable)
{
percent = Math.ceil(position / total * 100);
}
status.setProgress(percent);
}, false);
}
return xhrobj;
},
url: uploadURL,
type: "POST",
contentType:false,
processData: false,
cache: false,
data: formData,
success: function(data){
status.setProgress(100);
$("#status1").append("File upload Done<br>");
}
});
status.setAbort(jqXHR);
}
To redirect to another page, use window.location.
window.location = "http://www.yoururl.com";

Rails Flash Notice Via Ajax after completed method

I want to have a flash notice sent back to my view via ajax when my controller successfully completed an uploaded file. However I don't know exactly how to handle the response from the server. What I have below is what I believe is very close to what I want but it's not quite working. Any help would be greatly appreciated. Thank you!
My Controller
def import
begin
Thread.new do
Order.import(params[:file])
ActiveRecord::Base.connection.close
end
rescue
redirect_to root_url, notice: "Invalid CSV file format."
end
format.js { flash.now[:notice] = "Here is my flash notice" }
end
My Ajax Javascript
$(function() {
var bar = $('.bar');
var percent = $('.percent');
var status = $('#status');
$('form').ajaxForm({
beforeSend: function() {
status.empty();
var percentVal = '0%';
bar.width(percentVal);
percent.html(percentVal);
},
uploadProgress: function(event, position, total, percentComplete) {
var percentVal = percentComplete + '%';
bar.width(percentVal);
percent.html(percentVal);
},
complete: function(xhr) {
status.html(xhr); //I think I need to change this but not sure what to
}
});
});
def import
begin
Thread.new do
Order.import(params[:file])
ActiveRecord::Base.connection.close
end
rescue
redirect_to root_url, notice: "Invalid CSV file format."
end
#notice = "Here is my flash notice"
end
$(function() {
var bar = $('.bar');
var percent = $('.percent');
var status = $('#status');
$('form').ajaxForm({
beforeSend: function() {
status.empty();
var percentVal = '0%';
bar.width(percentVal);
percent.html(percentVal);
},
uploadProgress: function(event, position, total, percentComplete) {
var percentVal = percentComplete + '%';
bar.width(percentVal);
percent.html(percentVal);
},
complete: function(response) {
// replace the response in the div which displays notice
status.html(response)
}
});
});

Categories