summaryrefslogtreecommitdiffstats
path: root/documentation/articles/CreatingABookmarkableApplicationWithBackButtonSupport.asciidoc
Commit message (Expand)AuthorAgeFilesLines
* Add headers to community articles (#10028)Henri Muurimaa2017-09-201-0/+6
* Migrate CreatingABookmarkableApplicationWithBackButtonSupportErik Lumme2017-09-131-0/+140
id='n21' href='#n21'>21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377
---
title: Date Input with DateField
order: 13
layout: page
---

[[components.datefield]]
= Date Input with [classname]#DateField#

ifdef::web[]
[.sampler]
image:{live-demo-image}[alt="Live Demo", link="http://demo.vaadin.com/sampler/#ui/data-input/dates/popup-date-field"]
endif::web[]

The [classname]#DateField# component provides the means to display and input
dates. The field comes in two variations: [classname]#PopupDateField#,
with a numeric input box and a popup calendar view, and
[classname]#InlineDateField#, with the calendar view always visible. The
[classname]#DateField# base class defaults to the popup variation.

The example below illustrates the use of the [classname]#DateField# base class,
which is equivalent to the [classname]#PopupDateField#. We set the initial date
of the date field to current date by using the factory method [methodname]#now#
of the [classname]#java.time.LocalDate# class.


[source, java]
----
// Create a DateField with the default style
DateField date = new DateField();

// Set the date to present
date.setValue(LocalDate.now());
----

The result is shown in <<figure.components.datefield.basic>>.

[[figure.components.datefield.basic]]
.[classname]#DateField# ([classname]#PopupDateField#) for Selecting a Date
image::img/datefield-example1.png[width=35%, scaledwidth=60%]

[[components.datefield.popupdatefield]]
== [classname]#PopupDateField#

The [classname]#PopupDateField# provides date input using a text box. As the
[classname]#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. The Down key also opens the popup.
Once opened, the user can navigate the calendar using the cursor keys.

The date selected from the popup is displayed in the text box according to the
default date and format of the current locale, or as specified with [methodname]#setDateFormat()#.
The same format definitions are used for parsing user input.

[[components.datefield.popupdatefield.format]]
=== Date Format

The date is normally displayed according to the default format for the current locale (see
<<dummy/../../../framework/components/components-features#components.features.locale,"Locale">>).
You can specify a custom format with [methodname]#setDateFormat()#. It takes a
format string that follows the format of the [classname]#java.time.format.DateTimeFormatter# in
Java.


[source, java]
----
// Display only year, month, and day in ISO format
date.setDateFormat("yyyy-MM-dd");
----

The result is shown in <<figure.components.datefield.popupdatefield.format>>.

[[figure.components.datefield.popupdatefield.format]]
.Custom Date Format for [classname]#PopupDateField#
image::img/datefield-formatting.png[width=35%, scaledwidth=60%]

The same format specification is also used for parsing user-input date,
as described later.


ifdef::web[]
[[components.datefield.popupdatefield.malformed]]
=== Handling Malformed User Input

A user can easily input a malformed or otherwise invalid date.
[classname]#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
[literal]#++v-datefield-parseerror++# style is set. Whether this causes a
visible indication of a problem depends on the theme. The built-in
[literal]#++reindeer++# theme does not shown any indication by default, making
server-side handling of the problem more convenient.


[source, css]
----
.mydate.v-datefield-parseerror .v-textfield {
    background: pink;
}
----

The [methodname]#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
[methodname]#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.


[source, java]
----
// 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 [classname]#Date# object or throw
a [classname]#ConversionException#. Returning [parameter]#null# will set the
field value to [parameter]#null# and clear the input box.

endif::web[]

ifdef::web[]
[[components.datefield.popupdatefield.error-customization]]
=== Customizing the Error Message

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:


[source, java]
----
// 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
        Notification.show(
                "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
[parameter]#null# value would make the input field empty, which is probably
undesired.

endif::web[]

[[components.datefield.popupdatefield.prompt]]
=== Input Prompt

Like other fields that have a text box, [classname]#PopupDateField# allows an
input prompt that is visible until the user has input a value. You can set the
prompt with [methodname]#setInputPrompt#.


[source, java]
----
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 [methodname]#setWidth()#.

The input prompt is not available in the [classname]#DateField# superclass.


[[components.datefield.popupdatefield.css]]
=== CSS Style Rules


[source, css]
----
.v-datefield, v-datefield-popupcalendar {}
  .v-textfield, v-datefield-textfield {}
  .v-datefield-button {}
----

The top-level element of [classname]#DateField# and all its variants have
[literal]#++v-datefield++# style. The base class and the
[classname]#PopupDateField# also have the
[literal]#++v-datefield-popupcalendar++# style.

In addition, the top-level element has a style that indicates the resolution,
with [literal]#++v-datefield-++# basename and an extension, which is one of
[literal]#++full++#, [literal]#++day++#, [literal]#++month++#, or
[literal]#++year++#. The [literal]#++-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 [literal]#++v-textfield++# and
[literal]#++v-datefield-textfield++# styles, and the calendar button
[literal]#++v-datefield-button++#.

Once opened, the calendar popup has the following styles at the top level:


[source, css]
----
.v-datefield-popup {}
  .v-popupcontent {}
    .v-datefield-calendarpanel {}
----

The top-level element of the floating popup calendar has
[literal]#++.v-datefield-popup++# style. Observe that the popup frame is outside
the HTML structure of the component, hence it is not enclosed in the
[literal]#++v-datefield++# element and does not include any custom styles.
// NOTE: May be changed in #5752.
The content in the [literal]#++v-datefield-calendarpanel++# is the same as in
[classname]#InlineDateField#, as described in <<components.datefield.calendar>>.

[[components.datefield.calendar]]
== [classname]#InlineDateField#

The [classname]#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 pop-up variant, the month view is always visible in the inline
field.


[source, java]
----
// Create a DateField with the default style
InlineDateField date = new InlineDateField();

// Set the date to present
date.setValue(LocalDate.now());
----

The result is shown in <<figure.components.datefield.inlinedatefield>>.

[[figure.components.datefield.inlinedatefield]]
.Example of the [classname]#InlineDateField#
image::img/datefield-inlinedatefield.png[width=35%, scaledwidth=60%]

The user can also navigate the calendar using the cursor keys.

=== CSS Style Rules


[source, css]
----
.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 [literal]#++v-datefield++# style. In addition, the
top-level element has a style name that indicates the resolution of the
calendar, with [literal]#++v-datefield-++# basename and an extension, which is
one of [literal]#++full++#, [literal]#++day++#, [literal]#++month++#, or
[literal]#++year++#. The [literal]#++-full++# style is enabled when the
resolution is smaller than a day.

The [literal]#++v-datefield-calendarpanel-weeknumbers++# and
[literal]#++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
[literal]#++v-first++# and [literal]#++v-last++# styles allow making rounded
endings for the weekday bar.

[[components.datefield.resolution]]
== Date and Time Resolution

In addition to display a calendar with dates, [classname]#DateField# can also
display just the month or year. The visibility of the input components is
controlled by __date resolution__, which you can set with [methodname]#setResolution()#.
The method takes as its parameter the highest resolution date element that should
be visible. Please see the API Reference for the complete list of resolution parameters.


[[components.datefield.locale]]
== DateField Locale

The date is displayed according to the locale of the user, as reported
by the browser. You can set a custom locale with the [methodname]#setLocale()#
method of [classname]#AbstractComponent#, as described in
<<dummy/../../../framework/components/components-features#components.features.locale,"Locale">>.
Only Gregorian calendar is supported.


ifdef::web[]
[[components.datefield.weeknumbers]]
== Week Numbers

You can enable week numbers in a date field with
[methodname]#setShowISOWeekNumbers()#. The numbers are shown in a column on the
left side of the field.


[source, java]
----
df.setShowISOWeekNumbers(true);
----

The supported numbering is defined in the ISO 8601 standard. Note that the ISO
standard applies only to calendar locales where the week starts on Monday. This
is not the case in many countries, such as Americas (North and South), many
East-Asian countries, and some African countries, where the week starts on
Sunday, nor in some North African and Middle-Eastern countries, where the week
begins on Saturday. In such locales, the week numbers are not displayed.

endif::web[]