jquery.ajaxfileupload.js 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. /*
  2. // jQuery Ajax File Uploader
  3. //
  4. // @author: Jordan Feldstein <jfeldstein.com>
  5. //
  6. // - Ajaxifies an individual <input type="file">
  7. // - Files are sandboxed. Doesn't matter how many, or where they are, on the page.
  8. // - Allows for extra parameters to be included with the file
  9. // - onStart callback can cancel the upload by returning false
  10. */
  11. (function($) {
  12. $.fn.ajaxfileupload = function(options) {
  13. var settings = {
  14. params: {},
  15. action: '',
  16. onStart: function() { },
  17. onComplete: function(response) { },
  18. onCancel: function() { },
  19. validate_extensions : true,
  20. valid_extensions : ['gif','png','jpg','jpeg'],
  21. submit_button : null
  22. };
  23. var uploading_file = false;
  24. if ( options ) {
  25. $.extend( settings, options );
  26. }
  27. // 'this' is a jQuery collection of one or more (hopefully)
  28. // file elements, but doesn't check for this yet
  29. return this.each(function() {
  30. var $element = $(this);
  31. // Skip elements that are already setup. May replace this
  32. // with uninit() later, to allow updating that settings
  33. if($element.data('ajaxUploader-setup') === true) return;
  34. $element.change(function()
  35. {
  36. // since a new image was selected, reset the marker
  37. uploading_file = false;
  38. // only update the file from here if we haven't assigned a submit button
  39. if (settings.submit_button == null)
  40. {
  41. upload_file();
  42. }
  43. });
  44. if (settings.submit_button == null)
  45. {
  46. // do nothing
  47. } else
  48. {
  49. settings.submit_button.click(function(e)
  50. {
  51. // Prevent non-AJAXy submit
  52. e.preventDefault();
  53. // only attempt to upload file if we're not uploading
  54. if (!uploading_file)
  55. {
  56. upload_file();
  57. }
  58. });
  59. }
  60. var upload_file = function()
  61. {
  62. if($element.val() == '') return settings.onCancel.apply($element, [settings.params]);
  63. // make sure extension is valid
  64. var ext = $element.val().split('.').pop().toLowerCase();
  65. if(true === settings.validate_extensions && $.inArray(ext, settings.valid_extensions) == -1)
  66. {
  67. // Pass back to the user
  68. settings.onComplete.apply($element, [{status: false, message: '文件类型必须为: ' + settings.valid_extensions.join(', ') + '.'}, settings.params]);
  69. } else
  70. {
  71. uploading_file = true;
  72. // Creates the form, extra inputs and iframe used to
  73. // submit / upload the file
  74. wrapElement($element);
  75. // Call user-supplied (or default) onStart(), setting
  76. // it's this context to the file DOM element
  77. var ret = settings.onStart.apply($element, [settings.params]);
  78. // let onStart have the option to cancel the upload
  79. if(ret !== false)
  80. {
  81. $element.parent('form').submit(function(e) { e.stopPropagation(); }).submit();
  82. } else {
  83. uploading_file = false;
  84. }
  85. }
  86. };
  87. // Mark this element as setup
  88. $element.data('ajaxUploader-setup', true);
  89. /*
  90. // Internal handler that tries to parse the response
  91. // and clean up after ourselves.
  92. */
  93. var handleResponse = function(loadedFrame, element) {
  94. var response, responseStr = $(loadedFrame).contents().text();
  95. try {
  96. //response = $.parseJSON($.trim(responseStr));
  97. response = JSON.parse(responseStr);
  98. } catch(e) {
  99. response = responseStr;
  100. }
  101. // Tear-down the wrapper form
  102. element.siblings().remove();
  103. element.unwrap();
  104. uploading_file = false;
  105. // Pass back to the user
  106. settings.onComplete.apply(element, [response, settings.params]);
  107. };
  108. /*
  109. // Wraps element in a <form> tag, and inserts hidden inputs for each
  110. // key:value pair in settings.params so they can be sent along with
  111. // the upload. Then, creates an iframe that the whole thing is
  112. // uploaded through.
  113. */
  114. var wrapElement = function(element) {
  115. // Create an iframe to submit through, using a semi-unique ID
  116. var frame_id = 'ajaxUploader-iframe-' + Math.round(new Date().getTime() / 1000)
  117. $('body').after('<iframe width="0" height="0" style="display:none;" name="'+frame_id+'" id="'+frame_id+'"/>');
  118. $('#'+frame_id).get(0).onload = function() {
  119. handleResponse(this, element);
  120. };
  121. // Wrap it in a form
  122. element.wrap(function() {
  123. return '<form action="' + settings.action + '" method="POST" enctype="multipart/form-data" target="'+frame_id+'" />'
  124. })
  125. // Insert <input type='hidden'>'s for each param
  126. .before(function() {
  127. var key, html = '';
  128. for(key in settings.params) {
  129. var paramVal = settings.params[key];
  130. if (typeof paramVal === 'function') {
  131. paramVal = paramVal();
  132. }
  133. html += '<input type="hidden" name="' + key + '" value="' + paramVal + '" />';
  134. }
  135. return html;
  136. });
  137. }
  138. });
  139. }
  140. })( jQuery )