Spring MVC tag interaction with custom tag

17,172

Frequently the only solution is to try it.

I tried it three different ways -- a JSP custom tag library, a parameterized JSP include, and a JSP2 tag file.

The first two didn't work (although I suspect the tag library can be made to work), but the tag file did! The solution was based loosely on an example given in Expert Spring MVC and Web Flow.

Here's my code in WEB-INF/tags/renderConditionalControl.tag :

<%@ tag body-content="tagdependent" isELIgnored="false" %>
<%@ attribute name="readOnly" required="true" %>
<%@ attribute name="path" required="true" %>
<%@ attribute name="type" required="false" %>
<%@ attribute name="className" required="true" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<%@ taglib prefix="form" uri="/WEB-INF/spring-form.tld" %>
<%@ taglib prefix="spring" uri="/WEB-INF/spring.tld" %>

<c:if test="${empty type}">
<c:set var="type" value="text" scope="page" />
</c:if>

<spring:bind path="${path}">
    <c:choose>
        <c:when test="${readOnly}">
            <span class="readOnly">${status.value}</span>
        </c:when>
        <c:otherwise>
           <input type="${type}" id="${status.expression}" name="${status.expression}"
                    value="${status.value}" class="${className}" />
        </c:otherwise>
    </c:choose>
</spring:bind>

And here's the code in the jsp:

First,with the other taglibs directives:

<%@ taglib tagdir="/WEB-INF/tags" prefix="tag" %> 

and within the form:

<tag:renderConditionalControl path="someObject.someField" type="text" readOnly="${someBoolean}" className="someClass" />
Share:
17,172
Jacob Mattison
Author by

Jacob Mattison

Like most software engineers, Jacob raises dairy goats and chickens, on a small farm in central Connecticut. He has gotten pretty good at milking; it is much like using vi: the key is remembering how to hold your fingers. Jacob is the inventor of TDD Karaoke, the wildly popular sport in which contestants are given a suite of tests drawn at random from multiple projects, and have 25 minutes to make them all pass. Jacob's 2009 essay on how to configure a Rails model to support multiple databases was, through a clerical error, shortlisted for the Booker Prize. You'd be astonished how often this type of thing happens. Jacob is Senior Engineering Manager at Technolutions, Inc., maker of Slate, an application used by many top universities to manage the admissions process. If you've applied to college or graduate school in the United States recently, you've probably used their code.

Updated on June 24, 2022

Comments

  • Jacob Mattison
    Jacob Mattison almost 2 years

    I have a JSP that is using Spring:form tags to bind controls to a command object.

    I would like to modify it as follows: if [some condition is true] than display the controls; otherwise, just display the text. (Examples: if the user is an Admin, display the controls, otherwise just display the text. If the whatsit is still open for modification, display the controls, otherwise display the text.)

    In other words, I want this:

    <c:choose>
         <c:when test="SOME TEST HERE">
              <form:input path="SOME PATH" />
         </c:when>
         <c:otherwise>
              <p>${SOME PATH}</p>
         </c:otherwise>
    </c:choose>
    

    But I want an easy way to create this for every field (there are many).

    If I create a custom tag to generate the above text (given "SOME PATH"), will the Spring custom tags get bound?

    I guess what I'm really asking is: can I create custom tags that generate Spring custom tags that then get bound? Or do all custom tags (mine and Spring's) get handled simultaneously?

  • Ben Thurley
    Ben Thurley over 11 years
    How have you got on with this? I've been using tag files but it all falls apart with <select>'s. The Spring tags check if the options tag has an ancestor parent tag but because they're in different tag files it doesn't find it. This throws an exception. :(
  • Jacob Mattison
    Jacob Mattison over 11 years
    That particular application is complete, but it's still running in production and works fine. We did end up adding another nested c:when tag inside the part that renders the input; it renders differently for certain tags such as textarea or select.