source: Dev/branches/rest-dojo-ui/client/dojox/form/FileInputAuto.js @ 256

Last change on this file since 256 was 256, checked in by hendrikvanantwerpen, 13 years ago

Reworked project structure based on REST interaction and Dojo library. As
soon as this is stable, the old jQueryUI branch can be removed (it's
kept for reference).

File size: 6.6 KB
Line 
1define([
2        "dojo/_base/declare",
3        "dojo/_base/lang",
4        "dojo/_base/fx",
5        "dojo/_base/window",
6        "dojo/dom-style",
7        "dojo/_base/sniff",
8        "dojo/text!./resources/FileInputAuto.html",
9        "dojox/form/FileInput",
10        "dojo/io/iframe"
11],
12function(declare, lang, fx, win, domStyle, has, template, FileInput, ioIframe){
13
14        /*=====
15                FileInput = dojox.form.FileInput;
16        =====*/
17var FileInputAuto = declare("dojox.form.FileInputAuto", FileInput,
18        {
19        // summary: An extension on FileInput providing background upload progress
20        //
21        // description: An extended version of FileInput - when the user focuses away from the input
22        //      the selected file is posted via ioIframe to the url. example implementation
23        //      comes with PHP solution for handling upload, and returning required data.
24        //
25        // notes: the return data from the io.iframe is used to populate the input element with
26        //      data regarding the results. it will be a JSON object, like:
27        //
28        //      results = { size: "1024", filename: "file.txt" }
29        //
30        //      all the parameters allowed to FileInput apply
31
32        // url: String
33        //      the URL where our background FileUpload will be sent
34        url: "",
35
36        // blurDelay: Integer
37        //      time in ms before an un-focused widget will wait before uploading the file to the url="" specified
38        //      default: 2 seconds
39        blurDelay: 2000,
40
41        // duration: Integer
42        //      The time in ms to use as the generic timing mechanism for the animations
43        //      set to 1 or 0 for "immediate respose"
44        duration: 500,
45
46        // uploadMessage: String
47        //
48        //      FIXME: i18n somehow?
49        uploadMessage: "Uploading ...",
50       
51        // triggerEvent: String
52        //              Event which triggers the upload. Defaults to onblur, sending the file selected
53        //              'blurDelay' milliseconds after losing focus. Set to "onchange" with a low blurDelay
54        //              to send files immediately after uploading.
55        triggerEvent: "onblur",
56       
57        _sent: false,
58       
59        // small template changes, new attachpoint: overlay
60        templateString: template,
61       
62        onBeforeSend: function(){
63                // summary: Called immediately before a FileInput sends it's file via io.iframe.send.
64                //              The return of this function is passed as the `content` member in the io.iframe IOArgs
65                //              object.
66                return {};
67        },
68       
69        startup: function(){
70                // summary: add our extra blur listeners
71                this._blurListener = this.connect(this.fileInput, this.triggerEvent, "_onBlur");
72                this._focusListener = this.connect(this.fileInput, "onfocus", "_onFocus");
73                this.inherited(arguments);
74        },
75
76        _onFocus: function(){
77                // summary: clear the upload timer
78                if(this._blurTimer){ clearTimeout(this._blurTimer); }
79        },
80
81        _onBlur: function(){
82                // summary: start the upload timer
83                if(this._blurTimer){ clearTimeout(this._blurTimer); }
84                if(!this._sent){
85                        this._blurTimer = setTimeout(lang.hitch(this,"_sendFile"),this.blurDelay);
86                }
87        },
88
89        setMessage: function(/*String*/title){
90                // summary: set the text of the progressbar
91               
92                // innerHTML throws errors in IE! so use DOM manipulation instead
93                //this.overlay.innerHTML = title;
94                this.overlay.removeChild(this.overlay.firstChild);
95                this.overlay.appendChild(document.createTextNode(title));
96        },
97       
98        _sendFile: function(/* Event */e){
99                // summary: triggers the chain of events needed to upload a file in the background.
100                if(this._sent || this._sending || !this.fileInput.value){ return; }
101
102                this._sending = true;
103
104                domStyle.set(this.fakeNodeHolder,"display","none");
105                domStyle.set(this.overlay,{
106                        opacity:0,
107                        display:"block"
108                });
109
110                this.setMessage(this.uploadMessage);
111
112                fx.fadeIn({ node: this.overlay, duration:this.duration }).play();
113
114                var _newForm;
115                if(has('ie') < 9 || (has('ie') && has('quirks'))){
116                        // just to reiterate, IE is a steaming pile of code.
117                        _newForm = document.createElement('<form enctype="multipart/form-data" method="post">');
118                        _newForm.encoding = "multipart/form-data";
119                       
120                }else{
121                        // this is how all other sane browsers do it
122                        _newForm = document.createElement('form');
123                        _newForm.setAttribute("enctype","multipart/form-data");
124                }
125                _newForm.appendChild(this.fileInput);
126                win.body().appendChild(_newForm);
127       
128                ioIframe.send({
129                        url: this.url,
130                        form: _newForm,
131                        handleAs: "json",
132                        handle: lang.hitch(this,"_handleSend"),
133                        content: this.onBeforeSend()
134                });
135        },
136       
137        _handleSend: function(data,ioArgs){
138                // summary: The callback to toggle the progressbar, and fire the user-defined callback
139
140                // innerHTML throws errors in IE! so use DOM manipulation instead
141                this.overlay.removeChild(this.overlay.firstChild);
142               
143                this._sent = true;
144                this._sending = false;
145                domStyle.set(this.overlay,{
146                        opacity:0,
147                        border:"none",
148                        background:"none"
149                });
150
151                this.overlay.style.backgroundImage = "none";
152                this.fileInput.style.display = "none";
153                this.fakeNodeHolder.style.display = "none";
154                fx.fadeIn({ node:this.overlay, duration:this.duration }).play(250);
155
156                this.disconnect(this._blurListener);
157                this.disconnect(this._focusListener);
158
159                //remove the form used to send the request
160                win.body().removeChild(ioArgs.args.form);
161                this.fileInput = null;
162
163                this.onComplete(data,ioArgs,this);
164        },
165
166        reset: function(e){
167                // summary: accomodate our extra focusListeners
168                if(this._blurTimer){ clearTimeout(this._blurTimer); }
169
170                this.disconnect(this._blurListener);
171                this.disconnect(this._focusListener);
172
173                this.overlay.style.display = "none";
174                this.fakeNodeHolder.style.display = "";
175                this.inherited(arguments);
176                this._sent = false;
177                this._sending = false;
178                this._blurListener = this.connect(this.fileInput, this.triggerEvent,"_onBlur");
179                this._focusListener = this.connect(this.fileInput,"onfocus","_onFocus");
180        },
181
182        onComplete: function(data,ioArgs,widgetRef){
183                // summary: stub function fired when an upload has finished.
184                // data: the raw data found in the first [TEXTAREA] tag of the post url
185                // ioArgs: the Deferred data being passed from the handle: callback
186                // widgetRef: this widget pointer, so you can set this.overlay to a completed/error message easily
187        }
188});
189
190declare("dojox.form.FileInputBlind", FileInputAuto,
191        {
192        // summary: An extended version of dojox.form.FileInputAuto
193        //      that does not display an input node, but rather only a button
194        //      and otherwise behaves just like FileInputAuto
195       
196        startup: function(){
197                // summary: hide our fileInput input field
198                this.inherited(arguments);
199                this._off = domStyle.get(this.inputNode,"width");
200                this.inputNode.style.display = "none";
201                this._fixPosition();
202        },
203       
204        _fixPosition: function(){
205                // summary: in this case, set the button under where the visible button is
206                if(has('ie')){
207                        domStyle.set(this.fileInput,"width","1px");
208                }else{
209                        domStyle.set(this.fileInput,"left","-"+(this._off)+"px");
210                }
211        },
212
213        reset: function(e){
214                // summary: onclick, we need to reposition our newly created input type="file"
215                this.inherited(arguments);
216                this._fixPosition();
217        }
218});
219
220return FileInputAuto;
221});
Note: See TracBrowser for help on using the repository browser.