Recipe3.13.Handling Date Input Fields


Recipe 3.13. Handling Date Input Fields

Problem

You want to allow a user to input a value for a calendar date.

Solution

First, only use String form fields to hold the input date values. If the user can manually type in the date, it helps if you provide graphical Calendar control, either client- or server-based, that can populate the date input fields automatically. When the date value is submitted, validate the input using the Struts Validator.

Here's a DynaActionForm, JSP page, and Action that demonstrate this approach. The DynaActionForm is declared with the following form-bean element:

<form-bean name="DateForm"             type="org.apache.struts.validator.DynaValidatorForm">     <!-- Date 1 -->     <form-property name="month" type="java.lang.String"/>     <form-property name="day" type="java.lang.String"/>     <form-property name="year" type="java.lang.String"/>     <!-- Birth Date-->     <form-property name="birthDateString" type="java.lang.String"/>     <!-- Date 3 -->     <form-property name="monthOpt" type="java.lang.String"/>     <form-property name="dayOpt" type="java.lang.String"/>     <form-property name="yearOpt" type="java.lang.String"/> </form-bean>

The JSP page shown in Example 3-19 (date_test.jsp) renders fields for inputting data for these three variations of date formats. The first variation uses three numeric fields to accept the month, day, and year. The second variation accepts the date as a single value in mm/dd/yyyy format. This variation utilizes a JavaScript calendar that can be used to pick the value. The third variation uses drop-down menus for selecting the month, day, and year.

Example 3-19. Date input methods and formatting
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <%@ taglib uri="http://jakarta.apache.org/struts/tags-html" prefix="html" %> <%@ taglib uri="http://java.sun.com/jstl/core" prefix="c" %> <%@ taglib uri="http://java.sun.com/jstl/fmt" prefix="fmt" %>   <html> <head>   <title>Struts Cookbook - Chapter 4 : Date Test</title>   <script language="JavaScript" src="/books/3/113/1/html/2/scripts/CalendarPopup.js"></script>   <!-- This prints out the default stylehseets used by the      DIV style calendar. Only needed if you are using the DIV style popup -->   <script language="JavaScript">document.write(getCalendarStyles( ));   </script> </head> <body>   <html:errors/>   <html:form action="/ProcessDate">     Date 1 (mm|dd|yyyy):     <html:text size="2" property="month"></html:text>     <html:text size="2" property="day"></html:text>     <html:text size="4" property="year"></html:text>     <br />   <c:if test="${not empty date1}">     Date 1: <b><fmt:formatDate dateStyle="full" value="${date1}"/></b>.   </c:if>   <p></p>     <script language="JavaScript" type="text/javascript" >       var cal1x = new CalendarPopup("testdiv1");       cal1x.showNavigationDropdowns( );       cal1x.setYearSelectStartOffset(60);     </script>     Birth Date (mm/dd/yyyy):     <html:text size="8" property="birthDateString"/>     <a href="" onClick="cal1x.select(document.forms[0].birthDateString,      'anchor1x','MM/dd/yyyy'); return false;" TITLE="cal1x.select(document.      forms[0].birthDateString,'anchor1x','MM/dd/yyyy'); return false;"       NAME="anchor1x" >select</A>     <br />   <c:if test="${not empty birthDate}">     Birth Date: <b><fmt:formatDate dateStyle="full"      value="${birthDate}"/></b>.   </c:if>   <p></p>     Date 3 (month day, year):     <html:select property="monthOpt">       <option value="1">January</option>       <option value="2">February</option>       <option value="3">March</option>       <option value="4">April</option>       <option value="5">May</option>       <option value="6">June</option>       <option value="7">July</option>       <option value="8">August</option>       <option value="9">September</option>       <option value="10">October</option>       <option value="11">November</option>       <option value="12">December</option>     </html:select>     <html:select property="dayOpt">       <option>1</option>       <option>2</option>       <option>3</option>       <option>4</option>       <option>5</option>       <option>6</option>       <option>7</option>       <option>8</option>       <option>9</option>       <option>10</option>       <option>11</option>       <option>12</option>       <option>13</option>       <option>14</option>       <option>15</option>       <option>16</option>       <option>17</option>       <option>18</option>       <option>19</option>       <option>20</option>       <option>21</option>       <option>22</option>       <option>23</option>       <option>24</option>       <option>25</option>       <option>26</option>       <option>27</option>       <option>28</option>       <option>29</option>       <option>30</option>       <option>31</option>     </html:select>, &nbsp;     <html:select property="yearOpt">       <option>2001</option>       <option>2002</option>       <option>2003</option>       <option>2004</option>       <option>2005</option>     </html:select>   <c:if test="${not empty date3}">     Date 3: <b><fmt:formatDate dateStyle="full" value="${date3}"/></b>.   </c:if>   <p></p>     <html:submit/>   </html:form>   <DIV  STYLE="position:absolute;visibility:hidden;    background-color:white;layer-background-color:white;"></DIV> </body> </html>

The generated page should look something like Figure 3-3.

Figure 3-3. Sample date fields


The "select" link beside the Birth Date field displays a JavaScript calendar pop up. The birth date input field is populated with a correctly formatted value when the user selects a date from the pop up. Figure 3-4 shows the pop up.

Figure 3-4. JavaScript calendar


Discussion

There are four primary rules of thumb that apply to handling dates. The first two are considered Struts best practices that apply to all form fields:

  • ActionForms should only contain String properties.

  • Validate all input fields, always on the server side and optionally on the client side.

  • Make the date format apparent to the user by showing an accepted format pattern or example beside the field.

  • For Date fields, use a Calendar control for better usability and to minimize typographical errors.

Working with dates can be aggravating; if you're not careful, it's easy for the user to input bad data. As a developer, using separate fields for the month, day, and year components of the date would seem to be a good approach. But users don't like having to move from field to field to enter a date; they would prefer entering the date in a single field. This mismatch of requirements can be frustrating for developers and users alike.

A compromise can be made by using a client-side calendar. (The calendar in the Solution was written by Matt Kruse.) This excellent calendar tool can be used to populate a single field with specific formatting as with the Birth Date field, or multiple fields as in the first and third date inputs shown in the Solution. If users have JavaScript turned off, then they can still manually key in the date.

Regardless of what approach you take, you should always validate the data. Recipe 8.6 provides all the details on date validation using the Struts Validator.

See Also

Recipe 8.6 shows the different ways you can validate date fields using the Validator's built-in rules, regular expressions, or your own custom rules.

Matt Kruse's awesome calendar pop up can be found at http://www.mattkruse.com/javascript/calendarpopup/. While some web purists may frown on the use of JavaScript, the pragmatic developer can see how helpful a tool like this can be.



    Jakarta Struts Cookbook
    Jakarta Struts Cookbook
    ISBN: 059600771X
    EAN: 2147483647
    Year: 2005
    Pages: 200

    flylib.com © 2008-2017.
    If you may any questions please contact us: flylib@qtcs.net