1/*! 2 * jQuery Upload File Plugin 3 * version: 3.1.0 4 * @requires jQuery v1.5 or later & form plugin 5 * Copyright (c) 2013 Ravishanker Kusuma 6 * http://hayageek.com/ 7 */ 8(function ($) { 9 if ($.fn.ajaxForm == undefined) { 10 $.getScript("/js/jquery.form.js"); 11 } 12 var feature = {}; 13 feature.fileapi = $("<input type='file'/>").get(0).files !== undefined; 14 feature.formdata = window.FormData !== undefined; 15 16 $.fn.uploadFile = function (options) { 17 // This is the easiest way to have default options. 18 var s = $.extend({ 19 // These are the defaults. 20 url: "", 21 method: "POST", 22 enctype: "multipart/form-data", 23 formData: null, 24 returnType: null, 25 allowedTypes: "*", 26 fileName: "file", 27 formData: {}, 28 dynamicFormData: function () { 29 return {}; 30 }, 31 maxFileSize: -1, 32 multiple: true, 33 dragDrop: true, 34 autoSubmit: true, 35 showCancel: true, 36 showAbort: true, 37 showDone: true, 38 showDelete:false, 39 showError: true, 40 showStatusAfterSuccess: true, 41 showStatusAfterError: true, 42 showFileCounter:true, 43 fileCounterStyle:"). ", 44 showProgress:false, 45 onSelect:function(files){ return true;}, 46 onSubmit: function (files, xhr) {}, 47 onSuccess: function (files, response, xhr) {}, 48 onError: function (files, status, message) {}, 49 deleteCallback: false, 50 afterUploadAll: false, 51 uploadButtonClass: "ajax-file-upload", 52 dragDropStr: "<span>ëëê·¸ & ëë</span>", 53 abortStr: "Abort", 54 cancelStr: "Cancel", 55 deletelStr: "Delete", 56 doneStr: "Done", 57 multiDragErrorStr: "Multiple File Drag & Drop is not allowed.", 58 extErrorStr: "ì§ìíì§ ìë íì¼ì ëë¤ ì§ìíì¼: ", 59 sizeErrorStr: "ì©ë ì´ê³¼ì ëë¤. ìµë:", 60 uploadErrorStr: "Upload is not allowed" 61 }, options); 62 63 this.fileCounter = 1; 64 this.fCounter = 0; //failed uploads 65 this.sCounter = 0; //success uploads 66 this.tCounter = 0; //total uploads 67 var formGroup = "ajax-file-upload-" + (new Date().getTime()); 68 this.formGroup = formGroup; 69 this.hide(); 70 71 //pp-add errorLog obj customize 72 //this.errorLog = $("<div class='jq-upload-err'></div>"); //Writing errors,org 73 var errorObjClass=$(this).parent().parent().find(".jq-upload-err").attr('class'); 74 if(errorObjClass){ 75 this.errorLog=$(this).parent().parent().find(".jq-upload-err"); 76 //console.log("err obj find:"+errorObjClass); 77 }else{ 78 this.errorLog = $("<div class='jq-upload-err'></div>"); //org error obj 79 this.after(this.errorLog); 80 //console.log("err obj not found"); 81 } 82 //pp-add:end 83 84 this.responses = []; 85 if (!feature.formdata) //check drag drop enabled. 86 { 87 s.dragDrop = false; 88 } 89 90 91 var obj = this; 92 93 var uploadLabel = $('<div class=text-center>' + $(this).html() + '</div>'); 94 $(uploadLabel).addClass(s.uploadButtonClass); 95 96 //wait form ajax Form plugin and initialize 97 (function checkAjaxFormLoaded() { 98 if ($.fn.ajaxForm) { 99 100 if (s.dragDrop) { 101 var dragDrop = $('<div class="ajax-upload-dragdrop" style="vertical-align:top;"></div>'); 102 $(obj).before(dragDrop); 103 $(dragDrop).append(uploadLabel); 104 $(dragDrop).append($(s.dragDropStr)); 105 setDragDropHandlers(obj, s, dragDrop); 106 107 } else { 108 $(obj).before(uploadLabel); 109 } 110 111 createCutomInputFile(obj, formGroup, s, uploadLabel); 112 113 }
113 else window.setTimeout(checkAjaxFormLoaded, 10); 114 })(); 115 116 this.startUpload = function () { 117 $("." + this.formGroup).each(function (i, items) { 118 if ($(this).is('form')) $(this).submit(); 119 }); 120 } 121 this.stopUpload = function () { 122 $(".ajax-file-upload-red").each(function (i, items) { 123 if ($(this).hasClass(obj.formGroup)) $(this).click(); 124 }); 125 } 126 127 this.getResponses = function () { 128 return this.responses; 129 } 130 var checking = false; 131 132 function checkPendingUploads() { 133 if (s.afterUploadAll && !checking) { 134 checking = true; 135 (function checkPending() { 136 if (obj.sCounter != 0 && (obj.sCounter + obj.fCounter == obj.tCounter)) { 137 s.afterUploadAll(obj); 138 checking = false; 139 } else window.setTimeout(checkPending, 100); 140 })(); 141 } 142 143 } 144 145 function setDragDropHandlers(obj, s, ddObj) { 146 ddObj.on('dragenter', function (e) { 147 e.stopPropagation(); 148 e.preventDefault(); 149 $(this).css('border', '2px solid #A5A5C7'); 150 }); 151 ddObj.on('dragover', function (e) { 152 e.stopPropagation(); 153 e.preventDefault(); 154 }); 155 ddObj.on('drop', function (e) { 156 $(this).css('border', '2px dotted #A5A5C7'); 157 e.preventDefault(); 158 obj.errorLog.html(""); 159 var files = e.originalEvent.dataTransfer.files; 160 if (!s.multiple && files.length > 1) { 161 if (s.showError) $("<div style='color:red;'>" + s.multiDragErrorStr + "</div>").appendTo(obj.errorLog); 162 return; 163 } 164 if(s.onSelect(files) == false) 165 return; 166 serializeAndUploadFiles(s, obj, files); 167 }); 168 169 $(document).on('dragenter', function (e) { 170 e.stopPropagation(); 171 e.preventDefault(); 172 }); 173 $(document).on('dragover', function (e) { 174 e.stopPropagation(); 175 e.preventDefault(); 176 ddObj.css('border', '2px dotted #A5A5C7'); 177 }); 178 $(document).on('drop', function (e) { 179 e.stopPropagation(); 180 e.preventDefault(); 181 ddObj.css('border', '2px dotted #A5A5C7'); 182 }); 183 184 } 185 186 function getSizeStr(size) { 187 var sizeStr = ""; 188 var sizeKB = size / 1024; 189 if (parseInt(sizeKB) > 1024) { 190 var sizeMB = sizeKB / 1024; 191 sizeStr = sizeMB.toFixed(2) + " MB"; 192 } else { 193 sizeStr = sizeKB.toFixed(2) + " KB"; 194 } 195 return sizeStr; 196 } 197 198 function serializeData(extraData) { 199 var serialized = []; 200 if (jQuery.type(extraData) == "string") { 201 serialized = extraData.split('&'); 202 } else { 203 serialized = $.param(extraData).split('&'); 204 } 205 var len = serialized.length; 206 var result = []; 207 var i, part; 208 for (i = 0; i < len; i++) { 209 serialized[i] = serialized[i].replace(/\+/g, ' '); 210 part = serialized[i].split('='); 211 result.push([decodeURIComponent(part[0]), decodeURIComponent(part[1])]); 212 } 213 return result; 214 } 215 216 function serializeAndUploadFiles(s, obj, files) { 217 for (var i = 0; i < files.length; i++) { 218 if (!isFileTypeAllowed(obj, s, files[i].name)) { 219 if (s.showError) $("<div style='color:red;'><b>" + files[i].name + "</b> " + s.extErrorStr + s.allowedTypes + "</div>").appendTo(obj.errorLog); 220 continue; 221 } 222 if (s.maxFileSize != -1 && files[i].size > s.maxFileSize) { 223 if (s.showError) $("<div style='color:red;'><b>
223" + files[i].name + "</b> " + s.sizeErrorStr + getSizeStr(s.maxFileSize) + "</div>").appendTo(obj.errorLog); 224 continue; 225 } 226 var ts = s; 227 var fd = new FormData(); 228 var fileName = s.fileName.replace("[]", ""); 229 fd.append(fileName, files[i]); 230 var extraData = s.formData; 231 if (extraData) { 232 var sData = serializeData(extraData); 233 for (var j = 0; j < sData.length; j++) { 234 if (sData[j]) { 235 fd.append(sData[j][0], sData[j][1]); 236 } 237 } 238 } 239 ts.fileData = fd; 240 241 var pd = new createProgressDiv(obj, s); 242 var fileNameStr=""; 243 if(s.showFileCounter) 244 fileNameStr = obj.fileCounter + s.fileCounterStyle + files[i].name 245 else 246 fileNameStr = files[i].name; 247 248 pd.filename.html(fileNameStr); 249 var form = $("<form style='display:block; position:absolute;left: 150px;' class='" + obj.formGroup + "' method='" + s.method + "' action='" + s.url + "' enctype='" + s.enctype + "'></form>"); 250 form.appendTo('body'); 251 var fileArray = []; 252 fileArray.push(files[i].name); 253 ajaxFormSubmit(form, ts, pd, fileArray, obj); 254 obj.fileCounter++; 255 256 257 } 258 } 259 260 function isFileTypeAllowed(obj, s, fileName) { 261 var fileExtensions = s.allowedTypes.toLowerCase().split(","); 262 var ext = fileName.split('.').pop().toLowerCase(); 263 if (s.allowedTypes != "*" && jQuery.inArray(ext, fileExtensions) < 0) { 264 return false; 265 } 266 return true; 267 } 268 269 function createCutomInputFile(obj, group, s, uploadLabel) { 270 271 var fileUploadId = "ajax-upload-id-" + (new Date().getTime()); 272 273 var form = $("<form method='" + s.method + "' action='" + s.url + "' enctype='" + s.enctype + "'></form>"); 274 var fileInputStr = "<input type='file' accept='"+s.acceptFiles+"' id='" + fileUploadId + "' name='" + s.fileName + "'/>"; 275 if (s.multiple) { 276 if (s.fileName.indexOf("[]") != s.fileName.length - 2) // if it does not endwith 277 { 278 s.fileName += "[]"; 279 } 280 fileInputStr = "<input type='file' accept='"+s.acceptFiles+"' id='" + fileUploadId + "' name='" + s.fileName + "' multiple/>"; 281 } 282 var fileInput = $(fileInputStr).appendTo(form); 283 284 fileInput.change(function () { 285 286 obj.errorLog.html(""); 287 var fileExtensions = s.allowedTypes.toLowerCase().split(","); 288 var fileArray = []; 289 if (this.files) //support reading files 290 { 291 for (i = 0; i < this.files.length; i++) 292 { 293 fileArray.push(this.files[i].name); 294 } 295 296 if(s.onSelect(this.files) == false) 297 return; 298 } else { 299 var filenameStr = $(this).val(); 300 var flist = []; 301 fileArray.push(filenameStr); 302 if (!isFileTypeAllowed(obj, s, filenameStr)) { 303 if (s.showError) $("<div style='color:red;'><b>" + filenameStr + "</b> " + s.extErrorStr + s.allowedTypes + "</div>").appendTo(obj.errorLog); 304 return; 305 } 306 //fallback for browser without FileAPI 307 flist.push({name:filenameStr,size:'NA'}); 308 if(s.onSelect(flist) == false) 309 return; 310 311 } 312 uploadLabel.unbind("click"); 313 form.hide(); 314 createCutomInputFile(obj, group, s, uploadLabel); 315 316 form.addClass(group); 317 if (feature.fileapi && feature.formdata) //use HTML5 support and split file submission 318 { 319 form.removeClass(group); //Stop Submitting when. 320 var files = this.files; 321 serializeAndUploadFiles(s, obj, files); 322 } else { 323 var fileList = ""; 324 for (var i = 0; i < fileArray.length; i++) { 325 if(s.showFileCounter) 326 fileList += obj.fileCounter + s.fileCounterStyle + fileArray[i]+"<br>"; 327 else 328 fileList += fileArray[i]+"<br>";; 329 obj.fileCounter++; 330 } 331 var pd = new createProgressDiv(obj, s); 332 pd.filename.html(fileList); 333 ajaxFormSubmit(form, s, pd, fileArray, obj); 334 } 335 336 337 338 }); 339 340 form.css({'margin':0,'padding':0}); 341 var uwidth=$(uploadLabel).width()+10; 342 if(uwidth == 10) 343 uwidth =110; 344 var uheight=uploadLabel.height()+10; 345 if(uheight == 10) 346 uheight = 35; 347 /* 348 uploadLabel.css({position: 'relative',overflow:'hidden',cursor:'pointer'}); 349 fileInput.css({position: 'absolute','cursor':'pointer', 350 'top': '5px', 351 'width': uwidth, 352 'height':uheight, 353 'left': '20%', 354 'z-index': '100', 355 'opacity': '0.0', 356 'filter':'alpha(opacity=0)', 357 '-ms-filter':"alpha(opacity=0)", 358 '-khtml-opacity':'0.0', 359 '-moz-opacity':'0.0' 360 }); 361 form.appendTo(uploadLabel);*/ 362 363 //dont hide it, but move it to 364 form.css({ 365 margin: 0, 366 padding: 0, 367 display: 'block', 368 position: 'absolute', 369 left: '50px' 370 }); 371 if (navigator.appVersion.indexOf("MSIE ") != -1) //IE Browser 372 { 373 uploadLabel.attr('for', fileUploadId); 374 } else { 375 uploadLabel.click(function () { 376 fileInput.click(); 377 }); 378 } 379 380 381 } 382 383 384 function createProgressDiv(obj, s) { 385 this.statusbar = $("<div class='ajax-file-upload-statusbar'></div>"); 386 this.filename = $("<div class='ajax-file-upload-filename'></div>").appendTo(this.statusbar); 387 this.progressDiv = $("<div class='ajax-file-upload-progress'>").appendTo(this.statusbar).hide(); 388 this.progressbar = $("<div class='ajax-file-upload-bar " + obj.formGroup + "'></div>").appendTo(this.progressDiv); 389 this.abort = $("<div class='ajax-file-upload-red " + obj.formGroup + "'>" + s.abortStr + "</div>").appendTo(this.statusbar).hide(); 390 this.cancel = $("<div class='ajax-file-upload-red'>" + s.cancelStr + "</div>").appendTo(this.statusbar).hide(); 391 this.done = $("<div class='ajax-file-upload-green'>" + s.doneStr + "</div>").appendTo(this.statusbar).hide(); 392 this.del = $("<div class='ajax-file-upload-red'>" + s.deletelStr + "</div>").appendTo(this.statusbar).hide(); 393 obj.errorLog.after(this.statusbar); 394 return this; 395 } 396 397 398 function ajaxFormSubmit(form, s, pd, fileArray, obj) { 399 var currentXHR = null; 400 var options = { 401 cache: false, 402 contentType: false, 403 processData: false, 404 forceSync: false, 405 data: s.formData, 406 formData: s.fileData, 407 dataType: s.returnType, 408 beforeSubmit: function (formData, $form, options) { 409 if (s.onSubmit.call(this, fileArray) != false) { 410 var dynData = s.dynamicFormData(); 411 if (dynData) { 412 var sData = serializeData(dynData); 413 if (sData) { 414 for (var j = 0; j < sData.length; j++) { 415 if (sData[j]) { 416 if (s.fileData != undefined) options.formData.append(sData[j][0], sData[j][1]); 417 else options.data[sData[j][0]] = sData[j][1]; 418 } 419 } 420 } 421 } 422 obj.tCounter += fileArray.length; 423 //window.setTimeout(checkPendingUploads, 1000); //not so critical 424 checkPendingUploads(); 425 return true; 426 } 427 pd.statusbar.append("<div style='color:red;'>" + s.uploadErrorStr + "</div>"); 428 pd.cancel.show() 429 form.remove(); 430 pd.cancel.click(function () { 431 pd.statusbar.remove(); 432 }); 433 return false;
434 }, 435 beforeSend: function (xhr, o) { 436 437 pd.progressDiv.show(); 438 pd.cancel.hide(); 439 pd.done.hide(); 440 if (s.showAbort) { 441 pd.abort.show(); 442 pd.abort.click(function () { 443 xhr.abort(); 444 }); 445 } 446 if (!feature.formdata) //For iframe based push 447 { 448 pd.progressbar.width('5%'); 449 } else pd.progressbar.width('1%'); //Fix for small files 450 }, 451 uploadProgress: function (event, position, total, percentComplete) { 452 //Fix for smaller file uploads in MAC 453 if(percentComplete > 98) percentComplete =98; 454 455 var percentVal = percentComplete + '%'; 456 if (percentComplete > 1) pd.progressbar.width(percentVal) 457 if(s.showProgress) 458 { 459 pd.progressbar.html(percentVal); 460 pd.progressbar.css('text-align', 'center'); 461 } 462 463 }, 464 success: function (data, message, xhr) { 465 obj.responses.push(data); 466 pd.progressbar.width('100%') 467 if(s.showProgress) 468 { 469 pd.progressbar.html('100%'); 470 pd.progressbar.css('text-align', 'center'); 471 } 472 473 pd.abort.hide(); 474 s.onSuccess.call(this, fileArray, data, xhr); 475 if (s.showStatusAfterSuccess) { 476 if (s.showDone) { 477 pd.done.show(); 478 pd.done.click(function () { 479 pd.statusbar.hide("slow"); 480 pd.statusbar.remove(); 481 }); 482 } else { 483 pd.done.hide(); 484 } 485 if(s.showDelete) 486 { 487 pd.del.show(); 488 pd.del.click(function () { 489 if(s.deleteCallback) s.deleteCallback.call(this, data,pd); 490 }); 491 } 492 else 493 { 494 pd.del.hide(); 495 } 496 } else { 497 pd.statusbar.hide("slow"); 498 pd.statusbar.remove(); 499 500 } 501 form.remove(); 502 obj.sCounter += fileArray.length; 503 }, 504 error: function (xhr, status, errMsg) { 505 pd.abort.hide(); 506 if (xhr.statusText == "abort") //we aborted it 507 { 508 pd.statusbar.hide("slow"); 509 } else { 510 s.onError.call(this, fileArray, status, errMsg); 511 if (s.showStatusAfterError) { 512 pd.progressDiv.hide(); 513 pd.statusbar.append("<span style='color:red;'>ERROR: " + errMsg + "</span>"); 514 } else { 515 pd.statusbar.hide(); 516 pd.statusbar.remove(); 517 } 518 } 519 520 form.remove(); 521 obj.fCounter += fileArray.length; 522 523 } 524 }; 525 if (s.autoSubmit) { 526 form.ajaxSubmit(options); 527 } else { 528 if (s.showCancel) { 529 pd.cancel.show(); 530 pd.cancel.click(function () { 531 form.remove(); 532 pd.statusbar.remove(); 533 }); 534 } 535 form.ajaxForm(options); 536 537 } 538 539 } 540 return this; 541 542 } 543 544 545}(jQuery));
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.