Динамические идентификаторы в JSF / Seam - PullRequest
5 голосов
/ 25 ноября 2008

У меня небольшая проблема с приложением Seam, над которым я работаю, и мне было интересно, если кто-нибудь знает способ обойти это. В моем приложении есть форма, которая использует AJAX для отображения определенных полей ввода в зависимости от элемента в раскрывающемся списке. Код работает нормально, за исключением установки идентификаторов в моих полях ввода. Похоже, JSF не позволяет мне устанавливать идентификатор через переменную. Другие атрибуты, такие как «для» в метках, в порядке. Вот код, объясняющий, что я имею в виду:

<ui:repeat value="#{serviceHome.instance.serviceSettings}" var="currSetting" >
  <li>
    <!-- Imagine the below works out as "settingABC" -->
    <c:set var="labelKey" value="setting#{jsfUtils.removeWhitespace(currSetting.key.name)}" />

    <!-- Labelkey is correctly added into this input so for = "settingABC" -->
    <h:outputLabel for="#{labelKey}" styleClass="required generated" value="#{currSetting.key.name}:"/>

    <s:decorate styleClass="errorwrapper">

      <!-- Labelkey ISN'T correctly added into this input. Instead we just get "setting" -->
      <h:inputText id="#{labelKey}" value="#{currSetting.value}"/>

      <a4j:outputPanel ajaxRendered="true">
        <h:message for="#{labelKey}" styleClass="errormessage" />
      </a4j:outputPanel>
    </s:decorate>
  </li>
</ui:repeat>

Кто-нибудь знает, как мне пройти через это?

Ответы [ 3 ]

8 голосов
/ 28 ноября 2008

Вы видите, почему они не позволяют вам установить ID, верно? JSF берет на себя создание идентификатора, потому что вы находитесь в повторяющемся цикле компонентов и, если они позволят вам просто установить идентификатор, вы получите дублирующие идентификаторы, которые в любом случае вам не помогут.

Не зная, ПОЧЕМУ вы хотите установить идентификатор в явном виде, трудно обойти вас. Если это для JavaScript, вы можете делать то, что предлагает Грант Вагнер, и позволить JSF дать вам то, что он назвал идентификатором. Вы также можете взглянуть на сгенерированный HTML и посмотреть, в каком формате находится идентификатор. JSF обычно использует

"form_id:loop_id:loop_index:component_id" 

как идентификатор, который он генерирует для компонентов в форме / повтор. Вы должны быть уверены и дать идентификаторы для вашей формы и пользовательского интерфейса: повторите теги, чтобы знать, что они были.

Хорошо, вы ответили, что хотите иметь тег h: message для определенного inputText внутри цикла, это просто.

<h:inputText id="myInput" .... />
<h:message for="myInput" ... />

Теперь сообщения, сгенерированные для ввода, будут отображаться в сообщении, и JSF будет манипулировать атрибутом «for» (хотя он не сгенерирован для HTML) так же, как и атрибут «id» в inputText, чтобы они матч.

Вы можете даже сделать свои СОБСТВЕННЫЕ сообщения в своем коде обработчика, чтобы перейти к конкретному сообщению h :, но вам нужно будет использовать вызов clientId, чтобы получить цель сообщения, учитывая компонент поддержки (а не значение). поддерживающий компонент) рассматриваемого компонента.

3 голосов
/ 25 ноября 2008

Я предполагаю, что вы хотите контролировать идентификатор вашего компонента ввода, чтобы вы могли ссылаться на него позже в Javascript?

Поскольку вы не можете установить идентификатор с помощью выражения, я делаю это:

<h:inputText id="whatever" value="..." />

Далее в коде:

<script type="text/javascript">
var theElement = document.getElementById('<h:outputText value="#{pagecode.whateverClientId}"/ >');
...
</script>

В коде страницы:

protected HtmlInputText getWhatever() {
    if (whatever == null) {
        whatever = (HtmlInputText) findComponentInRoot("whatever");
    }
}

public String getWhateverClientId() {
    return getWhatever().getClientId(getFacesContext());
}

Надеюсь, это поможет.

0 голосов
/ 19 марта 2009

Вы пробовали использовать лицевые маски?

Это позволит вам использовать ваши собственные идентификаторы, например:

me: labelKeyThingo может затем использовать id = # {labelKey} для создания уникальной метки. Вот пример лицевой стороны m: textPassword из моего неверного кода:

   <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
             "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
   <html xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core"
    xmlns:c="http://java.sun.com/jstl/core" xmlns:a4j="http://richfaces.org/a4j"
    xmlns:rich="http://richfaces.org/rich">

   <ui:composition>

    <c:set var="styleClass" value="formPrompt" />
    <c:set var="requiredLabel" value="" />
    <c:choose>
        <c:when test="${required=='true'}">

            <c:set var="required" value="true" />
            <c:set var="styleClass" value="formRequiredPrompt" />
            <c:set var="requiredLabel" value="*" />
        </c:when>
    </c:choose>

    <h:panelGroup id="#{id}_formRowTemplateLabel_panelGroup">
        <h:outputLabel for="#{id}" styleClass="#{styleClass}" id="#{id}_formRowTemplate_outPut"
            value="#{label}" />
        <c:if test="${required == 'true'}">
            <h:outputText value="#{requiredLabel}" styleClass="formRequiredPromptAsterix"></h:outputText>
        </c:if>
    </h:panelGroup>

    <h:panelGroup id="#{id}_textPasswordTemplate_panelGroup">
        <h:inputSecret required="${required}" id="#{id}" value="#{property}"
            styleClass="formText">

            <f:validator validatorId="Maserati.Password" />
            <f:validateLength maximum="16" minimum="8" />
            <ui:insert name="additionalTags"></ui:insert>
        </h:inputSecret>

        <h:message styleClass="formErrorMsg" id="#{id}_textPasswordTemplate_msg" for="#{id}" />
    </h:panelGroup>

   </ui:composition>

   </html>

Используется так:

 <m:textPassword id="password" label="#{msgs.passwordPrompt}"
 property="#{individualApplicationMBean.password}"
 required="true" maxlength="16" />
...