<<NamedFramePattern>>
The idea of this pattern is to provide help for the user to see a categorization of UI Items. In general ADF, this might be done via UI Categorization via UI Hints at View Object Level. Unfortunately, this resolves into af:group containers on UI, which are interpreted by the parent container to make sense out of the items. So all in all, we are limited by the frameworks default implementations.
To solve the problem, we thought about the general solution in free html/css context. Here the problem is easy to solve. See
http://jsfiddle.net/ZgEMM/685/
for a sample solution. To reach the explicit HTML code you need out of JSF components is (in most cases) not possible.
Again, ADF supports the creation of own declarative components, but typically we just join other JSF compontents to our liking.
So we have to go one step further. The next steps show you how to create a "component/renderer" mashup to achieve the NamedFramePattern in ADF.
1. Create a declarative container component that has only a panel group layout and a content facetRef. Be sure to add a ComponentClass to your Declarative component for easier access and uniqueness afterwards.
2. Create a RichRenderer that is based on the renderer for ADF Group Layouts and add additional HTML code to the rendered feature. This can be done by overriding the encodeAll(...) method of the parent class.
package de.teampb.ir.templates.nf; import java.io.IOException; import javax.faces.component.UIComponent; import javax.faces.context.FacesContext; import javax.faces.context.ResponseWriter; import oracle.adf.view.rich.component.rich.fragment.RichDeclarativeComponent; import oracle.adf.view.rich.component.rich.layout.RichPanelFormLayout; import oracle.adf.view.rich.render.ClientComponent; import oracle.adf.view.rich.render.RichRenderer; import oracle.adfinternal.view.faces.renderkit.rich.DeclarativeComponentRenderer; import org.apache.myfaces.trinidad.bean.FacesBean; import org.apache.myfaces.trinidad.context.RenderingContext; import org.apache.myfaces.trinidad.render.CoreRenderer; import oracle.adfinternal.view.faces.renderkit.rich.PanelGroupLayoutRenderer; public class NamedFrameRenderer extends PanelGroupLayoutRenderer { public NamedFrameRenderer() { super(); } private static final String DEFAULT_COLOR = "#AAAAAA"; private static final String IMPORTANT_COLOR = "#FFAAAA"; @Override protected void encodeAll(FacesContext facesContext, RenderingContext renderingContext, UIComponent uIComponent, ClientComponent clientComponent, FacesBean facesBean) throws IOException { ResponseWriter rw = facesContext.getResponseWriter(); if (uIComponent.getParent() instanceof NamedFrame) { NamedFrame nf = (NamedFrame) uIComponent.getParent(); rw.startElement("div", null); rw.writeAttribute("style", "border: 2px solid " + getColor(nf) + "; margin: 5px; padding: 5px", null); rw.startElement("h2", null); rw.writeAttribute("style", "text-indent: 30px;\n" + " margin-top: -10px;\n" + " height: 10px;\n" + " line-height: 20px;\n" + " font-size: 15px;", null); rw.startElement("span", null); rw.writeAttribute("style", "background-color:#FFFFFF; color:#000000;", null); rw.writeText(nf.getTitle(), null); rw.endElement("span"); rw.endElement("h2"); super.encodeAll(facesContext, renderingContext, uIComponent, clientComponent, facesBean); rw.endElement("div"); } else super.encodeAll(facesContext, renderingContext, uIComponent, clientComponent, facesBean); } private String getColor(NamedFrame nf) { if ("important".equals(nf.getType())) { return IMPORTANT_COLOR; } else return DEFAULT_COLOR; } }
The idea is that the renderer overrides the default Renderer for Panel Group layouts. So we have to keep the default implementation (the inside super.encodeAll line).
(The HTML code could be beautified by using classes instead of inline style, but I think you get the idea)
3. Add renderer to faces-Config.xml in the consuming ViewController Project.
4. Use declarative component as usual to achieve the layout addition by the renderer.
Please feel free to download the sources at
https://github.com/TEAMPB/ADF_POC.git
and pull the sources. To run the application, you need access to an HR schema. Then Run the hr-main.xml Task-Flow.
Cheers!
Keine Kommentare:
Kommentar veröffentlichen