2011-08-22 42 views
6

我正在寫一個自動完成自定義組件作爲JSF的學習練習 2.1.3。這個想法(可能很熟悉)是在 中輸入一些文本並輸入組件,並顯示一個帶有匹配值的列表框。這個想法是 在輸入上有一個keyup javascript事件,該事件調用jsf.ajax.request() 來更新組件。到目前爲止,我已經有了一個組成部分,我可以包括像 這樣:JSF自定義組件失去輸入焦點在AJAX更新

<mycc:autocomplete id="myauto" searchMethod="#{bean.doSearch}"/> 

這使得HTML這樣的:

<span id="myauto"> 
    <input type="text" id="myauto_input" name="myauto_input" 
    onkeyup="com.myco.ajaxRequest(this, event)"/> 
    <select id="myauto_listbox" name="myauto_listbox"> 
    <option value="1st">First</option> 
    <option value="2nd">Second</option> 
    </select> 
</span> 

的com.myco.ajaxRequest()JavaScript函數(KEYUP)不這樣的:

jsf.ajax.request(comp, null, { 
       execute: 'myauto', 
       render: 'myauto' 
       }); 

,是因爲我要重建,並與建議重新呈現列表框 列表,我重新呈現的自定義組件「myauto」。通過指定執行: 'myauto'decode()方法執行,我可以得到輸入值。通過 指定渲染:'myauto'的encode ...()方法執行重新生成 的html。

這樣很好,但是因爲我正在渲染myauto_input組件的父組件,所以每次keyup事件觸發時都會丟失輸入焦點。

如果我指定像渲染:「myauto_listbox」(我只是真的想 重新呈現在列表框中畢竟)的問題是編碼...()方法 不執行,因爲他們是爲自定義組件作爲一個整體,而不僅僅是 的列表框。這將是在編碼...()方法之一,我重建 包含建議的列表框。

組件延伸UIInput和我生成在encodeEnd()方法在單獨的渲染器 (componentFamily =「javax.faces.Input」)標記(所以這種 始終運行所提供的任何轉換器後 - 尚未實現)。我想 強制從JavaScript的焦點是一個可怕的黑客,並予以避免。

我有點不確定該去哪裏,但我懷疑我所看到的 表示我以某種方式以錯誤的方式接近這個。如果任何人 將足以指向我在正確的方向,我會非常感謝 它。

回答

1

我花了一些時間尋找到這一點,並 一個Ajax更新後失去焦點的普遍問題是相當普遍和吉姆·德里斯科爾的blog描述(見 「保持專注」)。

在我的自定義組件I(想我...)必須更新自定義組件 本身,這是輸入的父母,所以我要失去焦點作爲結果的阿賈克斯 更新,這就是它的方式。正因爲如此,我已經看過了什麼需要 做恢復焦點,而且看起來在我的渲染器編碼我只需要 強制恢復焦點到輸入,但只有當響應由onkeyup事件發送的POST jsf.ajax.request。我使用jQuery,只是打電話。focus()不是 就夠了,因爲您還必須將光標位置移動到任何現有的 輸入的末尾。下面這段代碼似乎工作確定:

<script> 
    jQuery(function($){var cid='#myauto_input';$(cid).focus().focus().click();$(cid).val($(cid).val());}); 
</script> 

(注意:.focus()對焦()點擊()所需的IE8,只是.focus()對鉻的作品...)

所以看起來這個可怕的黑客節省了一天的時間。我真的懷疑,如果我使用jQuery ajax例程而不是jsf ajax庫,是否會有 的差異,但我不認爲它會有什麼不同。