Hello guys,
i'll try to explain the problem i am facing here. I had searched for many file uploaders with drag and drop interface. I came across something at http://demos.9lessons.info/multiupload/index.php called the multiuploader. I saw the code and it was a bit of nightmare to me as am not so great at jquery and PHP is what i am good at. I am developing an App using Codeigniter and media uploader is an essential part of the app. I am aiming to create a file uploader like WordPress Media Uploader. Now its going is really really difficult to integrate the file uploader with CI through AJAX so just for now i thought of creating the upload.php in a folder called AJAX which i places at the root of the CI files i.e outside the applications/ folder.

Thats the brief landscape of the platform i am working on right now. If you use the above link the files after uploading shows up on the drag and drop area with an onclick event on the blue upload button to upload all the files. i successfully modified the entire layout. Instead of an on click, i made it to upload the files automatically on drag and drop itself and decorated a little bit.

This is the original code in the multiuploader.js

function multiUploader(config){

    this.config = config;
    this.items = "";
    this.all = []
    var self = this;
    var uploadBtn = $('#uploadbtn'),
        defaultUploadBtn = $('#multiUpload');

    uploadBtn.on('click', function(e) {
        e.stopPropagation();
        e.preventDefault();
        //trigger default file upload button
        defaultUploadBtn.click();
    });

    multiUploader.prototype._init = function(){
        if (window.File && 
            window.FileReader && 
            window.FileList && 
            window.Blob) {      
             var inputId = $("#"+this.config.form).find("input[type='file']").eq(0).attr("id");
             document.getElementById(inputId).addEventListener("change", this._read, false);
             document.getElementById(this.config.dragArea).addEventListener("dragover", function(e){ e.stopPropagation(); e.preventDefault(); }, false);
             document.getElementById(this.config.dragArea).addEventListener("drop", this._dropFiles, false);
             document.getElementById(this.config.dragArea).addEventListener("drop", this._submit, false);
             document.getElementById(this.config.form).addEventListener("change", this._submit, false);
        } else
            console.log("Browser supports failed");
    }

    multiUploader.prototype._submit = function(e){
        e.stopPropagation(); e.preventDefault();
        self._startUpload();
    }

    multiUploader.prototype._preview = function(data){
        this.items = data;
        if(this.items.length > 0){
            var html = "";      
            var uId = "";
            for(var i = 0; i<this.items.length; i++){
                uId = this.items[i].name._unique();
                var sampleIcon = '<img src="images/image.png" />';
                var errorClass = "";
                if(typeof this.items[i] != undefined){
                    if(self._validate(this.items[i].type) <= 0) {
                        sampleIcon = '<img src="images/unknown.png" />';
                        errorClass =" invalid";
                    } 
                    html += '<div class="dfiles'+errorClass+'" rel="'+uId+'"><h5>'+sampleIcon+this.items[i].name+'</h5><div id="'+uId+'" class="progress" style="display:none; font-size: 11px">Edit Media</div></div>';
                }
            }
            $("#filelist").append(html);
        }
    }

    multiUploader.prototype._read = function(evt){
        if(evt.target.files){
            self._preview(evt.target.files);
            self.all.push(evt.target.files);
        } else 
            console.log("Failed file reading");
    }

    multiUploader.prototype._validate = function(format){
        var arr = this.config.support.split(",");
        return arr.indexOf(format);
    }

    multiUploader.prototype._dropFiles = function(e){
        e.stopPropagation(); e.preventDefault();
        self._preview(e.dataTransfer.files);
        self.all.push(e.dataTransfer.files);
    }

    multiUploader.prototype._uploader = function(file,f){
        if(typeof file[f] != undefined && self._validate(file[f].type) > 0){
            var data = new FormData();
            var ids = file[f].name._unique();
            data.append('file',file[f]);
            data.append('index',ids);
            $(".dfiles[rel='"+ids+"']").find(".progress").show();
            $.ajax({
                type:"POST",
                url:this.config.uploadUrl,
                data:data,
                cache: false,
                contentType: false,
                processData: false,
                success:function(rponse){
                    $("#"+ids).hide();
                    var obj = $(".dfiles").get();
                    $.each(obj,function(k,fle){
                        if($(fle).attr("rel") == rponse){
//                          alert(rponse);
                    //      $(fle).slideUp("normal", function(){ $(this).remove(); });
                        }
                    });
                    if (f+1 < file.length) {
                        self._uploader(file,f+1);
                    }
                }
            });
        } else
            console.log("Invalid file format - "+file[f].name);
    }

    multiUploader.prototype._startUpload = function(){
        if(this.all.length > 0){
            for(var k=0; k<this.all.length; k++){
                var file = this.all[k];
                this._uploader(file,0);
            }
        }
    }

    String.prototype._unique = function(){
        return this.replace(/[a-zA-Z]/g, function(c){
           return String.fromCharCode((c <= "Z" ? 90 : 122) >= (c = c.charCodeAt(0) + 13) ? c : c - 26);
        });
    }

    this._init();
}

function initMultiUploader(){
    new multiUploader(config);
}

I changed some few lines in it and below given is the modified multiuploader.js file

function multiUploader(config){

    this.config = config;
    this.items = "";
    this.all = []
    var self = this;
    var uploadBtn = $('#uploadbtn'),
        defaultUploadBtn = $('#multiUpload');

    uploadBtn.on('click', function(e) {
        e.stopPropagation();
        e.preventDefault();
        //trigger default file upload button
        defaultUploadBtn.click();
    });

    multiUploader.prototype._init = function(){
        if (window.File && 
            window.FileReader && 
            window.FileList && 
            window.Blob) {      
             var inputId = $("#"+this.config.form).find("input[type='file']").eq(0).attr("id");
             document.getElementById(inputId).addEventListener("change", this._read, false);
             document.getElementById(this.config.dragArea).addEventListener("dragover", function(e){ e.stopPropagation(); e.preventDefault(); }, false);
             document.getElementById(this.config.dragArea).addEventListener("drop", this._dropFiles, false);
             document.getElementById(this.config.dragArea).addEventListener("drop", this._submit, false);
             document.getElementById(this.config.form).addEventListener("change", this._submit, false);
        } else
            console.log("Browser supports failed");
    }

    multiUploader.prototype._submit = function(e){
        e.stopPropagation(); e.preventDefault();
        self._startUpload();
    }

    multiUploader.prototype._preview = function(data){
        this.items = data;
        if(this.items.length > 0){
            var html = "";      
            var uId = "";
            for(var i = 0; i<this.items.length; i++){
                uId = this.items[i].name._unique();
                var sampleIcon = '<img src="images/icons/small/image.png" />';
                var errorClass = "";
                var msg="";
                if(typeof this.items[i] != undefined){
                    if(self._validate(this.items[i].type) <= 0) {
                        sampleIcon = '<img src="images/icons/small/alert.png" />';
                        errorClass =" invalid";
                        msg=" <span style='color: red'>Invalid File </span>";
                    } 
                    var sampleIcon = '';
                //  html += '<div class="dfiles'+errorClass+'" rel="'+uId+'"><div id="'+uId+'" class="progress" style="display:none; font-size: 11px"><a href="#">Edit Media</a></div><h5><b>'+sampleIcon+this.items[i].name+'</b> '+msg+'</h5></div>';
                }
            }
        //  $("#dragAndDropFiles").append(html);
        }
    }

    multiUploader.prototype._read = function(evt){
        if(evt.target.files){
            self._preview(evt.target.files);
            self.all.push(evt.target.files);
        } else 
            console.log("Failed file reading");
    }

    multiUploader.prototype._validate = function(format){
        var arr = this.config.support.split(",");
        return arr.indexOf(format);
    }

    multiUploader.prototype._dropFiles = function(e){
        e.stopPropagation(); e.preventDefault();
        self._preview(e.dataTransfer.files);
        self.all.push(e.dataTransfer.files);
    }

    multiUploader.prototype._uploader = function(file,f){
        if(typeof file[f] != undefined && self._validate(file[f].type) > 0){
            var data = new FormData();
            var ids = file[f].name._unique();
            data.append('file',file[f]);
            data.append('index',ids);
            $(".dfiles[rel='"+ids+"']").find(".progress").show();
            $.ajax({
                type:"POST",
                url:this.config.uploadUrl,
                data:data,
                cache: false,
                contentType: false,
                processData: false,
                success:function(rponse){
                    $("#"+ids).hide();
                    $("#filelist").append(rponse);

                    var obj = $(".dfiles").get();
                    $.each(obj,function(k,fle){
                        if($(fle).attr("rel") == rponse){
                            $(fle).slideUp("normal", function(){ $(this).remove(); });
                        }
                    });
                    if (f+1 < file.length) {
                        self._uploader(file,f+1);
                    }
                }
            });
        } else
            console.log("Invalid file format - "+file[f].name);
    }

    multiUploader.prototype._startUpload = function(){
        alert(this.all.length);
        if(this.all.length > 0){
            for(var k=0; k<this.all.length; k++){
                var file = this.all[k];
                this._uploader(file,0);
            }
        }
    }

    String.prototype._unique = function(){
        return this.replace(/[a-zA-Z]/g, function(c){
           return String.fromCharCode((c <= "Z" ? 90 : 122) >= (c = c.charCodeAt(0) + 13) ? c : c - 26);
        });
    }

    this._init();
}

function initMultiUploader(){
    new multiUploader(config);
}

Now finally..i got the script to work for drag and drop interface and its perfect but am getting repetitions in the filelist it produces, infact it is uploading the files uploaded before again. I can explain....

Upload No.1 : a.png (these are the files i selected)
All the above mentioned files are uploaded and done perfectly.
Upload No.2 : b.png (this is the file i selected while uploading in the second round)

The expected output after the 2nd upload is naturally a.png, b.png right? but the output i am getting is a.png, a.png, b.png. It is showing the previous upload again and again. Can i anyone kindly this script for me please? I literally spent 5 days on this shit. I have already gone nuts. :(

Any help would be much appreciated! Thanks!

Member Avatar for LastMitch

@unikorndesigns

I am aiming to create a file uploader like WordPress Media Uploader. Now its going is really really difficult to integrate the file uploader with CI through AJAX so just for now i thought of creating the upload.php in a folder called AJAX which i places at the root of the CI files i.e outside the applications/ folder.

The code you provided is in javascript I don't see any code related to PHP or in CI? I have Codeigniter on my server but I don't used it much but I think it's best to post this in javascript section since you are trying to modify a open source AJAX uploader on to Codeigniter.

@unikorndesigns,

Mitch is right, you will have to give us the codes for the upload.php as defined in your javascript function url:this.config.uploadUrl

On this upload.php, you will need to make it to check if the file already exist in the upload directory. It must return a response like 'file already exist'.

! Additional Information ONLY, without any commitment for further discussion on my part !
About the codeIgniter issues, although I was always tempted to respond, I don't normally respond to this type of questions because most of the time, the discussion is much bigger than what the poster thought it would be. We can probably help you, but it is not guarantee because it is pretty big of a topic that you must put a lot of efforts into it. You need to be extremely familiar how the MVC frameworks operate. Most frameworks are almost the same.

For example to create a new page or full application, the first step is to add your application file in the controller dir,in the model dir, and finally its own directory in the view directory.

So for example, if we want to create an uploader application, then the uploader.php in the controller file can be something like this..

class Uploader extends CI_Controller {

public function __construct()
{
    parent::__construct();
    ## tell the controller which file to call for this application. In this case it is the model/upload_model.php
    $this->load->model('upload_model');
}
## the method telling the application about the template files to be loaded as needed.

public function index()
{
$data['images'] = $this->upload_model->get_images();
$data['title'] = 'My UPloaded Images';
## add the sitewide header from the template directory
$this->load->view('templates/header', $data);
## load the index template of your application
$this->load->view('uploader/index', $data);
## add the sitewide footer from the template directory
$this->load->view('templates/footer');
}
## put the rest of the methods here as needed by your application. 
## honestly, this is where you put the method for viewing the contents of your site.

In the model directory, I must create a file called upload_model.php, because that is what my sample controller defined.

example of model for the upload_model.php

     class Uploader_model extends CI_Model {

    public function __construct()
    {
     ## if needed, the database connector built-in function or method can be loaded as shown below.
        $this->load->database();
    }

    ## I would begin by getting the images, if I will be showing them to the browser

    public function get_images(){
    ## do it here
    }

    public function set_images(){

    ## do it here

    }

    public function set_uploader(){
    ## this is where you create the uploader restrictions and control, similar to the upload.ph of your script.

    }

    private function insert_toDB(){

    ## you can build your db query to insert images as needed

    }

    public function process_upload(){

    ## since CI have its own validation, you can probably assume that collected data are safe., I strongly suggests to create a simple boolean switch here, before doing so.

    ## if all is well execute the query
    $this->db = self::insert_toDB();
    }

all files related to the views ( meaning, what will the browser can access should be placed in the view directory. example of an upload form in the view..

 <b> uPload Form </b>
 <!-- you can use CI built-in form validation if you want -->
<?php echo validation_errors(); ?>
<!-- the action will be this very same document. equivalent to 'PHP SELF' -->
<?php echo form_open('upload/NameOfThisFile') ?>

    <!-- put the uploader form here -->

put all the js in the template directory or wherever it is feasible to your needs..

@LastMitch: Sorry buddy my bad! I usually have queries related to PHP and so i bookmarked the PHP category of daniweb for easier access :P. I have posted the same in Javascript Columns http://www.daniweb.com/web-development/javascript-dhtml-ajax/threads/444488/ajax-file-uploading-issue#

@veedeoo: I'm thorough with the MVC architecture. I learned while i was familiarising myself with CI. For the time being am just doing the file uploader outside of CI, but surely later on after bug fixing and developing other modules of the app i'll be looking into integrating the upload script with CI. Thanks for the post though. Its really helpful. :D

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.