I am using jquery.filedrop.js to create a HTML5 drop box for users. Currently I have it working about 2/3s the way I want it to.

The company does yearly conferences, and I have a file path 'file/path/to/conferencefiles' where I save media (docs, images, vids, etc) based on the YEAR of the conference. I also have additional folders in the conference year folder for the various types of media (I use mimetype and a switch to figure that out).

The problem I'm having is telling the javascript what year to save the files to. For example, suppose there's a folder called '2011' with the audio, video, docs, and images sub folders (this folder and the subfolders were created in a previous step along with a database entry for this particular conference). Based on a database query on the "conferences.php" page which creates a variable for the year of the conference, I need to send that variable into the javascript so that it knows to save files in THAT year.

Here is some example of what I've got:

The conference.php file (the portion that has the drag n drop)

<?php
$qry2 = $dba->fetch_all_array("SELECT conf_year FROM tbl_conferences WHERE id = '$_POST[confid]'");
               foreach($qry2 AS $val2) {
                    $confyear = $val2['conf_year'];
               }
               echo '<h3>Conference Media</h3>
                     <p>Note: Only certain types of media is allowed.  Forbidden media types will be rejected before submission.  Valid media types are:<br /><br />
                     Documents and Text
                     <blockquote>doc, docx, pdf, xls, xlsx, txt, rtf</blockquote>
                     Images
                     <blockquote>jpg (jpeg), png, gif, tif (tiff)</blockquote>
                     Audio
                     <blockquote>mp3</blockquote>
                     Video
                     <blockquote>flv (recommended), fla, rma, wmv (NOT recommended), mp4, avi</blockquote>
                     <p>Also, a file cannot exceed 20 megabytes in size.  If you need to upload a larger file, please contact the Webmaster.</p>';
                     
                     // Drag n Drop Zone
                     echo '
                     <div id="dropbox">
                     <span class="message">Drop files here to upload!</span>
                     </div>
                     <script src="http://code.jquery.com/jquery-1.6.3.min.js"></script>
                     <script src="js/jquery.filedrop.js"></script>
                     <script src="js/script.js"></script> //THIS JS NEEDS TO KNOW THE $confyear!!

                     // end Drag n Drop zone
          }
     }
?>

The process.php file which performs the upload

<?php
session_start();
if(!isset($_SESSION['id'])) {
     die("You cannot access this page!");
}

$upload_dir = '/home/zionde5/public_html/assets/conferences/'; //the YEAR is the subfolder under conferences/ and there are additional folders in there too (which the last function determines)

$allowed_ext = array('jpg','jpeg','png','gif','doc','docx','flv','mp3','mp4'.'xls','xlsx','mov','ppt','pptx','wma'.'swf');


if(strtolower($_SERVER['REQUEST_METHOD']) != 'post'){
	exit_status('Error! Wrong HTTP method!');
}


if(array_key_exists('upload', $_FILES) && $_FILES['upload']['error'] == 0 ){
	$year = $_HTTP_GET_VARS['conf_year'] .'/';
	$fil = $_FILES['upload'];

	if(!in_array(get_extension($fil['name']), $allowed_ext)) {
		exit_status('Only '. implode(',', $allowed_ext) .' files are allowed!');
	}
     
     $folder = chooseFolder($fil['type']);	

	// Move the uploaded file from the temporary 
	// directory to the uploads folder:
	
	if(move_uploaded_file($fil['tmp_name'], $upload_dir . $year . $folder . $fil['name'])) {
		exit_status('File was uploaded successfuly!');
	}
}

exit_status('Something went wrong with your upload!');


// Helper functions

function exit_status($str){
	echo json_encode(array('status'=>$str));
	exit;
}

function get_extension($file_name){
	$ext = explode('.', $file_name);
	$ext = array_pop($ext);
	return strtolower($ext);
}

function chooseFolder($type)
{
     switch($type) {
          // doc/word/excel/powerpoint/text files
          case 'application/pdf':
          case 'vnd.ms-excel':
          case 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet':
          case 'application/vnd.ms-powerpoint':
          case 'application/vnd.openxmlformats-officedocument.presentationml.presentation':
          case 'application/msword':
          case 'application/vnd.openxmlformats-officedocument.wordprocessingml.document':
          case 'txt/plain':
               $folder = 'docs/';
               break;
          // audio files
          case 'audio/mp4':
          case 'audio/mpeg':
          case 'audio/x-ms-wma':
               $folder = 'audio/';
               break;
          // video files
          case 'video/mpeg':
          case 'video/mp4':
          case 'video/quicktime':
          case 'application/x-dvi':
          case 'application/x-shockwave-flash':
               $folder = 'video/';
               break;
          // image files
          case 'image/gif':
          case 'image/jpeg':
          case 'image/pjpeg':
          case 'image/png':
          case 'image/tiff':
               $folder = 'images/';
               break;
          default:
               echo 'Improper file format!!';
               break;
     }
     return $folder;
}
?>

The script.js file that does the ajax and needs the YEAR variable

$(function() {
	
	var dropbox = $('#dropbox'),
		message = $('.message', dropbox);
	
	dropbox.filedrop({
		// The name of the $_FILES entry:
		paramname:'upload',
          		
		maxfiles: 5,
    	maxfilesize: 10,
		url: 'http://blahblahblah.com/_admin/plugins/conf_uploader.php',
		
		uploadFinished:function(i,file,response){
			$.data(file).addClass('done');
			// response is the JSON object that post_file.php returns
		},
		
    	error: function(err, file) {
			switch(err) {
				case 'BrowserNotSupported':
					showMessage('Your browser does not support HTML5 file uploads!');
					break;
				case 'TooManyFiles':
					alert('Too many files! Please select 5 at most!');
					break;
				case 'FileTooLarge':
					alert(file.name+' is too large! Please upload files up to 20mb.');
					break;
				default:
					break;
			}
		},
		
		/*// Called before each upload is started
		beforeEach: function(file){
			if(!file.type.match(/^image\//)) {
				alert('Only the listed filetypes are allowed!');
				
				// Returning false will cause the
				// file to be rejected
				return false;
			}
		},*/
		
		uploadStarted:function(i, file, len){
			createImage(file);
		},
		
		progressUpdated: function(i, file, progress) {
			$.data(file).find('.progress').width(progress);
		}
    	 
	});
	
	var template = '<div class="preview">'+
						'<span class="imageHolder">'+
							'<img />'+
							'<span class="uploaded"></span>'+
						'</span>'+
						'<div class="progressHolder">'+
							'<div class="progress"></div>'+
						'</div>'+
					'</div>'; 
	
	
	function createImage(file){

		var preview = $(template), 
			image = $('img', preview);
			
		var reader = new FileReader();
		
		image.width = 100;
		image.height = 100;
		
		reader.onload = function(e){
			
			// e.target.result holds the DataURL which
			// can be used as a source of the image:
			
			image.attr('src',e.target.result);
		};
		
		// Reading the file as a DataURL. When finished,
		// this will trigger the onload function above:
		reader.readAsDataURL(file);
		
		message.hide();
		preview.appendTo(dropbox);
		
		// Associating a preview container
		// with the file, using jQuery's $.data():
		
		$.data(file,preview);
	}

	function showMessage(msg){
		message.html(msg);
	}

});

The jquery.filedrop.js file (standard jquery)

;(function($) {
  jQuery.event.props.push("dataTransfer");

  var opts = {},
  default_opts = {
    fallback_id: '',
    url: '',
    refresh: 1000,
    paramname: 'userfile',
    maxfiles: 25,           // Ignored if queuefiles is set > 0
    maxfilesize: 10,         // MB file size limit
    queuefiles: 4,          // Max files before queueing (for large volume uploads)
    queuewait: 200,         // Queue wait time if full
    data: {},
    headers: {},
    drop: empty,
    dragEnter: empty,
    dragOver: empty,
    dragLeave: empty,
    docEnter: empty,
    docOver: empty,
    docLeave: empty,
    beforeEach: empty,
    afterAll: empty,
    rename: empty,
    error: function(err, file, i) {
      alert(err);
    },
    uploadStarted: empty,
    uploadFinished: empty,
    progressUpdated: empty,
    speedUpdated: empty
  },
  errors = ["BrowserNotSupported", "TooManyFiles", "FileTooLarge"],
  doc_leave_timer, 
  stop_loop = false, 
  files_count = 0, 
  files;
  
  function empty() {}

  $.fn.filedrop = function(method) {
    var methods = {
      init : function(options) {
        // Already initialized
        if($(this).data('filedrop') != undefined || $(this).data('filedrop') != null)
          return false;
        
        var tb = new filedropInstance(this, options);
        tb.init();
        $(this).data('filedrop',tb);
      },
      
      destroy : function( ) { 
        $(this).data('filedrop').destroy();
        $(this).data('filedrop',null);
      }
    };
    
    if ( methods[method] ) {
      return methods[method].apply( this, Array.prototype.slice.call( arguments, 1 ));
    } else if ( typeof method === 'object' || ! method ) {
      return methods.init.apply( this, arguments );
    } else {
      $.error( 'Method ' +  method + ' does not exist on jQuery.filedrop' );
    }


    function filedropInstance(element, options) {

      this.init = function() {
        opts = $.extend({}, default_opts, options);

        element.bind('drop.filedrop', drop).bind('dragenter.filedrop', dragEnter).bind('dragover.filedrop', dragOver).bind('dragleave.filedrop', dragLeave);
        $(document).bind('drop.filedrop', docDrop).bind('dragenter.filedrop', docEnter).bind('dragover.filedrop', docOver).bind('dragleave.filedrop', docLeave);

        $('#' + opts.fallback_id).bind('change.filedrop', function(e) {
          opts.drop(e);
          files = e.target.files;
          files_count = files.length;
          upload();
        });
      };
      
      this.destroy = function() {
        element.unbind('.filedrop');
        $(document).unbind('.filedrop');
        $('#' + opts.fallback_id).unbind('.filedrop');
      };

      function drop(e) {
        opts.drop(e);
        files = e.dataTransfer.files;
        if (files === null || files === undefined) {
          opts.error(errors[0]);
          return false;
        }
        files_count = files.length;
        upload();
        e.preventDefault();
        return false;
      }

      function getBuilder(filename, filedata, mime, boundary) {
        var dashdash = '--',
            crlf = '\r\n',
            builder = '';

        if (opts.data) {
          var params = $.param(opts.data).split(/&/);

          $.each(params, function() {
            var pair = this.split(/=/, 2);
            var name = decodeURI(pair[0]);
            var val = decodeURI(pair[1]);

            builder += dashdash;
            builder += boundary;
            builder += crlf;
            builder += 'Content-Disposition: form-data; name="' + name + '"';
            builder += crlf;
            builder += crlf;
            builder += val;
            builder += crlf;
          });
        }

        builder += dashdash;
        builder += boundary;
        builder += crlf;
        builder += 'Content-Disposition: form-data; name="' + opts.paramname + '"';
        builder += '; filename="' + filename + '"';
        builder += crlf;

        builder += 'Content-Type: ' + mime;
        builder += crlf;
        builder += crlf;

        builder += filedata;
        builder += crlf;

        builder += dashdash;
        builder += boundary;
        builder += dashdash;
        builder += crlf;
        return builder;
      }

      function progress(e) {
        if (e.lengthComputable) {
          var percentage = Math.round((e.loaded * 100) / e.total);
          if (this.currentProgress != percentage) {

            this.currentProgress = percentage;
            opts.progressUpdated(this.index, this.file, this.currentProgress);

            var elapsed = new Date().getTime();
            var diffTime = elapsed - this.currentStart;
            if (diffTime >= opts.refresh) {
              var diffData = e.loaded - this.startData;
              var speed = diffData / diffTime; // KB per second
              opts.speedUpdated(this.index, this.file, speed);
              this.startData = e.loaded;
              this.currentStart = elapsed;
            }
          }
        }
      }

      // Respond to an upload
      function upload() {

        stop_loop = false;

        if (!files) {
          opts.error(errors[0]);
          return false;
        }

        var filesDone = 0,
            filesRejected = 0;

        if (files_count > opts.maxfiles && opts.queuefiles === 0) {
          opts.error(errors[1]);
          return false;
        }

        // Define queues to manage upload process
        var workQueue = [];
        var processingQueue = [];
        var doneQueue = [];

        // Add everything to the workQueue
        for (var i = 0; i < files_count; i++) {
          workQueue.push(i);
        }

        // Helper function to enable pause of processing to wait
        // for in process queue to complete
        var pause = function(timeout) {
            setTimeout(process, timeout);
            return;
        }

        // Process an upload, recursive
        var process = function() {

              var fileIndex;

              if (stop_loop) return false;

              // Check to see if are in queue mode
              if (opts.queuefiles > 0 && processingQueue.length >= opts.queuefiles) {

                return pause(opts.queuewait);

              } else {

                // Take first thing off work queue
                fileIndex = workQueue[0];
                workQueue.splice(0, 1);

                // Add to processing queue
                processingQueue.push(fileIndex);

              }

              try {
                if (beforeEach(files[fileIndex]) != false) {
                  if (fileIndex === files_count) return;
                  var reader = new FileReader(),
                      max_file_size = 1048576 * opts.maxfilesize;

                  reader.index = fileIndex;
                  if (files[fileIndex].size > max_file_size) {
                    opts.error(errors[2], files[fileIndex], fileIndex);
                    // Remove from queue
                    processingQueue.forEach(function(value, key) {
                      if (value === fileIndex) processingQueue.splice(key, 1);
                    });
                    filesRejected++;
                    return true;
                  }
                  reader.onloadend = send;
                  reader.readAsBinaryString(files[fileIndex]);

                } else {
                  filesRejected++;
                }
              } catch (err) {
                // Remove from queue
                processingQueue.forEach(function(value, key) {
                  if (value === fileIndex) processingQueue.splice(key, 1);
                });
                opts.error(errors[0]);
                return false;
              }

              // If we still have work to do,
              if (workQueue.length > 0) {
                process();
              }

            };

        var send = function(e) {

          var fileIndex = ((typeof(e.srcElement) === "undefined") ? e.target : e.srcElement).index

          // Sometimes the index is not attached to the
          // event object. Find it by size. Hack for sure.
          if (e.target.index == undefined) {
            e.target.index = getIndexBySize(e.total);
          }

          var xhr = new XMLHttpRequest(),
              upload = xhr.upload,
              file = files[e.target.index],
              index = e.target.index,
              start_time = new Date().getTime(),
              boundary = '------multipartformboundary' + (new Date).getTime(),
              builder;

          newName = rename(file.name);
          mime = file.type
          if (typeof newName === "string") {
            builder = getBuilder(newName, e.target.result, mime, boundary);
          } else {
            builder = getBuilder(file.name, e.target.result, mime, boundary);
          }

          upload.index = index;
          upload.file = file;
          upload.downloadStartTime = start_time;
          upload.currentStart = start_time;
          upload.currentProgress = 0;
          upload.startData = 0;
          upload.addEventListener("progress", progress, false);

          xhr.open("POST", opts.url, true);
          xhr.setRequestHeader('content-type', 'multipart/form-data; boundary=' + boundary);
          xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');

          // Add headers
          $.each(opts.headers, function(k, v) {
            xhr.setRequestHeader(k, v);
          });

          xhr.sendAsBinary(builder);

          opts.uploadStarted(index, file, files_count);

          xhr.onload = function() {
            if (xhr.responseText) {
              var now = new Date().getTime(),
                  timeDiff = now - start_time,
                  result = opts.uploadFinished(index, file, jQuery.parseJSON(xhr.responseText), timeDiff);
              filesDone++;

              // Remove from processing queue
              processingQueue.forEach(function(value, key) {
                if (value === fileIndex) processingQueue.splice(key, 1);
              });

              // Add to donequeue
              doneQueue.push(fileIndex);

              if (filesDone == files_count - filesRejected) {
                afterAll();
              }
              if (result === false) stop_loop = true;
            }
          };

        }

        // Initiate the processing loop
        process();

      }

      function getIndexBySize(size) {
        for (var i = 0; i < files_count; i++) {
          if (files[i].size == size) {
            return i;
          }
        }

        return undefined;
      }

      function rename(name) {
        return opts.rename(name);
      }

      function beforeEach(file) {
        return opts.beforeEach(file);
      }

      function afterAll() {
        return opts.afterAll();
      }

      function dragEnter(e) {
        clearTimeout(doc_leave_timer);
        e.preventDefault();
        opts.dragEnter(e);
      }

      function dragOver(e) {
        clearTimeout(doc_leave_timer);
        e.preventDefault();
        opts.docOver(e);
        opts.dragOver(e);
      }

      function dragLeave(e) {
        clearTimeout(doc_leave_timer);
        opts.dragLeave(e);
        e.stopPropagation();
      }

      function docDrop(e) {
        e.preventDefault();
        opts.docLeave(e);
        return false;
      }

      function docEnter(e) {
        clearTimeout(doc_leave_timer);
        e.preventDefault();
        opts.docEnter(e);
        return false;
      }

      function docOver(e) {
        clearTimeout(doc_leave_timer);
        e.preventDefault();
        opts.docOver(e);
        return false;
      }

      function docLeave(e) {
        doc_leave_timer = setTimeout(function() {
          opts.docLeave(e);
        }, 200);
      }

      try {
        if (XMLHttpRequest.prototype.sendAsBinary) return;
        XMLHttpRequest.prototype.sendAsBinary = function(datastr) {
          function byteValue(x) {
            return x.charCodeAt(0) & 0xff;
          }
          var ords = Array.prototype.map.call(datastr, byteValue);
          var ui8a = new Uint8Array(ords);
          this.send(ui8a.buffer);
        }
      } catch (e) {}
        
    } // End of fileDropInstance()
  }; // End of $.fn.filedrop()
})(jQuery);

Any help would be appreciated!!

Recommended Answers

All 4 Replies

Rocky,

<script src="http://code.jquery.com/jquery-1.6.3.min.js"></script>
<script src="js/jquery.filedrop.js"></script>
<script>
var confyear = <%php echo $confyear; %>;
</script>
<script src="js/script.js"></script> //THIS JS now KNOWs THE $confyear!! It is the javascript global variable confyear.

With a little thought, you can avoid using the global namespace if that is important to you. One way to do this would be to write $confyear to the DOM (you may well already do so), then read it from the DOM into javascript when the document has loaded, ie in a window.onload handler or a jQuery $(function(){...}); structure.

Airshow

After thinking this through a bit, I guess I don't have to have this variable passed to the script. I could assign it to a session (since I'm using a session anyway for security) and then just call it in the uploader php script...that may be the easiest way.

Yes, you could do it that way if you are confident the session and the served page will remain in synchronism.

What would happen if a user opened two windows, each looking at different years; would the session keep track? You need to test this scenario.

Airshow

Hi,
I am having an issue with the same plugin. When i replaced the url location with
url: '<?php echo site_url('media/upload_featureimage');?>',
which is the controller/function_name, enabling the file upload in CI....it doesn't work! The progress stops in the middle and the file is not getting uploaded! upload_featureimage function has the exact same code which is in post_file.php Any suggestions?

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.