Working with jQuery Ajax File Uploader with Laravel can be relatively simple. However, things can be confusing on both sides when working outside of the regular examples from the site. To start things off, we will work with the basic API and then start making more complex examples through a few articles. So, now let's get moving!
Setting up our project
To take advantage of some best practices, we should grab jQuery Ajax File Uploader from Bower instead of just grabbing the raw source from the github page.
So to start, let's create a bower.json
file with your project's name and the following:
"dependencies": {
"blueimp-file-upload": "~9.4"
}
I like all of my bower dependencies to be in a lib/bower
directory so I usually create a .bowerrc
file with the following:
{
"directory": "lib/bower"
}
And add a .gitignore
file to make sure that these dependencies aren't under source control (we'll want our servers to grab these on their own).
Now in our public
directory, create a js
directory and create to the various files in the lib/bower/blueimp-file-upload/js
.
The most important files to grab will be vendor/jquery.ui.widget.js
, js/jquery.iframe-transport.js
, and js/jquery.fileupload.js
.
In your public/css
directory you may want to make a symlink to the css/jquery.fileupload.css
and css/style.css
files in lib/bower/blueimp-file-upload/css
.
Setting Up the View
For this tutorial, lets setup a route that just returns the upload.basic
view.
To set this up, in our app/routes.php
file add the following:
Route::get('basic', function() {
return View::make('upload.basic');
});
Now lets go into our views directory and create a view upload/basic.php
.
If you are a terminal junkie like me, running
mkdir uploads && wget https://raw.github.com/blueimp/jQuery-File-Upload/master/basic.html -O uploads/basic.php
If you aren't feeling like adventuring into the command line, just copy the contents of that url into a file at app/views/uploads/basic.php
.
Just to make things look good, lets add some padding to the body by adding this to the head of that view we just created
<style>
body {
padding-top: 60px;
}
</style>
Hooking Up The Javascript
For this basic example, we will build an API to respond to our uploads at api/basic
.
So in the view replace the ternary opertation to set var url = 'api/basic';
Now when a file (or files) is selected, an AJAX call will be sent to api/basic
with an array of the files selected in a files
file form input.
Storing the Files
Now that we have the AJAX sending to our server, we need to go ahead and respond to our AJAX call. This is a pretty simple route action, but I will add comments along the way.
Route::post('api/basic', function()
{
// Grab our files input
$files = Input::file('files');
// We will store our uploads in public/uploads/basic
$assetPath = '/uploads/basic';
$uploadPath = public_path($assetPath);
// We need an empty arry for us to put the files back into
$results = array();
foreach ($files as $file) {
// store our uploaded file in our uploads folder
$file->move($uploadPath, $file->getClientOriginalName());
// set our results to have our asset path
$name = $assetPath . '/' . $file->getClientOriginalName();
$results[] = compact('name');
}
// return our results in a files object
return array(
'files' => $results
);
});
This will store all of our photos (this allows multi-file uploads), and then responds back with the relative path to the images that were just uploaded; Now if you upload an image, it should show progress and then list the uploaded files.
Showing an Uploaded Image
It's great to show just a list of the uploaded files, but wouldn't it be better to show that image we just uploaded? Luckily, this is available by just changing a little line.
In the scripts on our uploads.basic view, find the done
function and replace the p
tag with a img
tag.
And we want to change the call to jQuery's text
method with attr
and we will set the src
attribute.
After everything it will look a bit like this:
$('<img/>').attr('src', file.name).appendTo('#files');
Now you can style this any way you want.
This gets us through an implementation of the basic example from jQuery File Uploader. In a future article, we will look at more customized implementations both on the server side and client side.