2009-03-16 10 views
3

Je connais les méthodes startElement, endElement et writeAttribute sur ResponseWriter. Mon problème est que je veux par exemple produire un h: commandLink en le déclarant comme HtmlCommandLink link = new HtmlCommandLink();.Composants personnalisés JSF ResponseWriter

Comment puis-je générer d'autres composants UIC comme ceci dans mon propre composant? Je pourrais vouloir utiliser des trucs ajax RichFaces dans mes composants ainsi espérant que je puisse éviter de tout faire à zéro.

Editer: Ce que j'essaie de faire est de créer ma propre bibliothèque de balises avec l'étiquette suivante <myTags:commentTree>. Chaque commentaire a un bouton de réponse, quand le bouton de réponse est cliqué je rends le formulaire de réponse sous le commentaire. Une fois cela rendu, je voudrais sortir par exemple le composant richfaces <a4j:commandButton>. Cela doit être fait dans mon propre fichier java tag que j'ai appelé CommentsTreeUI.java.

Normalement, je sortie tous mes éléments qui affichent les formes et les boutons avec writer.startElement("input", myComponent); writer.writeAttribute("type", "button", null); mais si je pouvais plutôt faire par exemple startElement("a4j:commandbutton", myComponent) qui aiderait mon ALOT car il a tous les construit dans les dispositifs ajax etc.

Tous les indices?

+0

Qu'est-ce que vous essayez de faire? Créer un contrôle composite? Ou juste créer un nouveau contrôle à l'exécution? – McDowell

Répondre

2

Ce problème a été résolu en ajoutant de nouveaux composants en utilisant

HtmlCommandButton button = new HtmlCommandButton(); 
button.encodeAll(context); 
+0

Je sais que la question est très ancienne mais je faisais la même chose comme ça. Le problème avec cette approche est que HtmlCommandButton n'obtient pas de parent assigné, même si elle est rendue ok. Vous devez appeler 'button.setParent (this)' spécifiquement. Vérifiez: http://stackoverflow.com/questions/4268546/jsf-2-0-how-to-add-uicomponents-and-their-contents-to-view-root Juste un FYI pour quiconque lisant cette question. –

+0

Il est encore mieux de ne pas créer de composants via 'new' mais comme ici: http://stackoverflow.com/questions/19998802/how-to-add-component-programmatically-dynamically-to-a-pdatatable-facet – Kukeltje

1

Vous pouvez faire quelque chose comme ceci:

HtmlCommandLink link = new HtmlCommandLink(); 
getChildren().add(link); 

Il ne dépend de ce que vous voulez faire avec les composants de l'enfant mais à savoir si vous voulez les entourèrent avec HTML personnalisé (dans une liste HTML, par exemple) vous aurez besoin de quelque chose d'un peu plus complexe.

+0

Très très intéressant. Atm en faisant le getChildre(). Add (lien) il ajoute mon bouton/lien tout le chemin à la fin de la page. Comment puis-je le sortir où je le veux dans ma séquence de htmloutputs? Par exemple Im en train d'écrire une div et je veux que le lien soit dans cette div. Merci beaucoup pour l'instant! –

+0

En résumé, je veux fondamentalement ajouter ces composants enfants là où je les veux. Atm ils ajoutent juste à la fin de l'interface graphique. –

+0

Avez-vous essayé d'appeler encodeBegin (...) etc sur les composants que vous voulez rendre? –

0

Une approche pour faire des contrôles composites est d'utiliser la liant attribut à associer l'étiquette avec votre propre code:

<f:view> 
    <h:form> 
     <h:panelGroup binding="#{compositeControlBean.panelGrid}" /> 
    </h:form> 
</f:view> 

La configuration du haricot faces-config.xml:

<managed-bean> 
    <managed-bean-name>compositeControlBean</managed-bean-name> 
    <managed-bean-class> 
     composite.CompositeControlBean 
    </managed-bean-class> 
    <managed-bean-scope>request</managed-bean-scope> 
</managed-bean> 

Le code du haricot:

/** 
* Configure this bean in request scope as "compositeControlBean". 
*/ 
public class CompositeControlBean { 

    private transient UIComponent panelGrid; 

    public UIComponent getPanelGrid() { 
    if (panelGrid == null) { 
     panelGrid = createCompositePanel(); 
    } 
    return panelGrid; 
    } 

    public void setPanelGrid(UIComponent panelGrid) { 
    this.panelGrid = panelGrid; 
    } 

    private UIComponent createCompositePanel() { 
    initContextMemebers(); 

    UIComponent commandLink = createCommandLink(); 

    String id = view.createUniqueId(); 
    UIComponent panelGrid = application 
     .createComponent("javax.faces.HtmlPanelGroup"); 
    panelGrid.setId(id); 
    panelGrid.setRendererType("javax.faces.Group"); 

    panelGrid.getChildren().add(commandLink); 

    return panelGrid; 
    } 

    private UIComponent createCommandLink() { 
    // create control 
    String id = view.createUniqueId(); 
    UIComponent commandLink = application 
     .createComponent("javax.faces.HtmlCommandLink"); 
    commandLink.setId(id); 
    commandLink.setRendererType("javax.faces.Link"); 
    // set attributes (bind to printHello method) 
    Map<String, Object> attributes = commandLink 
     .getAttributes(); 
    MethodExpression action = expressionFactory 
     .createMethodExpression(elContext, 
      "#{compositeControlBean.printHello}", 
      String.class, new Class<?>[0]); 
    attributes.put("value", "print hello"); 
    attributes.put("actionExpression", action); 
    return commandLink; 
    } 

    private transient FacesContext context; 
    private transient Application application; 
    private transient ELContext elContext; 
    private transient ExpressionFactory expressionFactory; 
    private transient UIViewRoot view; 

    private void initContextMemebers() { 
    context = FacesContext.getCurrentInstance(); 
    application = context.getApplication(); 
    elContext = context.getELContext(); 
    expressionFactory = application.getExpressionFactory(); 
    view = context.getViewRoot(); 
    } 

    public String printHello() { 
    System.out.println("Hello"); 
    return null; 
    } 

} 
Questions connexes