Ребята доброе время суток. JSF генерирует свои айдишники поверх моих... Есть ли какая нибудь возможность этого избежать?
Чтобы избежать проблем при использовании идентификторов, требуется понять, как они работают. Предположим для примера, что у вас есть редактируемый 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). По умолчанию разделитель - это знак двоеточия :.
Проще говоря, чтобы получить "управляемые" клиентские идентификторы, необходимо явно задать идентификторы родительских контейнеров - форм, таблиц и т.п., а потом обращаться к нужному элементу по полному пути, включающему родительские идентификторы, разделённые двоеточиями.
Продвижение своими сайтами как стратегия роста и независимости