Пользовательский компонент JSF теряет фокус ввода при обновлении AJAX - PullRequest
6 голосов
/ 23 августа 2011

Я пишу пользовательский компонент автозаполнения в качестве учебного упражнения с JSF 2.1.3. Идея (которая, вероятно, довольно знакома) состоит в том, чтобы ввести некоторый текст в и введите компонент и представьте список с соответствующими значениями. Идея иметь на входе событие javascript keyup, которое вызывает jsf.ajax.request () обновить компонент. Пока у меня есть компонент, который я могу включить, как это:

<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>

Функция javascript (keyup) com.myco.ajaxRequest () делает это:

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

Итак, потому что я хочу перестроить и заново отобразить список с предложениями список, я перерисовываю пользовательский компонент 'myauto'. Указывая выполнить: 'myauto' метод decode () выполняется, и я могу получить входное значение. От указание render: 'myauto' методы encode ... () выполняются для регенерации HTML.

Это все хорошо, но потому что я рендерил родителя myauto_input Компонент I теряет фокус ввода каждый раз, когда срабатывает событие keyup.

Если я укажу что-то вроде render: 'myauto_listbox' (я очень хочу в конце концов, перерисовать список) проблема в том, что методы encode ... () не выполнять, потому что они для пользовательского компонента в целом, а не только список. И это будет в одном из методов кодирования ... (), который я перестроить список, содержащий предложения.

Компонент расширяет UIInput, и я генерирую разметку в отдельном рендерере (componentFamily = "javax.faces.Input") в методе encodeEnd () (поэтому это всегда работает после любого поставляемого конвертера - еще не реализовано). Я полагаю что заставлять фокусироваться на javascript - это ужасный хак, и его следует избегать.

Я немного не уверен, куда идти с этим, но я подозреваю, что то, что я вижу указывает на то, что я как-то неправильно подхожу к этому. Если кто-то было бы достаточно, чтобы указать мне правильное направление, я был бы очень признателен это.

1 Ответ

1 голос
/ 24 июля 2014

Я потратил некоторое время на изучение этого вопроса, и общая проблема потери фокуса после обновления ajax довольно распространена и описана в блоге Джима Дрисколла (см. «Сохранение фокуса»).

В случае моего пользовательского компонента я (думаю, что ...) должен обновить сам пользовательский компонент, который является родительским элементом ввода, поэтому я потеряю фокус в результате обновления ajax, итак оно и есть.Таким образом, я посмотрел на то, что необходимо сделать для восстановления фокуса, и кажется, что в моем кодере рендерера мне просто нужно принудительно восстановить фокус на входе, но только при ответе на POST, отправленный с события onkeyup jsf.Ajax.Request.Я использую jQuery, и просто вызова .focus () недостаточно, потому что вам также нужно получить позицию курсора до конца любого существующего ввода.Этот код ниже, кажется, работает нормально:

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

(примечание: .focus (). Focus (). Click () требуется для IE8, просто .focus () работает на chrome ...)

Похоже, что ужасный хак спас день.Я действительно задавался вопросом, будет ли какая-либо разница, если бы я использовал подпрограммы jQuery ajax вместо библиотеки jsf ajax, но я не думаю, что это будет иметь какое-либо значение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...