最近在用dojo做一個項目的前台。版本是1.2.3,期間使用到了FilteringSelect這個下拉式功能表控制項。這個控制項的功能不錯,即可以像傳統的select標籤一樣下拉選擇,還可以讓使用者直接輸入進行逐字搜尋匹配。不過,東西畢竟是老外做的,使用時還是到了一些水土不服的問題,這些問題在網上搜過,但都沒什麼結果。現在有些問題解決了,有些沒有很完美的解決。現在拿出來和大家一起分享和討論一下。
問題1:FilteringSelect和ComboBox控制項中文顯示問題
發現FilteringSelect選定選項後,英文可以正常顯示在控制項中間,但中文有明顯的上移,字型上面一小部分被遮蓋,下面有較大的空隙。我想應該是dojo的css樣式設定問題,於是找到了dijit/themes/dijit.css檔案。其中有一段定義ComboBox文字框樣式的
.dijitTextBox INPUT,<br />.dijitComboBox INPUT,<br />.dijitSpinner INPUT {<br /> border-left: solid black 1px;<br /> display:inline;<br /> position:static !important;<br /> border:0 !important;<br /> margin:0 !important;<br /> vertical-align:top!important; </p><p> visibility:visible !important;<br /> background-color:transparent !important;<br /> background-image:none !important;<br /> width:100% !important; </p><p>}<br />
其中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<br />//"html" or "text"<br />labelType: "text",<br />// queryExpr: String<br />//dojo.data query expression pattern.<br />//`${0}` will be substituted for the user text.<br />//`*` is used for wildcards.<br />//`${0}*` means "starts with", `*${0}*` means "contains", `${0}` means "is"<br />queryExpr: "${0}*"<br />// ignoreCase: Boolean<br />ignoreCase: true,
無奈下,在代碼中直接將queryExpr的初始值改為 "*${0}*" ,問題解決。
問題3:在
FilteringSelect輸入中文後不像輸入英文或數字一樣自動進行搜尋匹配,只能敲了空格再敲回退鍵的時候才觸發顯示提示選項
這個問題比較頭疼。繼續翻ComboBox的源碼,找到ComboBox文字框處理按鍵事件的函數,如下
_onKeyPress: function(/*Event*/ evt){<br />// summary: handles keyboard events<br />var key = evt.charOrCode;<br />//except for cutting/pasting case - ctrl + x/v<br />if(evt.altKey || (evt.ctrlKey && (key != 'x' && key != 'v')) || evt.key == dojo.keys.SHIFT){<br />return; // throw out weird key combinations and spurious events<br />}<br />var doSearch = false;<br />var pw = this._popupWidget;<br />var dk = dojo.keys;<br />if(this._isShowingNow){<br />pw.handleKey(key);<br />}<br />switch(key){<br />case dk.PAGE_DOWN:<br />case dk.DOWN_ARROW:<br />if(!this._isShowingNow||this._prev_key_esc){<br />this._arrowPressed();<br />doSearch=true;<br />}else{<br />this._announceOption(pw.getHighlightedOption());<br />}<br />dojo.stopEvent(evt);<br />this._prev_key_backspace = false;<br />this._prev_key_esc = false;<br />break;<br />case dk.PAGE_UP:<br />case dk.UP_ARROW:<br />if(this._isShowingNow){<br />this._announceOption(pw.getHighlightedOption());<br />}<br />dojo.stopEvent(evt);<br />this._prev_key_backspace = false;<br />this._prev_key_esc = false;<br />break;<br />case dk.ENTER:<br />// prevent submitting form if user presses enter. Also<br />// prevent accepting the value if either Next or Previous<br />// are selected<br />var highlighted;<br />if(this._isShowingNow &&<br />(highlighted = pw.getHighlightedOption())<br />){<br />// only stop event on prev/next<br />if(highlighted == pw.nextButton){<br />this._nextSearch(1);<br />dojo.stopEvent(evt);<br />break;<br />}else if(highlighted == pw.previousButton){<br />this._nextSearch(-1);<br />dojo.stopEvent(evt);<br />break;<br />}<br />}else{<br />// Update 'value' (ex: KY) according to currently displayed text<br />this._setDisplayedValueAttr(this.attr('displayedValue'), true);<br />}<br />// default case:<br />// prevent submit, but allow event to bubble</p><p> // 加入按下enter鍵後觸發搜尋<br /> doSearch = true;<br />evt.preventDefault();<br />// fall through<br /> ...........................................<br />}<br />if(this.searchTimer){<br />clearTimeout(this.searchTimer);<br />}<br />if(doSearch){<br />// need to wait a tad before start search so that the event<br />// bubbles through DOM and we have value visible<br />setTimeout(dojo.hitch(this, "_startSearchFromInput"),1);<br />}<br />}
搜了下官網論壇,發現亞洲語言都會有這個問題,上面也沒有可借鑒的解決方案,這個問題直接原因應該是中文字都是通過IME軟體進行錄入的,控制項文字框中無法捕捉到鍵盤的敲擊事件導致無法觸發search方法。
我目前一個變通方式就是在捕捉到enter事件後進行search,添加代碼如上。使用者在輸入文字後按enter鍵進行模糊查詢並顯示搜尋後可選項。
最後一個問題不知道有沒有更好的解決方案,期待ing。