Solved

Creating A Controller In Ajax File Uploader

Posted on 2012-03-21
2
1,215 Views
Last Modified: 2012-05-27
Hello

I this jQuery plugin working as far as their own demo goes...

http://pixelcone.com/fileuploader/demo/

Apart from "Successfully Uploaded!". I do not know where to make changes so that I can copy the uploaded file (if it is being uploaded) to the final path. Very beginner question.

When I upload any file it returns with "Not Found" because I'm not totally sure where to add what I think is called a "controller", to actually copy the file to the path I want on the server.

Please show me the area of script where I begin working and tell me roughly what I need to add; php file for handling the file copy or should I figure out the javascript to copy the file on the server to the required path?

I tried within this code...
$(function(){
	$('#yourInputFileId').fileUploader({
		autoUpload: false,
		limit: false,
		buttonUpload: '#px-submit',
		buttonClear: '#px-clear',
		selectFileLabel: 'Select files',
		allowedExtension: 'jpg|jpeg|gif|png',
		timeInterval: [1, 2, 4, 2, 1, 5], //Mock percentage for iframe upload
		percentageInterval: [10, 20, 30, 40, 60, 80],
 
		//Callbacks
		onValidationError: function(e) {
 
		},
		onFileChange: function(e, form) {
 
		},
		onFileRemove: function(e) {
 
		},
		beforeUpload: function(e) {
 
		},
		beforeEachUpload: function(form) {
 
		},
		afterEachUpload: function(data, status, formContainer) {
 
		},
		afterUpload: function(formContainer) {
 
		}
	});
});

Open in new window


I'm just not sure how to add a controller, where to do at it. There is a controller shown but I see no where in the plugin where their own controller is in use or how to call it due to lack of experience...

http://pixelcone.com/jquery/ajax-file-upload-script/

Here is the plugin...

/*
*	Class: fileUploader
*	Use: Upload multiple files using jquery
*	Author: John Laniba (http://pixelcone.com)
*	Version: 1.3
*/

(function($) {
	$.fileUploader = {version: '1.3', count: 0};
	$.fn.fileUploader = function(config){

		config = $.extend({}, {
			autoUpload: false,
			limit: false,
			buttonUpload: '#px-submit',
			buttonClear: '#px-clear',
			selectFileLabel: 'Select files',
			allowedExtension: 'jpg|jpeg|gif|png',
			timeInterval: [1, 2, 4, 2, 1, 5], //Mock percentage for iframe upload
			percentageInterval: [10, 20, 30, 40, 60, 80],

			//Callbacks
			onValidationError: null,	//trigger if file is invalid
			onFileChange: function(){},
			onFileRemove: function(){},
			beforeUpload: function(){}, //trigger after the submit button is click: before upload
			beforeEachUpload: function(){}, //callback before each file has been uploaded ::: returns each Form
			afterUpload: function(){},
			afterEachUpload: function(){} //callback after each file has been uploaded

		}, config);

		$.fileUploader.count++;

		//Multiple instance of a FOrm Container
		var pxUploadForm = 'px-form-' + $.fileUploader.count,
		pxWidget = 'px-widget-' + $.fileUploader.count,
		pxButton = 'px-button-' + $.fileUploader.count,
		wrapper = ' \
			<div id="'+ pxWidget +'" class="px-widget ui-widget"> \
				<div class="ui-helper-clearfix"> \
					<div id="'+ pxUploadForm +'-input" class="px-form-input"></div> \
					<div id="'+ pxButton +'" class="px-buttons"></div> \
				</div> \
				<div id="'+ pxUploadForm +'"></div> \
			</div> \
		',
		pxUploadForm = '#' + pxUploadForm,
		pxUploadFormInput = pxUploadForm + '-input',
		pxButton = '#' + pxButton,
		pxWidget = '#' + pxWidget,
		buttonClearId = null,

		itr = 1, //index/itr of file
		isLimit = (config.limit)? true : false,
		limit = parseInt(config.limit),

		e = this, //set e as this
		selector = $(this).selector,
		buttonM = pxButton + ' input, '+ pxButton +' button'; //Accept button as input and as button
		isFile = false, //this is use to hide other inputs in a form
		progress = 0, //percentage of the upload,
		totalForm = 0,
		jqxhr = null, //return object from jquery.ajax,
		timeInterval = config.timeInterval,
		percentageInterval = config.percentageInterval,
		pcount = 0, //progress count to set interval,
		progressTime = null,
		stopUpload = false; //Stop all upload

		if (window.FormData) {
			var isHtml5 = true;
		} else {
			var isHtml5 = false;
		}

		//Wrap all function that is accessable within the plugin
		var px = {

			//Initialize and format data
			init: function(){
				px.form = $(e).parents('form');

				//prepend wrapper markup
				px.form.before(wrapper);

				//Wrap input button
				$(e).wrap('<div class="px-input-button" />');
				px.form.children('.px-input-button').prepend('<span>'+ config.selectFileLabel +'</span>');

				//move upload and clear button into id px_button
				px.form.find(config.buttonUpload + ',' + config.buttonClear).appendTo(pxButton);

				//Transform file input into ui button
				px.form.find('.px-input-button').button({
					icons: {
               			primary: "ui-icon-circle-plus"
            		}
				});
				$(config.buttonUpload, pxButton).button({
					icons: {
               			primary: "ui-icon-arrowthickstop-1-n"
            		}
				});
				$(config.buttonClear, pxButton).button({
					icons: {
               			primary: "ui-icon-circle-close"
            		}
				});

				//clear all form data
				px.clearFormData(px.form);

				px.form.hide();
				this.printForm();

				//Disable button
				$(buttonM).attr('disabled','disabled');
			},

			//Clone, format and append form
			printForm: function(){

				var formId = 'pxupload' + itr,
				iframeId = formId + '_frame';

				$('<iframe name="'+ iframeId +'"></iframe>').attr({
					id: iframeId,
					src: 'about:blank',
					style: 'display:none'
				}).prependTo(pxUploadFormInput);

				px.form.clone().attr({
					id: formId,
					target: iframeId
				}).prependTo(pxUploadFormInput).show();

				//Show only the file input
				px.showInputFile( '#'+formId );

				//This is not good but i left no choice because live function is not working on IE
				$(selector).change(function() {
					if (isHtml5) {
						html5Change(this);
					} else {
						uploadChange($(this));
					}
				});
			},

			//Show only the file input
			showInputFile: function(form) {
				$(pxUploadFormInput).find(form).children().each(function(){
					isFile = $(this).is(':file');
					if (!isFile && $(this).find(':file').length == 0) {
						$(this).hide();
					}
				});
			},
			//Hide file input and show other data
			hideInputFile: function($form) {
				$form.children().each(function(){
					isFile = $(this).is(':file');
					if (isFile || $(this).find(':file').length > 0) {
						$(this).hide();
					} else {
						$(this).show();
					}
				});
			},

			//Validate file
			getFileName: function(file) {

				if (file.indexOf('/') > -1){
					file = file.substring(file.lastIndexOf('/') + 1);
				} else if (file.indexOf('\\') > -1){
					file = file.substring(file.lastIndexOf('\\') + 1);
				}

				return file;
			},

			validateFileName: function(filename) {
				var extensions = new RegExp(config.allowedExtension + '$', 'i');
				if (extensions.test(filename)){
					return filename;
				} else {
					return -1;
				}
			},

			getFileSize: function(file) {
				var fileSize = 0;
				if (file.size > 1024 * 1024) {
					fileSize = (Math.round(file.size * 100 / (1024 * 1024)) / 100).toString() + 'MB';
				} else {
					fileSize = (Math.round(file.size * 100 / 1024) / 100).toString() + 'KB';
				}
				return fileSize;
			},

			//clear form data
			clearFormData: function(form) {
				$(form).find(':input').each(function() {
					if (this.type == 'file') {
						$(this).val('');
					}
				});
			}

		}

		//initialize
		px.init();

		/*
		*	Plugin Events/Method
		*/

		/*
		* Html5 file change
		*/
		function html5Change($this) {
			$.each( $this.files, function(index, file){
				uploadChange(file);
			});

			afterUploadChange();
		}

		/*
		*	Html5 Drag and Drop
		*/
		$.event.props.push('dataTransfer');
		$(pxWidget).bind( 'dragenter dragover', false)
		.bind( 'drop', function( e ) {
			e.stopPropagation();
			e.preventDefault();

			html5Change(e.dataTransfer);

		});

		/*
		*	On Change of upload file
		*/
		function uploadChange($this) {

			var $form = $(pxUploadFormInput + ' #pxupload'+ itr);

			//validate file
			var filename = (isHtml5)? $this.name : px.getFileName( $this.val() );
			if ( px.validateFileName(filename) == -1 ){
				if ($.isFunction(config.onValidationError)) {
					config.onValidationError($this);
				} else {
					alert ('Invalid file!');
				}
				$form.find(':file').val('');
				return false;
			}

			//Limit
			if (limit <= 0) {
				//Your message about exceeding limit

				return false;
			}
			limit = limit - 1;

			//remove disabled attr
			$(buttonM).removeAttr('disabled');

			//remove upload text after uploaded
			$('.upload-data', pxUploadForm).each(function() {
				if ( $(this).find('form').length <= 0 ) {
					$(this).remove();
				}
			});

			//append size of the file after filename
			if (isHtml5) {
				filename += ' (' + px.getFileSize($this) + ')';
			}

			//DIsplay syled markup				
			$(pxUploadForm).append(
				$('<div>').attr({
					'class': 'upload-data pending ui-widget-content ui-corner-all',
					id: 'pxupload'+ itr +'_text'
				})
				.data('formId', 'pxupload'+ itr)
				.append(' \
					<ul class="actions ui-helper-clearfix"> \
						<li title="Upload" class="upload ui-state-default ui-corner-all"> \
							<span class="ui-icon ui-icon-circle-triangle-e"></span> \
						</li> \
						<li title="Delete" class="delete ui-state-default ui-corner-all"> \
							<span class="ui-icon ui-icon-circle-minus"></span> \
						</li> \
					</ul> \
					<span class="filename">'+ filename +'</span> \
					<div class="progress ui-helper-clearfix"> \
						<div class="progressBar" id="progressBar_'+ itr +'"></div> \
						<div class="percentage">0%</div> \
					</div> \
					<div class="status">Pending...</div> \
				')
			);

			//Store input in form
			$form.data('input', $this);

			$form.appendTo(pxUploadForm + ' #pxupload'+ itr +'_text');

			//hide the input file
			px.hideInputFile( $form );

			//increment for printing form
			itr++;

			//print form
			px.printForm();

			//Callback on file Changed
			config.onFileChange($this, $form);

			if (!isHtml5) {
				afterUploadChange();
			}
		}

		/*
		*	After upload change triggers autoupload
		*/
		function afterUploadChange() {

			if (config.autoUpload) {

				//Display Cancel Button
				toogleCancel(true)

				stopUpload = false;
				//Queue and process upload
				uploadQueue();
			}
		}

		/*
		*	Queue Upload and send each form to process upload
		*/
		function uploadQueue() {

			//stop all upload
			if (stopUpload) {
				return;
			}

			totalForm = $(pxUploadForm + ' form').parent('.upload-data').get().length;
			if (totalForm > 0) {
				pendingUpload = $(pxUploadForm + ' form').parent('.upload-data').get(0);
				$form = $(pendingUpload).children('form');

				//before upload
				beforeEachUpload( $form );

				if (isHtml5) {
					//Upload Using Html5 api
					html5Upload( $form );
				} else {

					//upload using iframe
					iframeUpload( $form );
				}
			} else {
				config.afterUpload(pxUploadForm);

				//Revert Button to clear
				toogleCancel(false);
			}
		}

		/*
		*	Process form Upload
		*/
		function html5Upload($form) {
			file = $form.data('input');
			if (file) {
				var fd = new FormData();
				fd.append($form.find(selector).attr('name'), file);
				//get other form input and append to formData
				$form.find(':input').each(function() {
					if (this.type != 'file') {
						fd.append($(this).attr('name'), $(this).val());
					}
				});

				//show progress bar
				$uploadData = $form.parent();
				$uploadData.find('.progress').show();
				$progressBar = $uploadData.find('.progressBar');
				$percentage = $uploadData.find('.percentage');

				//Upload using jQuery AJAX
				jqxhr = $.ajax({
					url: $form.attr('action'),
					data: fd,
					cache: false,
					contentType: false,
					processData: false,
					type: 'POST',
					xhr: function() {
						var req = $.ajaxSettings.xhr();
						if (req) {
							req.upload.addEventListener('progress',function(ev){
								//Display progress Percentage
								progress = Math.round(ev.loaded * 100 / ev.total);
								$percentage.text(progress.toString() + '%');
								$progressBar.progressbar({
									value: progress
								});
							}, false);
						}
						return req;
					}
				})
				.success(function(data) {
					afterEachUpload($form.attr('id'), data );
				})
				.error(function(jqXHR, textStatus, errorThrown) {
					afterEachUpload($form.attr('id'), null, textStatus, errorThrown );
				})
				.complete(function(jqXHR, textStatus) {
					$progressBar.progressbar({
						value: 100
					});
					$percentage.text('100%');

					uploadQueue();
				});
			}

			$form.remove();
		}

		/*
		*	Iframe Upload Process
		*/
		function iframeUpload($form) {

			//show progress bar
			$uploadData = $form.parent();
			$uploadData.find('.progress').show();
			$percentage = $uploadData.find('.percentage');
			$progressBar = $uploadData.find('.progressBar');

			pcount = 0;
			dummyProgress($progressBar, $percentage);

			$form.submit();

			var id = pxWidget + ' #' + $form.attr('id');
			$(id +'_frame').load(function(){

				data = $(this).contents().find('body').html();

				afterEachUpload($form.attr('id'), data);

				clearTimeout ( progressTime );
				progress = 100;
				$percentage.text(progress.toString() + '%');
				$progressBar.progressbar({
					value: progress
				});

				uploadQueue();

			});
		}

		/*
		*	Show the progress bar to the user
		*/
		function dummyProgress($progressBar, $percentage) {

			if (percentageInterval[pcount]) {
				progress = percentageInterval[pcount] + Math.floor( Math.random() * 5 + 1 );
				$percentage.text(progress.toString() + '%');
				$progressBar.progressbar({
					value: progress
				});
			}

			if (timeInterval[pcount]) {
				progressTime = setTimeout(function(){
					dummyProgress($progressBar, $percentage)
				}, timeInterval[pcount] * 1000);
			}

			pcount++;
		}

		/*
		*	before Upload
		*/
		function beforeAllUpload() {
			//trigger before upload callback
			$continue = config.beforeUpload(e, pxButton);
			if ($continue === false) {			
				return false;
			}

			//Show Cancle Button
			toogleCancel(true);

			//process and queue upload
			uploadQueue();
		}

		/*
		* Before Each file is uploaded
		*/
		function beforeEachUpload($form) {

			//trigger before upload callback
			config.beforeEachUpload($form);

			$uploadData = $form.parent();
			$uploadData.find('.status').text('Uploading...');
			$uploadData.removeClass('pending').addClass('uploading');
			$uploadData.find('.delete').removeClass('delete').addClass('cancel').attr('title', 'Cancel');
		}

		/*
		* After Each file is uploaded
		*/
		function afterEachUpload(formId, data, status, errorThrown) {

			if (data) {
				data = $('<div>').append(data);
				status = $(data).find('#status').text();
			}

			formId = pxWidget + ' #' + formId;
			$uploadData = $(formId + '_text');

			if (status == 'success'){

				$uploadData.removeClass('uploading').addClass('success');
				$uploadData.children('.status').html( $(data).find('#message').text() );

			} else if (status == 'error'){

				$uploadData.removeClass('uploading').addClass('error');

				//if client side error other display error from backend
				if (errorThrown) {
					$uploadData.children('.status').html( errorThrown );
				} else {
					$uploadData.children('.status').html( $(data).find('#message').text() );
				}

			} else if (status == 'abort') {

				$uploadData.removeClass('uploading').addClass('cancel');

				$uploadData.children('.status').html( 'Cancelled' );
			}

			$uploadData.find('.cancel').removeClass('cancel').addClass('delete').attr('title', 'Delete');

			//hide progress bar
			$uploadData.find('.progress').hide();

			//trigger after each upload
			config.afterEachUpload(data, status, $uploadData);

			$(formId).remove();
			$(formId + '_frame').remove();
		}

		/*
		*	Toggle Cancel/Delete button
		*/
		function toogleCancel(cancel) {

			if (cancel) {
				//store button clear id
				buttonClearId = $(config.buttonClear, pxButton).attr('id');
				//Cancel Button
				$(config.buttonClear, pxButton).attr({ id: 'px-cancel', title: 'Cancel' });
			} else {
				//Clear button
				$('#px-cancel', pxButton).attr({ id: buttonClearId, title: 'Clear' });
			}
		}

		/*
		*	Onlick submit button: start upload
		*/
		$(config.buttonUpload, pxButton).click(function(){

			stopUpload = false;

			beforeAllUpload();
		});

		/*
		* Individual Upload
		*/
		$('.upload', pxUploadForm).live('click', function(){

			$form = $(this).parents('.upload-data').children('form');
			if ($form.length > 0) {

				//Show Cancle Button
				toogleCancel(true);

				//before upload
				beforeEachUpload( $form );

				if (isHtml5) {
					//Upload Using Html5 api
					html5Upload( $form );
				} else {

					//upload using iframe
					iframeUpload( $form );
				}

				stopUpload = true;
			}
		});

		//Button Clear Event
		$(config.buttonClear, pxButton).live('click', function(){
			$(pxUploadForm).fadeOut('slow',function(){
				$(this).empty();
				$(this).show();
				$(pxUploadFormInput).empty();

				itr = 1; //reset iteration
				limit = parseInt(config.limit);

				//print the First form
				px.printForm();

				//disable button
				$(buttonM).attr('disabled','disabled');
			});
		});

		$('.delete', pxUploadForm).live('click', function(){

			limit++;

			var id = pxWidget + ' #' + $(this).parents('.upload-data').data('formId');
			$(id+'_text').fadeOut('slow',function(){
				$(id+'_frame').remove();
				$(this).remove();

				//disable button
				if ($(pxUploadForm).find('form').length <= 1) {
					$(buttonM).attr('disabled','disabled');	
				}
			});

			//on file remove callback
			config.onFileRemove(this);
		});

		/*
		*	Cancel individual upload
		*/
		$('.cancel', pxUploadForm).live('click', function() {
			if (jqxhr) {
				jqxhr.abort();
			}

			if (!isHtml5) {
				$form = $(this).parents('.upload-data').children('form');
				$form.remove();
				afterEachUpload($form.attr('id'), null, 'abort', 'Cancelled');
			}
		});

		/*
		*	Cancel all uploads
		*/
		$('#px-cancel', pxButton).live('click', function(){
			stopUpload = true;
			if (jqxhr) {
				jqxhr.abort();
			}

			$('form', pxUploadForm).each(function(){
				afterEachUpload($(this).attr('id'), null, 'abort', 'Cancelled');
			});

			//Show Clear Button
			toogleCancel(false);
		});

		/* Icons hover */
		$(".px-widget .actions li").live("mouseover mouseout", function(event) {
			if ( event.type == "mouseover" ) {
				$(this).addClass('ui-state-hover');
			} else {
				$(this).removeClass("ui-state-hover");
			}
		});

		return this;
	}
})(jQuery);

Open in new window


The code for further customizing but I could not get it to work. I changed the ID's to match my form and it caused form buttons to stop working. What area of the script should I start with when adding the PHP that will actually copy the file to the server path I want?

jQuery(document).ready(function() {
/** customise this script to configure the media uploader **/
	jQuery('#upload_image_button').click(function() {
	 formfield = jQuery('#upload_image').attr('name');
	 tb_show('', 'media-upload.php?type=image&amp;TB_iframe=true');
	 return false;
	});
	
	window.send_to_editor = function(html) {
	 imgurl = jQuery('img',html).attr('src');
	 jQuery('#upload_image').val(imgurl);
	 tb_remove();
	}
});

Open in new window


Thank you
0
Comment
Question by:Ryan Bayne
2 Comments
 
LVL 108

Accepted Solution

by:
Ray Paseur earned 100 total points
Comment Utility
I may not be able to help much with the javaScript part of things, but I can suggest something on the PHP side.  Try this in the action script at media-upload.php so you can see what the client side is actually sending to the server.  Plug in your email address and this little script can email you the debugging information.
<?php // media-upload.php
error_reporting(E_ALL);
ob_start();
var_dump($_FILES);
var_dump($_GET);
var_dump($_POST);
$msg = ob_get_clean();
mail('You@Your.org', 'Upload vardumps', $msg); 

Open in new window

0
 
LVL 2

Author Comment

by:Ryan Bayne
Comment Utility
I did try that and there was no output and the upload button on my form stopped working. I put this scrip directly above the form however, do you think it would work any different in the header?

I will give it a try in the header but what I'm not totally sure about is the fact this script seems to suggest it is for images rather than any file.

I only want to upload .csv files so I tried using the first part and not using this part without any luck...

	
	window.send_to_editor = function(html) {
	 imgurl = jQuery('img',html).attr('src');
	 jQuery('#upload_image').val(imgurl);
	 tb_remove();
	}
});

Open in new window

0

Featured Post

Better Security Awareness With Threat Intelligence

See how one of the leading financial services organizations uses Recorded Future as part of a holistic threat intelligence program to promote security awareness and proactively and efficiently identify threats.

Join & Write a Comment

Suggested Solutions

This article discusses four methods for overlaying images in a container on a web page
Boost your ability to deliver ambitious and competitive web apps by choosing the right JavaScript framework to best suit your project’s needs.
The viewer will learn how to create and use a small PHP class to apply a watermark to an image. This video shows the viewer the setup for the PHP watermark as well as important coding language. Continue to Part 2 to learn the core code used in creat…
The viewer will learn the basics of jQuery including how to code hide show and toggles. Reference your jQuery libraries: (CODE) Include your new external js/jQuery file: (CODE) Write your first lines of code to setup your site for jQuery…

728 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

10 Experts available now in Live!

Get 1:1 Help Now