Upload progress bar using session in PHP 5.4 with codeigniter Upload progress bar using session in PHP 5.4 with codeigniter codeigniter codeigniter

Upload progress bar using session in PHP 5.4 with codeigniter


If you want to do it with only jQuery then i have used jQuery Form Submit Plugin, which will give you the progress and more. As you said in comments you don't need any plugin then follow these steps and implement like the tutorial suggesting.

Lets assume you have controller dashboard and method addRoom is displaying the your html form:

class Dashboard extends CI_Controller {    function addRoom() {        // Detect URI: http://example.com/dashboard/addRoom/upload_file        $upload_req = $this->uri->segment("3");        if( $upload_req == "upload_file" ) {            // Do the file upload Actions        }        // Generate Form        $this->load->view("Generate_view");    }}

View:

<?php     $ar = array("class"=>"form-horizontal");    echo form_open_multipart('dashboard/addRoom/upload_file',$ar); ?> <input type="text" name="fileName"> <input type="file" name="upload"> <input type="submit" value="add"> <?php echo form_close(); ?>

In this case your form is still on the same controller and method even you submit or not.

Update: According to updated answer, please use codeigniter default libraries for Session and File Uploads, In case of JS error, use console tab(Chrome) to debug error, or if you are using firefox then use firebug extension to debug Javascript.


If you just want to show upload progress there are many plugins available to do so, I don't know why you specifically mentioned Session in you title.

Here is a very nice and simple plugin which will work with any PHP framework with ease.

Code Sample

<script>/*jslint unparam: true *//*global window, $ */$(function () {    'use strict';    // Change this to the location of your server-side upload handler:    var url = window.location.hostname === 'blueimp.github.io' ?                '//jquery-file-upload.appspot.com/' : 'server/php/';    $('#fileupload').fileupload({        url: url,        dataType: 'json',        done: function (e, data) {            $.each(data.result.files, function (index, file) {                $('<p/>').text(file.name).appendTo('#files');            });        },        progressall: function (e, data) {            var progress = parseInt(data.loaded / data.total * 100, 10);            $('#progress .progress-bar').css(                'width',                progress + '%'            );        }    }).prop('disabled', !$.support.fileInput)        .parent().addClass($.support.fileInput ? undefined : 'disabled');});</script>

enter image description here


You're missing (I don't see it in your code) that the tutorial in your question declare and use an hidden iframe in the target attribute of the the upload form, this is a way to handle uploads preventing the form page to refresh (the action url will be loaded into the iframe).

google for hidden iframe upload (and eventually for formdata upload which nowadays should be a better way to handle uploads and show progress with few javascript)

here an old example which use the hidden iframe Ajax File Upload Response Handling

update

You should change the code in your view to $arr = array("id"=>"myForm")

Currently I see it is array("id"=>"myform") (all lowercase)

getElementById is case sensitive and you use .getElementById("myForm").onsubmit

When you use some javascript and something isn't working as expected the browser's javascript console is the first place to look, you should see an error like (chrome):

Uncaught TypeError: Cannot set property 'onsubmit' of null

This is because getElementById fail to find an element with id myForm and return null, in the html/DOM it is really named myform.

update

So, I got the thing working, instead of welcome controller I've created a new Upload controller (uppercase because I'm using CI 3 dev, should be easy to adapt it to old versions), below the working files.

The url will be http://your-host/optional-dir/index.php/upload.

application/controllers/Upload.php:

<?phpdefined('BASEPATH') OR exit('No direct script access allowed');class Upload extends CI_Controller {    public function index() {        $this->load->helper(array('form', 'url'));        $this->load->view('upload');    }    function progress() {        session_start();        $key = ini_get("session.upload_progress.prefix") . "myForm";        if (!empty($_SESSION[$key])) {            $current = $_SESSION[$key]["bytes_processed"];            $total = $_SESSION[$key]["content_length"];            echo $current < $total ? ceil($current / $total * 100) : 100;        }  else {            echo 100;        }    }    public function uploads() {        if(!empty($_FILES['images']['name'][0]))  {            //uploadinf file code        }    }}

application/views/upload.php:

<!DOCTYPE html><html>    <head>        <title>upload</title>        <style>            #bar_blank {                border: solid 1px #000;                height: 20px;                width: 300px;            }            #bar_color {                background-color: #006666;                height: 20px;                width: 0px;            }            #bar_blank, #hidden_iframe {                display: none;            }        </style>    </head>    <body>        <?php $arr = array("id"=>"myForm", "target"=>"hidden_iframe");        echo form_open_multipart("upload/uploads",$arr); ?>        <input type="hidden" value="myForm" name="<?php echo ini_get("session.upload_progress.name"); ?>">        <table>            <tr>                <td>file</td>                <td><input type="file" name="images[]" multiple></td>            </tr>            <tr>                <td>name</td>                <td><input type="text" name="naam"></td>            </tr>            <tr>                <td></td>                <td><input type="submit"></td>            </tr>        </table>        <?php echo form_close(); ?>        <iframe id="hidden_iframe" name="hidden_iframe" src="about:blank"></iframe>        <div id="status"></div>        <div id="bar_blank">            <div id="bar_color"></div>        </div>        <?php include_once(dirname(__FILE__).DIRECTORY_SEPARATOR.'upload.js.php'); ?>    </body></html>

./application/views/upload.js.php:

<script>function toggleBarVisibility() {    console.log('toggleBarVisibility');    var e = document.getElementById("bar_blank");    e.style.display = (e.style.display == "block") ? "none" : "block";}function createRequestObject() {    console.log('createRequestObject');    var http;    if (navigator.appName == "Microsoft Internet Explorer") {        http = new ActiveXObject("Microsoft.XMLHTTP");    } else {        http = new XMLHttpRequest();    }    return http;}function sendRequest() {    console.log('sendRequest');    var http = createRequestObject();    http.open("GET", "<?php echo base_url().'index.php/upload/progress' ?>");    http.onreadystatechange = function () { handleResponse(http); };    http.send(null);}function handleResponse(http) {    console.log('handleResponse');    var response;    if (http.readyState == 4) {        response = http.responseText;        document.getElementById("bar_color").style.width = response + "%";        document.getElementById("status").innerHTML = response + "%";        if (response < 100) {            setTimeout("sendRequest()", 1000);        } else {            toggleBarVisibility();            document.getElementById("status").innerHTML = "Done.";        }    }}function startUpload() {    console.log('startUpload');    toggleBarVisibility();    setTimeout("sendRequest()", 1000);}(function () {    console.log('init');    document.getElementById("myForm").onsubmit = startUpload;  //error is here})();</script>

notice

I'm using a raw include_once for convenience, because php base_url is used inside the javascript, probably would be better have a small inline javascript in the view's html which declare a javascript variable with the base_url value then include the static javascript from an assets directory as usual.