<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Ajax Upload with jQuery and ColdFusion</title>
<link href="style/style.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="Wrapper">
<h1>Ajax Upload with jQuery and ColdFusion</h1>
<p>Max. image size : 2 mb</p>
<div id="finaloutput"></div>
<div id="finalerroroutput"></div>
<form action="" method="post" enctype="multipart/form-data" id="UploadForm">
<div class='file_upload' id='f1'>
<div id="preview_1" class="preview">
<img id="thumb_1" width="90px" height="90px" src="no-image.gif" border="0">
</div>
<div id="counter_1" class="counter"><span>1</span></div>
<div id="up_1" class="upload">
<input name='attachment_1' type='file' id="attachment_1" class="filefield"/>
<span id="info_1" class="info"></span>
</div>
<div class="clearboth"></div>
</div>
<div id='file_tools'>
<img src='add-file-icon.png' id='add_file' title='Add new input'/>
<img src='delete-icon.png' id='del_file' title='Delete' style="display:none;"/>
</div>
<div id="SubmitButtondiv" style="padding-left:120px;">
<input type="submit" id="SubmitButton" value="Upload" />
</div>
<cfset filecounter = 1 />
<input type="hidden" name="filecounter" id="filecounter" value="<cfoutput>#filecounter#</cfoutput>">
</form>
<div id="newfileslink"><a href="<cfoutput>#CGI.SCRIPT_NAME#</cfoutput>">Add new images</a></div>
<div id="progressbox">
<div id="progressbar"></div>
<div id="statustxt">0%</div>
</div>
</div>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js" type="text/javascript"></script>
<script type="text/javascript" src="js/jquery.form.js"></script>
<script>
$(document).ready(function () {
var progressbox = $('#progressbox');
var progressbar = $('#progressbar');
var statustxt = $('#statustxt');
var submitbutton = $("#SubmitButton");
var myform = $("#UploadForm");
var finaloutput = $("#finaloutput");
var info = $('.info');
var maxfilesize = 2;
var maxfilesizeerror = 'Max upload filesize is 2 mb';
var accept = 'gif|jpg|jpeg|png|bmp';
var accepterror = 'Invalid file';
var completed = '0%';
var preview = $('.preview');
$(myform).ajaxForm({
dataType: 'json',
url: 'processupload.cfc?method=fupload&returnformat=json',
beforeSubmit: validate,
beforeSend: function () { //brfore sending form
submitbutton.attr('disabled', ''); // disable upload button
statustxt.empty();
progressbox.show(); //show progressbar
progressbar.width(completed); //initial value 0% of progressbar
statustxt.html(completed); //set status text
statustxt.css('color', '#000'); //initial color of status text
info.text('');
finaloutput.text('');
finaloutput.removeClass('error');
},
uploadProgress: function (event, position, total, percentComplete) { //on progress
progressbar.width(percentComplete + '%') //update progressbar percent complete
statustxt.html(percentComplete + '%'); //update status text
if (percentComplete > 50) {
statustxt.css('color', '#fff'); //change status text to white after 50%
}
},
complete: function (response) { // on complete
myform.resetForm(); // reset form
submitbutton.removeAttr('disabled'); //enable submit button
progressbox.hide(); // hide progressbar
d = response.responseText;
var d = $.parseJSON(d);
if (jQuery.isArray(d) === true) {
//The response is an array with one line. In js we start to count from 0
//Using response[0]['attribute'] we get the array data
var totalerrors = d[0]['totalerrors'];
var images = d[0]['images'];
var totalsize = d[0]['totalsize'];
var uploadedfiles = d[0]['uploadedfiles'];
var uploadedfiles = parseInt(uploadedfiles);
//var cnt = 0; //uncomment this if you want to change the counter
jQuery.each(images, function (index, value) {
var up = $('#up_' + index); //get the up div using the index
var pr = $('#preview_' + index); //get the preview div using the index
var cn = $('#counter_' + index); //get the counter div
if (value.match("^success")) { //If value strats with success
//cnt++ // add one to counter //uncomment this if you want to change the counter
var i = value.split("_"); //split value here "_"
var value = i[1]; //get the image file after "_"
pr.html('<img src="uploads/thumbs/' + value + '" alt="" width="90" height="90"/>');
//cn.html('<span>' + cnt + '</span>');//uncomment this if you want to change the counter
pr.removeClass('loading');
up.html('<span>Successfully upload</span>').addClass('success');
} else if (value.match("^false")) { //if value starts with false
var i = value.split("_"); //split value here "_"
var value = i[1]; //get the error message after "_"
pr.removeClass('loading');
up.html('<span>' + value + '</span>').addClass('error');
//cn.html('<span>' + cnt + '</span>');
$('#f' + index).delay(4000).slideUp('slow');
}
});
var fs = $("#finaloutput");
fs.addClass('success').html('<span>' + uploadedfiles + ' files have been uploaded successfully.<br>Total upload filesize:' + totalsize + ' mb</span>');
if (totalerrors > 0) {
var errors = d[0]['errors'];
if (jQuery.isArray(errors) === true) {
var fe = $("#finalerroroutput");
fe.addClass('error').html("<ul class='errorlist' id='errorlist'></ul>");
var output = [];
jQuery.each(errors, function (index, value) {
output.push('<li>' + value + '</li>');
});
$('#errorlist').html(output.join(''));
fe.delay(4000).slideUp('slow');
}
}
$('#newfileslink').show();
} else {
var fe = $("#finalerroroutput");
fe.addClass('error').text('There was an error. Please try later or contact with us.');
};
}
}, "json");
function validate(formData, jqForm, options) {
var error = 0;
var fileexists = 0;
var info = $('.info');
var output = $('#output');
output.removeClass('error');
output.text('');
info.text(''); // delete all info
$('.filefield', jqForm).each(function () {
if ($(this).val()) {
fileexists++
var target = $(this).attr('id');
var i = target.split("_");
var id = i[1];
var pid = $('#preview_' + id);
var inf = $('#info_' + id);
var aid = $('#attachment_' + id);
pid.addClass('loading');
if ($.browser.msie && $.browser.version < 10) { //file size validation except for Internet Explorer
//extension
var file = $(this).val();
var file = file.toLowerCase();
if (!eval('file.match(/(?:' + accept + ')$/)')) {
inf.show().text(accepterror); //show error
aid.val(''); // Delete value
pid.removeClass('loading');
error++
inf.delay(4000).slideUp('slow'); //remove error
}
} else {
var myFile = document.getElementById(target);
var filesize = myFile.files[0].size;
var mbfilesize = filesize / (1024 * 1024);
//extension
var file = $(this).val();
var file = file.toLowerCase();
//extension validation
if (!eval('file.match(/(?:' + accept + ')$/)')) {
inf.show().text(accepterror); //show error
aid.val(''); // Delete value
pid.removeClass('loading');
error++
inf.delay(4000).slideUp('slow'); //remove error
}
//filesize validation
else if (mbfilesize > maxfilesize) {
inf.show().text(maxfilesizeerror);
aid.val(''); // Delete value
pid.removeClass('loading');
error++
inf.delay(4000).slideUp('slow'); //remove error
}
}
}
});
if (error) { //If error exists: stop the upload process
$('.preview').removeClass('loading');
return false;
}
if (!fileexists) { //if no file select
$('.preview').removeClass('loading');
alert('Please select a file');
return false;
}
$('#file_tools,#SubmitButtondiv').hide(); //hide buttons
$('.filefield', jqForm).each(function () { //hide inputs without a file
if (!$(this).val()) {
var target = $(this).attr('id');
var i = target.split("_");
var id = i[1];
var divtohide = $('#f' + id);
divtohide.hide();
}
})
}
$('.filefield').live('change', function () { //validate onchange
if ($(this).val()) {
var target = $(this).attr('id');
var i = target.split("_");
var id = i[1];
var aid = $('#attachment_' + id);
var pid = $('#preview_' + id);
var inf = $('#info_' + id);
if ($.browser.msie && $.browser.version < 10) {
//extension
var file = $(this).val();
var file = file.toLowerCase();
//extension validation
if (!eval('file.match(/(?:' + accept + ')$/)')) {
inf.show().text(accepterror); //show error
inf.delay(4000).slideUp('slow'); //remove error
aid.delay(4000).val('');//remove file
}
} else { //file size validation except for Internet Explorer
var myFile = document.getElementById(target);
var filesize = myFile.files[0].size;
var mbfilesize = filesize / (1024 * 1024);
//extension
var file = $(this).val();
var file = file.toLowerCase();
//extension validation
if (!eval('file.match(/(?:' + accept + ')$/)')) {
inf.show().text(accepterror); //show error
inf.delay(4000).slideUp('slow'); //remove error
aid.delay(4000).val('');//remove file
}
//filesize validation
else if (!$.browser.msie && mbfilesize > maxfilesize) {
inf.show().text(maxfilesizeerror);//show error
inf.delay(4000).slideUp('slow'); //remove error
aid.delay(4000).val('');//remove file
}
}
}
});
//script to add - delete file field
var counter = 2;
$('img#add_file').click(function () {
var tmpcounter = parseInt($('#filecounter').val());
var newcounter = tmpcounter + 1;
$('#filecounter').val(newcounter);
$('#file_tools').before('<div class="file_upload" id="f' + counter + '"><div id="preview_' + counter + '" class="preview flleft inline"><img id="thumb_' + counter + '" width="90px" height="90px" src="no-image.gif" border="0"></div><div id="counter_' + counter + '" class="counter"><span>' + counter + '</span></div><div id="up_' + counter + '" class="upload"><input name="attachment_' + counter + '" id="attachment_' + counter + '" type="file" class="filefield"><span id="info_' + counter + '" class="info"></span></div><div class="clearboth"></div></div>');
$('#del_file').fadeIn(0);
counter++;
});
$('img#del_file').click(function () {
var tmpcounter = parseInt($('#filecounter').val());
var newcounter = tmpcounter - 1;
$('#filecounter').val(newcounter);
if (counter == 3) {
$('#del_file').hide();
}
counter--;
$('#f' + counter).remove();
});
});
</script>
</body>
</html>
body {
width:100%;
font-family:Arial, Helvetica, sans-serif;
color:#666;
margin:0;
padding:0;
}
#Wrapper {
width:70%;
margin-right:auto;
margin-left:auto;
margin-top:50px;
background:#EEE;
border:1px solid #E6E6E6;
padding:20px;
}
#progressbox {
border:1px solid #09C;
position:relative;
width:400px;
border-radius:3px;
display:none;
text-align:left;
margin:10px;
padding:1px;
}
#progressbar {
height:20px;
border-radius:3px;
background-color:#033;
width:1%;
}
#statustxt {
top:3px;
left:50%;
position:absolute;
display:inline-block;
color:#000;
}
#newfileslink {
display:none;
padding-left:120px;
}
.clearboth {
clear:both;
}
.info {
line-height:30px;
font-family:Arial;
padding-top:5px;
color:red;
font-size:14px;
}
.success {
line-height:30px;
margin-bottom:10px;
background:#99f099;
border:1px solid #393;
padding:5px;
}
.error {
line-height:30px;
margin-bottom:10px;
background:#f0c6c3;
border:1px solid #c62;
}
div.preview {
display:inline;
float:left;
width:90px;
height:90px;
border:2px dotted #CCC;
}
div.preview.loading {
background:url(../loading.gif)no-repeat 39px 40px;
}
div.preview.loading img {
display:none;
}
#highlight {
margin-bottom:20px;
}
div.file_upload {
min-height:40px;
padding-bottom:5px;
}
#file_tools {
display:inline-block;
min-height:40px;
}
.counter {
display:inline;
float:left;
width:20px;
padding-left:5px;
}
div.counter,div.upload {
display:inline;
float:left;
}
div.upload .filefield,label {
display:block;
}
<cfcomponent>
<cffunction name="init" output="false">
<cfif not isdefined('application.maxsize')>
<cfset variables.maxsize = 2464154 >
<cfelse>
<cfset variables.maxsize = application.maxsize >
</cfif>
<cfif not isdefined('application.bslash')>
<cfset variables.bslash = '\'>
<cfelse>
<cfset variables.bslash = application.bslash>
</cfif>
<cfif not isdefined('application.thumbwidth')>
<cfset variables.thumbwidth = 90 >
<cfelse>
<cfset variables.thumbwidth = application.thumbwidth>
</cfif>
<cfif not isdefined('application.thumbheight')>
<cfset variables.thumbheight = 90 >
<cfelse>
<cfset variables.thumbheight = application.thumbheight>
</cfif>
<cfreturn this>
</cffunction>
<cffunction name="fupload" access="remote" returntype="array" returnformat="json">
<cfargument name="filecounter" required="yes" default="1">
<cfset var totalerrors = 0 />
<cfset var errorlist = '' />
<cfset var uploadedfiles = 0 />
<cfset var totalsize = 0 />
<cfset var next = true />
<!--- RUN INIT FUNCTION --->
<cfset init()>
<!--- MAIN UPLOADS DIRECTORY --->
<cfset var dir = "uploads">
<cfset var destDir = ExpandPath("#dir#")>
<cfif not directoryExists(destdir)>
<cfdirectory action="create" directory="#destdir#">
</cfif>
<!--- THUMBS DIRECTORY --->
<cfset var dirthumbs = "thumbs" />
<cfset var thumDir = destdir & variables.bslash & dirthumbs />
<cfif not directoryExists(thumDir)>
<cfdirectory action="create" directory="#thumDir#">
</cfif>
<!--- LARGE IMAGE DIRECTORY --->
<cfset var dirlarge = "large" />
<cfset var largeDir = destdir & variables.bslash & dirlarge />
<cfif not directoryExists(largeDir)>
<cfdirectory action="create" directory="#largeDir#">
</cfif>
<!--- CREATE ARRAY TO CATCH A STRUCTURE WITH UPLOADED IMAGES--->
<cfset var imgstruct = structnew()>
<cfloop from="1" to="#arguments.filecounter#" index="i" step="1">
<!--- BUILD DYNAMIC FILE FIELD (FORM FIELD KEY). --->
<cfset var strField = "attachment_#i#" />
<cfif (StructKeyExists( arguments, strField ) AND Len( arguments[ strField ] ))>
<!--- WE CAN UPLOAD IMAGE FILE OUTSIDE OF THE ROOT FOLDER FOR MORE SECURITY, THAT'S WHY
I'M NOT UPLOADING THE IMG DIRECT INTO THE LARGE FOLDER --->
<cffile action="upload" filefield="#strField#" destination="#destdir#" nameconflict="makeunique">
<cfif IsImageFile("#destDir##variables.bslash##cffile.serverfile#")>
<!--- DO SOMETHING. I'M RENAMING - RESIZING LATER --->
<cfelse>
<!--- DELETE FILE --->
<cffile action="delete" file="#destDir##variables.bslash##cffile.serverfile#">
<cfset var next = false />
</cfif>
<cfif next is false >
<!--- SET FALSE IF THERE WAS FILE ERROR.
YOU CAN USE THE ID OF THIS FILE IN THE JQUERY CODE TO SHOW THE ERROR --->
<cfset var errorlist = listappend(errorlist,"Image file " & i & " is not valid !","|")>
<cfset var totalerrors = totalerrors + 1>
<cfset var imgstruct[i] = 'false_Invalid file' />
<cfelse>
<!--- CHECK THE MAX UPLOAD FILESIZE
( I HAVE NO VALIDATION FOR INTERNET EXPLORER ) --->
<cfif cffile.Filesize GT variables.maxsize>
<!--- CALCULATE IN MB TO SEND AN ERROR TEXT --->
<cfset newimagemaxsize = variables.maxsize / (1024 * 1024)>
<cfset newimagemaxsize = numberformat(newimagemaxsize,"0.00") />
<!--- DELETE FILE --->
<cffile action="delete" file="#destDir##variables.bslash##cffile.serverfile#">
<!--- ADD ERROR TEXT --->
<cfset var errorlist = listappend(errorlist,"Image file " & i & "extended max image size " & newimagemaxsize & " mb !","|")>
<cfset var totalerrors = totalerrors + 1>
<cfset var imgstruct[i] = 'false_Max upload size: ' & newimagemaxsize & ' mb' />
<cfelse>
<!--- CREATE A UNIQUE NAME TO RENAME THE UPLOADED IMAGE --->
<cfset var token = createuuid()>
<cfset var newname = token & '.' & file.clientfileext />
<cfset var source = destDir & variables.bslash & cffile.serverfile>
<cfset var newsrc = destDir & variables.bslash & newname >
<!--- RENAME IMAGE. --->
<cffile action="rename" source="#source#" destination="#newsrc#">
<cfimage source="#newsrc#" name="image">
<!--- ANTIALISING IMAGE BEFORE COPYING--->
<cfset ImageSetAntialiasing(image,"on")>
<!--- COPY FILE IN THUMBS FOLDER --->
<cffile action = "copy"
source="#newsrc#"
destination="#thumDir##variables.bslash##newname#"
nameconflict="makeunique">
<!--- COPY FILE IN LARGE FOLDER --->
<cffile action = "copy"
source="#newsrc#"
destination="#largeDir##variables.bslash##newname#"
nameconflict="makeunique">
<!--- DELETE UPLOADED FILE --->
<cffile action="delete" file="#newsrc#">
<!--- SOURCE IMAGE --->
<cfset var sourceImage = thumDir & variables.bslash & newname>
<cfset var img = imageRead(sourceImage)>
<!--- RESIZE THUMB
--->
<cfif (img.width GT img.height OR img.width EQ img.height) AND img.width GT variables.thumbwidth>
<cfset ImageScaleToFit(img,variables.thumbwidth,"","highestQuality")>
<cfelseif img.height GT img.width AND img.height GT variables.thumbheight>
<cfset ImageScaleToFit(img,"",variables.thumbheight,"highestQuality")>
</cfif>
<cfset ImageWrite(img,"#thumDir##variables.bslash##newname#")>
<!--- Image file to structure --->
<cfset var imgstruct[i] = 'success_' & newname />
<cfset var uploadedfiles = uploadedfiles + 1 />
<cfset var totalsize = totalsize + cffile.Filesize />
</cfif>
</cfif>
</cfif>
<cfset var next = true />
</cfloop>
<!--- GET TOTAl SIZE AND CONVERT TO MB --->
<cfset var totalsize = totalsize / (1024 * 1024)>
<cfset var totalsize = numberformat(totalsize,"0.00") />
<!--- CREATE ARRAY FOR ERRORS --->
<cfset var errors = []>
<cfloop list="#errorlist#" index="i" delimiters="|">
<cfset arrayAppend(errors, i)>
</cfloop>
<cfset var finalarr = []>
<cfset var datamain = {}>
<!--- ADD ERRORLIST TO ARRAY --->
<cfset datamain['errors'] = errors >
<cfset arrayAppend(finalarr, datamain)>
<!--- ADD ERRORS COUNT TO ARRAY --->
<cfset datamain['totalerrors'] = totalerrors />
<cfset arrayAppend(finalarr, datamain)>
<!--- ADD UPLOADED IMAGES TO ARRAY --->
<cfset datamain['images'] = imgstruct />
<cfset arrayAppend(finalarr, datamain)>
<!--- ADD TOTAL UPLOADED SIZE TO ARRAY --->
<cfset datamain['totalsize'] = totalsize />
<cfset arrayAppend(finalarr, datamain)>
<!--- ADD UPLOADED FILES COUNT TO ARRAY --->
<cfset datamain['uploadedfiles'] = uploadedfiles />
<cfset arrayAppend(finalarr, datamain)>
<cfreturn finalarr>
</cffunction>
</cfcomponent>
Have a question about something in this article? You can receive help directly from the article author. Sign up for a free trial to get started.
Comments (1)
Commented:
Keep up the Good work