2011-08-22 77 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库,是否会有 的差异,但我不认为它会有什么不同。