AJAX File upload in CodeIgniter and MVC

Upload a file without leaving the page

I've actually written up a more complete tutorial, which has been published on Nettuts+. You should go and read that instead!

Trying to set up AJAX file uploading within CodeIgniter can be a serious pain. I tried multiple scripts before settling on one that actually worked, so if you're having trouble, keep on reading.

The Failed Attempts

First, I tried Uploadify, which came highly recommended. Stupidly, I tried the new beta (the newest version is always better, right?) which comes with incomplete documentation and lots of bugs. After an hour of fiddling, and finally getting it to sort of work, I decided it didn't really suit my needs. I couldn't point the upload script path to a controller in CodeIgniter, I had to point it to a specific script (i.e., upload.php).

Secondly, I tried Vaulms, which looked promising; it even sort of worked on the first try! However, again, I couldn't get it to point to a controller. CodeIgniter seemed to be stripping out the $_GET stuff. (I'm using the latest reactor release.) I could probably have forced the script to only use the IFRAME $_FILES method, but I thought it might be too much faff.

And The Winner Is...

Finally, I tried PHP Letter AjaxFileUpload. Initially, I was put off by the site, but as they say, don't judge a book by its cover!

The script is a nice simple one; it works off of a native form field, and can be called from anywhere. It does lack some of the bells and whistles of the previous scripts, such as loading progress and multiple uploads (without tinkering), but it suited my needs perfectly.

The Code

So, here's how to implement it. Download the script, and include it in your page. (Obviously including jQuery before it!) Create your form, making sure to place in a form input field.

Now, add in your JS:

$('#form')
    .submit(function(e) {

        e.preventDefault();

        $.ajaxFileUpload({
            url:'/image/upload',
            secureuri:false,
            fileElementId:'image',
            dataType: 'json',
            data    : {
                'title' : $('#title').val()
            },
            success: function (data, status){

                if( data.error != '' ){

                   console.log(data.error);

                }else{

                    console.log(data.msg);
                    // Refresh image list

                }

            },
            error: function (data, status, e){

                console.log(e);

            }
        });
    });

As you can see, we're hijacking the form submit. The params are the same as a normal $.ajax, as all we're doing really is creating an iframe and submitting the form through that. Note that I'm sending extra data through (the other field on the form). This means you can submit the entire form at the same time.

Now for the PHP side. Create a controller called image and add a public function called upload. Within that function, place this code:

$error = "";
$msg = "";
$file_element_name = 'image';

if (empty($_POST['title'])) {
	$error = "Please enter a title";
}

if (!$error) {
    $config['upload_path'] = './images/';
    $config['allowed_types'] = 'gif|jpg|png';
    $config['max_size'] = 1024 * 3;
    $config['max_width']  = '1280';
    $config['max_height']  = '1024';

    $this->load->library('upload', $config);

    if (!$this->upload->do_upload($file_element_name)) {
      $error = $this->upload->display_errors('', '');
    } else {
      // Update your DB here
      $msg .= "success";
    }
    // For security reason, we remove the uploaded file
    @unlink($_FILES[$file_element_name]);
}

echo "{";
echo "error: '" . $error . "',\n";
echo "msg: '" . $msg . "'\n";
echo "}";

In this code we do some simple validation on the title, then initialize the upload library and try to upload the file. Note how the input name is passed into the do_upload() method, this is because by default CodeIgniter looks for a field called 'userfile'. (For more on the CodeIgniter Upload class, see the documentation.)

At the end of the controller, we echo out a response in JSON. Technically, we should pass it to a view and do it properly, but for the sake of the tutorial, this is fine.

And there you go, AJAX File Uploading in CodeIgniter!

Want to let me know what you think of AJAX File upload in CodeIgniter and MVC? Why not leave a comment, follow me on Twitter , or !

Comments

comments powered by Disqus