Skip to content

Commit

Permalink
MERGE
Browse files Browse the repository at this point in the history
  • Loading branch information
chillu committed Apr 3, 2017
1 parent 326aa37 commit 3b94d14
Show file tree
Hide file tree
Showing 11 changed files with 169 additions and 484 deletions.
41 changes: 10 additions & 31 deletions docs/en/02_Developer_Guides/03_Forms/Field_types/02_DateField.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,11 @@ summary: How to format and use the DateField class.
# DateField

This `FormField` subclass lets you display an editable date, in a single text input field.
It also provides a calendar date picker.
It implements the [HTML5 input date type](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/date)
(with `type=date`). In supported browsers, this will cause a localised date picker to appear for users.
HTML5 date fields present and save ISO 8601 date formats (`y-MM-dd`),
since the browser takes care of converting to/from a localised presentation.
Browsers without support receive an `<input type=text>` based polyfill.

The following example will add a simple DateField to your Page, allowing you to enter a date manually.

Expand Down Expand Up @@ -34,10 +38,13 @@ The following example will add a simple DateField to your Page, allowing you to
## Custom Date Format

A custom date format for a [api:DateField] can be provided through `setDateFormat`.
This is only necessary if you want to opt-out of the built-in browser localisation via `type=date`.

:::php
// will display a date in the following format: 31-06-2012
DateField::create('MyDate')->setDateFormat('dd-MM-yyyy');
// will display a date in the following format: 31/06/2012
DateField::create('MyDate')
->setHTML5(false)
->setDateFormat('dd/MM/yyyy');

<div class="info" markdown="1">
The formats are based on [ICU format](http://www.icu-project.org/apiref/icu4c/classSimpleDateFormat.html#details).
Expand All @@ -53,34 +60,6 @@ Sets the minimum and maximum allowed date values using the `min` and `max` confi
DateField::create('MyDate')
->setMinDate('-7 days')
->setMaxDate('2012-12-31')
## Separate Day / Month / Year Fields

To display separate input fields for day, month and year separately you can use the `SeparatedDateField` subclass`.
HTML5 placeholders 'day', 'month' and 'year' are enabled by default.

:::php
SeparatedDateField::create('MyDate');

<div class="alert" markdown="1">
Any custom date format settings will be ignored.
</div>

## Date Picker and HTML5 support

The field can be used as a [HTML5 input date type](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/date)
(with `type=date`) by calling `setHTML5(true)`.

:::php
DateField::create('MyDate')
->setHTML5(true);

In browsers [supporting HTML5 date inputs](caniuse.com/#feat=input-datetime),
this will cause a localised date picker to appear for users.
In this mode, the field will be forced to present and save ISO 8601 date formats (`y-MM-dd`),
since the browser takes care of converting to/from a localised presentation.

Browsers without support receive an `<input type=text>` based polyfill.

## Formatting Hints

Expand Down
13 changes: 7 additions & 6 deletions docs/en/04_Changelogs/4.0.0.md
Original file line number Diff line number Diff line change
Expand Up @@ -405,6 +405,7 @@ in `DateField` and `TimeField` now ([discussion](https://github.com/silverstripe
where the browser localises the output based on the browser/system preferences.
In this context it no longer makes sense to give users control over their own
date and time formats in their CMS profile.
Consequently, we've also removed `MemberDatetimeOptionsetField`.

`Member->getDateFormat()` and `Member->getTimeFormat()` still exist, and default to
the [IntlDateFormatter defaults](http://php.net/manual/en/class.intldateformatter.php) for the selected locale.
Expand Down Expand Up @@ -1514,13 +1515,11 @@ New `DateField` methods replace `getConfig()` / `setConfig()`:

The `DateField` has changed behavior:

* `DateField` no longer provides a jQuery UI date picker,
and uses [HTML5 date pickers](https://www.wufoo.com/html5/types/4-date.html) instead.
Use `setUseHTML()` to activate this mode (instead of `setConfig('showcalendar', true)`).
* `DateField` no longer provides a jQuery UI date picker (`showcalendar` option),
and uses [HTML5 date pickers](https://www.wufoo.com/html5/types/4-date.html) by default instead.
* `DateField` provides an optional polyfill for
[browsers without HTML5 date picker support](http://caniuse.com/#feat=input-datetime)
* The `dmyfields` option is now superceded with an `SeparatedDateField` class.
* `getPlaceholders()` / `setPlaceholders()` moved to a new `SeparatedDateField` class
* The `dmyfields` option has been replced with native HTML5 behaviour (as one single `<input type=date>`).
* `getClientLocale` / `setClientLocale` have been removed (handled by `DateField->locale` and browser settings)

New `TimeField` methods replace `getConfig()` / `setConfig()`
Expand Down Expand Up @@ -1569,7 +1568,9 @@ New `TimeField` methods replace `getConfig()` / `setConfig()`
* `set_source_file_comments()`
* `get_source_file_comments()`
* `getOption`
* `setOption`
* `setOption`
* Removed `MemberDatetimeOptionsetField` (no replacement)
* Removed `DateField_View_JQuery` (replaced with native HTML5 support in `DateField`)

### <a name="overview-i18n"></a>i18n API

Expand Down
62 changes: 33 additions & 29 deletions src/Forms/DateField.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
use IntlDateFormatter;
use SilverStripe\i18n\i18n;
use InvalidArgumentException;
use SilverStripe\ORM\FieldType\DBDate;
use SilverStripe\ORM\FieldType\DBDatetime;

/**
Expand Down Expand Up @@ -119,7 +120,7 @@ class DateField extends TextField
*
* @var bool
*/
protected $html5 = false;
protected $html5 = true;

/**
* @return bool
Expand Down Expand Up @@ -159,12 +160,8 @@ public function getDateLength()
}

/**
* Get length of the date format to use. One of:
*
* - IntlDateFormatter::SHORT
* - IntlDateFormatter::MEDIUM
* - IntlDateFormatter::LONG
* - IntlDateFormatter::FULL
* Get length of the date format to use.
* Only applicable with {@link setHTML5(false)}.
*
* @see http://php.net/manual/en/class.intldateformatter.php#intl.intldateformatter-constants
*
Expand All @@ -187,6 +184,11 @@ public function setDateLength($length)
*/
public function getDateFormat()
{
if ($this->getHTML5()) {
// Browsers expect ISO 8601 dates, localisation is handled on the client
$this->setDateFormat(DBDate::ISO_DATE);
}

if ($this->dateFormat) {
return $this->dateFormat;
}
Expand All @@ -197,6 +199,7 @@ public function getDateFormat()

/**
* Set date format in CLDR standard format.
* Only applicable with {@link setHTML5(false)}.
*
* @see http://userguide.icu-project.org/formatparse/datetime#TOC-Date-Field-Symbol-Table
* @param string $format
Expand All @@ -216,24 +219,33 @@ public function setDateFormat($format)
*/
protected function getFormatter()
{
if ($this->getHTML5() && $this->dateFormat && $this->dateFormat !== DBDate::ISO_DATE) {
throw new \LogicException(
'Please opt-out of HTML5 processing of ISO 8601 dates via setHTML5(false) if using setDateFormat()'
);
}

if ($this->getHTML5() && $this->dateLength) {
throw new \LogicException(
'Please opt-out of HTML5 processing of ISO 8601 dates via setHTML5(false) if using setDateLength()'
);
}

if ($this->getHTML5() && $this->locale) {
throw new \LogicException(
'Please opt-out of HTML5 processing of ISO 8601 dates via setHTML5(false) if using setLocale()'
);
}

$formatter = IntlDateFormatter::create(
$this->getLocale(),
$this->getDateLength(),
IntlDateFormatter::NONE
);

$isoFormat = 'y-MM-dd';

if ($this->dateFormat && $this->getHTML5() && $this->dateFormat !== $isoFormat) {
throw new \LogicException(sprintf(
'Can\'t use a custom dateFormat value with $html5=true (needs to be %s)',
$isoFormat
));
}

if ($this->getHTML5()) {
// Browsers expect ISO 8601 dates, localisation is handled on the client
$formatter->setPattern($isoFormat);
$formatter->setPattern(DBDate::ISO_DATE);
} elseif ($this->dateFormat) {
// Don't invoke getDateFormat() directly to avoid infinite loop
$ok = $formatter->setPattern($this->dateFormat);
Expand All @@ -259,20 +271,10 @@ protected function getISO8601Formatter()
);
$formatter->setLenient(false);
// CLDR ISO 8601 date.
$formatter->setPattern('y-MM-dd');
$formatter->setPattern(DBDate::ISO_DATE);
return $formatter;
}

public function FieldHolder($properties = array())
{
if ($this->getHTML5()) {
// Browsers expect ISO 8601 dates, localisation is handled on the client
$this->setDateFormat('y-MM-dd');
}

return parent::FieldHolder($properties);
}

public function getAttributes()
{
$attributes = parent::getAttributes();
Expand Down Expand Up @@ -421,7 +423,9 @@ public function getLocale()
}

/**
* Caution: Will not update the 'dateformat' config value.
* Determines the presented/processed format based on locale defaults,
* instead of explicitly setting {@link setDateFormat()}.
* Only applicable with {@link setHTML5(false)}.
*
* @param string $locale
* @return $this
Expand Down
Loading

0 comments on commit 3b94d14

Please sign in to comment.