In my previous posts, we discovered How to Use HTML5 File Drag & Drop, Open Files Using JavaScript and Asynchronously Upload Files Using Ajax. In the final part of this series, we cover the most exciting part of the process: graphical progress bars!
File upload progress bars provide essential user feedback but they’ve been notoriously difficult to implement. Until now that is. Both Firefox and Chrome support the XMLHttpRequest2 object which offers a progress event handler. But first, let’s consider how our progress bar will be implemented…
JQuery Upload File plugin provides Multiple file Uploads with progress bar.Works with any server-side platform (Google App Engine, PHP, Python, Ruby on Rails, Java, etc.) that supports standard HTML form file uploads. Asynchronous File Uploads in Rails. Creating a progress bar to track the file uploading progress and display bitrate. Implementing client-side validation.
The HTML5 progress tag
The new
progress tag provides two attributes:
The tag would have been ideal in this demonstration and, although it’s supported in Chrome, it’s only just appeared in Firefox 6. In addition, neither browser offers many styling properties so I dropped it in favor of a standard
p tag. This is appended as a child to a div with the ID “progress”.
Styling the Progress Bar
Our
p tag will show the file name in a bordered box which is 250px in size:
For the green bar itself, I created a graphic which was twice as wide as the progress element (500px). The left 250px is colored and the right 250px is transparent:
This graphic is used as a background image for the progress bar and positioned at “X% 0” where X% indicates the proportion which is REMAINING (not COMPLETED), i.e.
A solid color is applied by setting a class when the upload succeeds or fails:
![]() Ajax File Upload Progress BarImplementing the Progress Bar in JavaScript
We can now modify our UploadFile() function. When a valid JPG file is encountered, we append a new
p tag to the #progress element and add the file name as text:
We now require a “progress” event handler function. This receives an object with .loaded and .total properties — a little math is necessary to calculate the new backgroundPosition:
If you’re familiar with Ajax, you’ll recognise the onreadystatechange event handler. This determines when the upload has completed and styles the progress bar accordingly (sets a class of “success” if the upload was successful):
Finally, we send the file to our PHP server as before:
We finally have a solution which:
Please view the demonstration page, however, note this is hosted on a server without PHP so file uploads will not occur. To test it, please download the files to examine the code and host it on your own server.
I hope you’ve enjoyed this series and are considering how file drag and drop could help your web application.
If you enjoyed reading this post, you’ll love Learnable; the place to learn fresh skills and techniques from the masters. Members get instant access to all of SitePoint’s ebooks and interactive online courses, like Learn HTML5.
A couple of weeks ago I penned an article called Better File Uploads with Dragonfly explaining how to set up Dragonfly – a gem for handling attachments. The post set up a demo app and integrated Dragonfly into, allowing our users to share (upload) their photos.
Today, we’ll explore a bit more about file uploading, such as how to implement asynchronous file uploading with Rails as well as uploading multiple files using AJAX.
We are going to take a look at two solutions: Remotipart and File Upload.
Some other things to be covered in this article:
All this will be done in five iterations. Let’s get started!
The working demo can be found at https://sitepoint-async-upload.herokuapp.com.
The source code is available on GitHub.
Preparing the Project
For this demo I am using Rails 4.1.1 but the same solution can be implemented with Rails 3.
In the first iteration, we will create a new project and integrate Dragonfly into it really quick (for a more detailed guide check out my previous article).
Create a new app without the default testing suite:
Drop some gems into your Gemfile:
Gemfile
dragonfly is the gem that will handle all the uploading magic and dragonfly-s3_data_store will allow us to store images using Amazon S3 (we will need this in production). rack-cache adds a simple caching mechanism for the production environment. bootstrap-sass will equip our app with Twitter Bootstrap. remotipart will be used in the next iteration.
Now hook up Bootstrap’s styles and scripts (don’t forget that, for real apps, pick only the required components):
stylesheets/application.css.scss
javascripts/application.js
Now, run Dragonfly’s generator to create an initializer file:
Open it up and replace the default
datastore settings with these:
config/initializers/dragonfly.rb
For
access_key_id and secret_access_key , you need to register at Amazon and then open up “YourAccount – Security Credentials”, expand the “Access Keys” section, and create a new pair. A bucket can be created using AWS management console.
This key pair should be kept safe, so don’t put it in version control. I’m using Heroku environment variables.
Also if you are on Rails 4, enable
rack-cache for the production environment:
config/environments/production.rb
We are almost done setting up Dragonfly. The last thing to do is to create the model and add the file uploading requirements. Let’s say we want users to upload their photos. Apart from the default fields our
photos table will have these columns:
Great, now run these commands to create and apply the required migration:
On to the model:
models/photo.rb
At this point we are done with Dragonfly. Of course, we will also need a controller and corresponding view. The controller will be dead simple for now:
controllers/photos_controller.rb
As you see, the “New photo” will not only allow to create a new photo, but will also list all uploaded photos.
Php File Upload Progress
The routes:
config/routes.rb
The layout:
layouts/application.html.erb
And the view:
photos/new.html.erb
I am using
render @photos to render all photos using the _photos.html.erb partial, so create it as well: War thunder hack golden eagles no human verification for psn account.
Delta vfd-e series manual pdf. D.1.2 Ladder Diagram Editor – WPLSoft WPLSoft is a program editor of Delta DVP-PLC series and VFD-E series for WINDOWS. Besides general PLC program planning and general WINDOWS editing functions, such as cut, paste, copy, multi-windows, WPLSoft also provides various Chinese/English comment editing and other special functions (e.g.
photos/_photo.html.erb
And, lastly, a bit of styling:
stylesheets/application.css.scss
Phew, now we are done with the first iteration! At this point, launch the server and upload a couple of photos to make sure everything is working.
Making it Asynchronous
Our users can upload their photos, but the page is reloaded each time the form is submitted. How about making it asynchronous so the uploaded photo’s preview shows up instantly? This can be done easily.
You might think that all we need to do is add
remote: true to the form helper, like this:
photos/new.html.erb
But that won’t work because Rails doesn’t know how to send multipart forms asynchronously. Luckily, the solution is simple. Remember, we added
gem 'remotipart', '~> 1.2' to our Gemfile. This gem, created by Steve Schwartz and Greg Leppert, enables AJAX file uploads with Rails 3 and 4 which exactly what we need.
The only thing to do is add a single line to the
application.js file:
javascripts/application.js
And now our app knows kung fu! Pretty awesome, isn’t it?
Well, the controller needs a minor tweak so it responds to AJAX requests:
controllers/photos_controller.rb
Don’t forget to create the corresponding view:
photos/create.js.erb
The
if @photo.new_record? condition actually checks whether the photo was successfully saved (we added some validations, remember?). If it wasn’t, then present the user with a basic alert box displaying the errors.
If the record was saved, use jQuery’s
prepend method to add another element to the #photos-list unordered list. The j method is required because, otherwise, all HTML from the _photo.html.erb partial would be sanitized.
![]()
That’s all! Now, you can try some photos and check whether asynchronous uploading works.
Well, that was the easy part. Let’s move to the third iteration and implement functionality allowing users to upload multiple photos at once, asynchronously.
Uploading Multiple Photos Asynchronously
Create another view and the corresponding controller method so that we don’t mess up the previously written code.
controllers/photos_controller.rb
As you can see, this method is actually the same as the
new . The difference is in the view:
*photos/new_multiple.html.erb
Note that we do not need to provide
remote: true for the form helper in this case. Lastly, set up the route:
config/routes.rb
To allow multiple file uploading, we use the jQuery File Upload plugin, created by Sebastian Tschan. This plugin has numerous options and cool features. I encourage you to check out its documentation.
File Upload Progress Bar Html5
We will also use
jquery-fileupload-rails by Tors Dalid to integrate this plugin into our app. Unfortunately, this gem hasn’t been updated since 2012, so let’s use a forked version instead:
Gemfile
THe File Upload plugin comes in two versions: UI and basic. We are going to implement the basic version, as it provides more control and we can style the form the way we want.
javascripts/application.js
Now, make some modifications to the view:
photos/new_multiple.html.erb
The
multiple: true option tells the file field that the user may choose multiple files by holding the CTRL (or Shift) key.
hard codes the field’s name because, otherwise, Rails will name this field to
and the files will be submitted as an array. We want them to be submitted one by one, and File Upload will take care that. $('#new_photo').fileupload(); equips our form with File Upload’s magic and dataType: 'script' indicates we are expecting javascript in the response.
Also, note that our form has no “Submit” button. This is because as soon as the user selects the files, the form is submitted automatically (you may want to write a short warning message for the users regarding that).
At this point, go upload a couple of photos at once – the controller’s
create method requires no changes! Everything should be working, apart from the author’s name. The photos will be uploaded, but the author field will be empty. This is because File Upload submits only the files by default. To fix this, we need to tweak the script:
photos/new_multiple.html.erb
Here, we are listening for the
fileuploadsubmit event (the list of callbacks is available here) and attaching the author field’s value to the form data.
Adding Client-side Validation and a Progress Bar
We are ready to move to the fourth iteration. Right now, our form is fully functional, but it has some issues:
The solutions are simple: Add a client-side validation and a progress bar.
Let’s start with validation. Tweak the script:
photos/new_multiple.html.erb
We are checking if each file has the correct format. If it does, submit the form using
data.submit(); , otherwise, present the user with an error message. Now, the user will know if the files are the an acceptable format.
On to the progress bar. Bootstrap already provides a nicely styled bar, so let’s use it:
photos/new_multiple.html.erb
We don’t want the progress bar to be displayed until the form is actually submitted, so tweak the styles a bit:
stylesheets/application.css.scss
To track the overall file uploading progress, the script has to listen to the
fileuploadprogressall event, get the number of uploaded bites, and adjust progress bar. Also, the progress bar has to be shown once the uploading starts, complements of the fileuploadstart event. Lastly, the bar should be hidden again after uploading finishes, and fileuploaddone helps in this case.
Here is the modified script:
photos/new_multiple.html.erb
data.loaded gets the number of loaded bytes, whereas data.total contains the total number of bites to be uploaded.
The last neat thing to do is to show the bitrate (upload speed) to the user. This is easy:
photos/new_multiple.html.erb
And the script:
Our form looks pretty awesome and provides useful information to the user. Let’s move on to the fifth and final iteration.
Adding Dropzone
The File Upload plugin provides a way to setup a so-called “Dropzone” – an area where users may drag & drop their files to begin uploading immediately (check out the browser support).
This is a nice alternative to the default file dialog. It feels more natural to just drop some files to be uploaded.
Let’s add a new element to our markup:
photos/new_multiple.html.erb
The script:
photos/new_multiple.html.erb
We can also apply some CSS3 transitions to the drop zone (File Upload’s events will help us here). Here are some styles that you might use:
stylesheets/application.css.scss
Don't lose precious time manually performing tasks like distributing apps, setting up Wi-Fi networks, and making sure devices are secure. Jamf Now centralizes all of this and more for less than what you spend on your daily cup of coffee. Includes Marketing, Scheduling, Billing/Payroll integration, and more. Jamf Now is an on-demand mobile device management solution designed to help you set up, manage and protect your Apple devices with ease. Ignition interlock device models.
I am using some Compass utilities (I am too lazy to specify all the vendor prefixes for the CSS3 attributes), so don’t forget to drop these lines to the Gemfile:
Gemfile
and run
bundle install .
Here are scripts that will take care of animating the dropzone:
photos/new_multiple.html.erb
You can read more about it here.
You can now test out the form and see all this stuff is working. :)
ConclusionFile Upload Progress Bar With Jquery And Php
We’ve taken a look at two solutions for asynchronous file uploading. I hope you’ve found this article interesting and useful.
File Upload Progress
Have you ever tried to implement asynchronous file uploading in your apps? What solutions did you employ? What problems did you face? Share your experience in the comments!
Comments are closed.
|
AuthorWrite something about yourself. No need to be fancy, just an overview. ArchivesCategories |