diff --git a/app/code/Magento/Ui/Component/Form/Element/DataType/Date.php b/app/code/Magento/Ui/Component/Form/Element/DataType/Date.php index 4bbde097b143d822ffa8159ff395c32798bee371..f384cdd3f9dd113815416218f8d428789fb52399 100644 --- a/app/code/Magento/Ui/Component/Form/Element/DataType/Date.php +++ b/app/code/Magento/Ui/Component/Form/Element/DataType/Date.php @@ -60,14 +60,29 @@ class Date extends AbstractDataType public function prepare() { $config = $this->getData('config'); + + if (!isset($config['timeOffset'])) { + $config['timeOffset'] = (new \DateTime( + 'now', + new \DateTimeZone( + $this->localeDate->getConfigTimezone() + ) + ))->getOffset(); + } + + if (!isset($config['timeFormat'])) { + $config['timeFormat'] = $this->localeDate->getTimeFormat(\IntlDateFormatter::SHORT); + } + if (!isset($config['dateFormat'])) { - $config['dateFormat'] = $this->localeDate->getDateTimeFormat(\IntlDateFormatter::MEDIUM); - $this->setData('config', $config); + $config['dateFormat'] = $this->localeDate->getDateFormat(\IntlDateFormatter::MEDIUM); } + + $this->setData('config', $config); + parent::prepare(); } - /** * Get locale * diff --git a/app/code/Magento/Ui/view/base/web/js/form/element/date.js b/app/code/Magento/Ui/view/base/web/js/form/element/date.js index 45d9048cf60b73861fd8b5be88fd2d0c1516ab96..f6b86377d6fd2fcd095b2c22ba4dd0802ad8a3d0 100644 --- a/app/code/Magento/Ui/view/base/web/js/form/element/date.js +++ b/app/code/Magento/Ui/view/base/web/js/form/element/date.js @@ -1,5 +1,5 @@ /** - * Copyright © 2016 Magento. All rights reserved. + * Copyright © 2015 Magento. All rights reserved. * See COPYING.txt for license details. */ define([ @@ -11,9 +11,60 @@ define([ return Abstract.extend({ defaults: { + options: {}, + + timeOffset: 0, + + showsTime: false, + + dateFormat: 'MM/dd/y', // ICU Date Format + timeFormat: 'HH:mm', // ICU Time Format + + /** + * Format of date that comes from the + * server (ICU Date Format). + * + * Used only in date picker mode + * (this.showsTime == false). + * + * @type {String} + */ + inputDateFormat: 'y-MM-dd', + + /** + * Format of date that should be sent to the + * server (ICU Date Format). + * + * Used only in date picker mode + * (this.showsTime == false). + * + * @type {String} + */ + outputDateFormat: 'MM/dd/y', + + /** + * Date/time format that is used to display date in + * the input field. + * + * @type {String} + */ + datetimeFormat: '', + elementTmpl: 'ui/form/element/date', - dateFormat: 'MM/dd/YYYY', - options: {} + + listens: { + 'value': 'onValueChange', + 'shiftedValue': 'onShiftedValueChange' + }, + + /** + * Date/time value shifted to corresponding timezone + * according to this.timeOffset property. This value + * will be sent to the server. + * + * @type {String} + */ + shiftedValue: '' }, /** @@ -23,24 +74,91 @@ define([ */ initConfig: function () { this._super(); - this.dateFormat = utils.normalizeDate(this.dateFormat); + + utils.extend(this.options, { + showsTime: this.showsTime, + timeFormat: this.timeFormat, + dateFormat: this.dateFormat + }); + + this.prepareDatetimeFormats(); return this; }, /** - * Formats provided value according to 'dateFormat' property. + * @inheritdoc + */ + initObservable: function () { + return this._super().observe(['shiftedValue']); + }, + + /** + * Prepares and sets date/time value that will be displayed + * in the input field. * - * @returns {String} + * @param {String} value */ - normalizeData: function () { - var value = this._super(); + onValueChange: function (value) { + var dateFormat, + shiftedValue; if (value) { - value = moment(value).format(this.dateFormat); + if (this.showsTime) { + shiftedValue = moment.utc(value).add(this.timeOffset, 'seconds'); + } else { + dateFormat = this.shiftedValue() ? this.outputDateFormat : this.inputDateFormat; + + shiftedValue = moment(value, dateFormat); + } + + shiftedValue = shiftedValue.format(this.datetimeFormat); + + if (shiftedValue !== this.shiftedValue()) { + this.shiftedValue(shiftedValue); + } + } + }, + + /** + * Prepares and sets date/time value that will be sent + * to the server. + * + * @param {String} shiftedValue + */ + onShiftedValueChange: function (shiftedValue) { + var value; + + if (shiftedValue) { + if (this.showsTime) { + value = moment.utc(shiftedValue, this.datetimeFormat); + value = value.subtract(this.timeOffset, 'seconds').toISOString(); + } else { + value = moment(shiftedValue, this.datetimeFormat); + value = value.format(this.outputDateFormat); + } + + if (value !== this.value()) { + this.value(value); + } + } + }, + + /** + * Prepares and converts all date/time formats to be compatible + * with moment.js library. + */ + prepareDatetimeFormats: function () { + this.datetimeFormat = this.dateFormat; + + if (this.showsTime) { + this.datetimeFormat += ' ' + this.timeFormat; } - return value; + this.datetimeFormat = utils.normalizeDate(this.datetimeFormat); + + this.inputDateFormat = utils.normalizeDate(this.inputDateFormat); + this.outputDateFormat = utils.normalizeDate(this.outputDateFormat); } }); }); diff --git a/app/code/Magento/Ui/view/base/web/templates/form/element/date.html b/app/code/Magento/Ui/view/base/web/templates/form/element/date.html index 1644c4d6c0da147f34f587bf203692efdd4dd269..542b81fb918f1900b8b61498cf0a8f64c23872e8 100644 --- a/app/code/Magento/Ui/view/base/web/templates/form/element/date.html +++ b/app/code/Magento/Ui/view/base/web/templates/form/element/date.html @@ -6,10 +6,10 @@ --> <input class="admin__control-text" type="text" data-bind=" hasFocus: focused, - datepicker: { storage: value, options: options }, + datepicker: { storage: shiftedValue, options: options }, valueUpdate: valueUpdate, attr: { - value: value, + value: shiftedValue, name: inputName, placeholder: placeholder, 'aria-describedby': noticeId,