I have seen all the upload progress bar plugins, widgets, etc. – they all suck. They're either too bulky with too much useless code or they don't work.
What I want to know is where I can read up on how to display an easy upload progress indicator. Most browsers have a status progress bar on them below, but it isn't very professional to use just that when dealing with clients.
How does the browser do it? I want to know the internals of how the browser works with for indicating the status of something uploading so that maybe I can make something using PHP & jquery.
Thanks.
Since you want to use PHP, I'd start with the uploadprogress extension (PHP doesn't, by default, give you any data about until the upload is completed; this extension provides such server-side functionality). Note that it requires PHP 5.2+ and can be picky about configuration options. Also see its commentary and demo and troubleshooting hints). A short overview available in PHP documentation comments.
Using the extension, you can get some stats on the upload; then you can poll the server through AJAX and update some sort of progress bar.
To be a bit more specific:
get an unique identifier for the form, and include it in a hidden field
the upload should run in an IFRAME - some browsers won't allow DOM updates to the same page that is running the upload
poll the server via AJAX (using the identifier to specify which upload you're interested in) and parse the result (IIRC, you'll get something like "bytes_uploaded => 123, content-length=> 1000")
update your progress bar (the way you display it is up to you, I use "x% done" plus a graphical bar)
redirect whole page when form uploaded OK
(Oh, and btw, check PHP's upload_max_filesize and post_max_size settings, as both limit the maximum upload size)
There is no reliable method to get the progress of a file upload using JavaScript. Support for the XMLHttpRequest upload.onprogress event is missing in many browsers, even with HTML5, you will inevitably need to turn to Flash, or another method of file upload.
After asking this question, I eventually settled on using plupload for my uploading needs.
Javascript/Ecmascript cannot mess with native browser functionalitys (which uses C/C++ mostly along with OS APIs which access TCP/UDP sockets.
To display a progressbar with JS you need serverfeedback. That can be accomplished by using a server polling like COMET for instance.
But at this point, it's never that accurate like the browser buildin progressbar. It will change maybe with HTML5 WebSockets.
To have an accurate result, you need a continuous connection. You can fake and gild the client-server request delay, but it's still there. I don't know exactly how Flash handles this issues, but I guess it also does not have connection-oriented stream (Correct me if I'm wrong here).
I know this isnt what you're looking for but I've been using plupload for uploads recently and it seems pretty good plus doesnt rely on flash or html5 exclusively
example:
the url is the proccessing page (php
file)
container = the parent div or form that that the upload button lives in (its really important to set this - there are some example of how you can attach things to certain actions that plupload does. for example below you can see i have attached uploader.start();to the uploader.start(); hook.
you should also be able to see how i've made a custom upload progress bar, by attaching to the upload progress hook
worth asking questions on the forum on the plupload site if you get stuck, they're good at answering them!
$(function(){
//plupload
var uploader = new plupload.Uploader({
runtimes : 'gears,html5,flash',
browse_button : 'pickfiles',
container : 'form_2',
max_file_size : '10mb',
url : '<?php echo SITE_ROOT ?>plupload/upload.php',
//resize : {width : 320, height : 240, quality : 90},
flash_swf_url : '<?php echo SITE_ROOT ?>plupload/js/plupload.flash.swf',
filters : [
{title : "Image files", extensions : "jpg,gif,png"}
]
});
uploader.init();
uploader.bind('FilesAdded', function(up, files) {
uploader.start();
});
uploader.bind('UploadProgress', function(up, file) {
if(file.percent < 100 && file.percent >= 1){
$('#progress_bar div').css('width', file.percent+'%');
}
else{
$('#progress_bar').fadeOut(600);
}
});
Related
I've been working on a project for a couple of Minecraft servers that use Bukkit. I'm trying to create a web page that contains a dynamic map of the servers' worlds, as well as a real-time event update system, where a <div> is updated as events happen on the server. To give a brief outline of how my system works, the Minecraft servers communicate events with a Node.js webserver over the same network via UDP packets, and the Node.js webserver uses these packets to build JavaScript objects containing the event info. The objects are then stored, and passed to Jade whenever the page is requested. Jade takes care of the templating.
What I want to do is update this page dynamically, so that the user doesn't have to refresh the entire page to update the list of events. What I'm trying to implement is something like the Facebook ticker, which updates every time a Facebook friend does something like posting a status, commenting on a post, or 'liking' a post.
In reading this question on SO, I've concluded that I need to use long polling in a PHP script, but I'm not sure of how to integrate PHP with a webserver written almost entirely in Node.js. How could I go about doing this?
EDIT:
I've run into a problem in the clientside code.
This is the script block:
script(src='/scripts/jadeTemplate.js')
script(src='/socket.io/socket.io.js')
script(type='text/javascript')
var socket = io.connect();
socket.on('obj', function(obj) {
var newsItem = document.createElement("item");
jade.render(newsItem, 'objTemplate', { object: obj });
$('#newsfeed').prepend(newsItem);
console.log(obj);
alert(obj);
});
And this is objTemplate.jade:
p #{object}
// That's it.
When the alert() and console.log() are placed at the top of the script, it alerts and logs, but at the bottom, they don't execute (hence, I think it's a problem with either the creation of newsItem, the jade.render(), or the prepend.
If I need to provide any more snippets or files let me know. I'm still tinkering, so I might solve it on my own, but unless I update, I still need help. :)
I'd skip PHP and take a look at socket.io. It uses websockets when possible, but it will fall back to long-polling when necessary, and the client side library is very easy to use.
Whenever your node.js server has a new object ready to go, it will push it to all connected browsers. Use ClientJade to render the object using your template (you may have to break out the relevant part of the main template into its own file), then prepend the generated dom element to your feed.
First, if it isn't this way already, you'll need to break out the relevant part of your jade template into its own file. Call it objTemplate.jade. Then use ClientJade to create a compiled template that can be run in the browser: clientjade objTemplate.jade > jadeTemplate.js. Put jadeTemplate.js in your public js directory.
In your node.js app, you'll have something like this (pseudo-codey):
var io = require('socket.io').listen(httpServer);
listenForUDPPackets(function(obj) {
saveObjSomewhere(obj);
io.sockets.emit('obj', obj);
});
Then on the client, something like this:
<script src="/js/jadeTemplate.js"></script>
<script src="/socket.io/socket.io.js"></script>
<script>
var socket = io.connect();
socket.on('obj', function(obj) {
var newsItem = document.createElement();
jade.render(newsItem, 'objTemplate', obj);
$('#newsFeed').prepend(newsItem);
});
</script>
How can I send an image on my server using AJAX to a remote PHP server which is also mine? I don't know how to send and how to save using PHP. I tried to put the image in an iframe and send its content using AJAX like below but nothing happened as you might guess... It returns a message that show it is receiving some stuff and creates a very small broken image.
...
var url = "www.xyz.com/AJAX.php?content=" + document.getElementById('iframe').contentWindow.document;
...
here is a good example you could use Ajax Image Uploading
Have you had a look at jQuery yet? Its really easy doing ajax calls with it.
For your Image Uploading you might wanna have a look at jquery Forms, it has some sample codes in it here : http://www.malsup.com/jquery/form/#getting-started
I found a bug while using uploadify. When I user the scriptData attribute to pass post information to the script the loader does not work. The script is actually called and the items are uploaded but the loader hangs on 0 %. When you user multiple files it will hang on the first one sometimes on 95% and mostly on 0%.
It looks as tho the files arent uploaded but they are. This is very anoying though, seeing that the user will think their files arent uploaded and wait on the screen. I tried to work around this by just using GET information and putting my extra variables into the actual url in the script: attribute. This also results in the same problem. A simple note is that I am using CodeIgniter for this project so this could be a problem. It would really be helpful if this was fixed but dont know if its gonna happen any time soon.
I checked this problem on multiple browsers and have the same issue. Has anyone here dealt with this. I used to like uploadify but Im begging to start looking for something else
I had this problem, too, and it drove me crazy. It turns out that the script that you're using to handle the upload has to output something - anything - before uploadify will continue. So in your 'script', like upload.php below, make the last line of the script output something at the bottom of the script - even something simple like echo "done";. This will let uploadify know that the script is finished so it can continue.
$('#file_upload').uploadify({
'uploader' : '/js/jquery/uploadify/uploadify.swf',
'script' : '/distributed/ajax/upload.php',
'cancelImg' : '/js/jquery/uploadify/cancel.png',
'folder' : '/distributed/files',
'auto' : true,
'scriptData': { 'request_no':req_no },
'onComplete': function(evt, ID, fileObj, response, data) {
alert("Finished!");
}
}
});
I'm currently following this example for HTML 5 drag and drop. I am hoping to use this to upload the dropped files to a remote FTP server with a php script. However, how do my php script access these dropped files ?
With a regular web form, I can use $_FILES.. But I don't suppose I can use $_FILES for the dropped files..
On the example, the script calls handleFiles function after a drop event
function handleFiles(files) {
var file = files[0];
document.getElementById("droplabel").innerHTML = "Processing " + file.name;
var reader = new FileReader();
// init the reader event handlers
reader.onprogress = handleReaderProgress;
reader.onloadend = handleReaderLoadEnd;
// begin the read operation
reader.readAsDataURL(file);
}
I guessing that I can iterate each element of the array list, and send each element to my php script. As I've mentioned above, how can I send this element from the array list to the php script? JSON ? jQuery POST ?
I am aware that there are various jquery plugins available to achieve this, and I have downloaded a few of them... However I'm just curious to know if I can implement the same thing with this example.
I presume by upload you mean upload it in a ajax operation.
file refer to a File object, which is available for you after the user had drop the file. After that you have two options:
Read the file using FileReader, send the text in xhr as post data (not recommend as it only work with text)
Pass the object to FormData then pass the FormData object to xhr to send the file (Doesn't work with Firefox <= 3.6 though)
Check Mozilla Developer Center document for the usage of these interfaces. I have working projects that use these objects, however there are too much bridging code to be a good walk-through demo. https://github.com/timdream/html5-file-upload
Why not use an open source solution for your problem rather than re-inventing the wheel.
http://plupload.com/
Is pretty much all you will ever need. I use it and it works wonders. Also, it falls back onto html 4 form uploading when a browser cannot handle html5.
You all know the new generation of fancy, mostly Flash-based file uploaders like SWFUpload that can show a progress bar while uploading - a great improvement especially for shaky and low-bandwidth connections.
However, these uploaders all bring their own logic of how to handle uploads on the client side. I am looking for an unobtrusive way to "fancify" existing, classical file uploads, i.e. introducing a progress bar to normal file upload forms.
Due to the architecture of uploading files, this is most likely not possible without some tweaking on the client side.
I am looking for a solution that keeps the tweaking to an absolute minimum, e.g. a component that adds itself to the onsubmit event of a normal form, performs the file upload, displays a nice progress bar, puts the resulting temporary (server side) file path into the form, and submits it.
On the server side, I just have to modify my script to use the file path provided by the flash uploader, instead of $_FILES and consorts, and think about security for a moment.
This is not exactly what all the Flash-based uploaders do: They can use data from a form, but they do not provide possibilities to submit the form as is, what is what I'm looking for. I am looking for a (probably) Flash based upload function taken a step further.
If you use PHP 5.2 and up this file upload progress tutorial by IBM can help you.
This multiple file upload tutorial uses jQuery + AJAX Upload... It uses $_FILES on the server side and will transform a special <div> on the client side to make a <form>. I guess you could tweak it to fit your needs.
If tweaking the last one is too tricky, Uber-Uploader on SourceForge is another option.
There are dozens of open source project covering this topic. Unfortunately this is not something trivial to implement seamlessly (at least in the way you want - otherwise we would have saw this in the good old Netscape days already).
On the bright side, HTML5 will ease this as you can see in this demo and this one.
I hope this helps and good luck with you integration.
We implemented this very simple by installing the PECL extension pecl-uploadprogress and added a simple AJAX callback to the forms:
Generate an upload key:
$upload_id = genUploadKey();
function genUploadKey ($length = 11) {
$charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
for ($i=0; $i < $length; $i++)
$key .= $charset[(mt_rand(0,(strlen($charset)-1)))];
return $key;
}
Create an AJAX callback handler (eg. uploadprogress.php):
extract($_REQUEST);
// servlet that handles uploadprogress requests:
if ($upload_id) {
$data = uploadprogress_get_info($upload_id);
if (!$data)
$data['error'] = 'upload id not found';
else {
$avg_kb = $data['speed_average'] / 1024;
if ($avg_kb<100)
$avg_kb = round($avg_kb,1);
else if ($avg_kb<10)
$avg_kb = round($avg_kb,2);
else $avg_kb = round($avg_kb);
// two custom server calculations added to return data object:
$data['kb_average'] = $avg_kb;
$data['kb_uploaded'] = round($data['bytes_uploaded'] /1024);
}
echo json_encode($data);
exit;
}
// display on completion of upload:
if ($UPLOAD_IDENTIFIER) {
...
Download jQuery and the jQuery.uploadprogress libraries (which also includes the above snippet) and integrate with your form:
<script type="text/javascript" src="jquery.min.js"></script>
<script type="text/javascript" src="jquery.uploadprogress.0.3.js"></script>
<script type="text/javascript">
jQuery(function () {
// apply uploadProgress plugin to form element
// with debug mode and array of data fields to publish to readout:
jQuery('#upload_form').uploadProgress({
progressURL:'uploadprogress.php',
displayFields : ['kb_uploaded','kb_average','est_sec'],
start: function() {
$('.upload-progress').show();
},
success: function() {
$('.upload-progress').hide();
jQuery(this).get(0).reset();
}
});
});
</script>
Add this to your upload form:
<input name="UPLOAD_IDENTIFIER" type="hidden" value="$upload_id" />
That should do the trick. This is extracted from our code base and may not work out-of-the-box. But it should tell you the idea.
jquploader uses the info inside the form, such as the action attribute value as upload script. But i haven't updated it in a while and it lacks all the belts and whistles scripts like uploadify have (which is an excellent script btw). See if it could be a base for you to tweak.
Does the technique used in Uploadify (a jQuery plugin) meet your needs? Demo
How funny, I just saw Simon Willison blog about Plupload, which is a JavaScript library that I think does file upload progress bars (amongst other things).
It uses Flash, Silverlight, or whatever’s available, but I think abstracts all that away from you, so you’re still uploading with a regular HTML form.
You'll have to check the size of the part of the file wich is allready on the Server, then get it on the Client per Ajax where you can paint the progress bar. (Remember to check the size of the hole Data before, to calculate the percantage ;-) )