Кривые идентификаторы в jsf

363
07 августа 2017, 10:30

Ребята доброе время суток. JSF генерирует свои айдишники поверх моих... Есть ли какая нибудь возможность этого избежать?

Answer 1

Чтобы избежать проблем при использовании идентификторов, требуется понять, как они работают. Предположим для примера, что у вас есть редактируемый dataTable:

<h:form id="f1">
  <h:dataTable id="d1" value="#{tableBean.rows}" var="row">
    <h:column>
      <h:outputText value="#{row.name}" />
    </h:column>
    <h:column>
      <h:inputText id="x1" value="#{row.quantity}" />
    </h:column>
  </h:dataTable>
  <h:commandButton value="save" action="#{tableBean.save}" />
</h:form>

Мы указали id только один раз, но развернётся этот код в таблицу содержащую множество строк, в каждой из которых будет поле ввода, которое должно иметь уникальный идентификатор:

<table id="f1:d1">
 <tbody>
  <tr>
   <td>beans</td>
   <td><input id="f1:d1:0:x1" type="text" name="f1:d1:0:x1" value="0" /></td>
  </tr>
  <tr>
   <td>carrots</td>
   <td><input id="f1:d1:1:x1" type="text" name="f1:d1:1:x1" value="0" /></td>
  </tr>
  <tr>
   <td>corns</td>
   <td><input id="f1:d1:2:x1" type="text" name="f1:d1:2:x1" value="0" /></td>
  </tr>
 </tbody>
</table>

Прежде всего важно понять, что есть идентификтор компонента - это то, что вы задаёте в атрибуте id, и есть клиентский идентификтор - то, что появится в результирующей xhtml-разметке. Если не указать идентификатор компонента, метод UIComponent.getId() сгенерирует случайный, типа j_id_jsp_115874224_691. Клиентский идентификтор генерируется методом UIComponent.getClientId(FacesContext context), в описании которого описан принцип его работы:

Find the closest ancestor to this component in the view hierarchy that implements NamingContainer. Call getContainerClientId() on it and save the result as the parentId local variable. Call getId() on this component and save the result as the myId local variable. If parentId is non-null, let myId equal parentId + UINamingContainer.getSeparatorChar(javax.faces.context.FacesContext) + myId.

То есть метод находит ближайшего родителя, реализующего интерфейс NamingContainer, получает его имя и объединяет с именем компонента с помощью разделителя, полученного вызовом UINamingContainer.getSeparatorChar(javax.faces.context.FacesContext). По умолчанию разделитель - это знак двоеточия :.

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

READ ALSO
Не парсится стиль Google Maps

Не парсится стиль Google Maps

Следующий код выдаёт исключение Map style parsing failed при запуске:

309
Не подключается файл php к сайту

Не подключается файл php к сайту

Файл php открывается просто белым листомНа других страницах php всё отображается корректно

380
Как добавить полосу прокрутки?

Как добавить полосу прокрутки?

Здравствуйте, каким образом можно добавить полосу прокрутки на сайт (я имею виду не стандартную полосу в нижней или правой части экрана, а где...

391
Как задать 2 фона с разным раположением?

Как задать 2 фона с разным раположением?

Приветствую! Как можно сделать два фона в одном блоке с разным расположением? Первый фон выравнивается по правой стороне, без повторений,...

334