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
+
12
+
13
+ ( function ( $ ) {
14
+
15
+ var settings = {
16
+ params : { } ,
17
+ action : '' ,
18
+ onStart : function ( ) { console . log ( 'starting upload' ) ; console . log ( this ) ; } ,
19
+ onComplete : function ( response ) { console . log ( 'got response: ' ) ; console . log ( response ) ; console . log ( this ) ; } ,
20
+ onCancel : function ( ) { console . log ( 'cancelling: ' ) ; console . log ( this ) ; }
21
+ } ;
22
+
23
+ /*
24
+ // Internal handler that tries to parse the response
25
+ // and clean up after ourselves.
26
+ */
27
+ var handleResponse = function ( loadedFrame , element ) {
28
+ var response , responseStr = loadedFrame . contentWindow . document . body . innerHTML ;
29
+ try {
30
+ response = JSON . parse ( responseStr ) ;
31
+ } catch ( e ) {
32
+ response = responseStr ;
33
+ }
34
+
35
+ // Tear-down the wrapper form
36
+ element . siblings ( ) . remove ( ) ;
37
+ element . unwrap ( ) ;
38
+
39
+ // Pass back to the user
40
+ settings . onComplete . apply ( element , [ response , settings . params ] ) ;
41
+ } ;
42
+
43
+
44
+ /*
45
+ // Wraps element in a <form> tag, and inserts hidden inputs for each
46
+ // key:value pair in settings.params so they can be sent along with
47
+ // the upload. Then, creates an iframe that the whole thing is
48
+ // uploaded through.
49
+ */
50
+ var wrapElement = function ( element ) {
51
+ // Create an iframe to submit through, using a semi-unique ID
52
+ var frame_id = 'ajaxUploader-iframe-' + Math . round ( new Date ( ) . getTime ( ) / 1000 )
53
+ $ ( 'body' ) . after ( '<iframe width="0" height="0" style="display:none;" name="' + frame_id + '" id="' + frame_id + '"/>' ) ;
54
+ $ ( '#' + frame_id ) . load ( function ( ) {
55
+ handleResponse ( this , element ) ;
56
+ } ) ;
57
+
58
+ // Wrap it in a form
59
+ element . wrap ( function ( ) {
60
+ return '<form action="' + settings . action + '" method="POST" enctype="multipart/form-data" target="' + frame_id + '" />'
61
+ } )
62
+ // Insert <input type='hidden'>'s for each param
63
+ . after ( function ( ) {
64
+ var key , html = '' ;
65
+ for ( key in settings . params ) {
66
+ html += '<input type="hidden" name="' + key + '" value="' + settings . params [ key ] + '" />' ;
67
+ }
68
+ return html ;
69
+ } ) ;
70
+ }
71
+
72
+
73
+ $ . fn . ajaxfileupload = function ( options ) {
74
+ if ( options ) {
75
+ $ . extend ( settings , options ) ;
76
+ }
77
+
78
+ // 'this' is a jQuery collection of one or more (hopefully)
79
+ // file elements, but doesn't check for this yet
80
+ return this . each ( function ( ) {
81
+ var $element = $ ( this ) ;
82
+
83
+ // Skip elements that are already setup. May replace this
84
+ // with uninit() later, to allow updating that settings
85
+ if ( $element . data ( 'ajaxUploader-setup' ) === true ) return ;
86
+
87
+ $element . change ( function ( ) {
88
+ if ( $element . val ( ) == '' ) return settings . doCancel . apply ( $element , [ settings . params ] ) ;
89
+
90
+ // Creates the form, extra inputs and iframe used to
91
+ // submit / upload the file
92
+ wrapElement ( $element ) ;
93
+
94
+ // Call user-supplied (or default) onStart(), setting
95
+ // it's this context to the file DOM element
96
+ var ret = settings . onStart . apply ( $element ) ;
97
+
98
+ // let onStart have the option to cancel the upload
99
+ if ( ret !== false )
100
+ {
101
+ $element . parent ( 'form' ) . submit ( ) ;
102
+ }
103
+ } ) ;
104
+
105
+ // Mark this element as setup
106
+ $element . data ( 'ajaxUploader-setup' , true ) ;
107
+ } ) ;
108
+ }
109
+ } ) ( jQuery )
0 commit comments