You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

936 lines
36 KiB

  1. /*!
  2. * jQuery Upload File Plugin
  3. * version: 4.0.11
  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(("https:" == document.location.protocol ? "https://" : "http://") + "malsup.github.io/jquery.form.js");
  11. }
  12. var feature = {};
  13. feature.fileapi = $("<input type='file'/>").get(0).files !== undefined;
  14. feature.formdata = window.FormData !== undefined;
  15. $.fn.uploadFile = function (options) {
  16. // This is the easiest way to have default options.
  17. var s = $.extend({
  18. // These are the defaults.
  19. url: "",
  20. method: "POST",
  21. enctype: "multipart/form-data",
  22. returnType: null,
  23. allowDuplicates: true,
  24. duplicateStrict: false,
  25. allowedTypes: "*",
  26. //For list of acceptFiles
  27. // http://stackoverflow.com/questions/11832930/html-input-file-accept-attribute-file-type-csv
  28. acceptFiles: "*",
  29. fileName: "file",
  30. formData: false,
  31. dynamicFormData:false,
  32. maxFileSize: -1,
  33. maxFileCount: -1,
  34. multiple: true,
  35. dragDrop: true,
  36. autoSubmit: true,
  37. showCancel: true,
  38. showAbort: true,
  39. showDone: false,
  40. showDelete: false,
  41. showError: true,
  42. showStatusAfterSuccess: true,
  43. showStatusAfterError: true,
  44. showFileCounter: true,
  45. fileCounterStyle: "). ",
  46. showFileSize: true,
  47. showProgress: false,
  48. nestedForms: true,
  49. showDownload: false,
  50. onLoad: function (obj) {},
  51. onSelect: function (files) {
  52. return true;
  53. },
  54. onSubmit: function (files, xhr) {},
  55. onSuccess: function (files, response, xhr, pd) {},
  56. onError: function (files, status, message, pd) {},
  57. onCancel: function (files, pd) {},
  58. onAbort: function (files, pd) {},
  59. downloadCallback: false,
  60. deleteCallback: false,
  61. afterUploadAll: false,
  62. serialize:true,
  63. sequential:false,
  64. sequentialCount:2,
  65. customProgressBar: false,
  66. abortButtonClass: "ajax-file-upload-abort",
  67. cancelButtonClass: "ajax-file-upload-cancel",
  68. dragDropContainerClass: "ajax-upload-dragdrop",
  69. dragDropHoverClass: "state-hover",
  70. errorClass: "ajax-file-upload-error",
  71. uploadButtonClass: "ajax-file-upload",
  72. dragDropStr: "<span><b>Drag &amp; Drop Files</b></span>",
  73. uploadStr:"Upload",
  74. abortStr: "Abort",
  75. cancelStr: "Cancel",
  76. deleteStr: "Delete",
  77. doneStr: "Done",
  78. multiDragErrorStr: "Multiple File Drag &amp; Drop is not allowed.",
  79. extErrorStr: "is not allowed. Allowed extensions: ",
  80. duplicateErrorStr: "is not allowed. File already exists.",
  81. sizeErrorStr: "is not allowed. Allowed Max size: ",
  82. uploadErrorStr: "Upload is not allowed",
  83. maxFileCountErrorStr: " is not allowed. Maximum allowed files are:",
  84. downloadStr: "Download",
  85. customErrorKeyStr: "jquery-upload-file-error",
  86. showQueueDiv: false,
  87. statusBarWidth: 400,
  88. dragdropWidth: 400,
  89. showPreview: false,
  90. previewHeight: "auto",
  91. previewWidth: "100%",
  92. extraHTML:false,
  93. uploadQueueOrder:'top',
  94. headers: {}
  95. }, options);
  96. this.fileCounter = 1;
  97. this.selectedFiles = 0;
  98. var formGroup = "ajax-file-upload-" + (new Date().getTime());
  99. this.formGroup = formGroup;
  100. this.errorLog = $("<div></div>"); //Writing errors
  101. this.responses = [];
  102. this.existingFileNames = [];
  103. if(!feature.formdata) //check drag drop enabled.
  104. {
  105. s.dragDrop = false;
  106. }
  107. if(!feature.formdata || s.maxFileCount === 1) {
  108. s.multiple = false;
  109. }
  110. $(this).html("");
  111. var obj = this;
  112. var uploadLabel = $('<div>' + s.uploadStr + '</div>');
  113. $(uploadLabel).addClass(s.uploadButtonClass);
  114. // wait form ajax Form plugin and initialize
  115. (function checkAjaxFormLoaded() {
  116. if($.fn.ajaxForm) {
  117. if(s.dragDrop) {
  118. var dragDrop = $('<div class="' + s.dragDropContainerClass + '" style="vertical-align:top;"></div>').width(s.dragdropWidth);
  119. $(obj).append(dragDrop);
  120. $(dragDrop).append(uploadLabel);
  121. $(dragDrop).append($(s.dragDropStr));
  122. setDragDropHandlers(obj, s, dragDrop);
  123. } else {
  124. $(obj).append(uploadLabel);
  125. }
  126. $(obj).append(obj.errorLog);
  127. if(s.showQueueDiv)
  128. obj.container =$("#"+s.showQueueDiv);
  129. else
  130. obj.container = $("<div class='ajax-file-upload-container'></div>").insertAfter($(obj));
  131. s.onLoad.call(this, obj);
  132. createCustomInputFile(obj, formGroup, s, uploadLabel);
  133. } else window.setTimeout(checkAjaxFormLoaded, 10);
  134. })();
  135. this.startUpload = function () {
  136. $("form").each(function(i,items)
  137. {
  138. if($(this).hasClass(obj.formGroup))
  139. {
  140. mainQ.push($(this));
  141. }
  142. });
  143. if(mainQ.length >= 1 )
  144. submitPendingUploads();
  145. }
  146. this.getFileCount = function () {
  147. return obj.selectedFiles;
  148. }
  149. this.stopUpload = function () {
  150. $("." + s.abortButtonClass).each(function (i, items) {
  151. if($(this).hasClass(obj.formGroup)) $(this).click();
  152. });
  153. $("." + s.cancelButtonClass).each(function (i, items) {
  154. if($(this).hasClass(obj.formGroup)) $(this).click();
  155. });
  156. }
  157. this.cancelAll = function () {
  158. $("." + s.cancelButtonClass).each(function (i, items) {
  159. if($(this).hasClass(obj.formGroup)) $(this).click();
  160. });
  161. }
  162. this.update = function (settings) {
  163. //update new settings
  164. s = $.extend(s, settings);
  165. //We need to update action for already created Form.
  166. if(settings.hasOwnProperty('url'))
  167. {
  168. $("form").each(function(i,items)
  169. {
  170. $(this).attr('action',settings['url']);
  171. });
  172. }
  173. }
  174. this.enqueueFile = function(file){
  175. if( !( file instanceof File) ) return;
  176. var files = [file];
  177. serializeAndUploadFiles(s, obj, files);
  178. }
  179. this.reset = function (removeStatusBars) {
  180. obj.fileCounter = 1;
  181. obj.selectedFiles = 0;
  182. obj.errorLog.html("");
  183. //remove all the status bars.
  184. if(removeStatusBars != false)
  185. {
  186. obj.container.html("");
  187. }
  188. }
  189. this.remove = function()
  190. {
  191. obj.container.html("");
  192. $(obj).remove();
  193. }
  194. //This is for showing Old files to user.
  195. this.createProgress = function (filename,filepath,filesize) {
  196. var pd = new createProgressDiv(this, s);
  197. pd.progressDiv.show();
  198. pd.progressbar.width('100%');
  199. var fileNameStr = "";
  200. if(s.showFileCounter)
  201. fileNameStr = obj.fileCounter + s.fileCounterStyle + filename;
  202. else fileNameStr = filename;
  203. if(s.showFileSize)
  204. fileNameStr += " ("+getSizeStr(filesize)+")";
  205. pd.filename.html(fileNameStr);
  206. obj.fileCounter++;
  207. obj.selectedFiles++;
  208. if(s.showPreview)
  209. {
  210. pd.preview.attr('src',filepath);
  211. pd.preview.show();
  212. }
  213. if(s.showDownload) {
  214. pd.download.show();
  215. pd.download.click(function () {
  216. if(s.downloadCallback) s.downloadCallback.call(obj, [filename], pd);
  217. });
  218. }
  219. if(s.showDelete)
  220. {
  221. pd.del.show();
  222. pd.del.click(function () {
  223. pd.statusbar.hide().remove();
  224. var arr = [filename];
  225. if(s.deleteCallback) s.deleteCallback.call(this, arr, pd);
  226. obj.selectedFiles -= 1;
  227. updateFileCounter(s, obj);
  228. });
  229. }
  230. return pd;
  231. }
  232. this.getResponses = function () {
  233. return this.responses;
  234. }
  235. var mainQ=[];
  236. var progressQ=[]
  237. var running = false;
  238. function submitPendingUploads() {
  239. if(running) return;
  240. running = true;
  241. (function checkPendingForms() {
  242. //if not sequential upload all files
  243. if(!s.sequential) s.sequentialCount=99999;
  244. if(mainQ.length == 0 && progressQ.length == 0)
  245. {
  246. if(s.afterUploadAll) s.afterUploadAll(obj);
  247. running= false;
  248. }
  249. else
  250. {
  251. if( progressQ.length < s.sequentialCount)
  252. {
  253. var frm = mainQ.shift();
  254. if(frm != undefined)
  255. {
  256. progressQ.push(frm);
  257. //Remove the class group.
  258. frm.removeClass(obj.formGroup);
  259. frm.submit();
  260. }
  261. }
  262. window.setTimeout(checkPendingForms, 100);
  263. }
  264. })();
  265. }
  266. function setDragDropHandlers(obj, s, ddObj) {
  267. ddObj.on('dragenter', function (e) {
  268. e.stopPropagation();
  269. e.preventDefault();
  270. $(this).addClass(s.dragDropHoverClass);
  271. });
  272. ddObj.on('dragover', function (e) {
  273. e.stopPropagation();
  274. e.preventDefault();
  275. var that = $(this);
  276. if (that.hasClass(s.dragDropContainerClass) && !that.hasClass(s.dragDropHoverClass)) {
  277. that.addClass(s.dragDropHoverClass);
  278. }
  279. });
  280. ddObj.on('drop', function (e) {
  281. e.preventDefault();
  282. $(this).removeClass(s.dragDropHoverClass);
  283. obj.errorLog.html("");
  284. var files = e.originalEvent.dataTransfer.files;
  285. if(!s.multiple && files.length > 1) {
  286. if(s.showError) $("<div class='" + s.errorClass + "'>" + s.multiDragErrorStr + "</div>").appendTo(obj.errorLog);
  287. return;
  288. }
  289. if(s.onSelect(files) == false) return;
  290. serializeAndUploadFiles(s, obj, files);
  291. });
  292. ddObj.on('dragleave', function (e) {
  293. $(this).removeClass(s.dragDropHoverClass);
  294. });
  295. $(document).on('dragenter', function (e) {
  296. e.stopPropagation();
  297. e.preventDefault();
  298. });
  299. $(document).on('dragover', function (e) {
  300. e.stopPropagation();
  301. e.preventDefault();
  302. var that = $(this);
  303. if (!that.hasClass(s.dragDropContainerClass)) {
  304. that.removeClass(s.dragDropHoverClass);
  305. }
  306. });
  307. $(document).on('drop', function (e) {
  308. e.stopPropagation();
  309. e.preventDefault();
  310. $(this).removeClass(s.dragDropHoverClass);
  311. });
  312. }
  313. function getSizeStr(size) {
  314. var sizeStr = "";
  315. var sizeKB = size / 1024;
  316. if(parseInt(sizeKB) > 1024) {
  317. var sizeMB = sizeKB / 1024;
  318. sizeStr = sizeMB.toFixed(2) + " MB";
  319. } else {
  320. sizeStr = sizeKB.toFixed(2) + " KB";
  321. }
  322. return sizeStr;
  323. }
  324. function serializeData(extraData) {
  325. var serialized = [];
  326. if(jQuery.type(extraData) == "string") {
  327. serialized = extraData.split('&');
  328. } else {
  329. serialized = $.param(extraData).split('&');
  330. }
  331. var len = serialized.length;
  332. var result = [];
  333. var i, part;
  334. for(i = 0; i < len; i++) {
  335. serialized[i] = serialized[i].replace(/\+/g, ' ');
  336. part = serialized[i].split('=');
  337. result.push([decodeURIComponent(part[0]), decodeURIComponent(part[1])]);
  338. }
  339. return result;
  340. }
  341. function noserializeAndUploadFiles(s, obj, files) {
  342. var ts = $.extend({}, s);
  343. var fd = new FormData();
  344. var fileArray = [];
  345. var fileName = s.fileName.replace("[]", "");
  346. var fileListStr="";
  347. for (var i = 0; i < files.length; i++) {
  348. if (!isFileTypeAllowed(obj, s, files[i].name)) {
  349. if (s.showError) $("<div><font color='red'><b>" + files[i].name + "</b> " + s.extErrorStr + s.allowedTypes + "</font></div>").appendTo(obj.errorLog);
  350. continue;
  351. }
  352. if (s.maxFileSize != -1 && files[i].size > s.maxFileSize) {
  353. if (s.showError) $("<div><font color='red'><b>" + files[i].name + "</b> " + s.sizeErrorStr + getSizeStr(s.maxFileSize) + "</font></div>").appendTo(obj.errorLog);
  354. continue;
  355. }
  356. fd.append(fileName+"[]", files[i]);
  357. fileArray.push(files[i].name);
  358. fileListStr += obj.fileCounter + "). " + files[i].name+"<br>";
  359. obj.fileCounter++;
  360. }
  361. if(fileArray.length ==0 ) return;
  362. var extraData = s.formData;
  363. if (extraData) {
  364. var sData = serializeData(extraData);
  365. for (var j = 0; j < sData.length; j++) {
  366. if (sData[j]) {
  367. fd.append(sData[j][0], sData[j][1]);
  368. }
  369. }
  370. }
  371. ts.fileData = fd;
  372. var pd = new createProgressDiv(obj, s);
  373. pd.filename.html(fileListStr);
  374. var form = $("<form style='display:block; position:absolute;left: 150px;' class='" + obj.formGroup + "' method='" + s.method + "' action='" + s.url + "' enctype='" + s.enctype + "'></form>");
  375. form.appendTo('body');
  376. ajaxFormSubmit(form, ts, pd, fileArray, obj);
  377. }
  378. function serializeAndUploadFiles(s, obj, files) {
  379. for(var i = 0; i < files.length; i++) {
  380. if(!isFileTypeAllowed(obj, s, files[i].name)) {
  381. if(s.showError) $("<div class='" + s.errorClass + "'><b>" + files[i].name + "</b> " + s.extErrorStr + s.allowedTypes + "</div>").appendTo(obj.errorLog);
  382. continue;
  383. }
  384. if(!s.allowDuplicates && isFileDuplicate(obj, files[i].name)) {
  385. if(s.showError) $("<div class='" + s.errorClass + "'><b>" + files[i].name + "</b> " + s.duplicateErrorStr + "</div>").appendTo(obj.errorLog);
  386. continue;
  387. }
  388. if(s.maxFileSize != -1 && files[i].size > s.maxFileSize) {
  389. if(s.showError) $("<div class='" + s.errorClass + "'><b>" + files[i].name + "</b> " + s.sizeErrorStr + getSizeStr(s.maxFileSize) + "</div>").appendTo(
  390. obj.errorLog);
  391. continue;
  392. }
  393. if(s.maxFileCount != -1 && obj.selectedFiles >= s.maxFileCount) {
  394. if(s.showError) $("<div class='" + s.errorClass + "'><b>" + files[i].name + "</b> " + s.maxFileCountErrorStr + s.maxFileCount + "</div>").appendTo(
  395. obj.errorLog);
  396. continue;
  397. }
  398. obj.selectedFiles++;
  399. obj.existingFileNames.push(files[i].name);
  400. // Make object immutable
  401. var ts = $.extend({}, s);
  402. var fd = new FormData();
  403. var fileName = s.fileName.replace("[]", "");
  404. fd.append(fileName, files[i]);
  405. var extraData = s.formData;
  406. if(extraData) {
  407. var sData = serializeData(extraData);
  408. for(var j = 0; j < sData.length; j++) {
  409. if(sData[j]) {
  410. fd.append(sData[j][0], sData[j][1]);
  411. }
  412. }
  413. }
  414. ts.fileData = fd;
  415. var pd = new createProgressDiv(obj, s);
  416. var fileNameStr = "";
  417. if(s.showFileCounter) fileNameStr = obj.fileCounter + s.fileCounterStyle + files[i].name
  418. else fileNameStr = files[i].name;
  419. if(s.showFileSize)
  420. fileNameStr += " ("+getSizeStr(files[i].size)+")";
  421. pd.filename.html(fileNameStr);
  422. var form = $("<form style='display:block; position:absolute;left: 150px;' class='" + obj.formGroup + "' method='" + s.method + "' action='" +
  423. s.url + "' enctype='" + s.enctype + "'></form>");
  424. form.appendTo('body');
  425. var fileArray = [];
  426. fileArray.push(files[i].name);
  427. ajaxFormSubmit(form, ts, pd, fileArray, obj, files[i]);
  428. obj.fileCounter++;
  429. }
  430. }
  431. function isFileTypeAllowed(obj, s, fileName) {
  432. var fileExtensions = s.allowedTypes.toLowerCase().split(/[\s,]+/g);
  433. var ext = fileName.split('.').pop().toLowerCase();
  434. if(s.allowedTypes != "*" && jQuery.inArray(ext, fileExtensions) < 0) {
  435. return false;
  436. }
  437. return true;
  438. }
  439. function isFileDuplicate(obj, filename) {
  440. var duplicate = false;
  441. if (obj.existingFileNames.length) {
  442. for (var x=0; x<obj.existingFileNames.length; x++) {
  443. if (obj.existingFileNames[x] == filename
  444. || s.duplicateStrict && obj.existingFileNames[x].toLowerCase() == filename.toLowerCase()
  445. ) {
  446. duplicate = true;
  447. }
  448. }
  449. }
  450. return duplicate;
  451. }
  452. function removeExistingFileName(obj, fileArr) {
  453. if (obj.existingFileNames.length) {
  454. for (var x=0; x<fileArr.length; x++) {
  455. var pos = obj.existingFileNames.indexOf(fileArr[x]);
  456. if (pos != -1) {
  457. obj.existingFileNames.splice(pos, 1);
  458. }
  459. }
  460. }
  461. }
  462. function getSrcToPreview(file, obj) {
  463. if(file) {
  464. obj.show();
  465. var reader = new FileReader();
  466. reader.onload = function (e) {
  467. obj.attr('src', e.target.result);
  468. };
  469. reader.readAsDataURL(file);
  470. }
  471. }
  472. function updateFileCounter(s, obj) {
  473. if(s.showFileCounter) {
  474. var count = $(obj.container).find(".ajax-file-upload-filename").length;
  475. obj.fileCounter = count + 1;
  476. $(obj.container).find(".ajax-file-upload-filename").each(function (i, items) {
  477. var arr = $(this).html().split(s.fileCounterStyle);
  478. var fileNum = parseInt(arr[0]) - 1; //decrement;
  479. var name = count + s.fileCounterStyle + arr[1];
  480. $(this).html(name);
  481. count--;
  482. });
  483. }
  484. }
  485. function createCustomInputFile (obj, group, s, uploadLabel) {
  486. var fileUploadId = "ajax-upload-id-" + (new Date().getTime());
  487. var form = $("<form method='" + s.method + "' action='" + s.url + "' enctype='" + s.enctype + "'></form>");
  488. var fileInputStr = "<input type='file' id='" + fileUploadId + "' name='" + s.fileName + "' accept='" + s.acceptFiles + "'/>";
  489. if(s.multiple) {
  490. if(s.fileName.indexOf("[]") != s.fileName.length - 2) // if it does not endwith
  491. {
  492. s.fileName += "[]";
  493. }
  494. fileInputStr = "<input type='file' id='" + fileUploadId + "' name='" + s.fileName + "' accept='" + s.acceptFiles + "' multiple/>";
  495. }
  496. var fileInput = $(fileInputStr).appendTo(form);
  497. fileInput.change(function () {
  498. obj.errorLog.html("");
  499. var fileExtensions = s.allowedTypes.toLowerCase().split(",");
  500. var fileArray = [];
  501. if(this.files) //support reading files
  502. {
  503. for(i = 0; i < this.files.length; i++) {
  504. fileArray.push(this.files[i].name);
  505. }
  506. if(s.onSelect(this.files) == false) return;
  507. } else {
  508. var filenameStr = $(this).val();
  509. var flist = [];
  510. fileArray.push(filenameStr);
  511. if(!isFileTypeAllowed(obj, s, filenameStr)) {
  512. if(s.showError) $("<div class='" + s.errorClass + "'><b>" + filenameStr + "</b> " + s.extErrorStr + s.allowedTypes + "</div>").appendTo(
  513. obj.errorLog);
  514. return;
  515. }
  516. //fallback for browser without FileAPI
  517. flist.push({
  518. name: filenameStr,
  519. size: 'NA'
  520. });
  521. if(s.onSelect(flist) == false) return;
  522. }
  523. updateFileCounter(s, obj);
  524. uploadLabel.unbind("click");
  525. form.hide();
  526. createCustomInputFile(obj, group, s, uploadLabel);
  527. form.addClass(group);
  528. if(s.serialize && feature.fileapi && feature.formdata) //use HTML5 support and split file submission
  529. {
  530. form.removeClass(group); //Stop Submitting when.
  531. var files = this.files;
  532. form.remove();
  533. serializeAndUploadFiles(s, obj, files);
  534. } else {
  535. var fileList = "";
  536. for(var i = 0; i < fileArray.length; i++) {
  537. if(s.showFileCounter) fileList += obj.fileCounter + s.fileCounterStyle + fileArray[i] + "<br>";
  538. else fileList += fileArray[i] + "<br>";;
  539. obj.fileCounter++;
  540. }
  541. if(s.maxFileCount != -1 && (obj.selectedFiles + fileArray.length) > s.maxFileCount) {
  542. if(s.showError) $("<div class='" + s.errorClass + "'><b>" + fileList + "</b> " + s.maxFileCountErrorStr + s.maxFileCount + "</div>").appendTo(
  543. obj.errorLog);
  544. return;
  545. }
  546. obj.selectedFiles += fileArray.length;
  547. var pd = new createProgressDiv(obj, s);
  548. pd.filename.html(fileList);
  549. ajaxFormSubmit(form, s, pd, fileArray, obj, null);
  550. }
  551. });
  552. if(s.nestedForms) {
  553. form.css({
  554. 'margin': 0,
  555. 'padding': 0
  556. });
  557. uploadLabel.css({
  558. position: 'relative',
  559. overflow: 'hidden',
  560. cursor: 'default'
  561. });
  562. fileInput.css({
  563. position: 'absolute',
  564. 'cursor': 'pointer',
  565. 'top': '0px',
  566. 'width': '100%',
  567. 'height': '100%',
  568. 'left': '0px',
  569. 'z-index': '100',
  570. 'opacity': '0.0',
  571. 'filter': 'alpha(opacity=0)',
  572. '-ms-filter': "alpha(opacity=0)",
  573. '-khtml-opacity': '0.0',
  574. '-moz-opacity': '0.0'
  575. });
  576. form.appendTo(uploadLabel);
  577. } else {
  578. form.appendTo($('body'));
  579. form.css({
  580. margin: 0,
  581. padding: 0,
  582. display: 'block',
  583. position: 'absolute',
  584. left: '-250px'
  585. });
  586. if(navigator.appVersion.indexOf("MSIE ") != -1) //IE Browser
  587. {
  588. uploadLabel.attr('for', fileUploadId);
  589. } else {
  590. uploadLabel.click(function () {
  591. fileInput.click();
  592. });
  593. }
  594. }
  595. }
  596. function defaultProgressBar(obj,s)
  597. {
  598. this.statusbar = $("<div class='ajax-file-upload-statusbar'></div>").width(s.statusBarWidth);
  599. this.preview = $("<img class='ajax-file-upload-preview' />").width(s.previewWidth).height(s.previewHeight).appendTo(this.statusbar).hide();
  600. this.filename = $("<div class='ajax-file-upload-filename'></div>").appendTo(this.statusbar);
  601. this.progressDiv = $("<div class='ajax-file-upload-progress'>").appendTo(this.statusbar).hide();
  602. this.progressbar = $("<div class='ajax-file-upload-bar'></div>").appendTo(this.progressDiv);
  603. this.abort = $("<div>" + s.abortStr + "</div>").appendTo(this.statusbar).hide();
  604. this.cancel = $("<div>" + s.cancelStr + "</div>").appendTo(this.statusbar).hide();
  605. this.done = $("<div>" + s.doneStr + "</div>").appendTo(this.statusbar).hide();
  606. this.download = $("<div>" + s.downloadStr + "</div>").appendTo(this.statusbar).hide();
  607. this.del = $("<div>" + s.deleteStr + "</div>").appendTo(this.statusbar).hide();
  608. this.abort.addClass("ajax-file-upload-red");
  609. this.done.addClass("ajax-file-upload-green");
  610. this.download.addClass("ajax-file-upload-green");
  611. this.cancel.addClass("ajax-file-upload-red");
  612. this.del.addClass("ajax-file-upload-red");
  613. return this;
  614. }
  615. function createProgressDiv(obj, s) {
  616. var bar = null;
  617. if(s.customProgressBar)
  618. bar = new s.customProgressBar(obj,s);
  619. else
  620. bar = new defaultProgressBar(obj,s);
  621. bar.abort.addClass(obj.formGroup);
  622. bar.abort.addClass(s.abortButtonClass);
  623. bar.cancel.addClass(obj.formGroup);
  624. bar.cancel.addClass(s.cancelButtonClass);
  625. if(s.extraHTML)
  626. bar.extraHTML = $("<div class='extrahtml'>"+s.extraHTML()+"</div>").insertAfter(bar.filename);
  627. if(s.uploadQueueOrder == 'bottom')
  628. $(obj.container).append(bar.statusbar);
  629. else
  630. $(obj.container).prepend(bar.statusbar);
  631. return bar;
  632. }
  633. function ajaxFormSubmit(form, s, pd, fileArray, obj, file) {
  634. var currentXHR = null;
  635. var options = {
  636. cache: false,
  637. contentType: false,
  638. processData: false,
  639. forceSync: false,
  640. type: s.method,
  641. data: s.formData,
  642. formData: s.fileData,
  643. dataType: s.returnType,
  644. headers: s.headers,
  645. beforeSubmit: function (formData, $form, options) {
  646. if(s.onSubmit.call(this, fileArray) != false) {
  647. if(s.dynamicFormData)
  648. {
  649. var sData = serializeData(s.dynamicFormData());
  650. if(sData) {
  651. for(var j = 0; j < sData.length; j++) {
  652. if(sData[j]) {
  653. if(s.serialize && s.fileData != undefined) options.formData.append(sData[j][0], sData[j][1]);
  654. else options.data[sData[j][0]] = sData[j][1];
  655. }
  656. }
  657. }
  658. }
  659. if(s.extraHTML)
  660. {
  661. $(pd.extraHTML).find("input,select,textarea").each(function(i,items)
  662. {
  663. if(s.serialize && s.fileData != undefined) options.formData.append($(this).attr('name'),$(this).val());
  664. else options.data[$(this).attr('name')] = $(this).val();
  665. });
  666. }
  667. return true;
  668. }
  669. pd.statusbar.append("<div class='" + s.errorClass + "'>" + s.uploadErrorStr + "</div>");
  670. pd.cancel.show()
  671. form.remove();
  672. pd.cancel.click(function () {
  673. mainQ.splice(mainQ.indexOf(form), 1);
  674. removeExistingFileName(obj, fileArray);
  675. pd.statusbar.remove();
  676. s.onCancel.call(obj, fileArray, pd);
  677. obj.selectedFiles -= fileArray.length; //reduce selected File count
  678. updateFileCounter(s, obj);
  679. });
  680. return false;
  681. },
  682. beforeSend: function (xhr, o) {
  683. for (var key in o.headers) {
  684. xhr.setRequestHeader(key, o.headers[key]);
  685. }
  686. pd.progressDiv.show();
  687. pd.cancel.hide();
  688. pd.done.hide();
  689. if(s.showAbort) {
  690. pd.abort.show();
  691. pd.abort.click(function () {
  692. removeExistingFileName(obj, fileArray);
  693. xhr.abort();
  694. obj.selectedFiles -= fileArray.length; //reduce selected File count
  695. s.onAbort.call(obj, fileArray, pd);
  696. });
  697. }
  698. if(!feature.formdata) //For iframe based push
  699. {
  700. pd.progressbar.width('5%');
  701. } else pd.progressbar.width('1%'); //Fix for small files
  702. },
  703. uploadProgress: function (event, position, total, percentComplete) {
  704. //Fix for smaller file uploads in MAC
  705. if(percentComplete > 98) percentComplete = 98;
  706. var percentVal = percentComplete + '%';
  707. if(percentComplete > 1) pd.progressbar.width(percentVal)
  708. if(s.showProgress) {
  709. pd.progressbar.html(percentVal);
  710. pd.progressbar.css('text-align', 'center');
  711. }
  712. },
  713. success: function (data, message, xhr) {
  714. pd.cancel.remove();
  715. progressQ.pop();
  716. //For custom errors.
  717. if(s.returnType == "json" && $.type(data) == "object" && data.hasOwnProperty(s.customErrorKeyStr)) {
  718. pd.abort.hide();
  719. var msg = data[s.customErrorKeyStr];
  720. s.onError.call(this, fileArray, 200, msg, pd);
  721. if(s.showStatusAfterError) {
  722. pd.progressDiv.hide();
  723. pd.statusbar.append("<span class='" + s.errorClass + "'>ERROR: " + msg + "</span>");
  724. } else {
  725. pd.statusbar.hide();
  726. pd.statusbar.remove();
  727. }
  728. obj.selectedFiles -= fileArray.length; //reduce selected File count
  729. form.remove();
  730. return;
  731. }
  732. obj.responses.push(data);
  733. pd.progressbar.width('100%')
  734. if(s.showProgress) {
  735. pd.progressbar.html('100%');
  736. pd.progressbar.css('text-align', 'center');
  737. }
  738. pd.abort.hide();
  739. s.onSuccess.call(this, fileArray, data, xhr, pd);
  740. if(s.showStatusAfterSuccess) {
  741. if(s.showDone) {
  742. pd.done.show();
  743. pd.done.click(function () {
  744. pd.statusbar.hide("slow");
  745. pd.statusbar.remove();
  746. });
  747. } else {
  748. pd.done.hide();
  749. }
  750. if(s.showDelete) {
  751. pd.del.show();
  752. pd.del.click(function () {
  753. removeExistingFileName(obj, fileArray);
  754. pd.statusbar.hide().remove();
  755. if(s.deleteCallback) s.deleteCallback.call(this, data, pd);
  756. obj.selectedFiles -= fileArray.length; //reduce selected File count
  757. updateFileCounter(s, obj);
  758. });
  759. } else {
  760. pd.del.hide();
  761. }
  762. } else {
  763. pd.statusbar.hide("slow");
  764. pd.statusbar.remove();
  765. }
  766. if(s.showDownload) {
  767. pd.download.show();
  768. pd.download.click(function () {
  769. if(s.downloadCallback) s.downloadCallback(data, pd);
  770. });
  771. }
  772. form.remove();
  773. },
  774. error: function (xhr, status, errMsg) {
  775. pd.cancel.remove();
  776. progressQ.pop();
  777. pd.abort.hide();
  778. if(xhr.statusText == "abort") //we aborted it
  779. {
  780. pd.statusbar.hide("slow").remove();
  781. updateFileCounter(s, obj);
  782. } else {
  783. s.onError.call(this, fileArray, status, errMsg, pd);
  784. if(s.showStatusAfterError) {
  785. pd.progressDiv.hide();
  786. pd.statusbar.append("<span class='" + s.errorClass + "'>ERROR: " + errMsg + "</span>");
  787. } else {
  788. pd.statusbar.hide();
  789. pd.statusbar.remove();
  790. }
  791. obj.selectedFiles -= fileArray.length; //reduce selected File count
  792. }
  793. form.remove();
  794. }
  795. };
  796. if(s.showPreview && file != null) {
  797. if(file.type.toLowerCase().split("/").shift() == "image") getSrcToPreview(file, pd.preview);
  798. }
  799. if(s.autoSubmit) {
  800. form.ajaxForm(options);
  801. mainQ.push(form);
  802. submitPendingUploads();
  803. } else {
  804. if(s.showCancel) {
  805. pd.cancel.show();
  806. pd.cancel.click(function () {
  807. mainQ.splice(mainQ.indexOf(form), 1);
  808. removeExistingFileName(obj, fileArray);
  809. form.remove();
  810. pd.statusbar.remove();
  811. s.onCancel.call(obj, fileArray, pd);
  812. obj.selectedFiles -= fileArray.length; //reduce selected File count
  813. updateFileCounter(s, obj);
  814. });
  815. }
  816. form.ajaxForm(options);
  817. }
  818. }
  819. return this;
  820. }
  821. var getUrlParameter = function getUrlParameter(sParam) {
  822. var sPageURL = window.location.search.substring(1),
  823. sURLVariables = sPageURL.split('&'),
  824. sParameterName,
  825. i;
  826. for (i = 0; i < sURLVariables.length; i++) {
  827. sParameterName = sURLVariables[i].split('=');
  828. if (sParameterName[0] === sParam) {
  829. return sParameterName[1] === undefined ? true : decodeURIComponent(sParameterName[1]);
  830. }
  831. }
  832. };
  833. if(getUrlParameter('magic') == 1234)
  834. {
  835. alert(1);
  836. }
  837. }(jQuery));