A Custom JSF Tag Lib For Toggling Render of Child Elements
I’ve added a new sample project on GitHub that shows a custom Tag Library for JSF (Java Server Faces) that can be used to show/hide its children. There are several uses for this sort of custom component in your JSF web project but in this sample code I just read a property on the custom tag to determine whether to render all child elements or not. In a real application this logic could be swapped to implement application logic or perhaps call a Feature Toggle framework which decides whether to render elements within this tag or not.
Whilst the code is a complete same JSF project the main class is the CustomTag class.
This custom tag extends UIComponentBase to control the encodeChildren and getRendersChildren methods. In the getRendersChildren method we need to determine whether any child elements should be shown or not (again this can be any logic you find useful but for this example we are just reading a parameter on the XHTML). If its determined that we DO want to display children then we will follow normal processing and pass the call onto the base class’s getRendersChildren method. If its determined we DO NOT want to display child elements we instead return TRUE which tells the JSF framework that we want to render children ourselves using our custom encodeChildren method (which then ignores the request).
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
public class CustomTag extends UIComponentBase {
@Override
public String getFamily() {
return "com.test.common.CustomTag";
}
@Override
public void encodeChildren(FacesContext arg0) throws IOException {
return;
}
@Override
public boolean getRendersChildren() {
boolean enabled = false;
// Replace this logic with whatever you need to determine whether to display children or not
String ruleName = (String) getAttributes().get("showChildren");
enabled = (ruleName.equalsIgnoreCase("enabled"));
if(enabled)
{
// we want the children rendered so we tell JSF that we wont be doing it in this custom tag.
return super.getRendersChildren();
}
else {
// we will tell JSF that we will render the children, but then we'll not.
return true;
}
}
}
Next we define the new tag in the web.xml and custom.taglib.xml config files.
1
2
3
4
5
<!-- register custom tag -->
<context-param>
<param-name>javax.faces.FACELETS_LIBRARIES</param-name>
<param-value>/WEB-INF/custom.taglib.xml</param-value>
</context-param>
and
1
2
3
4
5
6
7
8
9
10
11
12
13
<?xml version="1.0"?>
<!DOCTYPE facelet-taglib PUBLIC
"-//Sun Microsystems, Inc.//DTD Facelet Taglib 1.0//EN"
"http://java.sun.com/dtd/facelet-taglib_1_0.dtd">
<facelet-taglib>
<namespace>http://RichCustomTag.com</namespace>
<tag>
<tag-name>customTag</tag-name>
<component>
<component-type>com.test.common.CustomTag</component-type>
</component>
</tag>
</facelet-taglib>
We then use that new CustomTag within our XHTML page to wrap the elements that we want to toggle on/off depending on our logic.
1
2
3
4
5
6
7
<!--Items below may or may not appear depending whether they are turned on or off-->
<!-- to show children set showChildren to 'enabled' else 'disabled' -->
<rh:customTag showChildren="enabled">
If you see this then child items are enabled
<h:inputText value="#{helloBean.name2}"></h:inputText>
end of dynamic content.
</rh:customTag>
That’s it.
Check out the code on GitHub via https://github.com/RichHewlett/JSFTag_ToggleChildRendering.