📄 combobox.js
字号:
/* Copyright (c) 2004-2006, The Dojo Foundation All Rights Reserved. Licensed under the Academic Free License version 2.1 or above OR the modified BSD license. For more information on Dojo licensing, see: http://dojotoolkit.org/community/licensing.shtml*/dojo.provide("dojo.widget.html.ComboBox");dojo.require("dojo.widget.ComboBox");dojo.require("dojo.widget.*");dojo.require("dojo.io.*");dojo.require("dojo.lfx.*");dojo.require("dojo.dom");dojo.require("dojo.html");dojo.require("dojo.string");dojo.require("dojo.widget.html.stabile");dojo.widget.html.ComboBox = function(){ dojo.widget.ComboBox.call(this); dojo.widget.HtmlWidget.call(this); this.autoComplete = true; this.formInputName = ""; this.name = ""; // clone in the name from the DOM node this.textInputNode = null; this.comboBoxValue = null; this.comboBoxSelectionValue = null; this.optionsListWrapper = null; this.optionsListNode = null; this.downArrowNode = null; this.cbTableNode = null; this.searchTimer = null; this.searchDelay = 100; this.dataUrl = ""; // maxListLength limits list to X visible rows, scroll on rest this.maxListLength = 8; // mode can also be "remote" for JSON-returning live search or "html" for // dumber live search this.mode = "local"; this.selectedResult = null; this._highlighted_option = null; this._prev_key_backspace = false; this._prev_key_esc = false; this._result_list_open = false; this._gotFocus = false; this._mouseover_list = false;}dojo.inherits(dojo.widget.html.ComboBox, dojo.widget.HtmlWidget);// copied from superclass since we can't really over-ride via prototypedojo.lang.extend(dojo.widget.html.ComboBox, dojo.widget.ComboBox.defaults);dojo.lang.extend(dojo.widget.html.ComboBox, { templatePath: dojo.uri.dojoUri("src/widget/templates/HtmlComboBox.html"), templateCssPath: dojo.uri.dojoUri("src/widget/templates/HtmlComboBox.css"), setValue: function(value) { this.comboBoxValue.value = value; if (this.textInputNode.value != value) { // prevent mucking up of selection this.textInputNode.value = value; } dojo.widget.html.stabile.setState(this.widgetId, this.getState(), true); }, getValue: function() { return this.comboBoxValue.value; }, getState: function() { return {value: this.getValue()}; }, setState: function(state) { this.setValue(state.value); }, getCaretPos: function(element){ // khtml 3.5.2 has selection* methods as does webkit nightlies from 2005-06-22 if(dojo.lang.isNumber(element.selectionStart)){ // FIXME: this is totally borked on Moz < 1.3. Any recourse? return element.selectionStart; }else if(dojo.render.html.ie){ // in the case of a mouse click in a popup being handled, // then the document.selection is not the textarea, but the popup // var r = document.selection.createRange(); // hack to get IE 6 to play nice. What a POS browser. var tr = document.selection.createRange().duplicate(); var ntr = element.createTextRange(); tr.move("character",0); ntr.move("character",0); try { // If control doesnt have focus, you get an exception. // Seems to happen on reverse-tab, but can also happen on tab (seems to be a race condition - only happens sometimes). // There appears to be no workaround for this - googled for quite a while. ntr.setEndPoint("EndToEnd", tr); return String(ntr.text).replace(/\r/g,"").length; } catch (e) { return 0; // If focus has shifted, 0 is fine for caret pos. } } }, setCaretPos: function(element, location){ location = parseInt(location); this.setSelectedRange(element, location, location); }, setSelectedRange: function(element, start, end){ if(!end){ end = element.value.length; } // NOTE: Strange - should be able to put caret at start of text? // Mozilla // parts borrowed from http://www.faqts.com/knowledge_base/view.phtml/aid/13562/fid/130 if(element.setSelectionRange){ element.focus(); element.setSelectionRange(start, end); }else if(element.createTextRange){ // IE var range = element.createTextRange(); with(range){ collapse(true); moveEnd('character', end); moveStart('character', start); select(); } }else{ //otherwise try the event-creation hack (our own invention) // do we need these? element.value = element.value; element.blur(); element.focus(); // figure out how far back to go var dist = parseInt(element.value.length)-end; var tchar = String.fromCharCode(37); var tcc = tchar.charCodeAt(0); for(var x = 0; x < dist; x++){ var te = document.createEvent("KeyEvents"); te.initKeyEvent("keypress", true, true, null, false, false, false, false, tcc, tcc); twe.dispatchEvent(te); } } }, // does the keyboard related stuff _handleKeyEvents: function(evt){ if(evt.ctrlKey || evt.altKey){ return; } // reset these this._prev_key_backspace = false; this._prev_key_esc = false; var k = dojo.event.browser.keys; var doSearch = true; // mozilla quirk // space has no keyCode in mozilla var keyCode = evt.keyCode; if(keyCode==0 && evt.charCode==k.KEY_SPACE){ keyCode = k.KEY_SPACE; } switch(keyCode){ case k.KEY_DOWN_ARROW: if(!this._result_list_open){ this.startSearchFromInput(); } this.highlightNextOption(); dojo.event.browser.stopEvent(evt); return; case k.KEY_UP_ARROW: this.highlightPrevOption(); dojo.event.browser.stopEvent(evt); return; case k.KEY_ENTER: // prevent to send form if we press enter with list open if(this._result_list_open){ dojo.event.browser.stopEvent(evt); } // falltrough case k.KEY_TAB: // using linux alike tab for autocomplete if(!this.autoComplete && this._result_list_open && this._highlighted_option){ dojo.event.browser.stopEvent(evt); this.selectOption({ 'target': this._highlighted_option, 'noHide': true }); // put caret last this.setSelectedRange(this.textInputNode, this.textInputNode.value.length, null); }else{ this.selectOption(); return; } break; case k.KEY_SPACE: if(this._result_list_open && this._highlighted_option){ dojo.event.browser.stopEvent(evt); 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.hideResultList(); doSearch = false; } break; case k.KEY_RIGHT_ARROW: // falltrough case k.KEY_LEFT_ARROW: // falltrough case k.KEY_SHIFT: doSearch = false; break; default:// non char keys (F1-F12 etc..) shouldnt open list if(evt.charCode==0){ doSearch = false; } }// this.setValue(this.textInputNode.value); 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 bubbels through DOM and we have value visible this.searchTimer = setTimeout(dojo.lang.hitch(this, this.startSearchFromInput), this.searchDelay); } }, onKeyDown: function(evt){ // IE needs to stop keyDown others need to stop keyPress if(!document.createEvent){ // only IE this._handleKeyEvents(evt); } // FIXME: What about ESC ?? }, onKeyPress: function(evt){ if(document.createEvent){ // never IE this._handleKeyEvents(evt); } }, onKeyUp: function(evt){ this.setValue(this.textInputNode.value); }, setSelectedValue: function(value){ // FIXME, not sure what to do here! this.comboBoxSelectionValue.value = value; this.hideResultList(); }, // opera, khtml, safari doesnt support node.scrollIntoView(), workaround scrollIntoView: function(){ var node = this._highlighted_option; var parent = this.optionsListNode; // dont rely on that node.scrollIntoView works just because the function is there // it doesnt work in Konqueror or Opera even though the function is there and probably // not safari either // dont like browser sniffs implementations but sometimes you have to use it if(dojo.render.html.ie || dojo.render.html.mozilla){ // IE, mozilla node.scrollIntoView(false); }else{ var parentBottom = parent.scrollTop + dojo.style.getInnerHeight(parent); var nodeBottom = node.offsetTop + dojo.style.getOuterHeight(node); if(parentBottom < nodeBottom){ parent.scrollTop += (nodeBottom - parentBottom); }else if(parent.scrollTop > node.offsetTop){ parent.scrollTop -= (parent.scrollTop - node.offsetTop); } } }, // does the actual highlight focusOptionNode: function(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);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -