I found myself adding a Remove link throughout my JSF application. It looked like this:
<h:commandlink value="Remove" actionlistener="#{MyBean.remove}">
I wanted to add a confirm dialog. So I added this.
<h:commandlink value="Remove" actionlistener="#{MyBean.remove}" onclick="javascript return confirm('Are you sure')">
But as I copied and pasted this through 5 or 6 different pages, I got to thinking, there has to be a better way.
So I created a custom jsf component by extending Command Link.
Step 1
First step was to create my new tag. It simply wraps the default command link.
package com.acme;
import com.sun.faces.taglib.html_basic.CommandLinkTag;
import javax.el.MethodExpression;
import javax.el.ValueExpression;
import javax.faces.component.UIComponent;
import javax.faces.component.html.HtmlCommandLink;
import javax.faces.event.MethodExpressionActionListener;
import javax.faces.webapp.UIComponentELTag;
/**
* @author cmcintosh
*/
public class RemoveCommandLinkTag extends UIComponentELTag { // Declare a bean property for the hellomsg attribute.
CommandLinkTag commandLink = new CommandLinkTag();
ValueExpression value;
MethodExpression actionListener;
// Associate the renderer and component type.
public String getComponentType() {
return commandLink.getComponentType();
}
public String getRendererType() {
return commandLink.getRendererType();
}
@Override
protected void setProperties(UIComponent component) {
super.setProperties(component);
component.setValueExpression("value", value);
((HtmlCommandLink)component).addActionListener(new MethodExpressionActionListener(actionListener));
((HtmlCommandLink)component).setOnclick("javascript:return confirm('Are you sure you want to remove?')");
}
@Override
public void release() {
super.release();
commandLink.release();
}
public void setValue(ValueExpression value) {
this.value = value;
}
public void setActionListener(MethodExpression actionListener) {
this.actionListener = actionListener;
}
}
Step 2
Next I needed to create a tld.
<taglib version="2.0" xmlns="http://java.sun.com/xml/ns/j2ee" xsi="http://www.w3.org/2001/XMLSchema-instance" schemalocation="http://java.sun.com/xml/ns/j2ee web-jsptaglibrary_2_0.xsd">
<tlib-version>1.0</tlib-version>
<short-name>datastore</short-name>
<uri>/WEB-INF/tlds/datastore</uri>
<tag>
<name>RemoveCommandLink</name>
<tag-class>com.acme.datastore.web.components.tags.RemoveCommandLinkTag</tag-class>
<attribute>
<name>value</name>
<deferred-value>
<type>java.lang.String</type>
</deferred-value>
</attribute>
<attribute>
<name>actionListener</name>
<required>false</required>
<deferred-method>
<method-signature>
actionListener(javax.faces.event.ActionEvent)
</method-signature>
</deferred-method>
<type>String</type>
</attribute>
</tag>
</taglib>
This was one of the hardest parts note the deferred-method and deferredvalue. I've never encountered those before.
Step 3
Add it to the web.xml:
<jsp-config>
<taglib>
<taglib-uri>http://datastore.acme.com/datastore</taglib-uri>
<taglib-location>/WEB-INF/tlds/datastore.tld</taglib-location>
</taglib>
</jsp-config>
Step 4
Finally to use it:
<%@taglib prefix="ds" uri="http://datastore.acme.com/datastore"%>
.
.
.
<ds:removecommandlink value="Remove" actionlistener="#{ViewModifyTable.removeColumn}">
<f:param name="applicationId" value="#{ViewModifyTable.applicationId}">
<f:param name="tableName" value="#{ViewModifyTable.tableName}">
</f:param></f:param></ds:removecommandlink></h:commandlink></h:commandlink>
Monday, October 5, 2009
Subscribe to:
Post Comments (Atom)
1 comment:
I found this article to very useful as I was figuring this out:
http://technology.amis.nl/blog/6047/creating-a-custom-jsf-12-component-with-facets-resource-handling-events-and-listeners-valueexpression-and-methodexpression-attributes
Post a Comment