From f4f2e209782065796719a7926b130a9a5b4ca617 Mon Sep 17 00:00:00 2001 From: Gary Steinert Date: Fri, 29 Dec 2017 20:04:14 +0000 Subject: [PATCH 01/10] Partial Fix: Field type 'Datetime' - format customization missing #3160 Properties in DatetimeType were not being carried through to DatetimeField. Now resolved. format property replaced by dateFormat and timeFormat properties. Requires properly set parseFormat property (inclusing time zone format (Z) to function correctly. We should be able to calculate this based on the dateFormat and timeFormat properties and pass through form the Type to the Field. --- fields/types/datetime/DatetimeField.js | 30 +++++++++++++++++--------- fields/types/datetime/DatetimeType.js | 7 ++++-- 2 files changed, 25 insertions(+), 12 deletions(-) diff --git a/fields/types/datetime/DatetimeField.js b/fields/types/datetime/DatetimeField.js index 55d4b724c6..4e89ab7693 100644 --- a/fields/types/datetime/DatetimeField.js +++ b/fields/types/datetime/DatetimeField.js @@ -21,8 +21,8 @@ module.exports = Field.create({ focusTargetRef: 'dateInput', // default input formats - dateInputFormat: 'YYYY-MM-DD', - timeInputFormat: 'h:mm:ss a', + //dateInputFormat: 'YYYY-MM-DD', + //timeInputFormat: 'h:mm:ss a', tzOffsetInputFormat: 'Z', // parse formats (duplicated from lib/fieldTypes/datetime.js) @@ -30,15 +30,25 @@ module.exports = Field.create({ getInitialState () { return { - dateValue: this.props.value && this.moment(this.props.value).format(this.dateInputFormat), - timeValue: this.props.value && this.moment(this.props.value).format(this.timeInputFormat), + dateValue: this.props.value && this.moment(this.props.value).format(this.getDateInputFormat()), + timeValue: this.props.value && this.moment(this.props.value).format(this.getTimeInputFormat()), tzOffsetValue: this.props.value ? this.moment(this.props.value).format(this.tzOffsetInputFormat) : this.moment().format(this.tzOffsetInputFormat), }; }, + getDateInputFormat () { + return this.props.formatDateString; + }, + + getTimeInputFormat () { + return this.props.formatTimeString; + }, + getDefaultProps () { return { - formatString: 'Do MMM YYYY, h:mm:ss a', + //formatString: 'Do MMM YYYY, h:mm:ss a', + formatDateString: 'YYYY-MM-DD', + formatTimeString: 'h:mm:ss a', }; }, @@ -54,13 +64,13 @@ module.exports = Field.create({ // TODO: Move format() so we can share with server-side code format (value, format) { - format = format || this.dateInputFormat + ' ' + this.timeInputFormat; + format = format || this.getDateInputFormat() + ' ' + this.getTimeInputFormat(); return value ? this.moment(value).format(format) : ''; }, handleChange (dateValue, timeValue, tzOffsetValue) { var value = dateValue + ' ' + timeValue; - var datetimeFormat = this.dateInputFormat + ' ' + this.timeInputFormat; + var datetimeFormat = this.getDateInputFormat() + ' ' + this.getTimeInputFormat(); // if the change included a timezone offset, include that in the calculation (so NOW works correctly during DST changes) if (typeof tzOffsetValue !== 'undefined') { @@ -89,8 +99,8 @@ module.exports = Field.create({ }, setNow () { - var dateValue = this.moment().format(this.dateInputFormat); - var timeValue = this.moment().format(this.timeInputFormat); + var dateValue = this.moment().format(this.getDateInputFormat()); + var timeValue = this.moment().format(this.getTimeInputFormat()); var tzOffsetValue = this.moment().format(this.tzOffsetInputFormat); this.setState({ dateValue: dateValue, @@ -113,7 +123,7 @@ module.exports = Field.create({
Date: Sat, 30 Dec 2017 10:31:24 +0000 Subject: [PATCH 02/10] In DatetimeType, add tzFormat option to control timezone format string instead of hardcoding in DatetimeField. Updated validation for options to reflect change from format to dateFormat, timeFormat and tzFormat. --- fields/types/datetime/DatetimeField.js | 17 ++++++++--------- fields/types/datetime/DatetimeType.js | 13 ++++++++++--- 2 files changed, 18 insertions(+), 12 deletions(-) diff --git a/fields/types/datetime/DatetimeField.js b/fields/types/datetime/DatetimeField.js index 4e89ab7693..976dccaf45 100644 --- a/fields/types/datetime/DatetimeField.js +++ b/fields/types/datetime/DatetimeField.js @@ -20,11 +20,6 @@ module.exports = Field.create({ focusTargetRef: 'dateInput', - // default input formats - //dateInputFormat: 'YYYY-MM-DD', - //timeInputFormat: 'h:mm:ss a', - tzOffsetInputFormat: 'Z', - // parse formats (duplicated from lib/fieldTypes/datetime.js) parseFormats: ['YYYY-MM-DD', 'YYYY-MM-DD h:m:s a', 'YYYY-MM-DD h:m a', 'YYYY-MM-DD H:m:s', 'YYYY-MM-DD H:m'], @@ -32,7 +27,7 @@ module.exports = Field.create({ return { dateValue: this.props.value && this.moment(this.props.value).format(this.getDateInputFormat()), timeValue: this.props.value && this.moment(this.props.value).format(this.getTimeInputFormat()), - tzOffsetValue: this.props.value ? this.moment(this.props.value).format(this.tzOffsetInputFormat) : this.moment().format(this.tzOffsetInputFormat), + tzOffsetValue: this.props.value ? this.moment(this.props.value).format(this.getTzInputFormat()) : this.moment().format(this.getTzInputFormat()), }; }, @@ -44,6 +39,10 @@ module.exports = Field.create({ return this.props.formatTimeString; }, + getTzInputFormat () { + return this.props.formatTzString; + }, + getDefaultProps () { return { //formatString: 'Do MMM YYYY, h:mm:ss a', @@ -75,11 +74,11 @@ module.exports = Field.create({ // if the change included a timezone offset, include that in the calculation (so NOW works correctly during DST changes) if (typeof tzOffsetValue !== 'undefined') { value += ' ' + tzOffsetValue; - datetimeFormat += ' ' + this.tzOffsetInputFormat; + datetimeFormat += ' ' + this.getTzInputFormat(); } // if not, calculate the timezone offset based on the date (respect different DST values) else { - this.setState({ tzOffsetValue: this.moment(value, datetimeFormat).format(this.tzOffsetInputFormat) }); + this.setState({ tzOffsetValue: this.moment(value, datetimeFormat).format(this.getTzInputFormat()) }); } this.props.onChange({ @@ -101,7 +100,7 @@ module.exports = Field.create({ setNow () { var dateValue = this.moment().format(this.getDateInputFormat()); var timeValue = this.moment().format(this.getTimeInputFormat()); - var tzOffsetValue = this.moment().format(this.tzOffsetInputFormat); + var tzOffsetValue = this.moment().format(this.getTzInputFormat()); this.setState({ dateValue: dateValue, timeValue: timeValue, diff --git a/fields/types/datetime/DatetimeType.js b/fields/types/datetime/DatetimeType.js index e9223936e1..56c139a0ff 100644 --- a/fields/types/datetime/DatetimeType.js +++ b/fields/types/datetime/DatetimeType.js @@ -15,14 +15,21 @@ function datetime (list, path, options) { this._nativeType = Date; this._underscoreMethods = ['format', 'moment', 'parse']; this._fixedSize = 'full'; - this._properties = ['formatDateString', 'formatTimeString', 'isUTC']; + this._properties = ['formatDateString', 'formatTimeString', 'formatTzString', 'isUTC']; this.typeDescription = 'date and time'; this.parseFormatString = options.parseFormat || parseFormats; this.formatDateString = (options.dateFormat === false) ? false : (options.dateFormat || 'YYYY-MM-DD'); this.formatTimeString = (options.timeFormat === false) ? false : (options.timeFormat || 'h:mm:ss a'); + this.formatTzString = (options.tzFormat === false) ? false : (options.tzFormat || 'Z'); this.isUTC = options.utc || false; - if (this.formatString && typeof this.formatString !== 'string') { - throw new Error('FieldType.DateTime: options.format must be a string.'); + if (this.formatDateString && typeof this.formatDateString !== 'string') { + throw new Error('FieldType.DateTime: options.dateFormat must be a string.'); + } + if (this.formatTimeString && typeof this.formatTimeString !== 'string') { + throw new Error('FieldType.DateTime: options.timeFormat must be a string.'); + } + if (this.formatTzString && typeof this.formatTzString !== 'string') { + throw new Error('FieldType.DateTime: options.tzFormat must be a string.'); } datetime.super_.call(this, list, path, options); this.paths = { From 8d4962891d3992d1d6b534b75a601fbe5fe58a8a Mon Sep 17 00:00:00 2001 From: Gary Steinert Date: Sat, 30 Dec 2017 15:16:09 +0000 Subject: [PATCH 03/10] In DatetimeType, automatically calculate a parseFormat to suit the dateFormat, timeFormat and tzFormat specified. This removes the requirement for a parseFormat option to be specified. The parseFormat option is still available, and if supplied is appended along with the calculated format to the default list. --- fields/types/datetime/DatetimeType.js | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/fields/types/datetime/DatetimeType.js b/fields/types/datetime/DatetimeType.js index 56c139a0ff..70ac13b316 100644 --- a/fields/types/datetime/DatetimeType.js +++ b/fields/types/datetime/DatetimeType.js @@ -17,7 +17,7 @@ function datetime (list, path, options) { this._fixedSize = 'full'; this._properties = ['formatDateString', 'formatTimeString', 'formatTzString', 'isUTC']; this.typeDescription = 'date and time'; - this.parseFormatString = options.parseFormat || parseFormats; + this.parseFormatString = parseFormats; this.formatDateString = (options.dateFormat === false) ? false : (options.dateFormat || 'YYYY-MM-DD'); this.formatTimeString = (options.timeFormat === false) ? false : (options.timeFormat || 'h:mm:ss a'); this.formatTzString = (options.tzFormat === false) ? false : (options.tzFormat || 'Z'); @@ -31,6 +31,30 @@ function datetime (list, path, options) { if (this.formatTzString && typeof this.formatTzString !== 'string') { throw new Error('FieldType.DateTime: options.tzFormat must be a string.'); } + + //For backward compatibility, if parseFormat option is specified, add it to the parseFormatString array + if( this.options.parseFormat ) { + if( Array.isArray(this.options.parseFormat) ) { + this.parseFormatString = this.parseFormatString.concat(this.options.parseFormat); + } else if ( typeof this.options.parseFormat == 'string' ) { + this.parseFormatString.push(this.options.parseFormat); + } + } + + //If a custom format is specified by the user, it should be added to the parseFormatString array to ensure + //successful validation + if( this.formatDateString || this.formatTimeString || this.formatTzString ) { + let customFormat = []; + + if( this.formatDateString ) customFormat.push(this.formatDateString); + if( this.formatTimeString ) customFormat.push(this.formatTimeString); + if( this.formatTzString ) customFormat.push(this.formatTzString); + + this.parseFormatString.push(customFormat.join(' ')); + } + + this.parseFormatString = options.parseFormat || parseFormats; + datetime.super_.call(this, list, path, options); this.paths = { date: this.path + '_date', From 57f8b2abb124f45e5f36d57d7d03cc6a1a10f0af Mon Sep 17 00:00:00 2001 From: Gary Steinert Date: Sat, 30 Dec 2017 15:25:26 +0000 Subject: [PATCH 04/10] Update Datetime field docs. --- fields/types/datetime/Readme.md | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/fields/types/datetime/Readme.md b/fields/types/datetime/Readme.md index d408de5a87..026b9ef608 100644 --- a/fields/types/datetime/Readme.md +++ b/fields/types/datetime/Readme.md @@ -7,7 +7,8 @@ Internally uses [moment.js](http://momentjs.com/) to manage date parsing, format If the `utc` option is set, `moment(value).utc()` is called in all methods to enable moment's utc mode. -String parsing with moment will be done using the `parseFormat` option, which defaults to `"'YYYY-MM-DD h:m:s a'"`. +String parsing with moment will be done using the `dateFormat`, `timeFormat` and `tzFormat` options which default to +`'YYYY-MM-DD'`, `'h:mm:ss a'` and `'Z'` respectively. ## Example @@ -19,18 +20,33 @@ String parsing with moment will be done using the `parseFormat` option, which de * `parseFormat` `string` -The default pattern to read in values with. Defaults to an array of values to try: +The default pattern to read in values with. This pattern is added to the below array of default values along with the +format specified in the `dateFormat`, `timeFormat` and `tzFormat` options. + +This option option need only be specified if you require format(s) that don't appear below and don't match the display +format. `['YYYY-MM-DD', 'YYYY-MM-DD h:m:s a', 'YYYY-MM-DD h:m a', 'YYYY-MM-DD H:m:s', 'YYYY-MM-DD H:m', 'YYYY-MM-DD h:mm:s a Z', moment.ISO_8601]` +* `dateFormat` `string` + +The default format pattern to use when displaying the date portion of the value. Defaults to `YYYY-MM-DD` + +See the [momentjs format docs](http://momentjs.com/docs/#/displaying/format/) for information on the supported formats and options. + +* `timeFormat` `string` + +The default format pattern to use when displaying the time portion of the value. Defaults to `h:mm:ss a` + +See the [momentjs format docs](http://momentjs.com/docs/#/displaying/format/) for information on the supported formats and options. -* `format` `string` +* `dateFormat` `string` -The default format pattern to use when display the information. Defaults to `Do MMM YYYY hh:mm:ss a` +The default format pattern to use when displaying the timezone offset portion of the value. Defaults to `Z` See the [momentjs format docs](http://momentjs.com/docs/#/displaying/format/) for information on the supported formats and options. -`utc` `boolean` +* `utc` `boolean` Sets whether the string should be displayed in the admin UI in UTC time or local time. Defaults to `false`. From 9e9fed8d55b72c15a25f6c9227207509a7482666 Mon Sep 17 00:00:00 2001 From: Gary Steinert Date: Sat, 30 Dec 2017 15:31:55 +0000 Subject: [PATCH 05/10] Incorrect reference - change this.options to options --- fields/types/datetime/DatetimeType.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/fields/types/datetime/DatetimeType.js b/fields/types/datetime/DatetimeType.js index 70ac13b316..8c5a1eca63 100644 --- a/fields/types/datetime/DatetimeType.js +++ b/fields/types/datetime/DatetimeType.js @@ -33,11 +33,11 @@ function datetime (list, path, options) { } //For backward compatibility, if parseFormat option is specified, add it to the parseFormatString array - if( this.options.parseFormat ) { - if( Array.isArray(this.options.parseFormat) ) { - this.parseFormatString = this.parseFormatString.concat(this.options.parseFormat); - } else if ( typeof this.options.parseFormat == 'string' ) { - this.parseFormatString.push(this.options.parseFormat); + if( options.parseFormat ) { + if( Array.isArray(options.parseFormat) ) { + this.parseFormatString = this.parseFormatString.concat(options.parseFormat); + } else if ( typeof options.parseFormat == 'string' ) { + this.parseFormatString.push(options.parseFormat); } } From 8f36861bc2d78001eb0fcdbe6300e1cca3447a30 Mon Sep 17 00:00:00 2001 From: Gary Steinert Date: Sat, 30 Dec 2017 15:32:45 +0000 Subject: [PATCH 06/10] FIX: Field type 'Datetime' - format customization missing #3160 Placeholder for time field now displays correct format. --- fields/types/datetime/DatetimeField.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fields/types/datetime/DatetimeField.js b/fields/types/datetime/DatetimeField.js index 976dccaf45..7f50b1f611 100644 --- a/fields/types/datetime/DatetimeField.js +++ b/fields/types/datetime/DatetimeField.js @@ -134,7 +134,7 @@ module.exports = Field.create({ autoComplete="off" name={this.getInputName(this.props.paths.time)} onChange={this.timeChanged} - placeholder="HH:MM:SS am/pm" + placeholder={this.getTimeInputFormat()} value={this.state.timeValue} />
From b1efb934a1c47b75b0a184732b4d76a65f2fa692 Mon Sep 17 00:00:00 2001 From: Gary Steinert Date: Sun, 31 Dec 2017 09:15:23 +0000 Subject: [PATCH 07/10] Clone parseFormats array in DatetimeType. Failing to do so results in the same array being shared by all Datetime field instances. Fixed test 'should throw when format is not a string'. Now fails if exception is not thrown, rather than timing out. --- fields/types/datetime/DatetimeType.js | 2 +- fields/types/datetime/test/type.js | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/fields/types/datetime/DatetimeType.js b/fields/types/datetime/DatetimeType.js index 8c5a1eca63..838a7c584f 100644 --- a/fields/types/datetime/DatetimeType.js +++ b/fields/types/datetime/DatetimeType.js @@ -17,7 +17,7 @@ function datetime (list, path, options) { this._fixedSize = 'full'; this._properties = ['formatDateString', 'formatTimeString', 'formatTzString', 'isUTC']; this.typeDescription = 'date and time'; - this.parseFormatString = parseFormats; + this.parseFormatString = parseFormats.slice(0); this.formatDateString = (options.dateFormat === false) ? false : (options.dateFormat || 'YYYY-MM-DD'); this.formatTimeString = (options.timeFormat === false) ? false : (options.timeFormat || 'h:mm:ss a'); this.formatTzString = (options.tzFormat === false) ? false : (options.tzFormat || 'Z'); diff --git a/fields/types/datetime/test/type.js b/fields/types/datetime/test/type.js index 2d3fab7f12..995c02bc1a 100644 --- a/fields/types/datetime/test/type.js +++ b/fields/types/datetime/test/type.js @@ -23,6 +23,10 @@ exports.testFieldType = function (List) { List.add({ invalidFormatOption: { type: DatetimeType, format: /aregexp/ }, }); + + //If control reaches here, exception has not been thrown. Test failed. + demand(true).not.eql(true); + done(); } catch (err) { demand(err.message).eql('FieldType.DateTime: options.format must be a string.'); done(); From f6b1890af07f0f82e974cf021e37e5de4d30bbb7 Mon Sep 17 00:00:00 2001 From: Gary Steinert Date: Sun, 31 Dec 2017 09:18:23 +0000 Subject: [PATCH 08/10] Updated Datetime tests to reflect change of format to dateFormat, timeFormat and tzFormat. --- fields/types/datetime/test/type.js | 36 +++++++++++++++++++++++++++--- 1 file changed, 33 insertions(+), 3 deletions(-) diff --git a/fields/types/datetime/test/type.js b/fields/types/datetime/test/type.js index 995c02bc1a..cbb94ad234 100644 --- a/fields/types/datetime/test/type.js +++ b/fields/types/datetime/test/type.js @@ -18,17 +18,47 @@ exports.initList = function (List) { exports.testFieldType = function (List) { describe('invalid options', function () { - it('should throw when format is not a string', function (done) { + it('should throw when dateFormat is not a string', function (done) { try { List.add({ - invalidFormatOption: { type: DatetimeType, format: /aregexp/ }, + invalidFormatOption: { type: DatetimeType, dateFormat: /aregexp/ }, }); //If control reaches here, exception has not been thrown. Test failed. demand(true).not.eql(true); done(); } catch (err) { - demand(err.message).eql('FieldType.DateTime: options.format must be a string.'); + demand(err.message).eql('FieldType.DateTime: options.dateFormat must be a string.'); + done(); + } + }); + + it('should throw when timeFormat is not a string', function (done) { + try { + List.add({ + invalidFormatOption: { type: DatetimeType, timeFormat: /aregexp/ }, + }); + + //If control reaches here, exception has not been thrown. Test failed. + demand(true).not.eql(true); + done(); + } catch (err) { + demand(err.message).eql('FieldType.DateTime: options.timeFormat must be a string.'); + done(); + } + }); + + it('should throw when tzFormat is not a string', function (done) { + try { + List.add({ + invalidFormatOption: { type: DatetimeType, tzFormat: /aregexp/ }, + }); + + //If control reaches here, exception has not been thrown. Test failed. + demand(true).not.eql(true); + done(); + } catch (err) { + demand(err.message).eql('FieldType.DateTime: options.tzFormat must be a string.'); done(); } }); From 992f370ed60da092cb587528c6a2481e529fedd0 Mon Sep 17 00:00:00 2001 From: Gary Steinert Date: Sun, 31 Dec 2017 10:14:48 +0000 Subject: [PATCH 09/10] Added test to cover validation of a custom display format. Altered test for validation of the default format when a parseFormat is specified. Previously, if a parseFormat is specified, this became the only acceptable format, even if a different display format is defined. If the display format differs from the parse format, the field will not validate as populated from the database. Now, if a parseFormat (or formats, in an array) is specified it will be added to the list of acceptable formats (the default array plus the display format). --- fields/types/datetime/DatetimeType.js | 2 -- fields/types/datetime/test/type.js | 18 ++++++++++++++++-- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/fields/types/datetime/DatetimeType.js b/fields/types/datetime/DatetimeType.js index 838a7c584f..f2bbbdec9b 100644 --- a/fields/types/datetime/DatetimeType.js +++ b/fields/types/datetime/DatetimeType.js @@ -53,8 +53,6 @@ function datetime (list, path, options) { this.parseFormatString.push(customFormat.join(' ')); } - this.parseFormatString = options.parseFormat || parseFormats; - datetime.super_.call(this, list, path, options); this.paths = { date: this.path + '_date', diff --git a/fields/types/datetime/test/type.js b/fields/types/datetime/test/type.js index cbb94ad234..80d5b414a3 100644 --- a/fields/types/datetime/test/type.js +++ b/fields/types/datetime/test/type.js @@ -6,6 +6,11 @@ var DatetimeType = require('../DatetimeType'); exports.initList = function (List) { List.add({ datetime: DatetimeType, + customDisplayFormat: { + type: DatetimeType, + dateFormat: 'D MMM YYYY', + timeFormat: 'HH:mm', + }, customFormat: { type: DatetimeType, parseFormat: 'DD.MM.YY h:m a', @@ -203,6 +208,15 @@ exports.testFieldType = function (List) { }); }); + it('should validate a date time string in a custom format when a custom display format is specified', function (done) { + List.fields.customDisplayFormat.validateInput({ + customDisplayFormat: '20 Jan 2018 14:00 +00:00', + }, function (result) { + demand(result).be.true(); + done(); + }); + }); + it('should validate a date time string in a custom format when specified', function (done) { List.fields.customFormat.validateInput({ customFormat: '25.02.16 04:45 am', @@ -221,11 +235,11 @@ exports.testFieldType = function (List) { }); }); - it('should invalidate a date time string in the default format when a custom one is specified', function (done) { + it('should validate a date time string in the default format when a custom one is specified', function (done) { List.fields.customFormat.validateInput({ customFormat: '2016-02-25 04:45:00 am', }, function (result) { - demand(result).be.false(); + demand(result).be.true(); done(); }); }); From be45c0755d35ee20a4c561239f15477bad11fec4 Mon Sep 17 00:00:00 2001 From: Gary Steinert Date: Sun, 31 Dec 2017 10:30:24 +0000 Subject: [PATCH 10/10] Linting --- fields/types/datetime/DatetimeField.js | 1 - fields/types/datetime/DatetimeType.js | 27 +++++++++++++------------- fields/types/datetime/test/type.js | 6 +++--- 3 files changed, 17 insertions(+), 17 deletions(-) diff --git a/fields/types/datetime/DatetimeField.js b/fields/types/datetime/DatetimeField.js index 7f50b1f611..cb22c08ea1 100644 --- a/fields/types/datetime/DatetimeField.js +++ b/fields/types/datetime/DatetimeField.js @@ -45,7 +45,6 @@ module.exports = Field.create({ getDefaultProps () { return { - //formatString: 'Do MMM YYYY, h:mm:ss a', formatDateString: 'YYYY-MM-DD', formatTimeString: 'h:mm:ss a', }; diff --git a/fields/types/datetime/DatetimeType.js b/fields/types/datetime/DatetimeType.js index f2bbbdec9b..d1e1058b87 100644 --- a/fields/types/datetime/DatetimeType.js +++ b/fields/types/datetime/DatetimeType.js @@ -6,6 +6,7 @@ var utils = require('keystone-utils'); // ISO_8601 is needed for the automatically created createdAt and updatedAt fields var parseFormats = ['YYYY-MM-DD', 'YYYY-MM-DD h:m:s a', 'YYYY-MM-DD h:m a', 'YYYY-MM-DD H:m:s', 'YYYY-MM-DD H:m', 'YYYY-MM-DD h:mm:s a Z', moment.ISO_8601]; + /** * DateTime FieldType Constructor * @extends Field @@ -20,7 +21,7 @@ function datetime (list, path, options) { this.parseFormatString = parseFormats.slice(0); this.formatDateString = (options.dateFormat === false) ? false : (options.dateFormat || 'YYYY-MM-DD'); this.formatTimeString = (options.timeFormat === false) ? false : (options.timeFormat || 'h:mm:ss a'); - this.formatTzString = (options.tzFormat === false) ? false : (options.tzFormat || 'Z'); + this.formatTzString = (options.tzFormat === false) ? false : (options.tzFormat || 'Z'); this.isUTC = options.utc || false; if (this.formatDateString && typeof this.formatDateString !== 'string') { throw new Error('FieldType.DateTime: options.dateFormat must be a string.'); @@ -32,23 +33,23 @@ function datetime (list, path, options) { throw new Error('FieldType.DateTime: options.tzFormat must be a string.'); } - //For backward compatibility, if parseFormat option is specified, add it to the parseFormatString array - if( options.parseFormat ) { - if( Array.isArray(options.parseFormat) ) { + // For backward compatibility, if parseFormat option is specified, add it to the parseFormatString array + if (options.parseFormat) { + if (Array.isArray(options.parseFormat)) { this.parseFormatString = this.parseFormatString.concat(options.parseFormat); - } else if ( typeof options.parseFormat == 'string' ) { + } else if (typeof options.parseFormat === 'string') { this.parseFormatString.push(options.parseFormat); } } - //If a custom format is specified by the user, it should be added to the parseFormatString array to ensure - //successful validation - if( this.formatDateString || this.formatTimeString || this.formatTzString ) { + // If a custom format is specified by the user, it should be added to the parseFormatString array to ensure + // successful validation + if (this.formatDateString || this.formatTimeString || this.formatTzString) { let customFormat = []; - if( this.formatDateString ) customFormat.push(this.formatDateString); - if( this.formatTimeString ) customFormat.push(this.formatTimeString); - if( this.formatTzString ) customFormat.push(this.formatTzString); + if (this.formatDateString) customFormat.push(this.formatDateString); + if (this.formatTimeString) customFormat.push(this.formatTimeString); + if (this.formatTzString) customFormat.push(this.formatTzString); this.parseFormatString.push(customFormat.join(' ')); } @@ -60,6 +61,7 @@ function datetime (list, path, options) { tzOffset: this.path + '_tzOffset', }; } + datetime.properName = 'Datetime'; util.inherits(datetime, FieldType); @@ -87,7 +89,6 @@ datetime.prototype.getInputFromData = function (data) { return this.getValueFromData(data); }; - datetime.prototype.validateRequiredInput = function (item, data, callback) { var value = this.getInputFromData(data); var result = !!value; @@ -146,7 +147,7 @@ datetime.prototype.updateItem = function (item, data, callback) { if (!item.get(this.path) || !newValue.isSame(item.get(this.path))) { item.set(this.path, newValue.toDate()); } - // If it's null or empty string, clear it out + // If it's null or empty string, clear it out } else { item.set(this.path, null); } diff --git a/fields/types/datetime/test/type.js b/fields/types/datetime/test/type.js index 80d5b414a3..062733c62a 100644 --- a/fields/types/datetime/test/type.js +++ b/fields/types/datetime/test/type.js @@ -29,7 +29,7 @@ exports.testFieldType = function (List) { invalidFormatOption: { type: DatetimeType, dateFormat: /aregexp/ }, }); - //If control reaches here, exception has not been thrown. Test failed. + // If control reaches here, exception has not been thrown. Test failed. demand(true).not.eql(true); done(); } catch (err) { @@ -44,7 +44,7 @@ exports.testFieldType = function (List) { invalidFormatOption: { type: DatetimeType, timeFormat: /aregexp/ }, }); - //If control reaches here, exception has not been thrown. Test failed. + // If control reaches here, exception has not been thrown. Test failed. demand(true).not.eql(true); done(); } catch (err) { @@ -59,7 +59,7 @@ exports.testFieldType = function (List) { invalidFormatOption: { type: DatetimeType, tzFormat: /aregexp/ }, }); - //If control reaches here, exception has not been thrown. Test failed. + // If control reaches here, exception has not been thrown. Test failed. demand(true).not.eql(true); done(); } catch (err) {