Problem with progress upload bar using XMLHttpRequest in Django - javascript

I have an issue with a progress upload bar in Django when the site is deployed to Heroku, when I click on the upload button the progress bar shows up at 10% then doesn't change or count up to 100%, when the upload is finished, it redirects as instructed in my views.py , the function runs fine locally, but after deploying to heroku it doesn't work. I think it may be something to do with the deployed url using 'https', but not sure and how to fix it? appreciate any help.
custom.js
function progressBar() {
progressBox.classList.remove('not-visible')
cancelBox.classList.remove('not-visible')
const upload_data = input.files[0]
const url = URL.createObjectURL(upload_data)
// console.log(upload_data);
const fd = new FormData()
fd.append('csrfmiddlewaretoken', csrf[0].value)
fd.append('track', upload_data)
$.ajax({
type: 'POST',
enctype: 'multipart/form-data',
data: fd,
beforeSend: function(){
},
xhr: function(){
const xhr = new XMLHttpRequest();
xhr.upload.addEventListener('progress', e=>{
// console.log(e);
if (e.lengthComputable) {
const percent = (e.loaded / e.total) * 100;
// console.log(percent);
progressBox.innerHTML = `<h5 style="text-align:center;">${percent.toFixed(1)}%</h5>
<div class="progress" style="height: 30px;">
<div class="progress-bar bg-success" role="progressbar" style="width: ${percent}%"
aria-valuenow="${percent}" aria-valuemin="0" aria-valuemax="100"></div>
</div>`
}
})
cancelBtn.addEventListener('click', ()=>{
xhr.abort()
progressBox.innerHTML=""
cancelBox.classList.add('not-visible')
window.location.reload();
})
return xhr;
},
success: function(response){
// console.log(response);
uploadForm.reset()
cancelBox.classList.add('not-visible')
},
error: function(error){
console.log(error);
},
cache: false,
contentType: false,
processData: false,
})
}

Related

xhr.abort(); on cancelBtn event

I am working on file upload with progress bar and cancel button to abort uploading.
I have my upload.html as below,
<div class="row">
<div id="alert-box">{{ msg }}</div>
<div id="image-box"></div>
<div class="col-md-2"><label><b>File :</b></label></div>
<div class="col-md-2"><input type="file" id="fileupload" name="fileupload" required multiple></div>
</div><br>
<div class="container">
<div id="progress-box" class="progress not-visible">
<div class="progress-bar bg-success" role="progessbar" >progress</div>
</div>
</div>
<div id="cancel-box" class="not-visible">
<button id="cancel-btn" class="btn btn-danger">cancel</button>
</div>
and main.js as,
const uploadForm = document.getElementById('upload-form')
const input = document.getElementById('fileupload')
const submitBtn = document.getElementById('submitBtn')
const alertBox = document.getElementById('alert-box')
const progressBox = document.getElementById('progress-box')
const cancelBox = document.getElementById('cancel-box')
const cancelBtn = document.getElementById('cancel-btn')
const csrf = document.getElementsByName('csrfmiddlewaretoken')
$("#upload-form").submit(function(e){
$form = $(this)
var formData = new FormData(this);
const media_data = input.files[0];
if(media_data != null){
console.log(media_data);
progressBox.classList.remove("not-visible");
cancelBox.classList.remove("not-visible");
}
$.ajax({
type: 'POST',
url:'/',
data: formData,
dataType: 'json',
beforeSend: function(){
},
xhr:function(){
const xhr = new window.XMLHttpRequest();
xhr.upload.addEventListener('progress', e=>{
if(e.lengthComputable){
const percentProgress = (e.loaded/e.total)*100;
console.log(percentProgress);
progressBox.innerHTML = `<div class="progress-bar progress-bar-striped bg-success"
role="progressbar" style="width: ${percentProgress}%" aria-valuenow="${percentProgress}" aria-valuemin="0"
aria-valuemax="100"></div>`
}
})
cancelBtn.addEventListener('click', e=>{
xhr.abort();
console.log("Abort event");
progressBox.innerHTML="";
progressBox.classList.add("not-visible");
cancelBox.classList.add('not-visible');
})
return xhr
},
success: function(response){
console.log(response);
console.log("successfully upload");
progressBox.classList.add("not-visible");
cancelBox.classList.add("not-visible");
uploadForm.reset();
},
error: function(err){
console.log(err);
},
cache: false,
contentType: false,
processData: false,
});
});
I am trying to abort uploading file when some one click on cancel button which appears when file is uploading.
thought it is setting 'not-visible' class to progress bar and cancel button. file still continue to upload.
any thoughts why it is not stop uploading file on xhr.abort() ?
Thanks,
PB.

Ajax method working twice in a button click

The file upload function working on the Upload button click.The function
$("#fuPDFAdd").change(function () {})
file upload change is working two time when click the 'btnUploadAdd' button.
How can avoid this
<div id="divUploadFileAdd">
<form enctype="multipart/form-data" id="frmUplaodFileAdd">
#Html.AntiForgeryToken()
<input id="fuPDFAdd" name="file" type="file" style = "display:none;"/>
<button class="" id="btnUploadAdd" type="button" onclick="test()">Upload</button>
<label id="txtuploadedMsgAdd"> </label>
</form>
</div>
$(document).ready(function () {
$("#fuPDFAdd").change(function () {
console.log("tst1");
var file = this.files[0];
fileName = file.name;
size = file.size;
type = file.type;
if (type.toLowerCase() == "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet") { //I just want pdf files and only want to show
var formData = new FormData($('#frmUplaodFileAdd')[0]);
$.ajax({
url: "UploadFile", //Server script to process data
type: 'POST',
async: false,
xhr: function () { // Custom XMLHttpRequest
var myXhr = $.ajaxSettings.xhr();
if (myXhr.upload) { // Check if upload property exists
myXhr.upload.addEventListener('progress',
progressHandlingFunction, false); // For handling the progress of the upload
}
return myXhr;
},
data: formData,
//Options to tell jQuery not to process data or worry about content-type.
cache: false,
contentType: false,
processData: false,
success: function (data) {
grdStaffAddition.PerformCallback({ transStatus: "New" });
ShowClientToastr('False', 'False', 'toast-bottom-right', 'True', 'success', 'Template migration completed' + data.result, 'CAM - Contract Staff');
}
});
}
else {
ShowClientToastr('False', 'False', 'toast-bottom-right', 'True', 'error', 'Please select xls/xlsx file.', 'CAM - Contract Staff');
}
});
});
function test() {
$("#fuPDFAdd").click();
}
Something like this will work, I did wrap the file upload code to a separate function there, and make it to call this new function from your event listeners.
function uploadTheFile() {
console.log("tst1");
var file = this.files[0];
fileName = file.name;
size = file.size;
type = file.type;
if (type.toLowerCase() == "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet") { //I just want pdf files and only want to show
var formData = new FormData($('#frmUplaodFileAdd')[0]);
$.ajax({
url: "UploadFile", //Server script to process data
type: 'POST',
async: false,
xhr: function() { // Custom XMLHttpRequest
var myXhr = $.ajaxSettings.xhr();
if (myXhr.upload) { // Check if upload property exists
myXhr.upload.addEventListener('progress',
progressHandlingFunction, false); // For handling the progress of the upload
}
return myXhr;
},
data: formData,
//Options to tell jQuery not to process data or worry about content-type.
cache: false,
contentType: false,
processData: false,
success: function(data) {
grdStaffAddition.PerformCallback({
transStatus: "New"
});
ShowClientToastr('False', 'False', 'toast-bottom-right', 'True', 'success', 'Template migration completed' + data.result, 'CAM - Contract Staff');
}
});
} else {
ShowClientToastr('False', 'False', 'toast-bottom-right', 'True', 'error', 'Please select xls/xlsx file.', 'CAM - Contract Staff');
}
}
$("#fuPDFAdd").change(function() {
uploadTheFile();
});
function test() {
uploadTheFile();
}

"Load-Image" Javascript resize image before upload

I'm developing a small function for an image-upload. This image-upload resizes selected pictures on the client and upload the resized image.
This works, but the browser will hang a lot between "resizes-functionality".
This is my code:
function manageImage(file) {
if (!file) return;
var mime = file.type;
var src = URL.createObjectURL(file);
loadImage.parseMetaData(file, function (data) {
var options = { maxWidth: 1920, maxHeight: 1920, canvas: true };
if (data.exif) {
options.orientation = data.exif.get('Orientation');
}
loadImage(file,
function (img, test) {
loaded++;
var formData = new FormData();
formData.append("image", dataURI);
$.ajax({
url: "/URL",
data: formData,
cache: false,
contentType: false,
processData: false,
async: false,
type: "POST",
success: function (resp) {
}
}).error(function () {
}).done(function () {
if (loaded < checkedFiles.length) {
manageImage(files[loaded]);
} else {
//FINISHED
}
});
},
options);
});
}
manageImage(files[0]);
This funcition is recursive, because i had some problems with the iteration (browser-hang, memory and cpu-usage).
Additionally, i'm using this library for EXIF-Data and correct orientation on mobile phones:
https://github.com/blueimp/JavaScript-Load-Image
With one or two selected pictures (e.g. 7MB) it works perfect, but i want to upload maybe 50 pictures.
It would be great if someone can give me a clue?!

ajaxSubmit uploadprogress always return 100

I am trying to make a progress bar to show the user how much of the file is uploaded, I am using ajaxSubmit and uploadprogress function, however this function doesn't update it just gives me 100 and that is it:
Here is my JS code:
function UploadImage(){
$('#new-post-upload-images').ajaxSubmit({
dataType: "json",
beforeSend: function(a,f,o) {
$('input.images').unwrap().css('display','none');
$('#new_post_overlay,#upload_plus,#upload_wrapper .edit-menu-post').remove();
$(".new_post_btn").attr('disabled', true);
$(".load_new_post").show();
},
uploadProgress: function(event, position, total, percentComplete) {
console.log(percentComplete + '%');
},
complete: function(XMLHttpRequest, textStatus) {
var data= XMLHttpRequest.responseText;
var jsonResponse = JSON.parse(data);
$(".load_new_post").hide();
$('#new_post_wrapper').append('<div class="edit-menu-post"><a class="delete dismiss_image dismiss icon-cancel" title="Remove"><span>Delete</span></a><a class="repos-drag icon-drag" title="Reposition"><span>Reposition</span></a></div><div style="width:100%;height:100%;background-repeat: no-repeat;background-size: cover;position: relative;" id="preview"></div>').parent().find('.bg-port').val('0px 0px');
$('#preview').css('background-position', '0 0').css('background-image', 'url(' + jsonResponse[0]["path"] + ')');
var ids = $.map(jsonResponse, function(n){
return n["id"];
});
$('#uploaded_images_ids').val(ids.join("#"));
$(".new_post_btn").attr('disabled', false);
}
});
}
Here is my Ruby and HTML code:
<div id="upload_wrapper">
<%= form_tag(upload_images_path, :multipart => true, method: :post ,id: "new-post-upload-images") do %>
<div class="new_photo_viewport">
<div class="load_new_post" style="340px">
<div><h2>Uploading <%= image_tag("ajax-loader2.gif") %></h2></div>
</div>
<div class="new_post_error edit-menu-post" style="background-color: #fff;">
<span><b>Recommendation:</b> Picture dimensions should be at least 800 x 600 for better quality and the size doesn't exceed 12MB</span>
</div>
<div id="new_post_wrapper" class="new_post_viewport" style="display:block;width:100%;height:100%;">
<div class="add_image_button" id="new_post_overlay">
<span class="icon-camera" id="upload_plus"><br><span>Upload</span></span>
<%= file_field_tag "images[]", type: :file, accept: "image/*" ,class: "images" %>
</div>
</div>
</div>
<% end %>
</div>
Inside beforeSend: function(a,f,o) { add:
a.upload.addEventListener("progress", function(evt){
if (evt.lengthComputable) {
console.log(evt.loaded / evt.total);
}
}, false);
Source: JQuery ajax progress - HTML5
I found the solution for this problem, i had to deploy my code to the server, i was trying it on my localhost that is way it always gave me 100%
try this
$.ajax({
xhr : function() {
var xhr = new window.XMLHttpRequest();
xhr.upload.addEventListener('progress', function(e){
if(e.lengthComputable){
//you can get percent here
var percent_total = Math.round((e.loaded / e.total) * 100);
//then do with your progress bar, i used bootstrap here
$('#theProgressBar').attr('aria-valuenow', percent_total).css('width', percent_total + '%').text(percent_total + '%');
}
});
return xhr;
},
url: url,
data: formdata,
processData: false,
contentType: false,
type: 'POST',
dataType: "json",
success: function (response) {
},
err: function(err){
}
});

uploading file using JavaScript - how to get more frequent onprogress events

I'm using jQuery to upload a photo, and have attached a listener for onprogress events. However even when uploading photos that are a few megabytes, the only onprogress event that gets fired is when its at 100%. I've seen other sites like dropbox and facebook show a much more fluid progress bar. How can I get more frequent updates on the upload progress?
Sample upload Code:
var file = $photoFile.get(0).files[0];
var fileBlob = file && file.slice();
var formData = new FormData();
var title = $photoTitle.val();
formData.append('file', fileBlob);
formData.append('title', title);
$.ajax({
url: '/api/v1/photo/submit',
data: formData,
cache: false,
contentType: false,
processData: false,
type: 'POST',
xhrFields: {
onprogress: function(ev) {
console.info('upload progress', ev);
if (ev.lengthComputable) {
var percentUploaded = Math.floor(ev.loaded * 100 / ev.total);
console.info('Uploaded '+percentUploaded+'%');
// update UI to reflect percentUploaded
} else {
console.info('Uploaded '+ev.loaded+' bytes');
// update UI to reflect bytes uploaded
}
}
}
}).done(function(response) {
// do stuff
}).fail(function() {
// handle error
});
I was able to do this borrowing code from this stackoverflow question.
The key mistake I was making was relying on the onprogress within the xhrFields property of the call to $.ajax. Instead, to get more frequent progress updates I passed a custom XMLHttpRequest using the xhr property:
$.ajax({
url: '/api/v1/photo/submit',
data: formData,
cache: false,
contentType: false,
processData: false,
type: 'POST',
xhr: function() {
var myXhr = $.ajaxSettings.xhr();
if (myXhr.upload) {
myXhr.upload.addEventListener('progress',function(ev) {
if (ev.lengthComputable) {
var percentUploaded = Math.floor(ev.loaded * 100 / ev.total);
console.info('Uploaded '+percentUploaded+'%');
// update UI to reflect percentUploaded
} else {
console.info('Uploaded '+ev.loaded+' bytes');
// update UI to reflect bytes uploaded
}
}, false);
}
return myXhr;
}
}).done(function(response) {
// do stuff
}).fail(function() {
// handle error
});
Warning: This leverages newer web technologies and doesn't work with older browsers, especially IE.

Categories