Skip to content

Commit c60588a

Browse files
committed
Merge branch 'jacek-jaskolski-datetime_default_value'
2 parents 4db20a6 + 77fcaef commit c60588a

File tree

4 files changed

+114
-56
lines changed

4 files changed

+114
-56
lines changed

src/components/datetime/datetime.ts

Lines changed: 54 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -322,6 +322,14 @@ export class DateTime extends BaseInput<DateTimeData> implements AfterContentIni
322322
*/
323323
@Input() displayFormat: string;
324324

325+
/**
326+
* @input {string} The default datetime selected in picker modal if field value is empty.
327+
* Value must be a date string following the
328+
* [ISO 8601 datetime format standard](https://www.w3.org/TR/NOTE-datetime),
329+
* `1996-12-19`.
330+
*/
331+
@Input() initialValue: string;
332+
325333
/**
326334
* @input {string} The format of the date and time picker columns the user selects.
327335
* A datetime input can have one or many datetime parts, each getting their
@@ -550,11 +558,6 @@ export class DateTime extends BaseInput<DateTimeData> implements AfterContentIni
550558
* @hidden
551559
*/
552560
generate() {
553-
// If the date doesn't have a value yet, set it to now or the max value
554-
if (Object.keys(this._value).length === 0) {
555-
this._value = this.getDefaultValue();
556-
}
557-
558561
const picker = this._picker;
559562
// if a picker format wasn't provided, then fallback
560563
// to use the display format
@@ -605,7 +608,7 @@ export class DateTime extends BaseInput<DateTimeData> implements AfterContentIni
605608

606609
// cool, we've loaded up the columns with options
607610
// preselect the option for this column
608-
const optValue = getValueFromFormat(this.getValue(), format);
611+
const optValue = getValueFromFormat(this.getValueOrDefault(), format);
609612
const selectedIndex = column.options.findIndex(opt => opt.value === optValue);
610613
if (selectedIndex >= 0) {
611614
// set the select index for this column's options
@@ -781,6 +784,51 @@ export class DateTime extends BaseInput<DateTimeData> implements AfterContentIni
781784
return this._value;
782785
}
783786

787+
/**
788+
* @hidden
789+
*/
790+
getValueOrDefault(): DateTimeData {
791+
if (this.hasValue()) {
792+
return this._value;
793+
}
794+
795+
const initialDateString = this.getDefaultValueDateString();
796+
const _default = {};
797+
updateDate(_default, initialDateString);
798+
return _default;
799+
}
800+
801+
/**
802+
* Get the default value as a date string
803+
* @hidden
804+
*/
805+
getDefaultValueDateString() {
806+
if (this.initialValue) {
807+
return this.initialValue;
808+
}
809+
810+
const nowString = (new Date).toISOString();
811+
if (this.max) {
812+
const now = parseDate(nowString);
813+
const max = parseDate(this.max);
814+
815+
let v;
816+
for (let i in max) {
817+
v = (<any>max)[i];
818+
if (v === null) {
819+
(<any>max)[i] = (<any>now)[i];
820+
}
821+
}
822+
823+
const diff = compareDates(now, max);
824+
// If max is before current time, return max
825+
if (diff > 0) {
826+
return this.max;
827+
}
828+
}
829+
return nowString;
830+
}
831+
784832
/**
785833
* @hidden
786834
*/
@@ -844,25 +892,6 @@ export class DateTime extends BaseInput<DateTimeData> implements AfterContentIni
844892
}
845893
}
846894
}
847-
848-
/**
849-
* Get the default value to show when none is provided,
850-
* and within the bounds of the max value
851-
* @private
852-
*/
853-
getDefaultValue() {
854-
const now = parseDate((new Date).toISOString());
855-
if (this.max) {
856-
const max = parseDate(this.max);
857-
const diff = compareDates(now, max);
858-
859-
// If max is before current time, return max
860-
if (diff > 0) {
861-
return max;
862-
}
863-
}
864-
return now;
865-
}
866895
}
867896

868897
/**

src/components/datetime/test/basic/pages/root-page/root-page.html

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,12 @@
1616

1717
<ion-item>
1818
<ion-label>MM DD YY</ion-label>
19-
<ion-datetime displayFormat="MM DD YY" [(ngModel)]="placeholderDate" placeholder="Select Date"></ion-datetime>
19+
<ion-datetime pickerFormat="YYYY-MM-DDThh:mm" [(ngModel)]="placeholderDate" placeholder="Select Date"></ion-datetime>
20+
</ion-item>
21+
22+
<ion-item>
23+
<ion-label>MM DD YY</ion-label>
24+
<ion-datetime displayFormat="MM DD YY" [(ngModel)]="placeholderDate" placeholder="Select Date" initialValue="1987-10-19"></ion-datetime>
2025
</ion-item>
2126

2227
<ion-item>
@@ -77,6 +82,11 @@
7782
<ion-datetime monthValues="6,7,8" yearValues="2014,2015" dayValues="01,02,03,04,05,06,08,09,10, 11, 12, 13, 14" displayFormat="DD/MMM/YYYY" [(ngModel)]="specificDaysMonthsYears"></ion-datetime>
7883
</ion-item>
7984

85+
<ion-item>
86+
<ion-label>Default value</ion-label>
87+
<ion-datetime max="2100" pickerDefault="2017-08-06" [(ngModel)]="defaultValue"></ion-datetime>
88+
</ion-item>
89+
8090
<p aria-hidden="true" padding>
8191
<code>monthOnly: {{monthOnly}}</code><br>
8292
<code>wwwInvented: {{wwwInvented}}</code><br>
@@ -88,6 +98,7 @@
8898
<code>time: {{time}}</code><br>
8999
<code>Leap year, summer months: {{leapYearsSummerMonths}}</code><br>
90100
<code>Specific days/months/years: {{specificDaysMonthsYears}}</code><br>
101+
<code>Default value: {{defaultValue}}</code><br>
91102
</p>
92103

93104
<p>

src/components/datetime/test/basic/pages/root-page/root-page.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ export class RootPage {
1717
leapYearsSummerMonths = '';
1818
convertedDate = '';
1919
specificDaysMonthsYears = '';
20+
defaultValue: any;
2021

2122
leapYearsArray = [2020, 2016, 2008, 2004, 2000, 1996];
2223

src/components/datetime/test/datetime.spec.ts

Lines changed: 47 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -14,36 +14,6 @@ describe('DateTime', () => {
1414

1515
describe('validate', () => {
1616

17-
it('should default to now if no initial value or bounds supplied', () => {
18-
const now = datetimeUtil.parseDate(new Date().toISOString());
19-
datetime.generate();
20-
const val = datetime.getValue();
21-
expect(val.year).toEqual(now.year);
22-
expect(val.month).toEqual(now.month);
23-
expect(val.day).toEqual(now.day);
24-
expect(val.hour).toEqual(now.hour);
25-
expect(val.minute).toEqual(now.minute);
26-
});
27-
28-
it('should default to max if no initial value supplied but max specified and max before current', () => {
29-
datetime.max = '1987-10-19';
30-
datetime.generate();
31-
const val = datetime.getValue();
32-
expect(val.year).toEqual(1987);
33-
expect(val.month).toEqual(10);
34-
expect(val.day).toEqual(19);
35-
});
36-
37-
it('should default to current if no initial value supplied but max specified and max after current', () => {
38-
const now = datetimeUtil.parseDate(new Date().toISOString());
39-
datetime.max = '2100-10-19';
40-
datetime.generate();
41-
const val = datetime.getValue();
42-
expect(val.year).toEqual(now.year);
43-
expect(val.month).toEqual(now.month);
44-
expect(val.day).toEqual(now.day);
45-
});
46-
4717
it('should restrict January 1-14, 2000 from selection, then allow it, and restrict December 15-31, 2001', () => {
4818
datetime.max = '2001-12-15';
4919
datetime.min = '2000-01-15';
@@ -521,6 +491,53 @@ describe('DateTime', () => {
521491

522492
});
523493

494+
describe('defaultValue', () => {
495+
it('should default to now if no initial value or bounds supplied', () => {
496+
const now = datetimeUtil.parseDate(new Date().toISOString());
497+
datetime.pickerFormat = 'YYYY-MM-DDThh:mm';
498+
datetime.generate();
499+
var columns = picker.getColumns();
500+
expect(columns[0].options[columns[0].selectedIndex].value).toEqual(now.year);
501+
expect(columns[1].options[columns[1].selectedIndex].value).toEqual(now.month);
502+
expect(columns[2].options[columns[2].selectedIndex].value).toEqual(now.day);
503+
expect(columns[3].options[columns[3].selectedIndex].value).toEqual(now.hour % 12);
504+
expect(columns[4].options[columns[4].selectedIndex].value).toEqual(now.minute);
505+
});
506+
507+
it('should default to max if no initial value supplied but max specified and max before current', () => {
508+
datetime.max = '1987-10-19';
509+
datetime.generate();
510+
var columns = picker.getColumns();
511+
expect(columns[0].options[columns[0].selectedIndex].value).toEqual(10);
512+
expect(columns[1].options[columns[1].selectedIndex].value).toEqual(19);
513+
expect(columns[2].options[columns[2].selectedIndex].value).toEqual(1987);
514+
});
515+
516+
it('should default to current if no initial value supplied but max specified and max after current', () => {
517+
const now = datetimeUtil.parseDate(new Date().toISOString());
518+
datetime.max = '2100-10-19';
519+
datetime.generate();
520+
var columns = picker.getColumns();
521+
expect(columns[0].options[columns[0].selectedIndex].value).toEqual(now.month);
522+
expect(columns[1].options[columns[1].selectedIndex].value).toEqual(now.day);
523+
expect(columns[2].options[columns[2].selectedIndex].value).toEqual(now.year);
524+
});
525+
526+
it('should use pickerDefault if has no value', zoned(() => {
527+
datetime.max = '2100-12-31';
528+
datetime.pickerFormat = 'DD MMMM YYYY';
529+
datetime.initialValue = '2004-08-06';
530+
531+
datetime.generate();
532+
var columns = picker.getColumns();
533+
534+
expect(columns[0].options[columns[0].selectedIndex].value).toEqual(6);
535+
expect(columns[1].options[columns[1].selectedIndex].value).toEqual(8);
536+
expect(columns[2].options[columns[2].selectedIndex].value).toEqual(2004);
537+
}));
538+
539+
});
540+
524541
describe('setValue', () => {
525542

526543
it('should update existing time value with 12-hour PM DateTimeData value', zoned(() => {

0 commit comments

Comments
 (0)