📄 combobox.js
字号:
this.selectOption(); this.hideResultList(); return; } break; case k.KEY_ESCAPE: this.hideResultList(); this._prev_key_esc = true; return; case k.KEY_BACKSPACE: this._prev_key_backspace = true; if(!this.textInputNode.value.length){ this.setAllValues("", ""); this.hideResultList(); doSearch = false; } break; case k.KEY_RIGHT_ARROW: // fall through case k.KEY_LEFT_ARROW: // fall through doSearch = false; break; default:// non char keys (F1-F12 etc..) shouldn't open list if(evt.charCode==0){ doSearch = false; } } if(this.searchTimer){ clearTimeout(this.searchTimer); } if(doSearch){ // if we have gotten this far we dont want to keep our highlight this.blurOptionNode(); // need to wait a tad before start search so that the event bubbles through DOM and we have value visible this.searchTimer = setTimeout(dojo.lang.hitch(this, this.startSearchFromInput), this.searchDelay); } }, // When inputting characters using an input method, such as Asian // languages, it will generate this event instead of onKeyDown event compositionEnd: function(/*Event*/ evt){ evt.key = evt.keyCode; this._handleKeyEvents(evt); }, onKeyUp: function(/*Event*/ evt){ this.setValue(this.textInputNode.value); }, setSelectedValue: function(/*String*/ value){ // FIXME, not sure what to do here! this.comboBoxSelectionValue.value = value; }, setAllValues: function(/*String*/ value1, /*String*/ value2){ this.setSelectedValue(value2); this.setValue(value1); }, // does the actual highlight focusOptionNode: function(/*DomNode*/ node){ if(this._highlighted_option != node){ this.blurOptionNode(); this._highlighted_option = node; dojo.html.addClass(this._highlighted_option, "dojoComboBoxItemHighlight"); } }, // removes highlight on highlighted blurOptionNode: function(){ if(this._highlighted_option){ dojo.html.removeClass(this._highlighted_option, "dojoComboBoxItemHighlight"); this._highlighted_option = null; } }, highlightNextOption: function(){ if((!this._highlighted_option) || !this._highlighted_option.parentNode){ this.focusOptionNode(this.optionsListNode.firstChild); }else if(this._highlighted_option.nextSibling){ this.focusOptionNode(this._highlighted_option.nextSibling); } dojo.html.scrollIntoView(this._highlighted_option); }, highlightPrevOption: function(){ if(this._highlighted_option && this._highlighted_option.previousSibling){ this.focusOptionNode(this._highlighted_option.previousSibling); }else{ this._highlighted_option = null; this.hideResultList(); return; } dojo.html.scrollIntoView(this._highlighted_option); }, itemMouseOver: function(/*Event*/ evt){ if (evt.target === this.optionsListNode){ return; } this.focusOptionNode(evt.target); dojo.html.addClass(this._highlighted_option, "dojoComboBoxItemHighlight"); }, itemMouseOut: function(/*Event*/ evt){ if (evt.target === this.optionsListNode){ return; } this.blurOptionNode(); }, // reset button size; this function is called when the input area has changed size onResize: function(){ var inputSize = dojo.html.getContentBox(this.textInputNode); if( inputSize.height == 0 ){ // need more time to calculate size dojo.lang.setTimeout(this, "onResize", 50); return; } var buttonSize = { width: inputSize.height, height: inputSize.height}; dojo.html.setContentBox(this.downArrowNode, buttonSize); }, fillInTemplate: function(/*Object*/ args, /*Object*/ frag){ // For inlining a table we need browser specific CSS dojo.html.applyBrowserClass(this.domNode); var source = this.getFragNodeRef(frag); if (! this.name && source.name){ this.name = source.name; } this.comboBoxValue.name = this.name; this.comboBoxSelectionValue.name = this.name+"_selected"; /* different nodes get different parts of the style */ dojo.html.copyStyle(this.domNode, source); dojo.html.copyStyle(this.textInputNode, source); dojo.html.copyStyle(this.downArrowNode, source); with (this.downArrowNode.style){ // calculate these later width = "0px"; height = "0px"; } var dpClass; if(this.mode == "remote"){ dpClass = dojo.widget.incrementalComboBoxDataProvider; }else if(typeof this.dataProviderClass == "string"){ dpClass = dojo.evalObjPath(this.dataProviderClass) }else{ dpClass = this.dataProviderClass; } this.dataProvider = new dpClass(); this.dataProvider.init(this, this.getFragNodeRef(frag)); this.popupWidget = new dojo.widget.createWidget("PopupContainer", {toggle: this.dropdownToggle, toggleDuration: this.toggleDuration}); dojo.event.connect(this, 'destroy', this.popupWidget, 'destroy'); this.optionsListNode = this.popupWidget.domNode; this.domNode.appendChild(this.optionsListNode); dojo.html.addClass(this.optionsListNode, 'dojoComboBoxOptions'); dojo.event.connect(this.optionsListNode, 'onclick', this, 'selectOption'); dojo.event.connect(this.optionsListNode, 'onmouseover', this, '_onMouseOver'); dojo.event.connect(this.optionsListNode, 'onmouseout', this, '_onMouseOut'); dojo.event.connect(this.optionsListNode, "onmouseover", this, "itemMouseOver"); dojo.event.connect(this.optionsListNode, "onmouseout", this, "itemMouseOut"); }, focus: function(){ // summary // set focus to input node from code this.tryFocus(); }, openResultList: function(/*Array*/ results){ if (!this.isEnabled){ return; } this.clearResultList(); if(!results.length){ this.hideResultList(); } if( (this.autoComplete)&& (results.length)&& (!this._prev_key_backspace)&& (this.textInputNode.value.length > 0)){ var cpos = this.getCaretPos(this.textInputNode); // only try to extend if we added the last character at the end of the input if((cpos+1) > this.textInputNode.value.length){ // only add to input node as we would overwrite Capitalisation of chars this.textInputNode.value += results[0][0].substr(cpos); // build a new range that has the distance from the earlier // caret position to the end of the first string selected this.setSelectedRange(this.textInputNode, cpos, this.textInputNode.value.length); } } var even = true; while(results.length){ var tr = results.shift(); if(tr){ var td = document.createElement("div"); td.appendChild(document.createTextNode(tr[0])); td.setAttribute("resultName", tr[0]); td.setAttribute("resultValue", tr[1]); td.className = "dojoComboBoxItem "+((even) ? "dojoComboBoxItemEven" : "dojoComboBoxItemOdd"); even = (!even); this.optionsListNode.appendChild(td); } } // show our list (only if we have content, else nothing) this.showResultList(); }, onFocusInput: function(){ this._hasFocus = true; }, onBlurInput: function(){ this._hasFocus = false; this._handleBlurTimer(true, 500); }, // collect all blur timers issues here _handleBlurTimer: function(/*Boolean*/clear, /*Number*/ millisec){ if(this.blurTimer && (clear || millisec)){ clearTimeout(this.blurTimer); } if(millisec){ // we ignore that zero is false and never sets as that never happens in this widget this.blurTimer = dojo.lang.setTimeout(this, "checkBlurred", millisec); } }, // these 2 are needed in IE and Safari as inputTextNode loses focus when scrolling optionslist _onMouseOver: function(/*Event*/ evt){ if(!this._mouseover_list){ this._handleBlurTimer(true, 0); this._mouseover_list = true; } }, _onMouseOut:function(/*Event*/ evt){ var relTarget = evt.relatedTarget; if(!relTarget || relTarget.parentNode!=this.optionsListNode){ this._mouseover_list = false; this._handleBlurTimer(true, 100); this.tryFocus(); } }, _isInputEqualToResult: function(/*String*/ result){ var input = this.textInputNode.value; if(!this.dataProvider.caseSensitive){ input = input.toLowerCase(); result = result.toLowerCase(); } return (input == result); }, _isValidOption: function(){ var tgt = dojo.html.firstElement(this.optionsListNode); var isValidOption = false; while(!isValidOption && tgt){ if(this._isInputEqualToResult(tgt.getAttribute("resultName"))){ isValidOption = true; }else{ tgt = dojo.html.nextElement(tgt); } } return isValidOption; }, checkBlurred: function(){ if(!this._hasFocus && !this._mouseover_list){ this.hideResultList(); // clear the list if the user empties field and moves away. if(!this.textInputNode.value.length){ this.setAllValues("", ""); return; } var isValidOption = this._isValidOption(); // enforce selection from option list if(this.forceValidOption && !isValidOption){ this.setAllValues("", ""); return; } if(!isValidOption){// clear this.setSelectedValue(""); } } }, sizeBackgroundIframe: function(){ var mb = dojo.html.getMarginBox(this.optionsListNode); if( mb.width==0 || mb.height==0 ){ // need more time to calculate size dojo.lang.setTimeout(this, "sizeBackgroundIframe", 100); return; } }, selectOption: function(/*Event*/ evt){ var tgt = null; if(!evt){ evt = { target: this._highlighted_option }; } if(!dojo.html.isDescendantOf(evt.target, this.optionsListNode)){ // handle autocompletion where the the user has hit ENTER or TAB // if the input is empty do nothing if(!this.textInputNode.value.length){ return; } tgt = dojo.html.firstElement(this.optionsListNode); // user has input value not in option list if(!tgt || !this._isInputEqualToResult(tgt.getAttribute("resultName"))){ return; } // otherwise the user has accepted the autocompleted value }else{ tgt = evt.target; } while((tgt.nodeType!=1)||(!tgt.getAttribute("resultName"))){ tgt = tgt.parentNode; if(tgt === dojo.body()){ return false; } } this.selectedResult = [tgt.getAttribute("resultName"), tgt.getAttribute("resultValue")]; this.setAllValues(tgt.getAttribute("resultName"), tgt.getAttribute("resultValue")); if(!evt.noHide){ this.hideResultList(); this.setSelectedRange(this.textInputNode, 0, null); } this.tryFocus(); }, clearResultList: function(){ if(this.optionsListNode.innerHTML){ this.optionsListNode.innerHTML = ""; // browser natively knows how to collect this memory } }, hideResultList: function(){ this.popupWidget.close(); }, showResultList: function(){ // Our dear friend IE doesnt take max-height so we need to calculate that on our own every time var childs = this.optionsListNode.childNodes; if(childs.length){ var visibleCount = this.maxListLength; if(childs.length < visibleCount){ visibleCount = childs.length; } with(this.optionsListNode.style) { display = ""; if(visibleCount == childs.length){ //no scrollbar is required, so unset height to let browser calcuate it, //as in css, overflow is already set to auto height = ""; }else{ //show it first to get the correct dojo.style.getOuterHeight(childs[0]) //FIXME: shall we cache the height of the item? height = visibleCount * dojo.html.getMarginBox(childs[0]).height +"px"; } width = (dojo.html.getMarginBox(this.domNode).width-2)+"px"; } this.popupWidget.open(this.domNode, this, this.downArrowNode); }else{ this.hideResultList(); } }, handleArrowClick: function(){ this._handleBlurTimer(true, 0); this.tryFocus(); if(this.popupWidget.isShowingNow){ this.hideResultList(); }else{ // forces full population of results, if they click // on the arrow it means they want to see more options this.startSearch(""); } }, tryFocus: function(){ try { this.textInputNode.focus(); } catch (e){ // element isn't focusable if disabled, or not visible etc - not easy to test for. }; }, startSearchFromInput: function(){ this.startSearch(this.textInputNode.value); }, postCreate: function(){ this.onResize(); dojo.event.connect(this, "startSearch", this.dataProvider, "startSearch"); dojo.event.connect(this.dataProvider, "provideSearchResults", this, "openResultList"); dojo.event.connect(this.textInputNode, "onblur", this, "onBlurInput"); dojo.event.connect(this.textInputNode, "onfocus", this, "onFocusInput"); if (this.disabled){ this.disable(); } var s = dojo.widget.html.stabile.getState(this.widgetId); if (s){ this.setState(s); } } });
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -