Monday, October 5, 2009

Extend JSF Command Link

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();

protected void setProperties(UIComponent component) {
component.setValueExpression("value", value);
((HtmlCommandLink)component).addActionListener(new MethodExpressionActionListener(actionListener));
((HtmlCommandLink)component).setOnclick("javascript:return confirm('Are you sure you want to remove?')");

public void 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="" xsi="" schemalocation=" web-jsptaglibrary_2_0.xsd">


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:

Step 4
Finally to use it:
<%@taglib prefix="ds" uri=""%>
<ds:removecommandlink value="Remove" actionlistener="#{ViewModifyTable.removeColumn}">
<f:param name="applicationId" value="#{ViewModifyTable.applicationId}">
<f:param name="tableName" value="#{ViewModifyTable.tableName}">

1 comment:

developer-resource said...

I found this article to very useful as I was figuring this out: