So I don't use jQuery for everything, but I do use it for the good stuff such as AJAX, and right now that son of gun is giving me some issues. Below is a code that should change my upload progress bar while of course uploading.
function uploadProgess(){
var info = document.getElementById('infor');
var images = document.getElementsByName('file[]')[0].files;
$.ajax({
beforeSend: function(XMLHttpRequest){
XMLHttpRequest.upload.addEventListener("progress", function(evt){
if (evt.lengthComputable) {
document.getElementById('progress-bar').style.display="block";
var percentComplete = (evt.loaded / evt.total * 100) + '%';
//Do something with upload progress
document.getElementById('progress').style.width = percentComplete;
}
}, false);
},
type: 'POST',
url: "administration.php?mode=styling&part=pics_management",
data:{method:"upload",file:images},
success: function(response) {
info.innerHTML = response;
},
error:function(response){
info.innerHTML = response;
}
}).done(function(){
window.location.href = window.location.href;
});
}
This function is invoked when we click the submit button of the form.
$('#upload_images').click(function(e){
e.preventDefault();
uploadProgess();
});
But i am getting Uncaught TypeError: Illegal invocation jQuery.js:4 not sure what I did to invoke another property or whatever I did that was "illegal" Can someone explain what is wrong in my code?
This worked perfectly for me... Notes are within code for other users
function uploadProgess(){
//cache our "info" popup element
var info = document.getElementById('infor');
//cache our input element
var images = document.getElementsByName('file[]')[0];
//create a new FormData object (HTML5)
var fileData = new FormData();
//append type is upload
fileData.append("type","upload");
//append method is ajax (only allow ajax uploads)
fileData.append("method","ajax");
//get the files from the input element
var files = images.files;
//loop through the files
for(i=0;i<files.length;i++){
//append to the fileData with name of `file[]` and then the files object for each image
fileData.append('file[]',files[i]);
}
//new ajax request
var request = new XMLHttpRequest();
//event listener progress
request.upload.addEventListener('progress',function(event){
if(event.lengthComputable){
//cache the progress bar
var progress = document.getElementById('progress-bar');
//get our percentage
var percent = (Math.round(event.loaded / event.total) * 100) +"%";
//make the progress bar visible
progress.style.display="block";
//recache for the spinning bar inside progress
progress = document.getElementById('progress');
//change it's width to the percentage of upload
progress.style.width = percent;
}
});
//add event for when the progress is done
request.upload.addEventListener('load',function(event){
//cache progress bar
var progress = document.getElementById('progress-bar');
//hide the progress bar
progress.style.display="none";
});
//for errors we'll use the info element but for now console log it
request.upload.addEventListener('error',function(event){
console.log(event);
});
//open the request
request.open("POST","{URL}");
//set the request header for no caching
request.setRequestHeader("Cache-Control","no-cache");
//send the data
request.send(fileData);
}
Related
I have created a PHP upload class that takes a file as input and copies it to the server, this side of the application works fine. My issue that I am having is showing the progress bar updating within a bootstrap modal. The modal shows and I can see the progress bar within the Modal I just don't see the progress bar updating.
I have done the JS code and I have tested that this works, by taking the progress bar HTML out from the modal and placing it on the upload form page and this works fine.
my theory was that maybe the modal is causing the JS to lose context?
$("form").submit(function() {
//$("#loadingModal").modal("show");
$form = $(this);
uploadVideo($form);
});
function uploadVideo($form){
var formdata = new FormData($form[0]); //formelement
var ajax= new XMLHttpRequest();
ajax.upload.addEventListener("progress", function(event){
var percent = (event.loaded /event.total) * 100;
$form.find('.progress-bar').width(percent+'%');
//console.log(percent);
});
//progress completed load event
ajax.addEventListener("load", function(event){
$form.find('.progress-bar');
});
ajax.open("POST", "processing.php");
ajax.send(formdata);
}
If anyone is interested I have resolved this in the end I needed to expose the Modal properties so I added this:
var $el = $("#loadingModal");
I was then able to update the code as follows:
ajax.upload.addEventListener("progress", function(event){
var percent = (event.loaded /event.total) * 100;
$el.find('.progress-bar').width(percent+'%');
//console.log(percent);
});
//progress completed load event
ajax.addEventListener("load", function(event){
$el.find('.progress-bar');
});
I am trying to build a progress bar for multiple files drag and drop upload by combining code from tutorial on multiple files drag and drop uploading and tutorial on progress bar uploading.
Javascript part is:
var dropzone = document.getElementById("dropzone");
function updateProgress(e){
document.getElementById("progress").innerHTML = e.loaded + " of " + e.total;
}
function upload(files){
var formData = new FormData(),
xhr = new XMLHttpRequest(),
x;
for(x = 0; x < files.length; x++){
formData.append("file[]", files[x]);
}
xhr.addEventListener("progress", updateProgress, false);
xhr.open("post", "upload.php");
xhr.send(formData);
}
dropzone.ondrop = function(e){
e.preventDefault();
this.className = "dropzone";
upload(e.dataTransfer.files);
}
dropzone.ondragover = function(){
this.className = "dropzone dragover";
return false;
}
dropzone.ondragleave = function(){
this.className = "dropzone";
return false;
}
And upload.php is simply:
<?php
if(!empty($_FILES["file"]["name"][0]))
foreach($_FILES["file"]["name"] as $position => $name)
move_uploaded_file($_FILES["file"]["tmp_name"][$position], "uploads/".$name);
?>
For start, before making actual progress bar, I just want to show the number of uploaded and total bytes. However, function updateProgress doesn't get called if upload.php echoes nothing and otherwise (e.g. if I add echo "something";) e.loaded and e.total are small numbers of same value, unrelated to file size.
File upload itself works fine, even with large files (few hundred MBs). With large files, I've noticed that function updateProgress is called only once - after the upload is complete.
Why is this event handling behaving like this and how to fix it?
You are setting a progress handler for download, to set one for upload use
xhr.upload.addEventListener("progress", updateProgress, false);
I have a script to show a progress bar for when a user is uploading images. This upload form is within an open fancybox that I want to have closed once the images are finished uploading.
If I use a onclick event for when the user clicks the submit button to close the fancybox, it will not complete the image upload process.
Here is what I have for the progress bar. I'm wondering if there is a way to close fancybox once the progress bar gives the done message?
<script>
$(document).on('submit', 'form[profile-picture-data-remote]', function(e) {
e.preventDefault();
var fd = new FormData(this);
$.ajax({
url: $(this).attr('action'),
xhr: function() {
var xhr = new XMLHttpRequest();
var total = 0;
$.each(document.getElementById('profile-image-upload').files, function(i, file) {
total += file.size;
});
xhr.upload.addEventListener("progress", function(evt) {
var loaded = (evt.loaded / total).toFixed(2)*100;
$('#progress-container').css({
'display': 'block'
});
$('#progress').text('Uploading... ' + loaded + '%');
$('#progress').css({
'width': loaded+'%'
});
}, false);
return xhr;
},
type: 'post',
processData: false,
contentType: false,
data: fd,
success: function(data) {
var div = $('<div id="progress" class="uk-progress-bar" style="width: 100%;">Done!</div>')
$('#progress').replaceWith(div);
// ** IS THERE SOMETHING I CAN DO HERE TO CLOSE FANCYBOX NOW THAT THE IMAGE UPLOAD IS COMPLETE? **
}
});
});
</script>
The command to close fancybox is $.fancybox.close()
If the progress bar is in an IFrame within the fancybox, you'll need to use parent.$.fancybox.close()
Replacing your comment in the success method with the appropriate command should work.
I am trying to upload an image using AJAX. I have the local URL of my image
and I want to pass that image as a file to the web service to upload.
Suppose i have the local file URL as : file:///accounts/1000/shared/camera/IMG_00000322.jpg
Now using AJAX I want to pass this to webservice,
What will be the best way to do this? I also want show the progress while uploading
Using php in server side.
uploadImage : function(myImageUrl,chatId){
var formData = new FormData();
formData.append("chatId", chatId);
formData.append("fileimage", myImageUrl);
$.ajax(
{
type:"POST",
url:"http://suresh.sp.in/butler/public/uploadimage/getimage",
contentType:"image/png",
dataType:"json",
data:formData,
success:function(uploaded){
console.info(uploaded.status);
},
error:function(error){
console.info(error);
}
});
}
I used that snippet on several of my websites, it handles Multiples files upload, drag and drop, and a progress bar.
HTML
You will need a container to drop your batch of files, in our case it will be #output, and a list of files.
JS
First we will push the dataTransfer to jQuery's event and bind the drop event.
$(document).ready(function(){
// We add the dataTransfer special property to our jQuery event
$.event.props.push("dataTransfer");
// We bind events for drag and drop
$('#output').bind({
"dragenter dragexit dragover" : do_nothing,
drop : drop
});
});
// stop event propagation
function do_nothing(evt){
evt.stopPropagation();
evt.preventDefault();
}
Then we build our update progress function
// Progress bar update function
function update_progress(evt,fic) {
var id_tmp=fic.size;
//id_tmp help us keep track of which file is uploaded
//right now it uses the filesize as an ID: script will break if 2 files have the
// same size
if (evt.lengthComputable) {
var percentLoaded = Math.round((evt.loaded / evt.total) * 100);
if (percentLoaded <= 100) {
$('#'+id_tmp+' .percent').css('width', percentLoaded + '%');
$('#'+id_tmp+' .percent').html(percentLoaded + '%');
}
}
}
Last but not least our drop function
function drop(evt){
do_nothing(evt);
var files = evt.dataTransfer.files;
// Checking if there are files
if(files.length>0){
for(var i in files){
// if its really a file
if(files[i].size!=undefined) {
var fic=files[i];
// We add a progress listener
xhr = jQuery.ajaxSettings.xhr();
if(xhr.upload){
xhr.upload.addEventListener('progress', function (e) {
update_progress(e,fic);
},false);
}
provider=function(){ return xhr; };
// We build our FormData object
var fd=new FormData;
fd.append('fic',fic);
// For each file we build and Ajax request
$.ajax({
url:'/path/to/save_fic.php',
type: 'POST',
data: fd,
xhr:provider,
processData:false,
contentType:false,
complete:function(data){
//on complete we set the progress to 100%
$('#'+data.responseText+' .percent').css('width', '100%');
$('#'+data.responseText+' .percent').html('100%');
}
});
// for each file we setup a progress bar
var id_tmp=fic.size;
$('#output').after('<div class="progress_bar loading" id="'+id_tmp+'"><div class="percent">0%</div></div>');
$('#output').addClass('output_on');
// We add our file to the list
$('#output-listing').append('<li>'+files[i].name+'</li>');
}
}
}
}
That method doesn't work in IE9 or below.
Hope it helped!
Source(in french)
Some infos on progress tracking using XMLHttpRequest
Some infos on the datatransfer prop
EDIT:
PHP
From the server side you can handle the files normally using $_FILES etc...
In order to set the progress to 100% in the complete function your php script must echo the filesize.
I am loading external js using $.getScript(url). Now until the js is loaded I want percentage loader (to show how much js is loaded) to be shown. How am I to do this.
$(document).on('click', 'div#play', function(){
$(this).hide();
$('div#stop').css('display', 'block');
$('div#processing_load').show();
var url = 'https://www.gstatic.com/swiffy/v5.4/runtime.js';
$.getScript(url)
.done(function(){
$('div#processing_load').hide();
$('#swiffycontainer').css('display', 'block');
$('.landing-banner').css('display', 'none');
stage = new swiffy.Stage(document.getElementById('swiffycontainer'), swiffyobject);
stage.start();
stage.setBackground(null);
})
})
Here I want to show the loader before done with percentage.Thanks in advance. Any help/suggestion is welcome.
Instead of getScript(), use ajax(), which is more powerful. It also allows you to parse xhr data to set a loading status, I edited your code (untested):
$.ajax({
xhr: function () {
var xhr = new window.XMLHttpRequest();
xhr.addEventListener("progress", function (evt) {
//check if the length of the requested file is computable (if you generate the requested file using php, you require ob_start(); and ob_end_flush();)
if (evt.lengthComputable) {
//Calculate the percentage completed
var percentComplete = Math.floor((evt.loaded / evt.total) * 100) + '%';
//Do something with download progress
$('div#processing_load').show().html(percentComplete);
}
}, false);
return xhr;
},
url: 'https://www.gstatic.com/swiffy/v5.4/runtime.js',
dataType: 'script',
complete: function(xhr) {
//you can use the xhr object to check for response codes
$('div#processing_load').hide();
$('#swiffycontainer').css('display', 'block');
$('.landing-banner').css('display', 'none');
var stage = new swiffy.Stage(document.getElementById('swiffycontainer'), swiffyobject);
stage.start();
stage.setBackground(null);
}
});
I think you can't do it exactly ( show by progress bar)
Why ? Because we don't know that how long time Loading is finished.
But you can use some tips to show progressbar :
You need to know file size and can calculate the internet speed.
time to load = your file size / your internet speed ;
=> show progress bar when you begin to load .
To calculate the speed you can base on
Connection type (2G, 3G, WiFi, wired ) => get its speed
Calculate speed connection at the load time . You can read more in http://stackoverflow.com/questions/4583395/calculate-speed-using-javascript
Using Navigation Timing API: window.performance.*
Finally, Noways to show exactly with progress bar( That depends on networks).