在本篇中,我們將向你展示怎樣使用Mabon來建立一個簡單而強有力的輸入組件,它具有類似於Google Suggest所提供的內建的建議功能。為了使Web開發人員更為容易地使用我們的JDJ InputSuggest組件,我們藉助於Weblets開源工程來把外部資源,例標和JavaScript庫,綁定到一個Java檔案檔案(JAR)中—由它來描述我們的JSF組件綁定。
一、建立支援AJAX的JSF HtmlInputSuggest組件
這個JSF AJAX輸入建議方案共包括四個類,見圖1。
圖1.類圖:構建輸入建議組件所需要的類
這些類分別是:
•HtmlInputSuggest—螢幕產生器特定的子類。
•HtmlRenderer—這是一個超類,它提供一些便利的方法來實現資源編碼。
•HtmlInputSuggestRenderer—是你的新定製的螢幕產生器,它負責把標註產生到用戶端螢幕上,包括需要的資源,例如JavaScript庫和式樣表等。
•HtmlInputSuggestTag是標籤處理器。
在我們的輸入建議解決方案中,我們實現了一個JavaScript庫—inputSuggest.js—它包含利用Mabon從Web開發人員的支援bean中檢索資料的功能。在本文中,我們將詳細討論inputSuggest.js檔案和HtmlInputSuggestRenderer—它們都受Mabon的影響並且提供了輸入欄位這些輸入欄位都具有輸入探測type-ahead)和建議列表功能)。
二、輸入建議JavaScript庫
既然我們使用Mabon,因此不需要擔心從支援bean中取回資料的問題。我們可以把這項任務交給Mabon來完成。然而,我們關心的是,如何處理XMLHttpRequest對象返回的資料,如何填充實際的建議列表以及如何處理使用者互動。這個inputSuggest.js庫中包含了大量的函數,用來處理鍵盤導航和滑鼠互動。篇幅所限,在此我們將集中分析對該JSF HtmlInputSuggest組件有重大影響的函數。
(一)doKeyPress函數
顯示於列表1中的doKeyPress函數負責處理鍵擊事件並檢查是否使用者按下了TAB鍵。在正常情況下,這個TAB鍵將移出輸入欄位並激發blur事件。對於本文中的輸入建議解決方案來說,一次TAB鍵擊也可以用於從建議列表中選擇一個活動行。為此,我們需要跟蹤TAB鍵,從建議列表中選擇一行,把值添加到輸入欄位,或者,如果沒有列表資料可用的話,離開該輸入欄位。如果發生控制項導航,那麼將啟用doBlur()函數並關閉建議列表。
列表1—doKeyPress函數
projsf.jdj.doKeyPress = function(event){ var input = (event.srcElement || event.target); var inputId = input.id; var div = document.getElementById(inputId + "$suggest"); var divStyle = (div.currentStyle || div.style); if (event.keyCode == 9 && divStyle.display == "block") { div.style.display = "none"; var activeRow = projsf.jdj._findActiveRow(div); input.value = activeRow.innerHTML; return false; //取消按Tab鍵離開輸入欄位 } return true; //繼續:按Tab鍵離開輸入欄位,它將調用doBlur() }
|
列表2—doKeyUp函數
projsf.jdj.doKeyUp = function(event){ var input = (event.srcElement || event.target); var inputId = input.id; var div = document.getElementById(inputId + "$suggest"); if (event.keyCode == 9)//Tab鍵 { return false; } else if ((div.style.display == "block" || div.childNodes.length > 0) && (event.keyCode == 40 || event.keyCode == 38)) { if (div.style.display == "none") { div.style.display = "block"; } else { var activeRow = projsf.jdj._findActiveRow(div); switch (event.keyCode) { case 40: /向下箭頭 if (activeRow.nextSibling) { activeRow.className = "HtmlInputSuggestRow"; activeRow = activeRow.nextSibling; activeRow.className = "HtmlInputSuggestActiveRow"; } break; case 38: /向上箭頭 if (activeRow.previousSibling) { activeRow.className = "HtmlInputSuggestRow"; activeRow = activeRow.previousSibling; activeRow.className = "HtmlInputSuggestActiveRow"; } break; } input.value = activeRow.innerHTML; } return false; } if (event.keyCode != 8)//不是一個Backspace鍵 { input.blur(); input.focus(); } if (input.value.length <= 2) div.style.display = "none"; }
|