Struts 2 custom tags

Custom textarea tag

In this example we will create a custom textarea component that integrates with Hdiv.

The result will be a tag similar to this:

<custom:customTextarea name="persons.lastName" value="%{lastName}"></custom:customTextarea>

Custom tag classes

It is necessary to create some tag classes in the project.

Create component class:

package org.apache.struts2.showcase.custom;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.struts2.components.TextArea;
import org.apache.struts2.views.annotations.StrutsTag;

import com.opensymphony.xwork2.util.ValueStack;

@StrutsTag(name = "htmlTextarea", tldTagClass = "org.apache.struts2.showcase.custom.CustomTextAreaTag", description = "Render HTML textarea tag.")
public class CustomTextArea extends TextArea {

    final public static String TEMPLATE = "customTextarea";

    public CustomTextArea(final ValueStack stack, final HttpServletRequest request, final HttpServletResponse response) {
        super(stack, request, response);
    }

    @Override
    protected String getDefaultTemplate() {
        return TEMPLATE;
    }

}

Create model class:

package org.apache.struts2.showcase.custom;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.struts2.components.Component;
import org.apache.struts2.views.freemarker.tags.TextAreaModel;

import com.opensymphony.xwork2.util.ValueStack;

public class CustomTextAreaModel extends TextAreaModel {

    public CustomTextAreaModel(final ValueStack stack, final HttpServletRequest req, final HttpServletResponse res) {
        super(stack, req, res);
    }

    @Override
    protected Component getBean() {
        return new CustomTextArea(stack, req, res);
    }

}

Create tag class:

package org.apache.struts2.showcase.custom;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.struts2.components.Component;
import org.apache.struts2.views.jsp.ui.TextareaTag;

import com.opensymphony.xwork2.util.ValueStack;

public class CustomTextAreaTag extends TextareaTag {

    @Override
    public Component getBean(final ValueStack stack, final HttpServletRequest req, final HttpServletResponse res) {
        return new CustomTextArea(stack, req, res);
    }

}

Custom tag freemarker file

Create freemarker file that will generate the HTML output.

Create the file in src/main/resources/template/simple/customTextarea.ftl.

Note the Hdiv IDataComposer invocation registers an editable parameter of type textarea.

My sample textarea label: 

<textarea<#rt/>
 name="${parameters.name?default("")?html}"<#rt/>
 cols="${parameters.cols?default("")?html}"<#rt/>
 rows="${parameters.rows?default("")?html}"<#rt/>
<#if parameters.name?exists>
  <#assign hdivValue = dataComposer.compose(parameters.name?default("")?html, "", true, "textarea")/>
</#if>
<#if parameters.wrap?exists>
 wrap="${parameters.wrap?html}"<#rt/>
</#if>
<#if parameters.disabled?default(false)>
 disabled="disabled"<#rt/>
</#if>
<#if parameters.readonly?default(false)>
 readonly="readonly"<#rt/>
</#if>
<#if parameters.tabindex?exists>
 tabindex="${parameters.tabindex?html}"<#rt/>
</#if>
<#if parameters.id?exists>
 id="${parameters.id?html}"<#rt/>
</#if>
<#if parameters.cssClass?exists>
 class="${parameters.cssClass?html}"<#rt/>
</#if>
<#if parameters.cssStyle?exists>
 style="${parameters.cssStyle?html}"<#rt/>
</#if>
<#if parameters.title?exists>
 title="${parameters.title?html}"<#rt/>
</#if>
<#include "/${parameters.templateDir}/simple/scripting-events.ftl" />
<#include "/${parameters.templateDir}/simple/common-attributes.ftl" />
><#rt/>
<#if parameters.nameValue?exists>
<@s.property value="parameters.nameValue"/><#t/>
</#if>
</textarea>

Custom tag tld file

Create tld file to use the new tag in JSP files.

Create the file in src/main/webapp/WEB-INF/tlds/custom.tld.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN"
        "http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd">
<taglib>
    <tlib-version>2.2.3</tlib-version>
    <jsp-version>1.2</jsp-version>
    <short-name>lab</short-name>
    <uri>/custom-tag</uri>
    <display-name>Custom Tags</display-name>
    <description>Custom tag example</description>
    <tag>
        <name>customTextarea</name>
        <tag-class>org.apache.struts2.showcase.custom.CustomTextAreaTag</tag-class>
        <body-content>JSP</body-content>
        <description><![CDATA[Render HTML textarea tag.]]></description>
        <attribute>
            <name>name</name>
            <required>false</required>
            <rtexprvalue>false</rtexprvalue>
            <description><![CDATA[The name to set for element]]></description>
        </attribute>
        <attribute>
            <name>value</name>
            <required>false</required>
            <rtexprvalue>false</rtexprvalue>
            <description><![CDATA[Preset the value of input element.]]></description>
        </attribute>
        ... more attributes
    </tag>
</taglib>

Use the custom tag

Sample JSP file that uses the custom tag:

<%@taglib prefix="custom" uri="/custom-tag" %>

<custom:customTextarea name="persons.lastName" value="%{lastName}"></custom:customTextarea>