Changeset 8458
- Timestamp:
- 05/07/07 14:43:15 (20 months ago)
- Location:
- dijit/trunk
- Files:
-
- 9 modified
-
form/AutoCompleter.js (modified) (19 diffs)
-
form/Calendar.js (modified) (2 diffs)
-
form/DateTextbox.js (modified) (2 diffs)
-
form/Select.js (modified) (9 diffs)
-
form/templates/AutoCompleter.html (modified) (1 diff)
-
form/_DropDownTextBox.js (modified) (3 diffs)
-
tests/form/autoCompleterData.json (modified) (1 diff)
-
tests/form/test_AutoCompleter.html (modified) (3 diffs)
-
tests/form/test_Select.html (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
-
dijit/trunk/form/AutoCompleter.js
r8413 r8458 5 5 dojo.require("dojo.data.JsonItemStore"); 6 6 dojo.require("dijit.form._DropDownTextBox"); 7 7 dojo.require("dijit.form.ValidationTextbox"); 8 8 9 9 dojo.declare( 10 10 "dijit.form.AutoCompleter", 11 [dijit.form. _DropDownTextBox],11 [dijit.form.SerializableTextbox, dijit.form._DropDownTextBox], 12 12 { 13 13 // summary: … … 21 21 // provider. 22 22 23 // Fixes #2 313, #2562, #2790, #2883, #2884.23 // Fixes #2885, #2309 24 24 25 25 // searchLimit: Integer … … 88 88 _setTextFieldValue:function(/*String*/ value){ 89 89 // summary: Select wants to call AutoCompleter's setValue to reach FormElement's setValue 90 // But Select does not want to display the valuein the text field!91 // this function fixes that problem by separating the code 92 this.text InputNode.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; 93 93 }, 94 94 setValue:function(/*String*/ value){ … … 122 122 enable:function(){ 123 123 this.disabled=false; 124 this.text InputNode.removeAttribute("disabled");124 this.textbox.removeAttribute("disabled"); 125 125 }, 126 126 127 127 disable: function(){ 128 128 this.disabled = true; 129 this.text InputNode.setAttribute("disabled",true);129 this.textbox.setAttribute("disabled",true); 130 130 }, 131 131 … … 194 194 }, 195 195 196 _handleKeyEvents: function(/*Event*/ evt){196 onkeypress: function(/*Event*/ evt){ 197 197 // summary: handles keyboard events 198 198 if(evt.ctrlKey || evt.altKey){ return; } … … 235 235 236 236 // put caret last 237 this._setSelectedRange(this.text InputNode, this.textInputNode.value.length, null);237 this._setSelectedRange(this.textbox, this.textbox.value.length, null); 238 238 }else{ 239 239 this._selectOption(); … … 272 272 //try{ 273 273 this._prev_key_backspace = true; 274 if(!this.text InputNode.value.length){274 if(!this.textbox.value.length){ 275 275 this.setValue(""); 276 276 //this._hideResultList(); … … 307 307 // languages, it will generate this event instead of onKeyDown event 308 308 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){ 313 313 // summary: callback on key up event 314 this.setValue(this.text InputNode.value);314 this.setValue(this.textbox.value); 315 315 }, 316 316 … … 373 373 return; 374 374 } 375 var zerothvalue=new String( results[0][this.searchField]);375 var zerothvalue=new String(this.store.getValue(results[0], this.searchField)); 376 376 if(zerothvalue&&(this.autoComplete)&& 377 377 (!this._prev_key_backspace)&& 378 (this.text InputNode.value.length > 0)&&379 (new RegExp("^"+this.text InputNode.value, "").test(zerothvalue))){380 var cpos = this._getCaretPos(this.text InputNode);378 (this.textbox.value.length > 0)&& 379 (new RegExp("^"+this.textbox.value, "").test(zerothvalue))){ 380 var cpos = this._getCaretPos(this.textbox); 381 381 // only try to extend if we added the last character at the end of the input 382 if((cpos+1) > this.text InputNode.value.length){382 if((cpos+1) > this.textbox.value.length){ 383 383 // only add to input node as we would overwrite Capitalisation of chars 384 this.text InputNode.value += zerothvalue.substr(cpos);384 this.textbox.value += zerothvalue.substr(cpos); 385 385 // build a new range that has the distance from the earlier 386 386 // caret position to the end of the first string selected 387 this._setSelectedRange(this.text InputNode, cpos, this.textInputNode.value.length);387 this._setSelectedRange(this.textbox, cpos, this.textbox.value.length); 388 388 } 389 389 } 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]; 392 393 if(tr){ 393 394 var td=this._createOption(tr); … … 405 406 // summary: creates an option to appear on the popup menu 406 407 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; 410 410 return td; 411 411 }, 412 413 _onFocusInput: function(){412 onfocus:function(){ 413 dijit.form.RangeBoundTextbox.prototype.onfocus.apply(this, arguments); 414 414 this._hasFocus = true; 415 415 }, 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); 421 421 422 422 }, … … 455 455 456 456 }, 457 458 459 457 _checkBlurred: function(){ 460 461 462 458 if(!this._hasFocus && !this._mouseover_list){ 463 459 this._hideResultList(); 464 //this._checkValueChanged(); 465 } 466 467 }, 468 460 } 461 }, 469 462 _selectOption: function(/*Event*/ evt){ 470 463 var tgt = null; 471 464 if(!evt){ 472 465 // 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){ 476 470 477 471 // handle autocompletion where the the user has hit ENTER or TAB 478 472 // if the input is empty do nothing 479 if(!this.text InputNode.value.length){473 if(!this.textbox.value.length){ 480 474 //this._checkValueChanged(); 481 475 return; … … 492 486 tgt = evt.target; 493 487 } 494 while((tgt.nodeType!=1)||(!tgt [this.searchField])){488 while((tgt.nodeType!=1)||(!tgt.item[this.searchField])){ 495 489 tgt = tgt.parentNode; 496 490 if(tgt == dojo.body()){ … … 502 496 if(!evt.noHide){ 503 497 this._hideResultList(); 504 this._setSelectedRange(this.text InputNode, 0, null);498 this._setSelectedRange(this.textbox, 0, null); 505 499 } 506 500 //this._checkValueChanged(); … … 510 504 511 505 _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)); 552 507 }, 553 508 554 509 arrowClicked: function(){ 555 510 // summary: callback when arrow is clicked 556 511 if(this.disabled) return; 557 512 this._handleBlurTimer(true, 0); 558 513 this.focus(); … … 566 521 }, 567 522 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 575 524 576 525 _startSearchFromInput: function(){ 577 this._startSearch(this.text InputNode.value);526 this._startSearch(this.textbox.value); 578 527 }, 579 528 … … 589 538 }, 590 539 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); 592 543 593 544 /* different nodes get different parts of the style */ 594 545 // FIXME: test different style attributes 595 546 //var source = this.srcNodeRef; 596 //this.text InputNode.style=source.style;547 //this.textbox.style=source.style; 597 548 598 549 var dpClass=dojo.getObject(this.dataProviderClass, false); … … 602 553 if(this.store==null){ 603 554 if(this.url==""&&this.data==null){ 555 dpClass=dojo.getObject("dojo.data.JsonItemStore", false); 604 556 var opts = this.domNode.getElementsByTagName("option"); 605 557 var ol = opts.length; … … 620 572 } 621 573 622 dojo.addClass(this.optionsListNode, 'dojoMenu'); 623 this.optionsListNode.style.overflow="scroll"; 574 624 575 dojo.connect(this.optionsListNode, 'onclick', this, '_selectOption'); 625 576 dojo.connect(this.optionsListNode, 'onmouseover', this, '_onMouseOver'); … … 640 591 else this.setValue(this.value);*/ 641 592 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); 642 595 } 643 596 } -
dijit/trunk/form/Calendar.js
r8414 r8458 7 7 dojo.require("dijit.base.Widget"); 8 8 dojo.require("dijit.base.TemplatedWidget"); 9 dojo.require("dijit.base.FormElement"); 9 10 10 11 dojo.declare( 11 12 "dijit.form.Calendar", 12 [dijit.base. Widget, dijit.base.TemplatedWidget],13 [dijit.base.FormElement, dijit.base.TemplatedWidget], 13 14 { 14 15 /* … … 51 52 } 52 53 this.clickedNode=null; 54 dijit.form.Calendar.superclass.setValue.apply(this, arguments); 53 55 }, 54 56 -
dijit/trunk/form/DateTextbox.js
r8283 r8458 1 1 dojo.provide("dijit.form.DateTextbox"); 2 2 3 dojo.require("dijit.form.ValidationTextbox"); 3 dojo.require("dijit.form.Calendar"); 4 dojo.require("dijit.form._DropDownTextBox"); 4 5 dojo.require("dojo.date.calc"); 5 6 dojo.require("dojo.date.local"); 6 7 dojo.require("dojo.date.serial"); 8 dojo.require("dijit.form.ValidationTextbox"); 7 9 8 10 dojo.declare( 9 11 "dijit.form.DateTextbox", 10 dijit.form.RangeBoundTextbox,12 [dijit.form.RangeBoundTextbox, dijit.form._DropDownTextBox], 11 13 { 12 14 // summary: 13 15 // A validating, serializable, range-bound date text box. 14 16 // constraints object: min, max 15 17 templatePath: dojo.moduleUrl("dijit.form", "templates/AutoCompleter.html"), 16 18 regExpGen: dojo.date.local.regexp, 17 19 compare: dojo.date.calc.compare, … … 21 23 postMixInProperties: function(){ 22 24 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); 24 28 }, 25 29 serialize: function(val){ 26 30 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(); 27 50 } 28 51 } -
dijit/trunk/form/Select.js
r8445 r8458 55 55 return state; 56 56 }, 57 57 getValue:function(){ 58 return this.comboBoxSelectionValue.value; 59 }, 58 60 setState: function(/*Object*/ state){ 59 61 // summary: … … 92 94 93 95 _isInputEqualToResult: function(/*Object*/ result){ 94 var input = this.text InputNode.value;96 var input = this.textbox.value; 95 97 var testlabel=this.store.getValue(result, this.searchField); 96 98 if(!this.ignoreCase){ … … 106 108 // get the actual label to display 107 109 var textlabel; 108 try {109 // throws exception if item not in store (item created by internal processes)110 111 if(this.store.isItem(item)) { 110 112 textlabel=this.store.getValue(item, this.searchField); 111 113 } 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]; 117 115 // 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; 122 120 }, 123 121 labelFunc: function(/*Object*/ item){ 124 122 // summary: Event handler called when the label changes 125 123 // returns the label that the AutoCompleter should display 126 return item[this.searchField];124 return this.store.getValue(item, this.searchField); 127 125 }, 128 126 getState: function(){ … … 146 144 return td; 147 145 }, 148 _onKeyUp: function(/*Event*/ evt){146 onkeyup: function(/*Event*/ evt){ 149 147 // summary: internal function 150 148 // Select needs to wait for the complete label before committing to a reverse lookup 151 //this.setTextValue(this.text InputNode.value);149 //this.setTextValue(this.textbox.value); 152 150 }, 153 151 … … 166 164 this.domNode.appendChild(this.comboBoxSelectionValue); 167 165 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()); 169 172 //console.log(this.value); 170 173 //this.setValue(this.value); … … 174 177 }, 175 178 _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); 178 181 }, 179 182 … … 183 186 var isValidOption = false; 184 187 // 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; 186 190 while(!isValidOption && tgt){ 187 if(this._isInputEqualToResult(tgt )){191 if(this._isInputEqualToResult(tgt.item)){ 188 192 isValidOption = true; 189 193 }else{ 194 //tgt = dojo.html.nextElement(tgt); //PORT 190 195 tgt=this.optionsListNode.nextSibling; 191 196 } … … 193 198 194 199 return isValidOption; 195 },196 getTextValue: function(){197 // summary: returns current label198 return this.textInputNode.value; // String199 200 }, 200 201 setTextValue:function(/*String*/ label){ 201 202 // summary: set the label to the passed label. 202 203 // The hidden value is set by reverse lookup 203 var query={}; 204 dijit.form.Select.superclass.setTextValue.apply(this, arguments); 205 /*var query={}; 204 206 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) });*/ 206 208 }, 207 209 _validateOption: function(/*Object*/ ret){ … … 231 233