Changeset 14229

Show
Ignore:
Timestamp:
07/02/08 08:56:50 (6 months ago)
Author:
toonetown
Message:

Refs #7033 - Update focus handling in rolling list and add in ability to set and get value by path on the file picker !strict

Location:
dojox/trunk/widget
Files:
6 modified

Legend:

Unmodified
Added
Removed
  • dojox/trunk/widget/FilePicker.js

    r14217 r14229  
    77 
    88dojo.declare("dojox.widget._FileInfoPane",  
    9         [dojox.widget._RollingListPane, dijit._Templated], { 
     9        [dojox.widget._RollingListPane], { 
    1010        // summary: a pane to display the information for the currently-selected 
    1111        //      file 
     
    4343        className: "dojoxFilePicker", 
    4444         
     45        // fileSeparator: string 
     46        //  Our file separator - it will be guessed if not set 
     47        fileSeparator: "", 
     48         
     49        // topDir: string 
     50        //      The top directory string - it will be guessed if not set 
     51        topDir: "", 
     52                 
    4553        // parentAttr: string 
    4654        //      the attribute to read for finding our parent directory 
    4755        parentAttr: "parentDir", 
     56         
     57        // pathAttr: string 
     58        //  the attribute to read for getting the full path of our file 
     59        pathAttr: "path", 
     60         
     61        startup: function(){ 
     62                if(this._started){ return; } 
     63                this.inherited(arguments); 
     64                // Figure out our file separator if we don't have it yet 
     65                var conn, child = this.getChildren()[0]; 
     66                var setSeparator = dojo.hitch(this, function(){ 
     67                        if(conn){ 
     68                                this.disconnect(conn); 
     69                        } 
     70                        delete conn; 
     71                        var item = child.items[0]; 
     72                        if(item){ 
     73                                var store = this.store; 
     74                                var parent = store.getValue(item, this.parentAttr); 
     75                                var path = store.getValue(item, this.pathAttr); 
     76                                if(!this.fileSeparator){ 
     77                                        this.fileSeparator = path.substring(parent.length, parent.length + 1); 
     78                                } 
     79                                if(!this.topDir){ 
     80                                        this.topDir = parent; 
     81                                } 
     82                        } 
     83                }); 
     84                if(!this.fileSeparator || !this.topDir){ 
     85                        if(!child.items){ 
     86                                conn = this.connect(child, "onItems", setSeparator); 
     87                        }else{ 
     88                                setSeparator(); 
     89                        } 
     90                } 
     91        }, 
    4892         
    4993        getChildItems: function(item){ 
     
    5498                } 
    5599                return ret; 
     100        }, 
     101         
     102        _onChange: function(/*item*/val){ 
     103                this.onChange(); 
     104                if(this.store.isItem(val)){ 
     105                        this.onPathChange(this.store.getValue(val, this.pathAttr)); 
     106                }else{ 
     107                        this.onPathChange(""); 
     108                } 
    56109        }, 
    57110         
     
    81134        }, 
    82135         
     136        onPathChange: function(/*string*/ newPath){ 
     137                // Summary: called with the new path whenever a path has been changed 
     138        }, 
     139         
    83140        setValueFromString: function(/*string*/ path){ 
    84141                // Summary: sets the value of this widget based off the given path 
  • dojox/trunk/widget/FilePicker/FilePicker.css

    r14194 r14229  
    11@import url("../RollingList/RollingList.css"); 
     2 
     3.dojoxFileInfoPane *{ 
     4        white-space: normal; 
     5} 
    26 
    37.dojoxFileInfoLabel { 
    48        font-weight: bold; 
     9        white-space: nowrap; 
     10} 
     11 
     12.dojoxFileInfoPane { 
     13        width: 20em; 
    514} 
    615 
  • dojox/trunk/widget/RollingList.js

    r14217 r14229  
    1010 
    1111dojo.declare("dojox.widget._RollingListPane", 
    12         [dijit.layout.ContentPane, dijit._Contained], { 
     12        [dijit.layout.ContentPane, dijit._Templated, dijit._Contained], { 
    1313        // summary: a core pane that can be attached to a RollingList.  All panes 
    1414        //  should extend this one 
     15 
     16        // templateString: string 
     17        //      our template 
     18        templateString: '<div class="dojoxRollingListPane"><table><tbody><tr><td dojoAttachPoint="containerNode"></td></tr></tbody></div>', 
    1519 
    1620        // class: string 
     
    4650        queryOptions: null, 
    4751         
    48         _setContentAndScroll: function(cont){ 
     52        // focusByNode: boolean 
     53        //  set to false if the subclass will handle its own node focusing 
     54        _focusByNode: true, 
     55         
     56        _setContentAndScroll: function(/*String|DomNode|Nodelist*/cont){ 
    4957                // summary: sets the value of the content and scrolls it into view 
    5058                this._setContent(cont); 
     
    6472                        }), 1); 
    6573                } 
     74                this.connect(this.focusNode||this.domNode, "onkeypress", "_focusKey"); 
    6675                this.parentWidget._updateClass(this.domNode, "Pane"); 
    6776                this.inherited(arguments); 
    6877        }, 
    6978 
     79        _focusKey: function(/*Event*/e){ 
     80                // summary: called when a keypress happens on the widget 
     81                if(e.charOrCode == dojo.keys.LEFT_ARROW && this.parentPane){ 
     82                        this.parentPane.focus(); 
     83                        this.parentWidget.scrollIntoView(this.parentPane); 
     84                }else if(e.charOrCode == dojo.keys.ENTER){ 
     85                        this.parentWidget.onExecute(); 
     86                } 
     87        }, 
     88         
     89        focus: function(){ 
     90                // summary: sets the focus to this current widget 
     91                if(this.parentWidget._focusedPane != this){ 
     92                        this.parentWidget._focusedPane = this; 
     93                        this.parentWidget.scrollIntoView(this); 
     94                        if(this._focusByNode){ 
     95                                try{dijit.focus(this.focusNode||this.domNode);}catch(e){} 
     96                        } 
     97                } 
     98        }, 
     99         
    70100        _loadCheck: function(/* Boolean? */ forceLoad){ 
     101                // summary: checks that the store is loaded 
    71102                if(!this._started){ 
    72103                        var c = this.connect(this, "startup", function(){ 
     
    75106                        }); 
    76107                } 
    77                 // summary: checks that the store is loaded 
    78108                var displayState = this._isShown(); 
    79109                if((this.store || this.items) && (forceLoad || (this.refreshOnShow && displayState) || (!this.isLoaded && displayState))){ 
     
    199229 
    200230dojo.declare("dojox.widget._RollingListGroupPane", 
    201         [dojox.widget._RollingListPane, dijit._Templated], { 
     231        [dojox.widget._RollingListPane], { 
    202232        // summary: a pane that will handle groups (treats them as menu items) 
    203233         
     
    221251        }, 
    222252         
    223         _setContent: function(cont){ 
     253        _setContent: function(/*String|DomNode|Nodelist*/cont){ 
    224254                if(!this._menu){ 
    225255                        // Only set the content if we don't already have a menu 
     
    282312         
    283313        focus: function(){ 
     314                // summary: sets the focus to this current widget 
    284315                if(this._menu){ 
    285                         var focusDom = dojo.query(".dojoxRollingListItemSelected",  
    286                                                 this.domNode)[0] || this._menu.getChildren()[0].domNode; 
    287                         if(focusDom){ 
    288                                 var focusWidget = dijit.byNode(focusDom); 
    289                                 if(focusWidget && focusWidget.focusNode){ 
    290                                         focusWidget.focusNode.focus(); 
    291                                 } 
    292                         } 
    293                 }else{ 
    294                         var conn = this.connect(this, "onItems", function(){ 
    295                                 this.disconnect(conn); 
    296                                 this.focus(); 
    297                         });                      
     316                        if(this._pendingFocus){ 
     317                                this.disconnect(this._pendingFocus); 
     318                        } 
     319                        delete this._pendingFocus; 
     320                         
     321                        // We focus the right widget - either the focusedChild, the 
     322                        //   selected node, the first menu item, or the menu itself 
     323                        var focusWidget = this._menu.focusedChild; 
     324                        if(!focusWidget) 
     325                        { 
     326                                var focusNode = dojo.query(".dojoxRollingListItemSelected", this.domNode)[0]; 
     327                                if(focusNode){ 
     328                                        focusWidget = dijit.byNode(focusNode); 
     329                                } 
     330                        } 
     331                        if(!focusWidget){ 
     332                                focusWidget = this._menu.getChildren()[0] || this._menu; 
     333                        } 
     334                        this._focusByNode = false; 
     335                        if(focusWidget.focusNode){ 
     336                                try{dijit.focus(focusWidget.focusNode);}catch(e){} 
     337                        }else if(focusWidget.focus){ 
     338                                focusWidget.focus(); 
     339                        }else{ 
     340                                this._focusByNode = true; 
     341                        } 
     342                        this.inherited(arguments); 
     343                }else if(!this._pendingFocus){ 
     344                        this._pendingFocus = this.connect(this, "onItems", "focus"); 
    298345                } 
    299346        }, 
     
    305352                        parentMenu: this.parentPane ? this.parentPane._menu : null, 
    306353                        onCancel: function(/*Boolean*/ closeAll){  
    307                                 if(self.parentPane &&self.parentPane.focus){ 
     354                                if(self.parentPane){ 
    308355                                        self.parentPane.focus(); 
    309356                                } 
     
    318365                        if(item.disabled){ return; } 
    319366                        evt.alreadySelected = dojo.hasClass(item.domNode, "dojoxRollingListItemSelected"); 
    320                         if(evt.alreadySelected && evt.type == "keypress"){ 
     367                        if(evt.alreadySelected &&  
     368                                ((evt.type == "keypress" && evt.charOrCode != dojo.keys.ENTER) || 
     369                                (evt.type == "internal"))){ 
    321370                                var p = this.parentWidget.getChildren()[this.getIndexInParent() + 1]; 
    322                                 if(p && p.focus){ 
     371                                if(p){ 
    323372                                        p.focus(); 
    324                                 } 
    325                                 this.parentWidget.scrollIntoView(this); 
    326                                 return; 
    327                         } 
    328                         this._setSelected(item, menu); 
    329                         this.parentWidget._onItemClick(evt, this, item.item, item.children); 
     373                                        this.parentWidget.scrollIntoView(p); 
     374                                } 
     375                        }else{ 
     376                                this._setSelected(item, menu); 
     377                                this.parentWidget._onItemClick(evt, this, item.item, item.children); 
     378                                if(evt.type == "keypress" && evt.charOrCode == dojo.keys.ENTER){ 
     379                                        this.parentWidget.onExecute(); 
     380                                } 
     381                        } 
    330382                }); 
    331383                if(!menu._started){ 
     
    368420        // templateString: string 
    369421        //  our template string to use 
    370         templateString: '<div class="dojoxRollingList ${className}" dojoAttachPoint="containerNode"></div>', 
     422        templateString: '<div class="dojoxRollingList ${className}" dojoAttachPoint="containerNode" dojoAttachEvent="onkeypress:_onKey"></div>', 
    371423         
    372424        // className: string 
     
    393445        //      the attribute to read for finding our parent item (if any) 
    394446        parentAttr: "", 
    395          
    396         // scrollDuration: integer 
    397         //  time (in millis) to animate the smooth scroll across 
    398         scrollDuration: 150, 
    399447         
    400448        // value: item 
     
    430478                var selItem = null; 
    431479                while(child && !selItem){ 
    432                         var val = child._getSelected(); 
     480                        var val = child._getSelected ? child._getSelected() : null; 
    433481                        if(val){ 
    434482                                selItem = val.item; 
     
    453501                } 
    454502                this.layout(); 
    455                 this.scrollIntoView(widget, this.getChildren().length > 1); 
     503                widget.focus(); 
    456504        }, 
    457505         
     
    471519                                        dojo.toggleClass(node, c + type + k, options[k]); 
    472520                                } 
     521                                dojo.toggleClass(node, c + type + "FocusSelected",  
     522                                        (dojo.hasClass(node, c + type + "Focus") && dojo.hasClass(node, c + type + "Selected"))); 
     523                                dojo.toggleClass(node, c + type + "HoverSelected",  
     524                                        (dojo.hasClass(node, c + type + "Hover") && dojo.hasClass(node, c + type + "Selected"))); 
    473525                        } 
    474526                }); 
    475527        }, 
    476528         
    477         scrollIntoView: function(/* Widget */ childWidget, /* Boolean? */ doFocus){ 
    478                 // summary: smoothly scrolls the given widget into view 
    479                 window.setTimeout(dojo.hitch(this, function(){ 
    480                         var node = this.domNode; 
    481                         if(this._currentAnim && this._currentAnim.status() == "playing"){ 
    482                                 this._currentAnim.stop(); 
    483                         } 
    484                         delete this._currentAnim; 
    485                         var tgt = node.scrollWidth - node.clientWidth; 
    486                         var _doFocus = function(){ 
    487                                 if(doFocus && childWidget.focus){ 
    488                                         childWidget.focus(); 
    489                                 } 
    490                         }; 
    491                         if(node.scrollLeft != tgt){ 
    492                                 this._currentAnim = new dojo._Animation({ 
    493                                         curve: new dojo._Line(node.scrollLeft, tgt), 
    494                                         onAnimate: function(val){ 
    495                                                 node.scrollLeft = val; 
    496                                         }, 
    497                                         duration: this.scrollDuration, 
    498                                         onEnd: _doFocus 
    499                                 }).play(); 
    500                         }else{ 
    501                                 _doFocus(); 
    502                         } 
     529        scrollIntoView: function(/* Widget */ childWidget){ 
     530                // summary: scrolls the given widget into view 
     531                if(this._scrollingTimeout){  
     532                        window.clearTimeout(this._scrollingTimeout); 
     533                } 
     534                delete this._scrollingTimeout; 
     535                this._scrollingTimeout = window.setTimeout(dojo.hitch(this, function(){ 
     536                        if(childWidget.domNode){ 
     537                                dijit.scrollIntoView(childWidget.domNode); 
     538                        } 
     539                        delete this._scrollingTimeout; 
     540                        return; 
    503541                }), 1); 
    504542        }, 
     
    516554                        }); 
    517555                } 
    518                 this.scrollIntoView(children[children.length-1]); 
    519         }, 
    520          
     556                if(this._focusedPane){ 
     557                        var foc = this._focusedPane; 
     558                        delete this._focusedPane; 
     559                        foc.focus(); 
     560                }else if(children && children.length){ 
     561                        children[0].focus(); 
     562                } 
     563        }, 
     564         
     565        _onChange: function(/*item*/ value){ 
     566                this.onChange(value); 
     567        }, 
     568 
    521569        _setValue: function(/* item */ value){ 
    522570                // summary: internally sets the value and fires onchange 
     
    524572                if(!this._itemsMatch(this.value, value)){ 
    525573                        this.value = value; 
    526                         this.onChange(value); 
     574                        this._onChange(value); 
    527575                } 
    528576        }, 
     
    661709                }else if(pane){ 
    662710                        this._removeAfter(pane); 
     711                        this.scrollIntoView(pane); 
    663712                } 
    664713                if(!evt || evt.type != "internal"){ 
     
    732781                                        if(!this.disabled){try{dijit.focus(this.focusNode);}catch(e){}} 
    733782                                }; 
    734                                 widgetItem.connect(widgetItem.focusNode, "blur", function(){ 
     783                                widgetItem.connect(widgetItem.focusNode, "onmouseenter", function(){ 
     784                                        self._updateClass(this.domNode, "Item", {"Hover": true}); 
     785                                }); 
     786                                widgetItem.connect(widgetItem.focusNode, "onmouseleave", function(){ 
    735787                                        self._updateClass(this.domNode, "Item", {"Hover": false}); 
    736788                                }); 
     789                                widgetItem.connect(widgetItem.focusNode, "blur", function(){ 
     790                                        self._updateClass(this.domNode, "Item", {"Focus": false}); 
     791                                }); 
    737792                                widgetItem.connect(widgetItem.focusNode, "focus", function(){ 
    738                                         self._updateClass(this.domNode, "Item", {"Hover": true}); 
     793                                        self._updateClass(this.domNode, "Item", {"Focus": true}); 
     794                                        self._focusedPane = parentPane; 
     795                                }); 
     796                                widgetItem.connect(widgetItem.focusNode, "ondblclick", function(){ 
     797                                        self.onExecute(); 
    739798                                }); 
    740799                        } 
     
    752811        }, 
    753812         
     813        _onKey: function(/*Event*/ e){ 
     814                // summary: called when a keypress event happens on this widget 
     815                if(e.charOrCode == dojo.keys.ESCAPE && this._savedFocus){ 
     816                        try{dijit.focus(this._savedFocus);}catch(e){} 
     817                        delete this._savedFocus; 
     818                        dojo.stopEvent(e); 
     819                        return; 
     820                } 
     821                if(e.charOrCode == dojo.keys.LEFT_ARROW ||  
     822                        e.charOrCode == dojo.keys.RIGHT_ARROW){ 
     823                        dojo.stopEvent(e); 
     824                        return; 
     825                } 
     826        }, 
     827         
     828        handleKey:function(/*Event*/e){ 
     829                // summary: handle the key for the given event - called by dropdown 
     830                //      widgets 
     831                if(e.charOrCode == dojo.keys.DOWN_ARROW){ 
     832                        if(!this._focusedPane){ 
     833                                var child = this.getChildren()[0]; 
     834                                if(child){ 
     835                                        this._savedFocus = dijit.getFocus(this); 
     836                                        child.focus(); 
     837                                } 
     838                        }else{ 
     839                                this._savedFocus = dijit.getFocus(this); 
     840                                var foc = this._focusedPane; 
     841                                delete this._focusedPane; 
     842                                foc.focus(); 
     843                        } 
     844                        return false; 
     845                }else if(e.charOrCode == dojo.keys.ESCAPE){ 
     846                        this.onCancel(); 
     847                        return false; 
     848                } 
     849                return true; 
     850        }, 
     851 
    754852        startup: function(){ 
    755853                if(this._started){ return; } 
     
    797895        }, 
    798896         
     897        onExecute: function(){ 
     898                // summary: exists so that popups don't disappear too soon 
     899        }, 
     900         
     901        onCancel: function(){ 
     902                // summary: exists so that we can close ourselves if we wish 
     903        }, 
     904         
    799905        onChange: function(/* item */ value){ 
    800906                // summary: called when the value of this widget has changed 
  • dojox/trunk/widget/RollingList/RollingList.css

    r14194 r14229  
    3636        background-color: #f7f7f7; 
    3737} 
    38 .tundra .dojoxRollingListPane .dojoxRollingListItemHover { 
     38.tundra .dojoxRollingListPane .dojoxRollingListItemHover, 
     39.tundra .dojoxRollingListPane .dojoxRollingListItemFocus { 
    3940        background-color: #e3e3e3; 
    4041} 
     
    4344        background-color: #3559ac; 
    4445        font-weight: bold; 
     46} 
     47.tundra .dojoxRollingListPane .dojoxRollingListItemHoverSelected, 
     48.tundra .dojoxRollingListPane .dojoxRollingListItemFocusSelected { 
     49        background-color: #9aacd6; 
    4550} 
    4651.tundra .dojoxRollingListItem { 
     
    5156        background-color: #fff; 
    5257} 
    53 .soria .dojoxRollingListPane .dojoxRollingListItemHover { 
     58.soria .dojoxRollingListPane .dojoxRollingListItemHover,  
     59.soria .dojoxRollingListPane .dojoxRollingListItemFocus { 
    5460        background-color: #e3e3e3; 
    5561} 
     
    5864        background-color: #d9e6f9; 
    5965        font-weight: bold; 
     66} 
     67.soria .dojoxRollingListPane .dojoxRollingListItemHoverSelected, 
     68.soria .dojoxRollingListPane .dojoxRollingListItemFocusSelected { 
     69        background-color: #ecf3fc; 
    6070} 
    6171.soria .dojoxRollingListItem { 
     
    6777        background-color: #fff; 
    6878} 
    69 .nihilo .dojoxRollingListPane .dojoxRollingListItemHover { 
     79.nihilo .dojoxRollingListPane .dojoxRollingListItemHover, 
     80.nihilo .dojoxRollingListPane .dojoxRollingListItemFocus { 
    7081        background-color: #e3e3e3; 
    7182} 
     
    7586        font-weight: bold; 
    7687} 
     88.nihilo .dojoxRollingListPane .dojoxRollingListItemHoverSelected, 
     89.nihilo .dojoxRollingListPane .dojoxRollingListItemFocusSelected { 
     90        background-color: #fff1c2; 
     91} 
    7792.nihilo .dojoxRollingListItem { 
    7893        font-family: inherit; 
  • dojox/trunk/widget/tests/test_FilePicker.html

    r14183 r14229  
    3838        <hr> 
    3939        <div dojoType="dojox.data.FileStore" url="../../data/demos/stores/filestore_dojotree.php" jsId="fileStore" pathAsQueryParam="true"></div> 
    40         <div dojoType="dojox.widget.FilePicker" style="width: 50%;" store="fileStore" query="{}"></div> 
     40        <div dojoType="dojox.widget.FilePicker" jsId="myPicker" id="myPicker" style="width: 50%;" store="fileStore" query="{}"></div> 
    4141</body> 
    4242</html> 
  • dojox/trunk/widget/tests/test_RollingList.html

    r14217 r14229  
    136136                doResize = function(){ 
    137137                        var newSize = isBig ? {w: 340, h: 100} : {w: 500, h: 300}; 
    138                         dijit.byId("myList").resize(newSize); 
     138                        myList.resize(newSize);