Tutorial :How to add existing JSF components to my own custom components?



Question:

I have a tag class which extends UIComponent and UIOutput. In this class I have encodeBegin and encodeEnd which I can use my contextWriter to output any kinda html tag I want too by using writer.startElement("div", myComponent) and so on.

My problem now is that I need to insert for example a instead of using the writer.startElement. I can get this done by doing getChildren().add(HtmlCommandButton button = new HtmlCommandButton()); but when doing it like that I cant seem to output the component where I want them to appear, like I can with write.startElement.

Does anyone have any good solutions in how I can take advantage of richfaces tags, JSF tags and similar in my own taglibrary? In short what I would really want to do is inside my encodeBegin:

writer.startElement("a4j:commandButton", myComponent);  writer.writeAttribite("action", "#{Handler.myAction}", null);  writer.endElement("a4j:commandButton");  

Thanks by advance


Solution:1

You cannot use the ResponseWriter as you wish to. Two ways I can think of how to add child controls programmatically are either via the binding attribute (see this answer) or in the place where controls usually get created (in JSPs, that is in the tag class).

There are two ways for JSF components to contain other controls: as children or as named facets. Components always control how they render their facets; if they are to render their children, they must return true for getRendersChildren.

This is untested code, but the sequence goes something like this:

  @Override    public boolean getRendersChildren() {      return true;    }      @Override    public void encodeBegin(FacesContext context)        throws IOException {      // should really delegate to a renderer, but this is only demo code      ResponseWriter writer = context.getResponseWriter();      writer.startElement("span", this);      String styleClass = getStyleClass();      writer          .writeAttribute("class", styleClass, "styleClass");        UIComponent headerComponent = getFacet("header");      if (headerComponent != null) {        headerComponent.encodeAll(context);      }        writer.startElement("hr", null);    }      @Override    public void encodeChildren(FacesContext context)        throws IOException {      ResponseWriter writer = context.getResponseWriter();      for (UIComponent kid : getChildren()) {        kid.encodeAll(context);        writer.startElement("br", null);      }    }      @Override    public void encodeEnd(FacesContext context)        throws IOException {      ResponseWriter writer = context.getResponseWriter();      writer.endElement("span");    }  


Solution:2

Not really an answer, more of a guess, but maybe you could extend one of the facelets controls?

Alternatively, either use facelets directly - which seems to be exactly what you want really though I've not used it myself. Or you could add UIOutput controls where you want HTML to appear and set the value of each to the HTML you want to appear - this is exactly what f:verbatim does under the hood, or so it seems from looking at the source code :-)


Note:If u also have question or solution just comment us below or mail us on toontricks1994@gmail.com
Previous
Next Post »