我正在编写一个自动完成的自定义组件作为使用 JSF 的学习练习 2.1.3.这个想法(可能很熟悉)是输入一些文本到 并输入组件并显示具有匹配值的列表框。这个想法是 在调用 jsf.ajax.request() 的输入上有一个 keyup javascript 事件 更新组件。到目前为止,我已经有了一个可以包含的组件 这个:
<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() 方法执行,我可以获得输入值。经过 指定 render: 'myauto' encode...() 方法执行以重新生成 html。
一切都很好,但是因为我正在渲染 myauto_input 的父级 组件每次触发 keyup 事件时我都会失去输入焦点。
如果我指定像 render: 'myauto_listbox' 这样的东西(我真的只想 毕竟重新渲染列表框)问题是编码...()方法 不要执行,因为它们是针对整个自定义组件的,而不仅仅是 列表框。它将在我重建的编码...() 方法之一中 包含建议的列表框。
该组件扩展了 UIInput,我在单独的渲染器中生成标记 (componentFamily = "javax.faces.Input") 在 encodeEnd() 方法中(所以这个 总是在任何提供的转换器之后运行 - 尚未实现)。我想 从 javascript 强制焦点是一个可怕的 hack,应该避免。
我有点不确定该去哪里,但我怀疑我所看到的 表明我以某种错误的方式接近这个。如果有人 足以为我指明正确的方向我将不胜感激
最佳答案
我花了一些时间研究这个问题以及之后失去焦点的一般问题 ajax 更新相当普遍,在 Jim Driscoll 的 blog 中有所描述。 (看 “保持专注”)。
对于我的自定义组件,我(认为我...)必须更新自定义组件 它本身是输入的父级,所以我会因为 ajax 更新,这就是它的方式。因此,我研究了需要做的事情 完成恢复焦点,似乎在我的渲染器编码中我只需要 强制将焦点恢复到输入,但仅在响应 jsf.ajax.request 从 onkeyup 事件发送的 POST 时。我使用 jQuery,只是调用 .focus() 不是 足够了,因为您还必须将光标位置定位到任何现有 输入。下面这段代码似乎工作正常:
<script>
jQuery(function($){var cid='#myauto_input';$(cid).focus().focus().click();$(cid).val($(cid).val());});
</script>
(注意:IE8 需要 .focus().focus().click(),只有 .focus() 适用于 chrome...)
看来可怕的黑客挽救了局面。我确实想知道是否会有 如果我使用 jQuery ajax 例程而不是 jsf ajax 库,会有什么不同但是 我认为这不会产生任何影响。
关于javascript - JSF 自定义组件失去对 ajax 更新的输入关注,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7153475/