Changeset 8458

Show
Ignore:
Timestamp:
05/07/07 14:43:15 (20 months ago)
Author:
doughays
Message:

Fixes #2885, #2309. AutoCompleter? now inherits from SerializableTextbox?. DateTextbox? now has a Calendar drop down, but still needs RangeBoundTextbox? min/max code working. Calendar now works under 0.9.

Location:
dijit/trunk
Files:
9 modified

Legend:

Unmodified
Added
Removed
  • dijit/trunk/form/AutoCompleter.js

    r8413 r8458  
    55dojo.require("dojo.data.JsonItemStore"); 
    66dojo.require("dijit.form._DropDownTextBox"); 
    7  
     7dojo.require("dijit.form.ValidationTextbox"); 
    88 
    99dojo.declare( 
    1010                        "dijit.form.AutoCompleter", 
    11         [dijit.form._DropDownTextBox], 
     11        [dijit.form.SerializableTextbox, dijit.form._DropDownTextBox], 
    1212{ 
    1313        // summary: 
     
    2121        //              provider. 
    2222         
    23         // Fixes #2313, #2562, #2790, #2883, #2884. 
     23        // Fixes #2885, #2309 
    2424         
    2525        // searchLimit: Integer 
     
    8888        _setTextFieldValue:function(/*String*/ value){ 
    8989                // summary: Select wants to call AutoCompleter's setValue to reach FormElement's setValue 
    90                 // But Select does not want to display the value in the text field! 
    91                 // this function fixes that problem by separating the code 
    92                 this.textInputNode.value=value; 
     90                // But Select does not want to display the "value" in the text field! 
     91                // this function fixes that problem by separating the code from Select's setTextValue 
     92                this.textbox.value=value; 
    9393        }, 
    9494        setValue:function(/*String*/ value){ 
     
    122122        enable:function(){ 
    123123                this.disabled=false; 
    124                 this.textInputNode.removeAttribute("disabled"); 
     124                this.textbox.removeAttribute("disabled"); 
    125125        }, 
    126126 
    127127        disable: function(){ 
    128128                this.disabled = true; 
    129                 this.textInputNode.setAttribute("disabled",true); 
     129                this.textbox.setAttribute("disabled",true); 
    130130        }, 
    131131 
     
    194194        }, 
    195195 
    196         _handleKeyEvents: function(/*Event*/ evt){ 
     196        onkeypress: function(/*Event*/ evt){ 
    197197                // summary: handles keyboard events 
    198198                if(evt.ctrlKey || evt.altKey){ return; } 
     
    235235 
    236236                                                // put caret last 
    237                                                 this._setSelectedRange(this.textInputNode, this.textInputNode.value.length, null); 
     237                                                this._setSelectedRange(this.textbox, this.textbox.value.length, null); 
    238238                                        }else{ 
    239239                                                this._selectOption(); 
     
    272272                                        //try{ 
    273273                                                this._prev_key_backspace = true; 
    274                                                 if(!this.textInputNode.value.length){ 
     274                                                if(!this.textbox.value.length){ 
    275275                                                        this.setValue(""); 
    276276                                                        //this._hideResultList(); 
     
    307307                // languages, it will generate this event instead of onKeyDown event 
    308308                evt.key = evt.charCode = -1; 
    309                 this._handleKeyEvents(evt); 
    310         }, 
    311  
    312         _onKeyUp: function(/*Event*/ evt){ 
     309                this.onkeypress(evt); 
     310        }, 
     311 
     312        onkeyup: function(/*Event*/ evt){ 
    313313                // summary: callback on key up event 
    314                 this.setValue(this.textInputNode.value); 
     314                this.setValue(this.textbox.value); 
    315315        }, 
    316316 
     
    373373                        return; 
    374374                } 
    375                 var zerothvalue=new String(results[0][this.searchField]); 
     375                var zerothvalue=new String(this.store.getValue(results[0], this.searchField)); 
    376376                if(zerothvalue&&(this.autoComplete)&& 
    377377                        (!this._prev_key_backspace)&& 
    378                         (this.textInputNode.value.length > 0)&& 
    379                         (new RegExp("^"+this.textInputNode.value, "").test(zerothvalue))){ 
    380                                 var cpos = this._getCaretPos(this.textInputNode); 
     378                        (this.textbox.value.length > 0)&& 
     379                        (new RegExp("^"+this.textbox.value, "").test(zerothvalue))){ 
     380                                var cpos = this._getCaretPos(this.textbox); 
    381381                                // only try to extend if we added the last character at the end of the input 
    382                                 if((cpos+1) > this.textInputNode.value.length){ 
     382                                if((cpos+1) > this.textbox.value.length){ 
    383383                                        // only add to input node as we would overwrite Capitalisation of chars 
    384                                         this.textInputNode.value += zerothvalue.substr(cpos); 
     384                                        this.textbox.value += zerothvalue.substr(cpos); 
    385385                                        // build a new range that has the distance from the earlier 
    386386                                        // caret position to the end of the first string selected 
    387                                         this._setSelectedRange(this.textInputNode, cpos, this.textInputNode.value.length); 
     387                                        this._setSelectedRange(this.textbox, cpos, this.textbox.value.length); 
    388388                                } 
    389389                } 
    390                 while(results.length){ 
    391                         var tr = results.shift(); 
     390                // #2309: iterate over cache nondestructively 
     391                for(var i=0; i<results.length; i++) { 
     392                        var tr=results[i]; 
    392393                        if(tr){ 
    393394                                var td=this._createOption(tr); 
     
    405406                // summary: creates an option to appear on the popup menu 
    406407                var td = document.createElement("div"); 
    407                 td.appendChild(document.createTextNode(tr[this.searchField])); 
    408  
    409                 td[this.searchField]=tr[this.searchField]; 
     408                td.appendChild(document.createTextNode(this.store.getValue(tr, this.searchField))); 
     409                td.item=tr; 
    410410                return td; 
    411411        }, 
    412  
    413         _onFocusInput: function(){ 
     412        onfocus:function(){ 
     413                dijit.form.RangeBoundTextbox.prototype.onfocus.apply(this, arguments); 
    414414                this._hasFocus = true; 
    415415        }, 
    416  
    417         _onBlurInput: function(){ 
    418                  
    419                         this._hasFocus = false; 
    420                         this._handleBlurTimer(true, 500); 
     416        onblur:function(){ 
     417                dijit.form._DropDownTextBox.prototype.onblur.apply(this, arguments); 
     418                dijit.form.RangeBoundTextbox.prototype.onblur.apply(this, arguments); 
     419                this._hasFocus = false; 
     420                this._handleBlurTimer(true, 500); 
    421421                 
    422422        }, 
     
    455455                 
    456456        }, 
    457  
    458                  
    459457        _checkBlurred: function(){ 
    460                          
    461                  
    462458                        if(!this._hasFocus && !this._mouseover_list){ 
    463459                                this._hideResultList(); 
    464                                 //this._checkValueChanged(); 
    465                         } 
    466                  
    467         }, 
    468  
     460                        } 
     461        }, 
    469462        _selectOption: function(/*Event*/ evt){ 
    470463                var tgt = null; 
    471464                if(!evt){ 
    472465                        // what if nothing is highlighted yet? 
    473                         evt = { target: (this._highlighted_option ? this._highlighted_option:this.optionsListNode.firstChild) }; 
    474                 } 
    475                 if(evt.target.parentNode!=this.optionsListNode){ 
     466                        evt = { target: this._highlighted_option }; 
     467                        if(!evt.target) return; 
     468                } 
     469                if(evt.target&&evt.target.parentNode!=this.optionsListNode){ 
    476470                         
    477471                                // handle autocompletion where the the user has hit ENTER or TAB 
    478472                                // if the input is empty do nothing 
    479                                 if(!this.textInputNode.value.length){ 
     473                                if(!this.textbox.value.length){ 
    480474                                        //this._checkValueChanged(); 
    481475                                        return; 
     
    492486                        tgt = evt.target; 
    493487                } 
    494                 while((tgt.nodeType!=1)||(!tgt[this.searchField])){ 
     488                while((tgt.nodeType!=1)||(!tgt.item[this.searchField])){ 
    495489                        tgt = tgt.parentNode; 
    496490                        if(tgt == dojo.body()){ 
     
    502496                if(!evt.noHide){ 
    503497                        this._hideResultList(); 
    504                         this._setSelectedRange(this.textInputNode, 0, null); 
     498                        this._setSelectedRange(this.textbox, 0, null); 
    505499                } 
    506500                //this._checkValueChanged(); 
     
    510504 
    511505        _doSelect: function(tgt){ 
    512                 this.setValue(tgt[this.searchField]); 
    513         }, 
    514  
    515          
    516  
    517         _showResultList: function(){ 
    518                         // Our dear friend IE doesnt take max-height so we need to calculate that on our own every time 
    519                 var childs = this.optionsListNode.childNodes; 
    520                 if(childs.length){ 
    521                         var visibleCount = Math.min(childs.length,this.maxListLength); 
    522                                  
    523                         this.popupWidget.open(this.optionsListNode, this); 
    524                         with(this.optionsListNode.style) 
    525                         { 
    526                                 //display = ""; 
    527                                 if(visibleCount == childs.length){ 
    528                                                 //no scrollbar is required, so unset height to let browser calcuate it, 
    529                                                 //as in css, overflow is already set to auto 
    530                                         height = ""; 
    531                                 }else{ 
    532                                         //show it first to get the correct dojo.style.getOuterHeight(childs[0]) 
    533                                         //FIXME: shall we cache the height of the item? 
    534                                         var calcheight = visibleCount * (childs[0]).offsetHeight; 
    535                                         var windowheight=dijit.util.getViewport().h; 
    536                                         if(calcheight>windowheight){ 
    537                                                 var coords=dojo.coords(this.popupWidget.domNode); 
    538                                                 calcheight=windowheight-coords.y; 
    539                                         } 
    540                                         height=calcheight+"px"; 
    541                                                  
    542                                 } 
    543                                 width = this.domNode.offsetWidth+"px"; 
    544                         } 
    545                         // do it again to reposition 
    546                         this.popupWidget.close(this); 
    547                         this.popupWidget.open(this.optionsListNode, this); 
    548                                  
    549                 }else{ 
    550                         this._hideResultList(); 
    551                 } 
     506                this.setValue(this.store.getValue(tgt.item, this.searchField)); 
    552507        }, 
    553508 
    554509        arrowClicked: function(){ 
    555510                        // summary: callback when arrow is clicked 
    556                  
     511                if(this.disabled) return; 
    557512                this._handleBlurTimer(true, 0); 
    558513                this.focus(); 
     
    566521        }, 
    567522 
    568         focus: function(){ 
    569                 try{ 
    570                         this.textInputNode.focus(); 
    571                 }catch (e){ 
    572                                 // element isn't focusable if disabled, or not visible etc - not easy to test for. 
    573                 }; 
    574         }, 
     523         
    575524 
    576525        _startSearchFromInput: function(){ 
    577                 this._startSearch(this.textInputNode.value); 
     526                this._startSearch(this.textbox.value); 
    578527        }, 
    579528 
     
    589538        }, 
    590539        postCreate: function(){ 
    591                 dijit.form.AutoCompleter.superclass.postCreate.apply(this, arguments); 
     540                //dijit.form.AutoCompleter.superclass.postCreate.apply(this, arguments); 
     541                dijit.form.SerializableTextbox.prototype.postCreate.apply(this, arguments); 
     542                dijit.form._DropDownTextBox.prototype.postCreate.apply(this, arguments); 
    592543 
    593544                /* different nodes get different parts of the style */ 
    594545                // FIXME: test different style attributes 
    595546                //var source = this.srcNodeRef; 
    596                 //this.textInputNode.style=source.style; 
     547                //this.textbox.style=source.style; 
    597548                         
    598549                var dpClass=dojo.getObject(this.dataProviderClass, false); 
     
    602553                if(this.store==null){ 
    603554                        if(this.url==""&&this.data==null){ 
     555                                dpClass=dojo.getObject("dojo.data.JsonItemStore", false); 
    604556                                var opts = this.domNode.getElementsByTagName("option"); 
    605557                                var ol = opts.length; 
     
    620572                } 
    621573 
    622                 dojo.addClass(this.optionsListNode, 'dojoMenu'); 
    623                 this.optionsListNode.style.overflow="scroll"; 
     574                 
    624575                dojo.connect(this.optionsListNode, 'onclick', this, '_selectOption'); 
    625576                dojo.connect(this.optionsListNode, 'onmouseover', this, '_onMouseOver'); 
     
    640591                else this.setValue(this.value);*/ 
    641592                this.setValue(this.value); 
     593                // setting the value here is needed since value="" in the template causes "undefined" on form reset 
     594                this.textbox.setAttribute("value", this.value); 
    642595        } 
    643596} 
  • dijit/trunk/form/Calendar.js

    r8414 r8458  
    77dojo.require("dijit.base.Widget"); 
    88dojo.require("dijit.base.TemplatedWidget"); 
     9dojo.require("dijit.base.FormElement"); 
    910 
    1011dojo.declare( 
    1112        "dijit.form.Calendar", 
    12         [dijit.base.Widget, dijit.base.TemplatedWidget], 
     13        [dijit.base.FormElement, dijit.base.TemplatedWidget], 
    1314        { 
    1415                /* 
     
    5152                        } 
    5253                        this.clickedNode=null; 
     54                        dijit.form.Calendar.superclass.setValue.apply(this, arguments); 
    5355                }, 
    5456 
  • dijit/trunk/form/DateTextbox.js

    r8283 r8458  
    11dojo.provide("dijit.form.DateTextbox"); 
    22 
    3 dojo.require("dijit.form.ValidationTextbox"); 
     3dojo.require("dijit.form.Calendar"); 
     4dojo.require("dijit.form._DropDownTextBox"); 
    45dojo.require("dojo.date.calc"); 
    56dojo.require("dojo.date.local"); 
    67dojo.require("dojo.date.serial"); 
     8dojo.require("dijit.form.ValidationTextbox"); 
    79 
    810dojo.declare( 
    911        "dijit.form.DateTextbox", 
    10         dijit.form.RangeBoundTextbox, 
     12        [dijit.form.RangeBoundTextbox, dijit.form._DropDownTextBox], 
    1113        { 
    1214                // summary: 
    1315                //              A validating, serializable, range-bound date text box. 
    1416                // constraints object: min, max 
    15  
     17                templatePath: dojo.moduleUrl("dijit.form", "templates/AutoCompleter.html"), 
    1618                regExpGen: dojo.date.local.regexp, 
    1719                compare: dojo.date.calc.compare, 
     
    2123                postMixInProperties: function(){ 
    2224                        this.constraints.selector = 'date'; 
    23                         dijit.form.DateTextbox.superclass.postMixInProperties.apply(this, arguments); 
     25                        // manual import of RangeBoundTextbox properties 
     26                        dijit.form.RangeBoundTextbox.prototype.postMixInProperties.apply(this, arguments); 
     27                        //dijit.form.DateTextbox.superclass.postMixInProperties.apply(this, arguments); 
    2428                }, 
    2529                serialize: function(val){ 
    2630                        return dojo.date.serial.toRfc3339(val, 'date'); 
     31                }, 
     32                setValue:function(value){ 
     33                        // summary: 
     34                        //      Sets the value on the calendar drop down to value 
     35                        //      This change is then propagated through the calendar's onValueChanged to DateTextbox 
     36                        this.optionsListNode.setValue(value); 
     37                }, 
     38                postCreate:function() { 
     39                         
     40                        // apply both postCreates 
     41                        dijit.form.RangeBoundTextbox.prototype.postCreate.apply(this, arguments); 
     42                        dijit.form._DropDownTextBox.prototype.postCreate.apply(this, arguments); 
     43                        //dijit.form.DateTextbox.superclass.postCreate.apply(this, arguments); 
     44                        this.optionsListNode=new dijit.form.Calendar({value:this.getValue(), onValueChanged:dojo.hitch(this, this._calendarOnValueChanged)},this.optionsListNode); 
     45                }, 
     46                _calendarOnValueChanged:function(value){ 
     47                        // summary: taps into the popup Calendar onValueChanged 
     48                        dijit.form.DateTextbox.superclass.setValue.apply(this, arguments); 
     49                        this._hideResultList(); 
    2750                } 
    2851        } 
  • dijit/trunk/form/Select.js

    r8445 r8458  
    5555                        return state; 
    5656                }, 
    57  
     57                getValue:function(){ 
     58                        return this.comboBoxSelectionValue.value; 
     59                }, 
    5860                setState: function(/*Object*/ state){ 
    5961                        // summary: 
     
    9294 
    9395                _isInputEqualToResult: function(/*Object*/ result){ 
    94                         var input = this.textInputNode.value; 
     96                        var input = this.textbox.value; 
    9597                        var testlabel=this.store.getValue(result, this.searchField); 
    9698                        if(!this.ignoreCase){ 
     
    106108                        // get the actual label to display 
    107109                        var textlabel; 
    108                         try { 
    109                                 // throws exception if item not in store (item created by internal processes) 
     110                         
     111                        if(this.store.isItem(item)) { 
    110112                                textlabel=this.store.getValue(item, this.searchField); 
    111113                        } 
    112                         catch(e) { 
    113                                 // item might have been created by Select (not by store) 
    114                                 // in this case, use associative array access 
    115                                 textlabel=item[this.searchField]; 
    116                         } 
     114                        else textlabel=item[this.searchField]; 
    117115                        // if custom label function present, call it 
    118                         if(this.textInputNode.value!=textlabel&&this.labelFunc){ 
    119                                 textlabel=this.labelFunc(item); 
    120                                 this.textInputNode.value = textlabel; 
    121                         } 
     116                        if(this.labelFunc){ 
     117                                textlabel=this.labelFunc(item);  
     118                        } 
     119                        this.textbox.value = textlabel; 
    122120                }, 
    123121                labelFunc: function(/*Object*/ item){ 
    124122                        // summary: Event handler called when the label changes 
    125123                        // returns the label that the AutoCompleter should display 
    126                         return item[this.searchField]; 
     124                        return this.store.getValue(item, this.searchField); 
    127125                }, 
    128126                getState: function(){ 
     
    146144                        return td; 
    147145                }, 
    148                 _onKeyUp: function(/*Event*/ evt){ 
     146                onkeyup: function(/*Event*/ evt){ 
    149147                        // summary: internal function 
    150148                        // Select needs to wait for the complete label before committing to a reverse lookup 
    151                         //this.setTextValue(this.textInputNode.value); 
     149                        //this.setTextValue(this.textbox.value); 
    152150                }, 
    153151 
     
    166164                        this.domNode.appendChild(this.comboBoxSelectionValue); 
    167165                        dijit.form.Select.superclass.postCreate.apply(this, arguments); 
    168                         this.textInputNode.removeAttribute("name"); 
     166                        this.textbox.removeAttribute("name"); 
     167                        // setting the value here is needed since value="" in the template causes "undefined" on form reset 
     168                        this.comboBoxSelectionValue.setAttribute("value", this.value); 
     169                        this.setValue(this.value); 
     170                        // FIXME: set this in the right spot so the form resets correctly 
     171                        this.textbox.setAttribute("value", this.getTextValue()); 
    169172                        //console.log(this.value); 
    170173                        //this.setValue(this.value); 
     
    174177                }, 
    175178                _doSelect: function(/*Event*/ tgt){ 
    176                         this._setValue(tgt[this.keyField]); 
    177                         this._setLabel(tgt); 
     179                        this._setValue(tgt.item[this.keyField]); 
     180                        this._setLabel(tgt.item); 
    178181                }, 
    179182                 
     
    183186                        var isValidOption = false; 
    184187                        // this test doesn't work if optionsListNode is empty (page first loaded) 
    185                         var tgt = this.optionsListNode.firstChild; 
     188                        //var tgt = dojo.html.firstElement(this.optionsListNode); //PORT 
     189                        var tgt=this.optionsListNode.firstChild; 
    186190                        while(!isValidOption && tgt){ 
    187                                 if(this._isInputEqualToResult(tgt)){ 
     191                                if(this._isInputEqualToResult(tgt.item)){ 
    188192                                        isValidOption = true; 
    189193                                }else{ 
     194                                        //tgt = dojo.html.nextElement(tgt); //PORT 
    190195                                        tgt=this.optionsListNode.nextSibling; 
    191196                                } 
     
    193198 
    194199                        return isValidOption; 
    195                 }, 
    196                 getTextValue: function(){ 
    197                         // summary: returns current label 
    198                         return this.textInputNode.value;        // String 
    199200                }, 
    200201                setTextValue:function(/*String*/ label){ 
    201202                        // summary: set the label to the passed label. 
    202203                        // The hidden value is set by reverse lookup 
    203                         var query={}; 
     204                        dijit.form.Select.superclass.setTextValue.apply(this, arguments); 
     205                        /*var query={}; 
    204206                        query[this.searchField]=label; 
    205                         this.store.fetch({queryIgnoreCase:this.ignoreCase, query: query, onComplete:dojo.hitch(this, this._validateOption) }); 
     207                        this.store.fetch({queryIgnoreCase:this.ignoreCase, query: query, onComplete:dojo.hitch(this, this._validateOption) });*/ 
    206208                }, 
    207209                _validateOption: function(/*Object*/ ret){ 
     
    231233