Id dinámicos en JSF/Seam
(3)
Supongo que quiere controlar la identificación de su componente de entrada para poder consultarlo más adelante en Javascript.
Como no puede establecer el ID a través de una expresión, hago esto:
<h:inputText id="whatever" value="..." />
Luego más adelante en el código:
<script type="text/javascript">
var theElement = document.getElementById(''<h:outputText value="#{pagecode.whateverClientId}"/ >'');
...
</script>
En el código de página:
protected HtmlInputText getWhatever() {
if (whatever == null) {
whatever = (HtmlInputText) findComponentInRoot("whatever");
}
}
public String getWhateverClientId() {
return getWhatever().getClientId(getFacesContext());
}
Espero que ayude.
Tengo un pequeño problema con una aplicación de Seam en la que estoy trabajando y me preguntaba si alguien sabe cómo sortearla. Tengo un formulario en mi aplicación que usa AJAX para mostrar ciertos cuadros de entrada dependiendo de un elemento en un cuadro desplegable. El código funciona bien, excepto para establecer los ID en mis cuadros de entrada. Parece que JSF no me deja establecer una ID a través de una variable. Otros atributos como "para" en las etiquetas están bien. Aquí hay un código que explica lo que quiero decir:
<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>
¿Alguien tiene alguna idea de cómo puedo superar esto?
Ya ves por qué no te dejan configurar la identificación, ¿verdad? JSF se hace cargo de la creación de ID porque se encuentra en un bucle repetido de componentes y, si le permitieran simplemente configurar la identificación, terminaría con ID duplicados, lo que de todos modos no lo ayudaría.
Sin saber POR QUÉ quiere establecer el ID de manera explícita, es difícil darle una solución. Si se trata de JavaScript, puede hacer lo que sugiere Grant Wagner y dejar que JSF le proporcione el ID. También puede echar un vistazo al código HTML generado y ver en qué formato está el ID. JSF generalmente usa
"form_id:loop_id:loop_index:component_id"
como el id que genera para los componentes en una forma / repetición. Tendría que estar seguro y dar los id a su formulario y ui: repetir las etiquetas para saber cuáles eran.
Ok, respondiste que quieres tener una etiqueta h: message para un texto de entrada específico dentro del ciclo, eso es fácil.
<h:inputText id="myInput" .... />
<h:message for="myInput" ... />
Ahora, los mensajes generados para la entrada se mostrarán en el mensaje, y JSF manipulará el atributo "para" (aunque eso no se genera en HTML) al igual que el atributo "id" en el texto de entrada para que coincida.
Incluso puede hacer que sus PROPIOS mensajes en su código de controlador para ir al mensaje h: específico, pero tendrá que utilizar una llamada a ID de cliente para obtener el objetivo del mensaje, dado el bean de respaldo (no el bean de respaldo de valor) del componente en cuestión.
¿Has probado usar facelets?
Eso le permitirá asignar sus propios ID, es decir:
me: labelKeyThingo puede usar id = # {labelKey} para hacer una etiqueta única. Aquí hay un ejemplo de facelet llamado m: textPassword de mi código incorrecto:
<!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>
Se usa así:
<m:textPassword id="password" label="#{msgs.passwordPrompt}"
property="#{individualApplicationMBean.password}"
required="true" maxlength="16" />