The DateField
component provides the means to display
and input date and time. The field comes in two variations:
PopupDateField
, with a numeric input box and a popup
calendar view, and InlineDateField
, with the calendar
view always visible. The DateField
base class defaults
to the popup variation.
The example below illustrates the use of the DateField
baseclass, which is equivalent to the
PopupDateField
. We set the initial time of the date
field to current time by using the default constructor of the
java.util.Date
class.
// Create a DateField with the default style DateField date = new DateField(); // Set the date and time to present date.setValue(new Date());
The result is shown in Figure 5.31, “DateField
(PopupDateField
) for Selecting Date and Time”.
The PopupDateField
provides date input using a text
box for the date and time. As the DateField
defaults to this component, the use is exactly the same as described
earlier. Clicking the handle right of the date opens a popup view for
selecting the year, month, and day, as well as time. Also the
Down key opens the popup. Once opened, the user can
navigate the calendar using the cursor keys.
The date and time selected from the popup are displayed in the text box
according to the default date and time format of the current locale, or as
specified with setDateFormat()
. The same format
definitions are used for parsing user input.
The date and time are normally displayed according to the default
format for the current locale (see Section 5.3.5, “Locale”). You can specify a custom
format with setDateFormat()
. It takes a
format string that follows the format of the
SimpleDateFormat
in Java.
// Display only year, month, and day in ISO format date.setDateFormat("yyyy-MM-dd");
The result is shown in Figure 5.32, “Custom Date Format for
PopupDateField
”.
The same format specification is also used for parsing user-input date and time, as described later.
A user can easily input a malformed or otherwise invalid date or
time. DateField
has two validation layers:
first on the client-side and then on the server-side.
The validity of the entered date is first validated on the
client-side, immediately when the input box loses focus. If the date
format is invalid, the v-datefield-parseerror
style
is set. Whether this causes a visible indication of a problem depends
on the theme. The built-in reindeer
theme does not
shown any indication by default, making server-side handling of the
problem more convenient.
.mydate.v-datefield-parseerror .v-textfield { background: pink; }
The setLenient(true)
setting enables relaxed
interpretation of dates, so that invalid dates, such as February 30th
or March 0th, are wrapped to the next or previous month, for example.
The server-side validation phase occurs when the date value is sent to the server. If the date field is set in immediate state, it occurs immediately after the field loses focus. Once this is done and if the status is still invalid, an error indicator is displayed beside the component. Hovering the mouse pointer over the indicator shows the error message.
You can handle the errors by overriding the
handleUnparsableDateString()
method. The
method gets the user input as a string parameter and can provide a
custom parsing mechanism, as shown in the following example.
// Create a date field with a custom parsing and a // custom error message for invalid format PopupDateField date = new PopupDateField("My Date") { @Override protected Date handleUnparsableDateString(String dateString) throws Property.ConversionException { // Try custom parsing String fields[] = dateString.split("/"); if (fields.length >= 3) { try { int year = Integer.parseInt(fields[0]); int month = Integer.parseInt(fields[1])-1; int day = Integer.parseInt(fields[2]); GregorianCalendar c = new GregorianCalendar(year, month, day); return c.getTime(); } catch (NumberFormatException e) { throw new Property. ConversionException("Not a number"); } } // Bad date throw new Property. ConversionException("Your date needs two slashes"); } }; // Display only year, month, and day in slash-delimited format date.setDateFormat("yyyy/MM/dd"); // Don't be too tight about the validity of dates // on the client-side date.setLenient(true);
The handler method must either return a parsed
Date
object or throw a
ConversionException
. Returning
null
will set the field value to
null
and clear the input box.
In addition to customized parsing, overriding the handler method for unparseable input is useful for internationalization and other customization of the error message. You can also use it for another way for reporting the errors, as is done in the example below:
// Create a date field with a custom error message for invalid format PopupDateField date = new PopupDateField("My Date") { @Override protected Date handleUnparsableDateString(String dateString) throws Property.ConversionException { // Have a notification for the error getWindow().showNotification( "Your date needs two slashes", Notification.TYPE_WARNING_MESSAGE); // A failure must always also throw an exception throw new Property.ConversionException("Bad date"); } };
If the input is invalid, you should always throw the exception;
returning a null
value would make the input
field empty, which is probably undesired.
Like other fields that have a text box,
PopupDateField
allows an input prompt that is
visible until the user has input a value. You can set the prompt with
setInputPrompt
.
PopupDateField date = new PopupDateField(); // Set the prompt date.setInputPrompt("Select a date"); // Set width explicitly to accommodate the prompt date.setWidth("10em");
The date field doesn't automatically scale to accommodate the prompt,
so you need to set it explicitly with
setWidth()
.
The input prompt is not available in the
DateField
superclass.
.v-datefield, v-datefield-popupcalendar {} .v-textfield, v-datefield-textfield {} .v-datefield-button {}
The top-level element of DateField
and all its
variants have v-datefield
style. The base class and
the PopupDateField
also have the
v-datefield-popupcalendar
style.
In addition, the top-level element has a style that indicates the
resolution, with v-datefield-
basename and an
extension, which is one of full
,
day
, month
, or
year
. The -full
style is enabled
when the resolution is smaller than a day. These styles are used
mainly for controlling the appearance of the popup calendar.
The text box has v-textfield
and
v-datefield-textfield
styles, and the calendar
button v-datefield-button
.
Once opened, the calendar popup has the following styles at the top level:
.v-datefield-popup {} .v-popupcontent {} .v-datefield-calendarpanel {}
The top-level element of the floating popup calendar has
.v-datefield-popup
style. Observe that the popup
frame is outside the HTML structure of the component, hence it is not
enclosed in the v-datefield
element and does not
include any custom styles.
The content in the v-datefield-calendarpanel
is the
same as in InlineDateField
, as described in
Section 5.10.2, “InlineDateField
”.
The InlineDateField
provides a date picker
component with a month view. The user can navigate months and years by
clicking the appropriate arrows. Unlike with the popup variant, the month
view is always visible in the inline field.
// Create a DateField with the default style InlineDateField date = new InlineDateField(); // Set the date and time to present date.setValue(new java.util.Date());
The result is shown in Figure 5.33, “Example of the InlineDateField
”.
The user can also navigate the calendar using the cursor keys.
.v-datefield {} .v-datefield-calendarpanel {} .v-datefield-calendarpanel-header {} .v-datefield-calendarpanel-prevyear {} .v-datefield-calendarpanel-prevmonth {} .v-datefield-calendarpanel-month {} .v-datefield-calendarpanel-nextmonth {} .v-datefield-calendarpanel-nextyear {} .v-datefield-calendarpanel-body {} .v-datefield-calendarpanel-weekdays, .v-datefield-calendarpanel-weeknumbers {} .v-first {} .v-last {} .v-datefield-calendarpanel-weeknumber {} .v-datefield-calendarpanel-day {} .v-datefield-calendarpanel-time {} .v-datefield-time {} .v-select {} .v-label {}
The top-level element has the v-datefield
style. In
addition, the top-level element has a style name that indicates the
resolution of the calendar, with v-datefield-
basename and an extension, which is one of full
,
day
, month
, or
year
. The -full
style is enabled
when the resolution is smaller than a day.
The v-datefield-calendarpanel-weeknumbers
and
v-datefield-calendarpanel-weeknumber
styles are
enabled when the week numbers are enabled. The former controls the
appearance of the weekday header and the latter the actual week
numbers.
The other style names should be self-explanatory. For weekdays, the
v-first
and v-last
styles allow
making rounded endings for the weekday bar.
You probably will not need milliseconds in most applications, and might
not even need the time, but just the date, or month or year. The
visibility of the input components is controlled by time
resolution, which can be set with
setResolution()
method. The method takes as its
parameters the lowest visible component, typically
RESOLUTION_DAY
for just dates and
RESOLUTION_MIN
for dates with time in hours and
minutes. Please see the API Reference for a complete list of resolution
parameters.
The date and time are displayed according to the locale of the user, as
reported by the browser. You can set a custom locale with the
setLocale()
method of
AbstractComponent
, as described in Section 5.3.5, “Locale”. Only Gregorian calendar is
supported.