Skip to content

Commit

Permalink
Merge branch 'pr/3032' into v0.3.x
Browse files Browse the repository at this point in the history
  • Loading branch information
JedWatson committed Jun 17, 2016
2 parents 0df560c + a5acd87 commit 8ec7878
Show file tree
Hide file tree
Showing 5 changed files with 63 additions and 40 deletions.
14 changes: 7 additions & 7 deletions fields/types/date/DateField.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,13 @@ module.exports = Field.create({

getInitialState: function() {
return {
value: this.props.value ? this.moment(this.props.value).format(this.props.formatString) : ''
value: this.props.value ? this.moment(this.props.value).format(this.props.dateFormat) : ''
};
},

getDefaultProps: function() {
return {
formatString: 'YYYY-MM-DD'
dateFormat: 'YYYY-MM-DD'
};
},

Expand All @@ -30,12 +30,12 @@ module.exports = Field.create({

// TODO: Move isValid() so we can share with server-side code
isValid: function(value) {
return moment(value, this.inputFormat).isValid();
return moment(value, this.props.dateFormat).isValid();
},

// TODO: Move format() so we can share with server-side code
format: function(dateValue, format) {
format = format || this.inputFormat;
format = format || this.props.dateFormat;
return dateValue ? this.moment(this.props.dateValue).format(format) : '';
},

Expand All @@ -48,7 +48,7 @@ module.exports = Field.create({
},

setToday: function() {
this.setDate(moment().format(this.props.formatString));
this.setDate(moment().format(this.props.dateFormat));
},

valueChanged: function(value) {
Expand All @@ -63,14 +63,14 @@ module.exports = Field.create({
if (this.shouldRenderField()) {
input = (
<div className={fieldClassName}>
<DateInput ref="dateInput" name={this.props.path} format={this.props.formatString} value={this.state.value} placeholder={this.props.placeholder} onChange={this.valueChanged} yearRange={this.props.yearRange} />
<DateInput ref="dateInput" name={this.props.path} format={this.props.dateFormat} value={this.state.value} placeholder={this.props.datePlaceholder} onChange={this.valueChanged} yearRange={this.props.yearRange} />
<button type="button" className="btn btn-default btn-set-today" onClick={this.setToday}>Today</button>
</div>
);
} else {
input = (
<div className={fieldClassName}>
<div className="field-value">{this.format(this.props.value, this.props.formatString)}</div>
<div className="field-value">{this.format(this.props.value, this.props.dateFormat)}</div>
</div>
);
}
Expand Down
18 changes: 9 additions & 9 deletions fields/types/date/DateType.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,13 @@ function date(list, path, options) {
this._nativeType = Date;
this._underscoreMethods = ['format', 'moment', 'parse'];
this._fixedSize = 'large';
this._properties = ['formatString', 'placeholder', 'yearRange', 'isUTC'];
this.parseFormatString = options.parseFormat || 'YYYY-MM-DD';
this.formatString = (options.format === false) ? false : (options.format || 'YYYY-MM-DD');
this.placeholder = this.formatString ? 'e.g. ' + moment().format(this.parseFormatString) : '';
this._properties = ['dateFormat', 'datePlaceholder', 'yearRange', 'isUTC'];
this.parseDateFormat = options.parseFormat || 'YYYY-MM-DD';
this.dateFormat = (options.format === false) ? false : (options.format || 'YYYY-MM-DD');
this.datePlaceholder = this.dateFormat ? 'e.g. ' + moment().format(this.parseDateFormat) : '';
this.yearRange = options.yearRange;
this.isUTC = options.utc || false;
if (this.formatString && 'string' !== typeof this.formatString) {
if (this.dateFormat && 'string' !== typeof this.dateFormat) {
throw new Error('FieldType.Date: options.format must be a string.');
}
date.super_.call(this, list, path, options);
Expand Down Expand Up @@ -62,8 +62,8 @@ date.prototype.addFilterToQuery = function(filter, query) {
* Formats the field value
*/
date.prototype.format = function(item, format) {
if (format || this.formatString) {
return item.get(this.path) ? this.moment(item).format(format || this.formatString) : '';
if (format || this.dateFormat) {
return item.get(this.path) ? this.moment(item).format(format || this.dateFormat) : '';
} else {
return item.get(this.path) || '';
}
Expand Down Expand Up @@ -94,7 +94,7 @@ date.prototype.parse = function(item) {
*/
date.prototype.validateInput = function(data, required, item) {
if (!(this.path in data) && item && item.get(this.path)) return true;
var newValue = moment(data[this.path], this.parseFormatString);
var newValue = moment(data[this.path], this.parseDateFormat);
if (required && (!newValue.isValid())) {
return false;
} else if (data[this.path] && newValue && !newValue.isValid()) {
Expand All @@ -112,7 +112,7 @@ date.prototype.updateItem = function(item, data) {
return;
}
var m = this.isUTC ? moment.utc : moment;
var newValue = m(data[this.path], this.parseFormatString);
var newValue = m(data[this.path], this.parseDateFormat);
if (newValue.isValid()) {
if (!item.get(this.path) || !newValue.isSame(item.get(this.path))) {
item.set(this.path, newValue.toDate());
Expand Down
6 changes: 3 additions & 3 deletions fields/types/date/test/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,13 @@ exports.testFieldType = function(List) {
it('should parse without error via underscore date', function() {
testItem._.date.parse('20131204', 'YYYYMMDD');
});

it('should be the date we expect', function() {
testItem.date = new Date(2013, 11, 4);
demand(testItem._.date.format()).to.equal('4th Dec 2013');
demand(testItem._.date.format()).to.equal('2013-12-04');
demand(testItem._.date.format('YYYYMMDD')).to.equal('20131204');
});

it('should be a moment object', function() {
testItem.date = new Date(2013, 11, 4);
demand(testItem._.date.moment()._isAMomentObject);
Expand Down
31 changes: 12 additions & 19 deletions fields/types/datetime/DatetimeField.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,28 +5,21 @@ var DateInput = require('../../components/DateInput');
var moment = require('moment');

module.exports = Field.create({

displayName: 'DatetimeField',

focusTargetRef: 'dateInput',

// default input formats
dateInputFormat: 'YYYY-MM-DD',
timeInputFormat: 'h:mm:ss a',

// 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'],

getInitialState: function() {
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.props.dateFormat) : '',
timeValue: this.props.value ? this.moment(this.props.value).format(this.props.timeFormat) : ''
};
},

getDefaultProps: function() {
return {
formatString: 'Do MMM YYYY, h:mm:ss a'
return {
formatString: 'YYYY-MM-DD, h:mm a'
};
},

Expand All @@ -38,18 +31,18 @@ module.exports = Field.create({

// TODO: Move isValid() so we can share with server-side code
isValid: function(value) {
return moment(value, this.parseFormats).isValid();
return moment(value, this.props.formatString).isValid();
},

// TODO: Move format() so we can share with server-side code
format: function(value, format) {
format = format || this.dateInputFormat + ' ' + this.timeInputFormat;
format = format || this.props.dateFormat + ' ' + this.props.timeFormat;
return value ? this.moment(value).format(format) : '';
},

handleChange: function(dateValue, timeValue) {
var value = dateValue + ' ' + timeValue;
var datetimeFormat = this.dateInputFormat + ' ' + this.timeInputFormat;
var datetimeFormat = this.props.dateFormat + ' ' + this.props.timeFormat;
this.props.onChange({
path: this.props.path,
value: this.isValid(value) ? moment(value, datetimeFormat).toISOString() : null
Expand All @@ -67,8 +60,8 @@ module.exports = Field.create({
},

setNow: function() {
var dateValue = moment().format(this.dateInputFormat);
var timeValue = moment().format(this.timeInputFormat);
var dateValue = moment().format(this.props.dateFormat);
var timeValue = moment().format(this.props.timeFormat);
this.setState({
dateValue: dateValue,
timeValue: timeValue
Expand All @@ -82,8 +75,8 @@ module.exports = Field.create({
if (this.shouldRenderField()) {
input = (
<div className={fieldClassName}>
<DateInput ref="dateInput" name={this.props.paths.date} value={this.state.dateValue} format={this.dateInputFormat} onChange={this.dateChanged} />
<input type="text" name={this.props.paths.time} value={this.state.timeValue} placeholder="HH:MM:SS am/pm" onChange={this.timeChanged} autoComplete="off" className="form-control time" />
<DateInput ref="dateInput" name={this.props.paths.date} value={this.state.dateValue} placeholder={this.props.datePlaceholder} format={this.props.dateFormat} onChange={this.dateChanged} />
<input type="text" name={this.props.paths.time} value={this.state.timeValue} placeholder={this.props.timePlaceholder} onChange={this.timeChanged} autoComplete="off" className="form-control time" />
<button type="button" className="btn btn-default btn-set-now" onClick={this.setNow}>Now</button>
</div>
);
Expand Down
34 changes: 32 additions & 2 deletions fields/types/datetime/DatetimeType.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ var moment = require('moment');
var DateType = require('../date/DateType');
var FieldType = require('../Type');
var util = require('util');
var _ = require('underscore');

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'];

Expand All @@ -14,10 +15,39 @@ function datetime(list, path, options) {
this._nativeType = Date;
this._underscoreMethods = ['format', 'moment', 'parse'];
this._fixedSize = 'large';
this._properties = ['formatString', 'isUTC'];
this._properties = ['formatString', 'dateFormat', 'timeFormat', 'datePlaceholder', 'timePlaceholder', 'isUTC'];
this.typeDescription = 'date and time';
this.parseFormatString = options.parseFormat || parseFormats;
this.formatString = (options.format === false) ? false : (options.format || 'YYYY-MM-DD h:mm:ss a');

// Create an array of moment time format characters to help find where the time portion of the format string beings
var timeOptions = ['h', 'H', 'm', 's', 'S'];
var timeIndex = -1;

var that = this;

if(this.formatString) {
// Loop through each moment time format character to determine which begins the time portion of format to segregate date from time
_.each(timeOptions, function(timeChar) {
var charIndex = that.formatString.indexOf(timeChar);

if((charIndex !== -1 && charIndex < timeIndex) || (charIndex !== -1 && timeIndex === -1)) {
timeIndex = charIndex;
}
});

this.dateFormat = this.formatString.slice(0, timeIndex).trim();
this.timeFormat = this.formatString.slice(timeIndex).trim();
this.datePlaceholder = 'e.g. ' + moment().format(this.dateFormat);
this.timePlaceholder = 'e.g. ' + moment().format(this.timeFormat);

} else {
this.dateFormat = '';
this.timeFormat = '';
this.datePlaceholder = '';
this.timePlaceholder = '';
}

this.isUTC = options.utc || false;
if (this.formatString && 'string' !== typeof this.formatString) {
throw new Error('FieldType.DateTime: options.format must be a string.');
Expand Down Expand Up @@ -71,7 +101,7 @@ datetime.prototype.updateItem = function(item, data) {
return;
}
var m = this.isUTC ? moment.utc : moment;
var newValue = m(this.getInputFromData(data), parseFormats);
var newValue = m(this.getInputFromData(data), this.formatString);
if (newValue.isValid()) {
if (!item.get(this.path) || !newValue.isSame(item.get(this.path))) {
item.set(this.path, newValue.toDate());
Expand Down

0 comments on commit 8ec7878

Please sign in to comment.