JSF Custom FacesBehavior TagHandler and Renderer
In this tutorial we will show you a JSF Custom FacesBehavior TagHandler and Renderer. Our goal is to add a style attribute on different events. When the component is focussed we add a focus-css rule and when the component is blurred we ad a blur-css rule. We are creating a custom TagHandler to add the Custom FacesBehavior to. And a custom FacesBehaviorRenderer to add the custom rules to the component.
Creating the FacesBehavior
This will be our focus and blur behavior holder.
package com.memorynotfound.jsf;
import javax.faces.component.behavior.ClientBehaviorBase;
import javax.faces.component.behavior.FacesBehavior;
@FacesBehavior(value = "focusblur")
public class FocusBlurBehavior extends ClientBehaviorBase {
public static final String FOCUS_EVENT = "focus";
public static final String BLUR_EVENT = "blur";
@Override
public String getRendererType() {
return FocusBlurRenderer.RENDERER_TYPE;
}
}
Creating the FocusBlur TagHandler
The tag handler will add the client behavior.
package com.memorynotfound.jsf;
import javax.faces.component.UIComponent;
import javax.faces.component.behavior.ClientBehaviorHolder;
import javax.faces.view.facelets.BehaviorConfig;
import javax.faces.view.facelets.FaceletContext;
import javax.faces.view.facelets.TagHandler;
import java.io.IOException;
public class FocusBlurHandler extends TagHandler {
private FocusBlurBehavior onfocus = new FocusBlurBehavior();
private FocusBlurBehavior onblur = new FocusBlurBehavior();
public FocusBlurHandler(BehaviorConfig config) {
super(config);
}
@Override
public void apply(FaceletContext ctx, UIComponent parent) throws IOException {
if (parent instanceof ClientBehaviorHolder){
ClientBehaviorHolder clientBehaviorHolder = (ClientBehaviorHolder)parent;
clientBehaviorHolder.addClientBehavior(FocusBlurBehavior.FOCUS_EVENT, onfocus);
clientBehaviorHolder.addClientBehavior(FocusBlurBehavior.BLUR_EVENT, onblur);
}
}
}
Creating the FocusBlur Renderer
The renderer will evaluate the event name and set the appropriate attribute on the component.
package com.memorynotfound.jsf;
import javax.faces.application.ResourceDependency;
import javax.faces.component.behavior.ClientBehavior;
import javax.faces.component.behavior.ClientBehaviorContext;
import javax.faces.render.ClientBehaviorRenderer;
import javax.faces.render.FacesBehaviorRenderer;
@ResourceDependency(name = "style.css", target = "head")
@FacesBehaviorRenderer(rendererType = FocusBlurRenderer.RENDERER_TYPE)
public class FocusBlurRenderer extends ClientBehaviorRenderer {
public static final String RENDERER_TYPE = "focusblurrenderer";
@Override
public String getScript(ClientBehaviorContext behaviorContext, ClientBehavior behavior) {
if (FocusBlurBehavior.FOCUS_EVENT.equals(behaviorContext.getEventName())){
return "this.setAttribute('class', 'focus-css');";
}
if (FocusBlurBehavior.BLUR_EVENT.equals(behaviorContext.getEventName())){
return "this.setAttribute('class','blur-css');";
}
return super.getScript(behaviorContext, behavior);
}
}
Defining the tag
We must define the tag in order to use it in the xhtml page.
<?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 version="2.0"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-facelettaglibrary_2_0.xsd">
<namespace>https://memorynotfound.com/example</namespace>
<tag>
<tag-name>focusBlur</tag-name>
<behavior>
<behavior-id>focusblur</behavior-id>
<handler-class>com.memorynotfound.jsf.FocusBlurHandler</handler-class>
</behavior>
</tag>
</facelet-taglib>
Registering the tag in the web.xml
Then we need to register the tag file in the web.xml.
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" version="3.1">
<!-- register custom tag -->
<context-param>
<param-name> javax.faces.FACELETS_LIBRARIES</param-name>
<param-value>/WEB-INF/focusblur.taglib.xml</param-value>
</context-param>
<!-- Change to "Production" when you are ready to deploy -->
<context-param>
<param-name>javax.faces.PROJECT_STAGE</param-name>
<param-value>Development</param-value>
</context-param>
<!-- Welcome page -->
<welcome-file-list>
<welcome-file>index.xhtml</welcome-file>
</welcome-file-list>
<!-- JSF mapping -->
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<!-- Mappings for JSF FacesServlet -->
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.xhtml</url-pattern>
</servlet-mapping>
</web-app>
Using the new tag
Now we can use the newly created tag to apply the behavior the the component.
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:b="https://memorynotfound.com/example">
<h:head>
<h:outputStylesheet name="style.css"/>
</h:head>
<h:body>
<h2>JSF Custom FacesBehavior TagHandler and Renderer</h2>
<h:form>
<h:inputText >
<b:focusBlur/>
</h:inputText>
</h:form>
</h:body>
</html>
Specifying the CSS
This css rules apply to the behavior.
.blur-css {
background: lightcoral;
}
.focus-css {
background: lightgreen;
}
Demo
URL: http://localhost:8081/jsf-focus-blur-behavior/
Focused.
Blurred.