Primefaces, JavaScript и JSF плохо работают вместе, или я что-то не так делаю

Вот что-то такое простое

<p:commandLink value="Tom" onclick="document.getElementById('tom').focus()"/><br/>
<input id="tom"/>

Когда вы нажимаете на Тома, текстовое поле получает фокус. Отлично, теперь попробуйте это

<p:commandLink value="Tom" onclick="document.getElementById('tom').focus()"/><br/>
<h:inputText id="tom"/> <br/>

когда я нажимаю ничего не происходит, я проверяю firebug, я вижу

document.getElementById("tom") is null

Когда я пытаюсь использовать jQuery $('#tom').focus(), ничего не происходит, ошибок нет, но и фокуса не получается. Это response (не уверен, что это ответ сервера), когда я вижу от firebug

<?xml version="1.0" encoding="utf-8"?>
<partial-response>
    <changes>
       <update id="javax.faces.ViewState"><![CDATA[455334589763307998:-2971181471269134244]]></update>
    </changes>
    <extension primefacesCallbackParam="validationFailed">{"validationFailed":false}</extension>
</partial-response>


person Thang Pham    schedule 27.10.2010    source источник


Ответы (5)


В JSF перед идентификаторами элементов стоит идентификатор формы, которая их содержит (в более общем случае перед их идентификаторами стоит идентификатор всех родительских компонентов, реализующих метод NamingContainer). Например:

<h:form id="myForm">
    <h:inputText id="tom" .../>

сгенерирует следующий HTML-код:

<input id="myForm:tom" ...>

Чтобы получить доступ к <input>, вы должны использовать идентификатор myForm:tom, а не сам идентификатор tom.

С jQuery вам придется использовать $("myForm\:tom").focus();

person Romain Linsolas    schedule 28.10.2010

JSF добавит идентификаторы дочерних элементов UINamingContainer (h:form, h:dataTable и т. д.) с идентификатором самого компонента UINamingContainer. Вы можете отключить это, установив для атрибута prependId значение false.

<h:form prependId="false">

Вы больше не сможете динамически включать один и тот же фрагмент кода где-то еще в том же представлении. Имейте это в виду при отключении этого.

person BalusC    schedule 28.10.2010

а с Primefaces2 вы должны использовать jQuery вместо $, например:

 <h:commandButton id="dome" value="提交" action="#{uInfo.doMe}">
  <f:ajax execute="@form" render="@form"/>
 </h:commandButton>
 ...
 <script type="text/javascript">
 function refresh() {
  jQuery("input#dome").click();
 }
 var t=setInterval('refresh()', 5000);
 </script>
person quakezh    schedule 17.01.2011

Вам нужно присвоить этому тегу JSF атрибут id, например:

<h:inputText id="tom" />

В противном случае он не будет отображаться с id, и поэтому не будет элемента id="tom" для поиска.

person Nick Craver    schedule 28.10.2010
comment
@Harry - как выглядит обработанный HTML? - person Nick Craver; 28.10.2010
comment
На самом деле я понимаю, что не так. За пределами этих commandLink находится форма, которая будет добавлять id к своему дочернему элементу, поэтому вместо идентификатора tom теперь он становится j_idt7:tom. Если я document.getElementById('j_idt7:tom'), то это работает. jQuery на самом деле умнее, если я делаю $('#tom'), он не говорит, что элемент tom имеет значение null, но и не получает фокуса. :( - person Thang Pham; 28.10.2010
comment
@Harry - вы можете сделать $("input[id$=tom]") для идентификаторов, которые заканчиваются на tom ... или вместо этого дать ему класс и использовать этот селектор, например class="tom" и $(".tom"). - person Nick Craver; 28.10.2010

Не забывайте, что простые лица также позволяют вам использовать атрибут widgetvar для привязки вашего компонента к объекту javascript.

так например:

<p:inputText widgetvar="tom" id="tom" />

то в вашем коде javascript или каком-либо обратном вызове javascript вы можете сделать:

tom.disable()

и т.п.

person arg20    schedule 24.05.2011