您的位置:首页 > 其它

dojo控件FilteringSelect的使用经历

2010-12-31 07:58 399 查看
最近在用dojo做一个项目的前台。版本是1.2.3,期间使用到了FilteringSelect这个下拉菜单控件。这个控件的功能不错,即可以像传统的select标签一样下拉选择,还可以让用户直接输入进行逐字搜索匹配。不过,东西毕竟是老外做的,使用时还是到了一些水土不服的问题,这些问题在网上搜过,但都没什么结果。现在有些问题解决了,有些没有很完美的解决。现在拿出来和大家一起分享和讨论一下。

问题1:FilteringSelect和ComboBox控件中文显示问题

发现FilteringSelect选定选项后,英文可以正常显示在控件中间,但中文有明显的上移,字体上面一小部分被遮盖,下面有较大的空隙。我想应该是dojo的css样式设定问题,于是找到了dijit/themes/dijit.css文件。其中有一段定义ComboBox文本框样式的

.dijitTextBox INPUT,
.dijitComboBox INPUT,
.dijitSpinner INPUT {
border-left: solid black 1px;
display:inline;
position:static !important;
border:0 !important;
margin:0 !important;
vertical-align:top!important;

visibility:visible !important;
background-color:transparent !important;
background-image:none !important;
width:100% !important;

}


其中vertical-align这项默认竟然是top,现改为middle后,中文显示正常。

问题2:

在FilteringSelect中输入文字时,控件默认是按照从第一个字开始匹配的。现想对

可选项根据
输入的字进行包含式模糊查询的功能

之前查看了FilteringSelect的API,发现有个queryExpr的属性,根据说明

dojo.data query expression pattern. ${0} will be substituted for the user
text. * is used for wildcards. ${0}* means "starts with", *${0}* means "contains",
${0} means "is"

这个*${0}*应该就是我们想要的包含查询了。于是将queryExpr=“

*${0}*
”属性加入到

FilteringSelect得input标签里。但发现这样声明并不起作用,无奈之下,翻了下ComboBox.js的源码,在其中发现了queryExpr属性初始化的位置如下

// labelType: String
//"html" or "text"
labelType: "text",
// queryExpr: String
//	dojo.data query expression pattern.
//	`${0}` will be substituted for the user text.
//	`*` is used for wildcards.
//	`${0}*` means "starts with", `*${0}*` means "contains", `${0}` means "is"
queryExpr: "${0}*"
// ignoreCase: Boolean
ignoreCase: true,


无奈下,在代码中直接将queryExpr的初始值改为 "*${0}*" ,问题解决。

问题3:在

FilteringSelect输入中文后不像输入英文或数字一样自动进行搜索匹配,只能敲了空格再敲回退键的时候才触发显示提示选项

这个问题比较头疼。继续翻ComboBox的源码,找到ComboBox文本框处理按键事件的函数,如下

_onKeyPress: function(/*Event*/ evt){
// summary: handles keyboard events
var key = evt.charOrCode;
//except for cutting/pasting case - ctrl + x/v
if(evt.altKey || (evt.ctrlKey && (key != 'x' && key != 'v')) || evt.key == dojo.keys.SHIFT){
return; // throw out weird key combinations and spurious events
}
var doSearch = false;
var pw = this._popupWidget;
var dk = dojo.keys;
if(this._isShowingNow){
pw.handleKey(key);
}
switch(key){
case dk.PAGE_DOWN:
case dk.DOWN_ARROW:
if(!this._isShowingNow||this._prev_key_esc){
this._arrowPressed();
doSearch=true;
}else{
this._announceOption(pw.getHighlightedOption());
}
dojo.stopEvent(evt);
this._prev_key_backspace = false;
this._prev_key_esc = false;
break;
case dk.PAGE_UP:
case dk.UP_ARROW:
if(this._isShowingNow){
this._announceOption(pw.getHighlightedOption());
}
dojo.stopEvent(evt);
this._prev_key_backspace = false;
this._prev_key_esc = false;
break;
case dk.ENTER:
// prevent submitting form if user presses enter. Also
// prevent accepting the value if either Next or Previous
// are selected
var highlighted;
if(this._isShowingNow &&
(highlighted = pw.getHighlightedOption())
){
// only stop event on prev/next
if(highlighted == pw.nextButton){
this._nextSearch(1);
dojo.stopEvent(evt);
break;
}else if(highlighted == pw.previousButton){
this._nextSearch(-1);
dojo.stopEvent(evt);
break;
}
}else{
// Update 'value' (ex: KY) according to currently displayed text
this._setDisplayedValueAttr(this.attr('displayedValue'), true);
}
// default case:
// prevent submit, but allow event to bubble

// 加入按下enter键后触发搜索
doSearch = true;
evt.preventDefault();
// fall through
...........................................
}
if(this.searchTimer){
clearTimeout(this.searchTimer);
}
if(doSearch){
// need to wait a tad before start search so that the event
// bubbles through DOM and we have value visible
setTimeout(dojo.hitch(this, "_startSearchFromInput"),1);
}
}


搜了下官网论坛,发现亚洲语言都会有这个问题,上面也没有可借鉴的解决方案,这个问题直接原因应该是中文字都是通过输入法软件进行录入的,控件文本框中无法捕捉到键盘的敲击事件导致无法触发search方法。

我目前一个变通方式就是在捕捉到enter事件后进行search,添加代码如上。用户在输入文字后按enter键进行模糊查询并显示搜索后可选项。

最后一个问题不知道有没有更好的解决方法,期待ing。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: