source: Dev/trunk/src/client/dojox/form/FilePickerTextBox.js @ 536

Last change on this file since 536 was 483, checked in by hendrikvanantwerpen, 11 years ago

Added Dojo 1.9.3 release.

File size: 9.2 KB
Line 
1define([
2        "dojo/_base/lang",
3        "dojo/_base/array",
4        "dojo/_base/event",
5        "dojo/window",
6        "dijit/focus",
7        "dijit/registry",
8        "dijit/form/_TextBoxMixin",
9        "dijit/form/ValidationTextBox",
10        "dijit/_HasDropDown",
11        "dojox/widget/FilePicker",
12        "dojo/text!./resources/FilePickerTextBox.html",
13        "dojo/_base/declare",
14        "dojo/keys" // keys
15], function(lang, array, event, windowUtils, focus, registry, _TextBoxMixin, ValidationTextBox, _HasDropDown, FilePicker, template, declare, keys){
16
17        return declare( "dojox.form.FilePickerTextBox", [ValidationTextBox, _HasDropDown], {
18                // summary:
19                //              A validating text box tied to a file picker popup
20
21                baseClass: "dojoxFilePickerTextBox",
22
23                templateString: template,
24
25                // searchDelay: Integer
26                //              Delay in milliseconds between when user types something and we start
27                //              searching based on that value
28                searchDelay: 500,
29
30                // valueItem: item
31                //              The item, in our store, of the directory relating to our value
32                valueItem: null,
33
34                // numPanes: number
35                //              The number of panes to display in our box (if we don't have any
36                //              minPaneWidth specified by our constraints)
37                numPanes: 2.25,
38
39                postMixInProperties: function(){
40                        this.inherited(arguments);
41                        this.dropDown = new FilePicker(this.constraints);
42                },
43
44                postCreate: function(){
45                        this.inherited(arguments);
46                        // Make our connections we want
47                        this.connect(this.dropDown, "onChange", this._onWidgetChange);
48                        this.connect(this.focusNode, "onblur", "_focusBlur");
49                        this.connect(this.focusNode, "onfocus", "_focusFocus");
50                        this.connect(this.focusNode, "ondblclick", function(){
51                                _TextBoxMixin.selectInputText(this.focusNode);
52                        });
53                },
54
55                _setValueAttr: function(/*String*/ value, priorityChange, fromWidget){
56                        // summary:
57                        //              sets the value of this widget
58                        if(!this._searchInProgress){
59                                this.inherited(arguments);
60                                value = value || "";
61                                var tVal = this.dropDown.get("pathValue") || "";
62                                if(value !== tVal){
63                                        this._skip = true;
64                                        var fx = lang.hitch(this, "_setBlurValue");
65                                        this.dropDown._setPathValueAttr(value, !fromWidget,
66                                                                                        this._settingBlurValue ? fx : null);
67                                }
68                        }
69                },
70
71                _onWidgetChange: function(/*item*/ item){
72                        // summary:
73                        //              called when the path gets changed in the dropdown
74                        if(!item && this.focusNode.value){
75                                this._hasValidPath = false;
76                                this.focusNode.value = "";
77                        }else{
78                                this.valueItem = item;
79                                var value = this.dropDown._getPathValueAttr(item);
80                                if(value){
81                                        this._hasValidPath = true;
82                                }
83                                if(!this._skip){
84                                        this._setValueAttr(value, undefined, true);
85                                }
86                                delete this._skip;
87                        }
88                        this.validate();
89                },
90
91                startup: function(){
92                        if(!this.dropDown._started){
93                                this.dropDown.startup();
94                        }
95                        this.inherited(arguments);
96                },
97
98                openDropDown: function(){
99                        // set width to 0 so that it will resize automatically
100                        this.dropDown.domNode.style.width="0px";
101                        if(!("minPaneWidth" in (this.constraints||{}))){
102                                this.dropDown.set("minPaneWidth", (this.domNode.offsetWidth / this.numPanes));
103                        }
104                        this.inherited(arguments);
105                },
106
107                toggleDropDown: function(){
108                        this.inherited(arguments);
109                        // Make sure our display is up-to-date with our value
110                        if(this._opened){
111                                this.dropDown.set("pathValue", this.get("value"));
112                        }
113                },
114
115                _focusBlur: function(/*Event*/ e){
116                        // summary:
117                        //              called when the focus node gets blurred
118                        if(e.explicitOriginalTarget == this.focusNode && !this._allowBlur){
119                                window.setTimeout(lang.hitch(this, function(){
120                                        if(!this._allowBlur){
121                                                this.focus();
122                                        }
123                                }), 1);
124                        }else if(this._menuFocus){
125                                this.dropDown._updateClass(this._menuFocus, "Item", {"Hover": false});
126                                delete this._menuFocus;
127                        }
128                },
129
130                _focusFocus: function(/*Event*/ e){
131                        // summary:
132                        //              called when the focus node gets focus
133                        if(this._menuFocus){
134                                this.dropDown._updateClass(this._menuFocus, "Item", {"Hover": false});
135                        }
136                        delete this._menuFocus;
137                        var focusNode = focus.curNode;
138                        if(focusNode){
139                                focusNode = registry.byNode(focusNode);
140                                if(focusNode){
141                                        this._menuFocus = focusNode.domNode;
142                                }
143                        }
144                        if(this._menuFocus){
145                                this.dropDown._updateClass(this._menuFocus, "Item", {"Hover": true});
146                        }
147                        delete this._allowBlur;
148                },
149
150                _onBlur: function(){
151                        // summary:
152                        //              called when focus is shifted away from this widget
153                        this._allowBlur = true;
154                        delete this.dropDown._savedFocus;
155                        this.inherited(arguments);
156                },
157
158                _setBlurValue: function(){
159                        // summary:
160                        //              sets the value of the widget once focus has left
161                        if(this.dropDown && !this._settingBlurValue){
162                                this._settingBlurValue = true;
163                                this.set("value", this.focusNode.value);
164                        }else{
165                                delete this._settingBlurValue;
166                                this.inherited(arguments);
167                        }
168                },
169
170                parse: function(/*String*/ value, /*Object*/ constraints){
171                        // summary:
172                        //              Function to convert a formatted string to a value - we use
173                        //              it to verify that it *really* is a valid value
174                        if(this._hasValidPath || this._hasSelection){
175                                return value;
176                        }
177                        var dd = this.dropDown, topDir = dd.topDir, sep = dd.pathSeparator;
178                        var ddVal = dd.get("pathValue");
179                        var norm = function(v){
180                                if(topDir.length && v.indexOf(topDir) === 0){
181                                        v = v.substring(topDir.length);
182                                }
183                                if(sep && v[v.length - 1] == sep){
184                                        v = v.substring(0, v.length - 1);
185                                }
186                                return v;
187                        };
188                        ddVal = norm(ddVal);
189                        var val = norm(value);
190                        if(val == ddVal){
191                                return value;
192                        }
193                        return undefined;
194                },
195
196                _startSearchFromInput: function(){
197                        // summary:
198                        //              kicks off a search based off the current text value of the widget
199                        var dd = this.dropDown, fn = this.focusNode;
200                        var val = fn.value, oVal = val, topDir = dd.topDir;
201                        if(this._hasSelection){
202                                _TextBoxMixin.selectInputText(fn, oVal.length);
203                        }
204                        this._hasSelection = false;
205                        if(topDir.length && val.indexOf(topDir) === 0){
206                                val = val.substring(topDir.length);
207                        }
208                        var dirs = val.split(dd.pathSeparator);
209                        var setFromChain = lang.hitch(this, function(idx){
210                                var dir = dirs[idx];
211                                var child = dd.getChildren()[idx];
212                                var conn;
213                                this._searchInProgress = true;
214                                var _cleanup = lang.hitch(this, function(){
215                                        delete this._searchInProgress;
216                                });
217                                if((dir || child) && !this._opened){
218                                        this.toggleDropDown();
219                                }
220                                if(dir && child){
221                                        var fx = lang.hitch(this, function(){
222                                                if(conn){
223                                                        this.disconnect(conn);
224                                                }
225                                                delete conn;
226                                                var children = child._menu.getChildren();
227                                                var exact = array.filter(children, function(i){
228                                                        return i.label == dir;
229                                                })[0];
230                                                var first = array.filter(children, function(i){
231                                                        return (i.label.indexOf(dir) === 0);
232                                                })[0];
233                                                if(exact &&
234                                                        ((dirs.length > idx + 1 && exact.children) ||
235                                                        (!exact.children))){
236                                                        idx++;
237                                                        child._menu.onItemClick(exact, {type: "internal",
238                                                                                                        stopPropagation: function(){},
239                                                                                                        preventDefault: function(){}});
240                                                        if(dirs[idx]){
241                                                                setFromChain(idx);
242                                                        }else{
243                                                                _cleanup();
244                                                        }
245                                                }else{
246                                                        child._setSelected(null);
247                                                        if(first && dirs.length === idx + 1){
248                                                                dd._setInProgress = true;
249                                                                dd._removeAfter(child);
250                                                                delete dd._setInProgress;
251                                                                var targetString = first.label;
252                                                                if(first.children){
253                                                                        targetString += dd.pathSeparator;
254                                                                }
255                                                                targetString = targetString.substring(dir.length);
256                                                                window.setTimeout(function(){
257                                                                        windowUtils.scrollIntoView(first.domNode);
258                                                                }, 1);
259                                                                fn.value = oVal + targetString;
260                                                                _TextBoxMixin.selectInputText(fn, oVal.length);
261                                                                this._hasSelection = true;
262                                                                try{first.focusNode.focus();}catch(e){}
263                                                        }else{
264                                                                if(this._menuFocus){
265                                                                        this.dropDown._updateClass(this._menuFocus, "Item", {"Hover": false, "Focus": false});
266                                                                }
267                                                                delete this._menuFocus;
268                                                        }
269                                                        _cleanup();
270                                                }
271                                        });
272                                        if(!child.isLoaded){
273                                                conn = this.connect(child, "onLoad", fx);
274                                        }else{
275                                                fx();
276                                        }
277                                }else{
278                                        if(child){
279                                                child._setSelected(null);
280                                                dd._setInProgress = true;
281                                                dd._removeAfter(child);
282                                                delete dd._setInProgress;
283                                        }
284                                        _cleanup();
285                                }
286                        });
287                        setFromChain(0);
288                },
289
290                _onKey: function(/*Event*/ e){
291                        // summary:
292                        //              callback when the user presses a key on menu popup node
293                        if(this.disabled || this.readOnly){ return; }
294                        var c = e.charOrCode;
295                        if(c==keys.DOWN_ARROW){
296                                this._allowBlur = true;
297                        }
298                        if(c==keys.ENTER && this._opened){
299                                this.dropDown.onExecute();
300                                _TextBoxMixin.selectInputText(this.focusNode, this.focusNode.value.length);
301                                this._hasSelection = false;
302                                event.stop(e);
303                                return;
304                        }
305                        if((c==keys.RIGHT_ARROW || c==keys.LEFT_ARROW || c==keys.TAB) && this._hasSelection){
306                                this._startSearchFromInput();
307                                event.stop(e);
308                                return;
309                        }
310                        this.inherited(arguments);
311                        var doSearch = false;
312                        if((c==keys.BACKSPACE || c==keys.DELETE) && this._hasSelection){
313                                this._hasSelection = false;
314                        }else if(c==keys.BACKSPACE || c==keys.DELETE || c==" "){
315                                doSearch = true;
316                        }else{
317                                doSearch = e.keyChar !== "";
318                        }
319                        if(this._searchTimer){
320                                window.clearTimeout(this._searchTimer);
321                        }
322                        delete this._searchTimer;
323                        if(doSearch){
324                                this._hasValidPath = false;
325                                this._hasSelection = false;
326                                this._searchTimer = window.setTimeout(lang.hitch(this, "_startSearchFromInput"), this.searchDelay + 1);
327                        }
328                }
329        });
330});
Note: See TracBrowser for help on using the repository browser.