diff --git a/docs/en/reference/datefield.md b/docs/en/reference/datefield.md new file mode 100644 index 000000000..703244261 --- /dev/null +++ b/docs/en/reference/datefield.md @@ -0,0 +1,131 @@ +# DateField + +## Introduction + +This `FormField` subclass lets you display an editable date, either in +a single text input field, or in three separate fields for day, month and year. +It also provides a calendar datepicker. + +## Adding a DateField + +The following example will add a simple DateField to your Page, allowing you to +enter a date manually. + + :::php + class Page extends SiteTree { + static $db = array( + 'MyDate' => 'Date', + ); + + public function getCMSFields() { + $fields = parent::getCMSFields(); + + $fields->addFieldToTab( + 'Root.Main', + $myDate = new DateField('MyDate', 'Enter a date') + ); + + return $fields; + } + } + +## Custom Dateformat + +You can define a custom dateformat for your Datefield based on [Zend_Date constants](http://framework.zend.com/manual/1.12/en/zend.date.constants.html). + + :::php + // will display a date in the following format: 31-06-2012 + DateField::create('MyDate')->setConfig('dateformat', 'dd-MM-yyyy'); + + +## Min and Max Dates + +Set the minimum and maximum allowed datevalues using the `min` and `max` +configuration settings (in ISO format or strtotime() compatible). Example: + + :::php + DateField::create('MyDate') + ->setConfig('min', '-7 days') + ->setConfig('max', '2012-12-31') + +## Separate Day/Month/Year Fields + +The following setting will display your DateField as `three input fields` for +day, month and year separately. Any custom dateformat settings will be ignored. +HTML5 placeholders 'day', 'month' and 'year' are enabled by default. + + :::php + DateField::create('MyDate') + ->setConfig('dmyfields', true); + ->setConfig('dmyseparator', '/') // set the separator + ->setConfig('dmyplaceholders', 'true'); // enable HTML 5 Placeholders + +## Calendar Field + +The following setting will add a Calendar to a single DateField, using the +`jQuery UI DatePicker widget` + + :::php + DateField::create('MyDate')->setConfig('showcalendar', true); + + +### 'Safe' Dateformats to Use with the Calendar + +The jQuery DatePicker doesn't support every constant available for Zend_Date. +If you choose to use the calendar, the following constants should at least be safe: + +Constant | xxxxx +-------- | ----- +d | numeric day of the month (without leading zero) +dd | numeric day of the month (with leading zero) +EEE | dayname, abbreviated +EEEE | dayname +M | numeric month of the year (without leading zero) +MM | numeric month of the year (with leading zero) +MMM | monthname, abbreviated +MMMM | monthname +y | year (4 digits) +yy | year (2 digits) +yyyy | year (4 digits) + +### Calendar localization issues + +Unfortunately the day- and monthname values in Zend Date do not always match +those in the existing jQuery UI locale files, so constants like `EEE` or `MMM`, +for day and monthnames could break validation. To fix this we had to slightly +alter the jQuery locale files, situated in +*/framework/thirdparty/jquery-ui/datepicker/i18n/*, to match Zend_Date. + +At this moment not all locale files may be present. If a locale file is +missing, the DatePicker calendar will fallback to 'yyyy-MM-dd' whenever day- +and/or monthnames are used. After saving, the correct format will be displayed. + +## Contributing jQuery Locale Files + +If you find the jQuery locale file for your chosen locale is missing, the +following section will explain how to create one. If you wish to contribute +your file to the SilverStripe core, please check out the guide on +['contributing code'](http://doc.silverstripe.org/framework/en/trunk/misc/contributing/code). + +### 1. Get the Sourcefile + +You can find a list of locale files for the jQuery UI DatePicker +[in the jQuery source code](https://github.com/jquery/jquery-ui/tree/master/ui/i18n). + +### 2. Find your Zend Locale File + +The Zend locale files are located in */framework/thirdparty/Zend/Locale/Data/*. +Find the one that has the information for your locale. + +### 3. Find the Date Values + +You're looking for the `Gregorian` date values for monthnames and daynames in +the Zend locale file. Edit the DatePicker locale File so your *full day- and +monthnames* and *short monthnames* match. For your *short daynames*, use the +first three characters of the full name. Note that Zend dates are `case +sensitive`! + +### 4. Filename + +Use the original jQuery UI filename 'jquery.ui.datepicker-xx.js', where xx +stands for the locale. \ No newline at end of file diff --git a/forms/DateField.php b/forms/DateField.php index 36155cfff..538b635d9 100644 --- a/forms/DateField.php +++ b/forms/DateField.php @@ -113,12 +113,26 @@ class DateField extends TextField { } public function FieldHolder($properties = array()) { - // TODO Replace with properly extensible view helper system - $d = DateField_View_JQuery::create($this); - $d->onBeforeRender(); + if ($this->getConfig('showcalendar')) { + // TODO Replace with properly extensible view helper system + $d = DateField_View_JQuery::create($this); + if(!$d->regionalSettingsExist()) { + $dateformat = $this->getConfig('dateformat'); + + // if no localefile is present, the jQuery DatePicker + // month- and daynames will default to English, so the date + // will not pass Zend validatiobn. We provide a fallback + if (preg_match('/(MMM+)|(EEE+)/', $dateformat)) { + $this->setConfig('dateformat', $this->getConfig('datavalueformat')); + } + } + $d->onBeforeRender(); + } $html = parent::FieldHolder(); - $html = $d->onAfterRender($html); - + + if(!empty($d)) { + $html = $d->onAfterRender($html); + } return $html; } @@ -199,9 +213,6 @@ class DateField extends TextField { $this->value = null; $this->valueObj = null; } else { - // Quick fix for overzealous Zend validation, its case sensitive on month names (see #5990) - if(is_string($val)) $val = ucwords(strtolower($val)); - if($this->getConfig('dmyfields')) { // Setting in correct locale if(is_array($val) && $this->validateArrayValue($val)) { @@ -480,6 +491,11 @@ class DateField_View_JQuery extends Object { protected $field; + /* + * the current jQuery UI DatePicker locale file + */ + protected $jqueryLocaleFile = ''; + /** * @var array Maps values from {@link i18n::$all_locales()} to * localizations existing in jQuery UI. @@ -488,7 +504,7 @@ class DateField_View_JQuery extends Object { 'en_GB' => 'en-GB', 'en_US' => 'en', 'en_NZ' => 'en-GB', - 'fr_CH' => 'fr-CH', + 'fr_CH' => 'fr', 'pt_BR' => 'pt-BR', 'sr_SR' => 'sr-SR', 'zh_CN' => 'zh-CN', @@ -509,7 +525,24 @@ class DateField_View_JQuery extends Object { public function getField() { return $this->field; } - + + /** + * Check if jQuery UI locale settings exists for the current locale + * @return boolean + */ + function regionalSettingsExist() { + $lang = $this->getLang(); + $localeFile = THIRDPARTY_DIR . "/jquery-ui/datepicker/i18n/jquery.ui.datepicker-{$lang}.js"; + if (file_exists(Director::baseFolder() . '/' .$localeFile)){ + $this->jqueryLocaleFile = $localeFile; + return true; + } else { + // file goes before internal en_US settings, + // but both will validate + return ($lang == 'en'); + } + } + public function onBeforeRender() { } @@ -524,16 +557,9 @@ class DateField_View_JQuery extends Object { Requirements::javascript(FRAMEWORK_DIR . '/thirdparty/jquery-ui/jquery-ui.js'); // Include language files (if required) - $lang = $this->getLang(); - if($lang != 'en') { - // TODO Check for existence of locale to avoid unnecessary 404s from the CDN - Requirements::javascript( - sprintf( - THIRDPARTY_DIR . '/jquery-ui/minified/i18n/jquery.ui.datepicker-%s.min.js', - // can be a mix between names (e.g. 'de') and combined locales (e.g. 'zh-TW') - $lang - )); - } + if ($this->jqueryLocaleFile){ + Requirements::javascript($this->jqueryLocaleFile); + } Requirements::javascript(FRAMEWORK_DIR . "/javascript/DateField.js"); } @@ -578,12 +604,12 @@ class DateField_View_JQuery extends Object { '/^d([^d])/' => 'd$1', '/([^d])d$/' => '$1d', '/dd/' => 'dd', - '/EEEE/' => 'DD', - '/EEE/' => 'D', '/SS/' => '', '/eee/' => 'd', '/e/' => 'N', '/D/' => '', + '/EEEE/' => 'DD', + '/EEE/' => 'D', '/w/' => '', // make single "M" lowercase '/([^M])M([^M])/' => '$1m$2', diff --git a/thirdparty/jquery-ui/datepicker/i18n/README b/thirdparty/jquery-ui/datepicker/i18n/README new file mode 100644 index 000000000..fdb56bbdb --- /dev/null +++ b/thirdparty/jquery-ui/datepicker/i18n/README @@ -0,0 +1,25 @@ +AUTHOR: Martine Bloem (http://www.balbuss.com) +********************************************** + +jQuery UI DatePicker localization files for SilverStripe 3.0 +------------------------------------------------------------ +These files are adaptations of the official localization files that can be found here: +http://jquery-ui.googlecode.com/svn/trunk/ui/i18n/ + +Day- and monthnames have been changed to match the values Zend Date uses, to make +the following dateformats validate: + +EEE: weekday short +EEEE: weekday +MMM: monthname short +MMMM: monthname + +For locales for which no file exists (yet), the DatePicker will revert to a numeric +format, that will validate, and after being saved will be displayed in the +required format. + +To create your own language fiel, download the original file from the URL above, +find the Zend Date locale file in framework/Zend/Locale/Data and make sure that + +- monthNames, monthNamesShort and dayNames are equivalent to Zend (Gregorian) names +- dayNamesShort should be the first 3 characters of dayNames diff --git a/thirdparty/jquery-ui/datepicker/i18n/jquery.ui.datepicker-da.js b/thirdparty/jquery-ui/datepicker/i18n/jquery.ui.datepicker-da.js new file mode 100644 index 000000000..0afa19229 --- /dev/null +++ b/thirdparty/jquery-ui/datepicker/i18n/jquery.ui.datepicker-da.js @@ -0,0 +1,25 @@ +/* + * Danish (UTF-8) initialisation for the jQuery UI date picker plugin. + * Adapted to match the Zend Data localization for SilverStripe CMS + * See: README + */ +jQuery(function($){ + $.datepicker.regional['da'] = { + closeText: 'Luk', + prevText: '<Forrige', + nextText: 'Næste>', + currentText: 'Idag', + monthNames: ['januar','februar','marts','april','maj','juni','juli','august','september','oktober','november','december'], + monthNamesShort: ['jan.','feb.','mar.','apr.','maj','jun.','jul.','aug.','sep.','okt.','nov.','dec.'], + dayNames: ['søndag','mandag','tirsdag','onsdag','torsdag','fredag','lørdag'], + dayNamesShort: ['søn','man','tir','ons','tor','fre','lør'], + dayNamesMin: ['Sø','Ma','Ti','On','To','Fr','Lø'], + weekHeader: 'Uge', + dateFormat: 'dd-mm-yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['da']); +}); + diff --git a/thirdparty/jquery-ui/datepicker/i18n/jquery.ui.datepicker-de.js b/thirdparty/jquery-ui/datepicker/i18n/jquery.ui.datepicker-de.js new file mode 100644 index 000000000..a6aae4bc7 --- /dev/null +++ b/thirdparty/jquery-ui/datepicker/i18n/jquery.ui.datepicker-de.js @@ -0,0 +1,25 @@ +/* + * German (UTF-8) initialisation for the jQuery UI date picker plugin. + * Adapted to match the Zend Data localization for SilverStripe CMS + * See: README + */ +jQuery(function($){ + $.datepicker.regional['de'] = { + closeText: 'schließen', + prevText: '<zurück', + nextText: 'Vor>', + currentText: 'heute', + monthNames: ['Januar','Februar','März','April','Mai','Juni','Juli','August','September','Oktober','November','Dezember'], + monthNamesShort: ['Jan','Feb','Mär','Apr','Mai','Jun','Jul','Aug','Sep','Okt','Nov','Dez'], + dayNames: ['Sonntag','Montag','Dienstag','Mittwoch','Donnerstag','Freitag','Samstag'], + dayNamesShort: ['Son','Mon','Die','Mit','Don','Fre','Sam'], + dayNamesMin: ['So','Mo','Di','Mi','Do','Fr','Sa'], + weekHeader: 'Wo', + dateFormat: 'dd.mm.yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['de']); +}); + diff --git a/thirdparty/jquery-ui/datepicker/i18n/jquery.ui.datepicker-en-GB.js b/thirdparty/jquery-ui/datepicker/i18n/jquery.ui.datepicker-en-GB.js new file mode 100644 index 000000000..148146aee --- /dev/null +++ b/thirdparty/jquery-ui/datepicker/i18n/jquery.ui.datepicker-en-GB.js @@ -0,0 +1,24 @@ +/* + * English/UK (UTF-8) initialisation for the jQuery UI date picker plugin. + * Adapted to match the Zend Data localization for SilverStripe CMS + * See: README + */ +jQuery(function($){ + $.datepicker.regional['en-GB'] = { + closeText: 'Done', + prevText: 'Prev', + nextText: 'Next', + currentText: 'Today', + monthNames: ['January','February','March','April','May','June','July','August','September','October','November','December'], + monthNamesShort: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'], + dayNames: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'], + dayNamesShort: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'], + dayNamesMin: ['Su','Mo','Tu','We','Th','Fr','Sa'], + weekHeader: 'Wk', + dateFormat: 'dd/mm/yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['en-GB']); +}); \ No newline at end of file diff --git a/thirdparty/jquery-ui/datepicker/i18n/jquery.ui.datepicker-en.js b/thirdparty/jquery-ui/datepicker/i18n/jquery.ui.datepicker-en.js new file mode 100644 index 000000000..6880295a1 --- /dev/null +++ b/thirdparty/jquery-ui/datepicker/i18n/jquery.ui.datepicker-en.js @@ -0,0 +1,25 @@ +/* + * English (UTF-8) initialisation for the jQuery UI date picker plugin. + * Adapted to match the Zend Data localization for SilverStripe CMS + * See: README + */ +jQuery(function($){ + $.datepicker.regional['en'] = { + closeText: 'Done', + prevText: 'Prev', + nextText: 'Next', + currentText: 'Today', + monthNames: ['January','February','March','April','May','June','July','August','September','October','November','December'], // For formatting + monthNamesShort: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'], // For formatting + dayNames: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'], // For formatting + dayNamesShort: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'], // For formatting + dayNamesMin: ['Su','Mo','Tu','We','Th','Fr','Sa'], + weekHeader: 'Wk', + dateFormat: 'mm/dd/yy', + firstDay: 0, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: '' + $.datepicker.setDefaults($.datepicker.regional['en']); +}); + diff --git a/thirdparty/jquery-ui/datepicker/i18n/jquery.ui.datepicker-es.js b/thirdparty/jquery-ui/datepicker/i18n/jquery.ui.datepicker-es.js new file mode 100644 index 000000000..e7fd01402 --- /dev/null +++ b/thirdparty/jquery-ui/datepicker/i18n/jquery.ui.datepicker-es.js @@ -0,0 +1,27 @@ +/* + * Spanish (UTF-8) initialisation for the jQuery UI date picker plugin. + * Adapted to match the Zend Data localization for SilverStripe CMS + * See: README + */ +jQuery(function($){ + $.datepicker.regional['es'] = { + closeText: 'Cerrar', + prevText: '<Ant', + nextText: 'Sig>', + currentText: 'Hoy', + monthNames: ['enero','febrero','marzo','abril','mayo','junio','julio','agosto','septiembre','octubre','noviembre','diciembre'], + monthNamesShort: ['ene','feb','mar','abr','may','jun','jul','ago','sep','oct','nov','dic'], + dayNames: ['domingo','lunes','martes','miércoles','jueves','viernes','sábado'], + dayNamesShort: ['dom','lun','mar','mié','juv','vie','sáb'], + dayNamesMin: ['Do','Lu','Ma','Mi','Ju','Vi','Sá'], + weekHeader: 'Sm', + dateFormat: 'dd/mm/yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['es']); +}); + + + diff --git a/thirdparty/jquery-ui/datepicker/i18n/jquery.ui.datepicker-fr.js b/thirdparty/jquery-ui/datepicker/i18n/jquery.ui.datepicker-fr.js new file mode 100644 index 000000000..b7162de9f --- /dev/null +++ b/thirdparty/jquery-ui/datepicker/i18n/jquery.ui.datepicker-fr.js @@ -0,0 +1,24 @@ +/* + * French (UTF-8) initialisation for the jQuery UI date picker plugin. + * Adapted to match the Zend Data localization for SilverStripe CMS + * See: README + */ +jQuery(function($){ + $.datepicker.regional['fr'] = { + closeText: 'Fermer', + prevText: '<Préc', + nextText: 'Suiv>', + currentText: 'Courant', + monthNames: ['janvier','février','mars','avril','mai','juin','juillet','août','septembre','octobre','novembre','décembre'], + monthNamesShort: ['janv.','févr.','mars','avr.','mai','juin','juil.','août','sept.','oct.','nov.','déc.'], + dayNames: ['dimanche','lundi','mardi','mercredi','jeudi','vendredi','samedi'], + dayNamesShort: ['dim','lun','mar','mer','jeu','ven','sam'], + dayNamesMin: ['Di','Lu','Ma','Me','Je','Ve','Sa'], + weekHeader: 'Sm', + dateFormat: 'dd/mm/yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['fr']); +}); diff --git a/thirdparty/jquery-ui/datepicker/i18n/jquery.ui.datepicker-nb.js b/thirdparty/jquery-ui/datepicker/i18n/jquery.ui.datepicker-nb.js new file mode 100644 index 000000000..709b1472d --- /dev/null +++ b/thirdparty/jquery-ui/datepicker/i18n/jquery.ui.datepicker-nb.js @@ -0,0 +1,24 @@ +/* + * Norwegian (UTF-8) initialisation for the jQuery UI date picker plugin. + * Adapted to match the Zend Data localization for SilverStripe CMS + * See: README + */ +jQuery(function($){ + $.datepicker.regional['no'] = { + closeText: 'Lukk', + prevText: '«Forrige', + nextText: 'Neste»', + currentText: 'I dag', + monthNames: ['januar','februar','mars','april','mai','juni','juli','august','september','oktober','november','desember'], + monthNamesShort: ['jan.','feb.','mar.','apr.','mai','juni','juli','aug.','sep.','okt.','nov.','des.'], + dayNames: ['søndag','mandag','tirsdag','onsdag','torsdag','fredag','lørdag'], + dayNamesShort: ['søn','man','tir','ons','tor','fre','lør'], + dayNamesMin: ['Sø','Ma','Ti','On','To','Fr','Lø'], + weekHeader: 'Uke', + dateFormat: 'yy-mm-dd', + firstDay: 0, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['no']); +}); diff --git a/thirdparty/jquery-ui/datepicker/i18n/jquery.ui.datepicker-nl.js b/thirdparty/jquery-ui/datepicker/i18n/jquery.ui.datepicker-nl.js new file mode 100644 index 000000000..1eaa7805d --- /dev/null +++ b/thirdparty/jquery-ui/datepicker/i18n/jquery.ui.datepicker-nl.js @@ -0,0 +1,26 @@ +/* + * Dutch (UTF-8) initialisation for the jQuery UI date picker plugin. + * Adapted to match the Zend Data localization for SilverStripe CMS + * See: README + */ +jQuery(function($){ + $.datepicker.regional['nl'] = { + closeText: 'Sluiten', + prevText: '←', + nextText: '→', + currentText: 'Vandaag', + monthNames: ['januari', 'februari', 'maart', 'april', 'mei', 'juni','juli', 'augustus', 'september', 'oktober', 'november', 'december'], + monthNamesShort: ['jan.', 'feb.', 'mrt.', 'apr.', 'mei.', 'jun.','jul.', 'aug.', 'sep.', 'okt.', 'nov.', 'dec.'], + dayNames: ['zondag', 'maandag', 'dinsdag', 'woensdag', 'donderdag', 'vrijdag', 'zaterdag'], + dayNamesShort: ['zon', 'maa', 'din', 'woe', 'don', 'vri', 'zat'], + dayNamesMin: ['zo', 'ma', 'di', 'wo', 'do', 'vr', 'za'], + weekHeader: 'Wk', + dateFormat: 'dd-mm-yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['nl']); +}); + + diff --git a/thirdparty/jquery-ui/datepicker/i18n/jquery.ui.datepicker-sv.js b/thirdparty/jquery-ui/datepicker/i18n/jquery.ui.datepicker-sv.js new file mode 100644 index 000000000..f07fdd16c --- /dev/null +++ b/thirdparty/jquery-ui/datepicker/i18n/jquery.ui.datepicker-sv.js @@ -0,0 +1,24 @@ +/* + * Swedish (UTF-8) initialisation for the jQuery UI date picker plugin. + * Adapted to match the Zend Data localization for SilverStripe CMS + * See: README + */ +jQuery(function($){ + $.datepicker.regional['sv'] = { + closeText: 'Stäng', + prevText: '«Förra', + nextText: 'Nästa»', + currentText: 'Idag', + monthNames: ['januari','februari','mars','april','maj','juni','juli','augusti','september','oktober','november','december'], + monthNamesShort: ['jan','feb','mar','apr','maj','jun','jul','aug','sep','okt','nov','dec'], + dayNames: ['söndag','måndag','tisdag','onsdag','torsdag','fredag','lördag'], + dayNamesShort: ['sön','mån','tis','ons','tor','fre','lör'], + dayNamesMin: ['Sö','Må','Ti','On','To','Fr','Lö'], + weekHeader: 'Ve', + dateFormat: 'yy-mm-dd', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['sv']); +});