Mixing JSF and Dojo widget for custom components

As you probably know, Dojo Toolkit is an "open-source JavaScript toolkit useful for building great web applications". In this recipe, you will see how to mix Dojo and JSF to create a custom component. JSF comes with a custom component that has a text field for entering e-mail addresses, while Dojo comes with e-mail validation and will add a few styles to our component.

Getting ready

We have developed this recipe with NetBeans 6.8, JSF 2.0, and GlassFish v3. The JSF 2.0 classes were obtained from the NetBeans JSF 2.0 bundled library.

In addition, you have to download Dojo, which is available at the address www.dojotoolkit.org or in the book code bundle under the /JSF_libs/Dojo JSF 2.0 folder. Dojo can be extracted in a folder named /script, next to the /WEB-INF folder of your project.

How to do it...

We start with the page itself. This page will import Dojo libraries, and will give an example of using the custom component:

<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>
<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h"%>
<%@ taglib uri="http://java.sun.com/jstl/core" prefix="c" %>
<%@ taglib uri="http://packt.net/cookbook/components" prefix="e" %>
<style type="text/css">
@import url("${pageContext.request.contextPath}
/script/dojo_lib/dijit/themes/nihilo/nihilo.css");
@import url("${pageContext.request.contextPath}
/script/dojo_lib/dojo/resources/dojo.css");
</style>
<script type="text/javascript"
src="${pageContext.request.contextPath}/script/dojo_lib/dojo/dojo.js"
djConfig="parseOnLoad: true, isDebug:false">
</script>
<script type="text/javascript">
dojo.require("dojo.parser");
dojo.require("dijit.form.ValidationTextBox");
dojo.require("dijit.form.Textarea");
</script>
<body class="nihilo">
<f:view>
<h2>JSF and Dojo working for great custom components</h2>
<h:form id="emailFormID">
<h:outputText value="Provide your e-mail:" />
<e:input id="emailID" type="text"
promptMessage="Provide your e-mail!"
invalidMessage="Invalid e-mail!"
dojoType="dijit.form.ValidationTextBox"
dojoRequired="true"
regExp="[a-zA-Z0-9._%-]+@[a-zA-Z0-9.-]+.[a-zA-Z]{2,4}"
value="#{dojoEmailBean.email}"/>
<h:commandButton id="emailBtnID"
action="response.jsp"
value="Submit"
type="submit">
</h:commandButton>
</h:form>
</f:view>
</body>

As you can see the component is named input and it has a set of attributes specific to Dojo components (promptMessage, inputMessage, dojoType, dojoRequired, and regExp).

Next, you have to develop two classes that you are already familiar with. The first one is the tag handler class, listed next:

package custom.component;
import com.sun.faces.taglib.html_basic.InputTextTag;
import javax.faces.component.UIComponent;
public class UIEmailInputTag extends InputTextTag {
@Override
public String getComponentType() {
return "javax.faces.HtmlInputText";
}
@Override
public String getRendererType() {
return "jsf.dojo.render";
}
private String promptMessage;
private String invalidMessage;
private String dojoRequired;
private String regExp;
private String dojoType;
private String type;
public String getPromptMessage() {
return promptMessage;
}
public void setPromptMessage(String promptMessage) {
this.promptMessage = promptMessage;
}
public String getInvalidMessage() {
return invalidMessage;
}
public void setInvalidMessage(String invalidMessage) {
this.invalidMessage = invalidMessage;
}
public String getDojoRequired() {
return dojoRequired;
}
public void setDojoRequired(String dojoRequired) {
this.dojoRequired = dojoRequired;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getRegExp() {
return regExp;
}
public void setRegExp(String regExp) {
this.regExp = regExp;
}
public String getDojoType() {
return dojoType;
}
public void setDojoType(String dojoType) {
this.dojoType = dojoType;
}
@Override
protected void setProperties(UIComponent component) {
super.setProperties(component);
component.getAttributes().put("promptMessage", promptMessage);
component.getAttributes().put("dojoRequired", dojoRequired);
component.getAttributes().put("invalidMessage", invalidMessage);
component.getAttributes().put("type", type);
component.getAttributes().put("dojoType", dojoType);
component.getAttributes().put("regExp", regExp);
}
}

The second is the renderer class. Again, we have a common renderer (nothing special):

package custom.component;
import javax.faces.component.UIComponent;
import javax.faces.component.ValueHolder;
import javax.faces.context.FacesContext;
import javax.faces.context.ResponseWriter;
import javax.faces.component.UIInput;
import com.sun.faces.renderkit.html_basic.TextRenderer;
import java.io.IOException;
public class UIEmailInputRender extends TextRenderer {
@Override
public void encodeEnd(FacesContext ctx, UIComponent ui_comp)
throws IOException {
ResponseWriter responseWriter = ctx.getResponseWriter();
responseWriter.startElement("input", ui_comp);
String id = (String) ui_comp.getClientId(ctx);
responseWriter.writeAttribute("id", id, "id");
responseWriter.writeAttribute("name", id, "id");
responseWriter.writeAttribute("value",
getValue(ui_comp), "value");
responseWriter.writeAttribute("type",
(String) ui_comp.getAttributes().get("type"), null);
responseWriter.writeAttribute("invalidMessage",
(String)ui_comp.getAttributes().get("invalidMessage"),null);
responseWriter.writeAttribute("regExp",
(String) ui_comp.getAttributes().get("regExp"), null);
responseWriter.writeAttribute("dojoType",
(String) ui_comp.getAttributes().get("dojoType"), null);
responseWriter.writeAttribute("required",
(String) ui_comp.getAttributes().get("dojoRequired"), null);
responseWriter.writeAttribute("promptMessage",
(String)ui_comp.getAttributes().get("promptMessage"), null);
responseWriter.endElement("input");
}
@Override
protected Object getValue(UIComponent ui_comp) {
Object objValue = null;
if (ui_comp instanceof UIInput) {
objValue = ((UIInput)ui_comp).getSubmittedValue();
}
if ((objValue == null) && (ui_comp instanceof ValueHolder)) {
objValue = ((ValueHolder) ui_comp).getValue();
}
if (objValue == null) {
objValue = "";
}
return objValue;
}
}

Finally, you need to write the TLD file for the input component (not listed here), configure the renderer in faces-config.xml, and write the DojoEmailBean, which is a trivial bean. You can see both these tasks accomplished in the complete example.

See also

The code bundled with this book contains the complete code of our custom component under the recipe: JSF_and_Dojo_widget_for_custom_components.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset