The Form Tag Library

Apr 9, 2001

0

The Form Tag Library

Posted in : JSP on by : master
Sponsor: nha tien che QSBSteel

Deployment

Version 1.4 is now released to the public. This is complete, although still in active development; changes and suggestions are welcomed.

  1. Download the Form tag library.
  2. Put the library in a directory accessible to your web application (in my case: /u/joeo/epesh.com/main-site/WEB-INF/lib/, where the web application is at .../main-site/.)
  3. Reference the library in your web application’s configuration file (web.xml) like this:
    <taglib>
      <taglib-uri>formtags</taglib-uri>
      <taglib-location>/WEB-INF/lib/formtags-1.4.jar</taglib-location>
    </taglib>
    

    If you’re using Tomcat, this isn’t correct. For this you’ll need to expand the jarfile, and refer to the taglib.tld file directly. I don’t know when Jakarta is planning on changing this.

  4. In your JSP, reference the tag library with a line similar to this:
    <%@ taglib uri="formtags" prefix="input" %>

    This will allow you to use tags named similar to: <input:form action="myformhandler" method="POST">...</input:form>

form

<input:form
  { method="<%= String %>" }
  { name="<%= String %>" }
  { action="<%= String %>" }
  { enctype="<%= String %>" }
  { accept="<%= String %>" }
  { onreset="<%= String %>" }
  { acceptcharsets="<%= String %>" }
  { id="<%= String %>" }
  { styleclass="<%= String %>" }
  { style="<%= String %>" }
  { title="<%= String %>" }
  { lang="<%= String %>" }
  { dir="<%= String %>" }
  { onclick="<%= String %>" }
  { ondblclick="<%= String %>" }
  { onmousedown="<%= String %>" }
  { onmouseup="<%= String %>" }
  { onmouseover="<%= String %>" }
  { onmousemove="<%= String %>" }
  { onmouseout="<%= String %>" }
  { onkeypress="<%= String %>" }
  { onkeydown="<%= String %>" }
  { onkeyup="<%= String %>" }
>
  ...
</input:form>

This tag creates an HTML form tag set, wrapping the body text with the form. Most of the relevant HTML 4.01 attributes for forms are included; only class had its attribute name changed to styleclass. Note that no onsubmit attribute is supported; currently, <input:form /> has its own submission handler and I am not enough of a Javascript programmer to add in a valid hook. If anyone would like to give me an example of doing this, I’ll be glad to hook it in.

text

<input:text
  name="<%= String %>"
  property="<%= String %>"
  { readonly="<%= String %>" }
  { minlength="<%= String %>" }
  { required="<%= String %>" }
  { id="<%= String %>" }
  { styleclass="<%= String %>" }
  { style="<%= String %>" }
  { title="<%= String %>" }
  { lang="<%= String %>" }
  { dir="<%= String %>" }
  { onclick="<%= String %>" }
  { ondblclick="<%= String %>" }
  { onmousedown="<%= String %>" }
  { onmouseup="<%= String %>" }
  { onmouseover="<%= String %>" }
  { onmousemove="<%= String %>" }
  { onmouseout="<%= String %>" }
  { onkeypress="<%= String %>" }
  { onkeydown="<%= String %>" }
  { onkeyup="<%= String %>" }
  { disabled="<%= String %>" }
  { size="<%= String %>" }
  { maxlength="<%= String %>" }
  { alt="<%= String %>" }
  { tabindex="<%= String %>" }
  { accesskey="<%= String %>" }
  { onfocus="<%= String %>" }
  { onblur="<%= String %>" }
  { onchange="<%= String %>" }
>
  default value
</input:text>

This tag creates an HTML input field, of type “text.” Most attributes map directly to the HTML 4.01 spec, except styleclassname, and propertystyleclass maps to the HTML 4.01 class attribute. name maps to a bean for the JSP; property maps to a property name in the bean, just like <jsp:getProperty /> uses name and property. The default value is used if the bean property’s value is an empty string or null. An empty body (i.e., <input:text name="myBean" property="myProperty" />) serves as an empty string (i.e., "").

For the most part, this tag is a convenience tag, replacing the following JSP code:

<input 
  type="text" 
  name="myProperty"
  value="<jsp:getProperty name="myBean" property="myProperty"/>">

with

<input:text name="myBean" property="myProperty" />

textarea

<input:textarea
  name="<%= String %>"
  property="<%= String %>"
  { readonly="<%= String %>" }
  { minlength="<%= String %>" }
  { required="<%= String %>" }
  { rows="<%= String %>" }
  { cols="<%= String %>" }
  { id="<%= String %>" }
  { styleclass="<%= String %>" }
  { style="<%= String %>" }
  { title="<%= String %>" }
  { lang="<%= String %>" }
  { dir="<%= String %>" }
  { onclick="<%= String %>" }
  { ondblclick="<%= String %>" }
  { onmousedown="<%= String %>" }
  { onmouseup="<%= String %>" }
  { onmouseover="<%= String %>" }
  { onmousemove="<%= String %>" }
  { onmouseout="<%= String %>" }
  { onkeypress="<%= String %>" }
  { onkeydown="<%= String %>" }
  { onkeyup="<%= String %>" }
  { disabled="<%= String %>" }
  { maxlength="<%= String %>" }
  { alt="<%= String %>" }
  { tabindex="<%= String %>" }
  { accesskey="<%= String %>" }
  { onfocus="<%= String %>" }
  { onblur="<%= String %>" }
  { onchange="<%= String %>" }
>
  default value
</input:textarea>

This tag creates an HTML textarea. Most attributes map directly to the HTML 4.01 spec, except styleclassname, and propertystyleclass maps to the HTML 4.01 class attribute. name maps to a bean for the JSP; property maps to a property name in the bean, just like <jsp:getProperty /> uses name and property. The default value is used if the bean property’s value is an empty string or null. An empty body (i.e., <input:text name="myBean" property="myProperty" />) serves as an empty string (i.e., "").

For the most part, this tag is a convenience tag, replacing the following JSP code:

<textarea 
  name="myProperty">
  <jsp:getProperty name="myBean" property="myProperty"/>
</textarea>

with

<input:textarea name="myBean" property="myProperty" />

checkbox

<input:checkbox
  name="<%= String %>"
  property="<%= String %>"
  value="<%= String %>"
  { id="<%= String %>" }
  { readonly="<%= String %>" }  
  { styleclass="<%= String %>" }
  { style="<%= String %>" }
  { title="<%= String %>" }
  { lang="<%= String %>" }
  { dir="<%= String %>" }
  { onclick="<%= String %>" }
  { ondblclick="<%= String %>" }
  { onmousedown="<%= String %>" }
  { onmouseup="<%= String %>" }
  { onmouseover="<%= String %>" }
  { onmousemove="<%= String %>" }
  { onmouseout="<%= String %>" }
  { onkeypress="<%= String %>" }
  { onkeydown="<%= String %>" }
  { onkeyup="<%= String %>" }
  { disabled="<%= String %>" }
  { alt="<%= String %>" }
  { tabindex="<%= String %>" }
  { accesskey="<%= String %>" }
  { onfocus="<%= String %>" }
  { onblur="<%= String %>" }
  { onchange="<%= String %>" }
/>

This tag creates an HTML checkbox. Most attributes map directly to the HTML 4.01 spec, except styleclassname, and propertystyleclass maps to the HTML 4.01 class attribute. name maps to a bean for the JSP; property maps to a property name in the bean, just like <jsp:getProperty /> uses name and property. If the property value is equivalent to the value attribute (ignoring case) then the checkbox is checked. Note that no body content is allowed.

For the most part, this tag is a convenience tag, replacing the following JSP code:

<input type="checkbox" 
  name="myProperty"
  value="checkvalue"
  <%= 
    (myBean.getMyproperty().equalsIgnorecase("checkvalue")?"CHECKED":"") 
  %>
>

with

<input:checkbox name="myBean" property="myProperty" value="checkvalue" />

radio

<input:radio
  name="<%= String %>"
  property="<%= String %>"
  value="<%= String %>"
  { id="<%= String %>" }
  { readonly="<%= String %>" }  
  { styleclass="<%= String %>" }
  { style="<%= String %>" }
  { title="<%= String %>" }
  { lang="<%= String %>" }
  { dir="<%= String %>" }
  { onclick="<%= String %>" }
  { ondblclick="<%= String %>" }
  { onmousedown="<%= String %>" }
  { onmouseup="<%= String %>" }
  { onmouseover="<%= String %>" }
  { onmousemove="<%= String %>" }
  { onmouseout="<%= String %>" }
  { onkeypress="<%= String %>" }
  { onkeydown="<%= String %>" }
  { onkeyup="<%= String %>" }
  { disabled="<%= String %>" }
  { alt="<%= String %>" }
  { tabindex="<%= String %>" }
  { accesskey="<%= String %>" }
  { onfocus="<%= String %>" }
  { onblur="<%= String %>" }
  { onchange="<%= String %>" }
/>

This tag creates an HTML radio button. Most attributes map directly to the HTML 4.01 spec, except styleclassname, and propertystyleclass maps to the HTML 4.01 class attribute. name maps to a bean for the JSP; property maps to a property name in the bean, just like <jsp:getProperty /> uses name and property. If the property value is equivalent to the value attribute (ignoring case) then the radio button is checked. Note that no body content is allowed.

This tag is identical to the checkbox tag, save in the type of widget it creates via HTML. Normally, this tag would be used in a group, with varying value tags in the group.

For the most part, this tag is a convenience tag, replacing the following JSP code:

<input type="radio" 
  name="myProperty"
  value="radiovalue1"
  <%= 
    (myBean.getMyproperty().equalsIgnorecase("radiovalue1")?"CHECKED":"") 
  %>
>
<input type="radio" 
  name="myProperty"
  value="radiovalue2"
  <%= 
    (myBean.getMyproperty().equalsIgnorecase("radiovalue2")?"CHECKED":"") 
  %>
>

with

<input:radio name="myBean" property="myProperty" value="radiovalue1" />
<input:radio name="myBean" property="myProperty" value="radiovalue2" />

radiolist

<input:radiolist
  name="<%= String %>"
  property="<%= String %>"
  collection="<%= Collection %>"
  valueproperty="<%= String %>"
  { textproperty="<%= String %>" }
  { id="<%= String %>" }
  { readonly="<%= String %>" }  
  { styleclass="<%= String %>" }
  { style="<%= String %>" }
  { title="<%= String %>" }
  { lang="<%= String %>" }
  { dir="<%= String %>" }
  { onclick="<%= String %>" }
  { ondblclick="<%= String %>" }
  { onmousedown="<%= String %>" }
  { onmouseup="<%= String %>" }
  { onmouseover="<%= String %>" }
  { onmousemove="<%= String %>" }
  { onmouseout="<%= String %>" }
  { onkeypress="<%= String %>" }
  { onkeydown="<%= String %>" }
  { onkeyup="<%= String %>" }
  { disabled="<%= String %>" }
  { alt="<%= String %>" }
  { tabindex="<%= String %>" }
  { accesskey="<%= String %>" }
  { onfocus="<%= String %>" }
  { onblur="<%= String %>" }
  { onchange="<%= String %>" }
/>
  separator
</input:radiolist>

This tag creates a set of HTML radio buttons. Most attributes map directly to the HTML 4.01 spec, except styleclassname, and propertystyleclass maps to the HTML 4.01 class attribute. name maps to a bean for the JSP; propertymaps to a property name in the bean, just like <jsp:getProperty /> uses name and property.

This tag iterates through the collection provided to generate the radio buttons. The value of each button is determined from the accessor of the valueproperty attribute; if a textproperty attribute is provided, the text following the radio button is pulled from that property (if not, the valueproperty is used for both.) Note that the collection is assumed to be homogenous; introspection is currently done only once (on the first item in the list) for speed reasons.

Any body content is output between each radio button. The last radio button does not have the separator text following.

For a working example, see the sample page. The collection attribute is set to getLanguages(), which is a java.util.ArrayList. This ArrayList contains com.es.jsp.language objects, which have two properties: key and name.

select

<input:select
  name="<%= String %>"
  property="<%= String %>"
  { multiple="<%= String %>" }
  { required="<%= String %>" }
  { readonly="<%= String %>" }  
  { id="<%= String %>" }
  { styleclass="<%= String %>" }
  { style="<%= String %>" }
  { title="<%= String %>" }
  { lang="<%= String %>" }
  { dir="<%= String %>" }
  { onclick="<%= String %>" }
  { ondblclick="<%= String %>" }
  { onmousedown="<%= String %>" }
  { onmouseup="<%= String %>" }
  { onmouseover="<%= String %>" }
  { onmousemove="<%= String %>" }
  { onmouseout="<%= String %>" }
  { onkeypress="<%= String %>" }
  { onkeydown="<%= String %>" }
  { onkeyup="<%= String %>" }
  { disabled="<%= String %>" }
  { size="<%= String %>" }
  { alt="<%= String %>" }
  { tabindex="<%= String %>" }
  { accesskey="<%= String %>" }
  { onfocus="<%= String %>" }
  { onblur="<%= String %>" }
  { onchange="<%= String %>" }
>
  ... option tags ...
</input:select>

This tag creates an HTML selection box. Most attributes map directly to the HTML 4.01 spec, except styleclassname, and propertystyleclass maps to the HTML 4.01 class attribute. name maps to a bean for the JSP; property maps to a property name in the bean, just like <jsp:getProperty /> uses name and property. If used with the option tags, the option values that match the property specified will be marked as selected.

option

<input:option
  value="<%= String %>"
  { id="<%= String %>" }
  { styleclass="<%= String %>" }
  { style="<%= String %>" }
  { title="<%= String %>" }
  { lang="<%= String %>" }
  { dir="<%= String %>" }
  { onclick="<%= String %>" }
  { ondblclick="<%= String %>" }
  { onmousedown="<%= String %>" }
  { onmouseup="<%= String %>" }
  { onmouseover="<%= String %>" }
  { onmousemove="<%= String %>" }
  { onmouseout="<%= String %>" }
  { onkeypress="<%= String %>" }
  { onkeydown="<%= String %>" }
  { onkeyup="<%= String %>" }
>
  text representation
</input:option>

This tag creates an HTML option for use in a selection box. Most attributes map directly to the HTML 4.01 spec, except styleclassname, and propertystyleclass maps to the HTML 4.01 class attribute. name maps to a bean for the JSP; property maps to a property name in the bean, just like <jsp:getProperty /> uses name and property. If the body content is null, the property value will be used as the textual representation of the entry.

optionlist

<input:optionlist
  { textproperty="<%= String %>" }
  { valueproperty="<%= String %>" }
  { sort="<%= String %>" }
  { map="<%= Map %>" }
  { collection="<%= Collection %>" }
>
</input:optionlist>

This tag creates a set of HTML option tags for use in a selection box. This tag requires either map or collection to be specified. sort is a boolean, indicating that the results should be sorted for the optionlist, which can be used in conjunction with simple HTML option tags as well as the input:option tag. textproperty and valueproperty have the same meaning as they do in radiolist.

Development Notes

Important

I’m starting work on Revision 2 of the form tag library, the pilpul release. It will be another complete rewrite, and will hopefully rectify the flaws found in the current library.

The problem the form tag library has had since its inception is that it’s tied to presentation of bean data, which – while useful – is also restrictive. There’s no way to consistently or orthogonally supply data manually while using the bean data, for example.

So the future holds something quite bright, based on the use cases I’ve worked with and from input from others. (Yes, all of the four responses I’ve gotten.) Here’s a quick glance at what I’m thinking of:

<input:form 
  action="/servlet/formhandler"
  method="POST"
  id="theInputForm"
  defaultbean="myInputBean">
  Name:
  <input:text 
    name="username" 
    size="64"
    default="Joseph Ottinger">
    <input:access name="userBean" />
  </input:text>
  <BR>
  Updated at:
  <input:text 
    name="updated" 
    size="64">
    
<jsp:expression>new java.util.Date()</jsp:expression>
  </input:text>
  <BR>
  Bean Specific:
  <input:text 
    name="beandata" 
    size="64" />
  <BR>
  <input:submit />
</input:form>

Now, on to the explanations. In <input:form />, you see defaultbean="myInputBean". This establishes a default bean to use for any element that doesn’t specify a separate bean to use itself. You’ll see this used in the last <input:text /> tag, which has only a name, which is roughly analogous to the property name.

The first <input:text /> element is fairly ordinary; as just mentioned, name="username" is a property name. The other attributes map to the HTML specification.

<input:access /> is a tag used to simply access bean data. It maps roughly to <jsp:getProperty />, except it doesn’t require a property name if it’s contained in one of the other input tags (rather, those of which that supply a property name analog). It also has some extra access specifiers, which haven’t been finalised yet, conceptually. It will require a <jsp:setProperty /> analog as well, I think, which is annoying but unavoidable, I think.

The second <input:text /> tag doesn’t use a bean for its data at all, as the expression will always be non-null.

The third <input:text /> element uses the default bean specified in the <input:form /> element to look up data. The access flow, then, look like this:

To be filled out once I have a mechanism that makes sense when you read it

The Regular

This tag library was constructed by following the HTML 4.01 docs found at http://www.w3.org/TR/html4/interact/forms.html. Some discrepancies were required due to different paradigms being used, but the goal is to have a JSP tag library that generates valid HTML forms as the standard specifies. Note that the form tag library does not validate attribute values; if the HTML spec requires a numerical attribute yet the JSP source supplies an alphabetic string, the JSP source value is quoted verbatim in the HTML. This behavior may change.

A sample bean is included with the library itself; its fully qualified classname is com.es.jsp.testbean. It currently has five exposed properties, all strings: namedesclanguagecoffee, and favoritecolor. This bean is primarily for use during testing and in sample code.

History

  • 1 Feb 2001
    • Minor fix applied instream to fix the readonly attribute for textarea, too. This was reported by Scott Farquhar multiple times (because it shows up in a few places); thanks, Scott.
  • 31 Jan 2001
    • 1.4 is released! It turns out readonly was missing from the attribute set; note that some bugs still live in optionlist, which I’m going to be trying to trace very soon. They’re probably caused by even more changes in InputBase, which gets thorny at times.
  • 22 Jan 2001
    • Bruce Ritchie did the dirty work and contributed the optionlist tag, which saves me from a lot of trouble. Thanks, Bruce!
    • Changed packaging of InputBase so that the Blackdown JDK can run the test page now.
  • 17 Jan 2001
    • Fixed handling of encoding type in the form tag, thanks to a bug report.
  • 2 Jan 2001
    • option and select added and documented.
  • 29 Dec 2000
    • radiolist added and documented. This will aid dramatically in providing boilerplate code for the select lists, which are next.
  • 28 Dec 2000
    • radio added and documented.
    • form now stores one copy of the javascript validation code; this code generation is now synchronized to prevent incorrect initialization. This may change if the onsubmit attribute is re-enabled for the JSP source.
    • checkbox added and documented.
    • Documentation for text and textarea added.
    • Correction made to textarea to properly use the rows and cols attribute (bug found in basic testing).
    • Modified build.xml to remove redundant compilation steps; note that build.xml is currently set up to use jikes.
  • 27 Dec 2000
    • Rewrite started; current progress is formtext, and textarea. Documentation started, too, in an flash of originality, and put online at http://epesh.com/formtags.jsp.
  • Unknown
    • Originally authored, put on Sourceforge in the IN16 project.

License

This library is released under the Artistic License.

Sample Page

A sample page demonstrating these tags can be found at http://epesh.com/testform.jsp.

Thought for the Moment
Use less passion. Not “Have less passion,” use less passion.