2008-11-25 10 views
5

Ich habe ein kleines Problem mit einer Seam-Anwendung, an der ich arbeite, und ich frage mich, ob jemand einen Weg dafür kennt. Ich habe ein Formular in meiner Anwendung, das AJAX verwendet, um bestimmte Eingabefelder abhängig von einem Element in einer Dropdown-Box anzuzeigen. Der Code funktioniert einwandfrei, außer dass ich die IDs in meinen Eingabefeldern festlege. Es sieht so aus, als ob JSF mich nicht über eine Variable eine ID setzen lässt. Andere Attribute wie "für" in Etiketten sind in Ordnung. Hier ist ein Code, der erklärt, was ich meine:Dynamische IDs in JSF/Seam

Hat jemand eine Idee, wie ich das hinter sich bringen kann?

Antwort

8

Sie sehen, warum sie nicht lassen Sie die ID, richtig? JSF übernimmt die Erstellung von IDs, weil Sie sich in einer wiederholten Schleife von Komponenten befinden. Wenn Sie die ID einfach festlegen, erhalten Sie doppelte IDs, was Ihnen ohnehin nicht weiterhilft.

Ohne zu wissen, WARUM Sie die ID explizit festlegen möchten, ist es schwierig, einen Workaround zu geben. Wenn es für JavaScript ist, können Sie tun, was Grant Wagner vorschlägt, und JSF Ihnen geben lassen, was es als die ID setzte. Sie können auch einen Blick auf dem generierten HTML-Code und sehen, welches Format der ID in ist. JSF in der Regel verwendet

"form_id:loop_id:loop_index:component_id" 

als id es für Komponenten in einer Form/Wiederholung erzeugt. Du musst dir sicher sein und deinem Formular und der ID IDs geben: wiederhole die Tags, um zu wissen, was sie waren.

Ok, Sie haben geantwortet, dass Sie ein h: Message-Tag für einen bestimmten inputText innerhalb der Schleife haben wollen, das ist einfach.

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

Nun Nachrichten für die Eingabe generiert werden in der Meldung angezeigt, und JSF wird mangle das Attribut „for“ nur (obwohl das nicht in HTML erzeugt wird), wie es wird das Attribut „id“ in der inputText, damit sie übereinstimmen.

Sie können sogar Ihre eigenen Nachrichten in Ihrem Handler-Code machen, um zu der spezifischen h: -Nachricht zu gelangen, aber Sie müssen einen Aufruf von clientId verwenden, um das Ziel der Nachricht zu erhalten, wenn die Backing-Bean (nicht die Backing-Bean) der betreffenden Komponente.

+0

Whoops. Ich habe das für eine Weile nicht gemacht, nicht ich. Ich verstehe, warum ich IDs in einer Schleife nicht zuweisen kann, aber ich weiß, was ich einstellen, da die ID (LabelKey) für jede Iteration über die Schleife eindeutig sein wird. –

+0

Was ich erreichen möchte, möchte ich einen Weg kennen, wie ich die h: inputText & h: Nachricht zusammen in der Schleife verknüpfen kann. Wenn also eine Validierung beim Eingabetext fehlschlägt, kann ein Fehler in der zugehörigen Nachrichtenbox auftreten. –

+0

Ich denke, ich muss es einfach anders machen und habe einfach eine allgemeine Nachricht für alle Felder, die bei der Dropdown-Änderung angezeigt werden. Entschuldigen Sie die mehrfachen Kommentare - Konnte nicht alles in 300 Buchstaben passen! –

3

Ich nehme an, dass Sie die ID Ihrer Eingabekomponente steuern möchten, damit Sie später in Javascript darauf verweisen können?

Da Sie nicht die ID über einen Ausdruck festgelegt, kann ich dies tun:

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

dann später im Code:

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

Im pagecode:

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

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

Hoffe, dass hilft.

+0

Ich habe ein äquivalentes Problem. Deine Antwort löst es nicht direkt, aber es gibt mir einen hilfreichen Hinweis. Manchmal kann sogar ein Hinweis das Leben retten. Danke;) – hirikarate

0

Haben Sie versucht, Facelets zu verwenden?

das Ihnen erlaubt, Ihren eigenen ids assing dh:

mich: labelKeyThingo kann dann die id = # {labelKey}, um eine eindeutige Bezeichnung zu machen.Hier ist ein Beispiel Facelet genannt m: textPassword von meinem schlechten Code:

<!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> 

Es verwendet thusly ist:

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