Skip to content
This repository was archived by the owner on Sep 5, 2024. It is now read-only.

Commit d6457e2

Browse files
Michael Chenjelbourn
authored andcommitted
feat(calendar): Add date completion detection
Provide (very) basic detection to see if a string contains enough information to be considered a date. Used to set the ngModel value when the input is being updated.
1 parent b60bd35 commit d6457e2

File tree

4 files changed

+51
-7
lines changed

4 files changed

+51
-7
lines changed

src/components/datepicker/calendar.js

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,6 @@
1313
]).directive('mdCalendar', calendarDirective);
1414

1515

16-
// PRE RELEASE
17-
// TODO(mchen): Date "isComplete" logic
18-
1916
// POST RELEASE
2017
// TODO(jelbourn): Mac Cmd + left / right == Home / End
2118
// TODO(jelbourn): Clicking on the month label opens the month-picker.

src/components/datepicker/dateLocale.spec.js

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,30 @@ describe('$mdDateLocale', function() {
4444
var dateStr = '2014-03-25';
4545
expect(dateLocale.parseDate(dateStr)).toEqual(jasmine.any(Date));
4646
});
47+
48+
it('should have default date completion detection', function() {
49+
// Valid dates.
50+
expect(dateLocale.isDateComplete('04/05/15')).toBe(true);
51+
expect(dateLocale.isDateComplete('04/05/2015')).toBe(true);
52+
expect(dateLocale.isDateComplete('4/5/2015')).toBe(true);
53+
expect(dateLocale.isDateComplete('2015 04 05')).toBe(true);
54+
expect(dateLocale.isDateComplete('2015-04-05')).toBe(true);
55+
expect(dateLocale.isDateComplete('2015,04,05')).toBe(true);
56+
expect(dateLocale.isDateComplete('2015.04.05')).toBe(true);
57+
expect(dateLocale.isDateComplete('April 5, 2015')).toBe(true);
58+
expect(dateLocale.isDateComplete('April 5 2015')).toBe(true);
59+
expect(dateLocale.isDateComplete('Apr 5, 2015')).toBe(true);
60+
expect(dateLocale.isDateComplete('Apr 5 2015')).toBe(true);
61+
expect(dateLocale.isDateComplete('2015 Apr 5')).toBe(true);
62+
63+
// Invalid dates.
64+
expect(dateLocale.isDateComplete('5')).toBe(false);
65+
expect(dateLocale.isDateComplete('4/5')).toBe(false);
66+
expect(dateLocale.isDateComplete('04/05')).toBe(false);
67+
expect(dateLocale.isDateComplete('Apr 5')).toBe(false);
68+
expect(dateLocale.isDateComplete('April 5')).toBe(false);
69+
expect(dateLocale.isDateComplete('April 5 200000')).toBe(false);
70+
});
4771
});
4872

4973
describe('with custom values', function() {
@@ -62,11 +86,14 @@ describe('$mdDateLocale', function() {
6286
$mdDateLocaleProvider.shortDays = fakeShortDays;
6387
$mdDateLocaleProvider.dates = fakeDates;
6488
$mdDateLocaleProvider.formatDate = function() {
65-
return 'Your birthday!'
89+
return 'Your birthday!';
6690
};
6791
$mdDateLocaleProvider.parseDate = function() {
6892
return new Date(1969, 6, 16);
6993
};
94+
$mdDateLocaleProvider.isDateComplete = function(dateString) {
95+
return dateString === 'The One True Date';
96+
};
7097
}));
7198

7299

@@ -83,6 +110,9 @@ describe('$mdDateLocale', function() {
83110
expect(dateLocale.dates).toEqual(fakeDates);
84111
expect(dateLocale.formatDate(new Date())).toEqual('Your birthday!');
85112
expect(dateLocale.parseDate('2020-01-20')).toEqual(new Date(1969, 6, 16));
113+
expect(dateLocale.parseDate('2020-01-20')).toEqual(new Date(1969, 6, 16));
114+
expect(dateLocale.isDateComplete('The One True Date')).toBe(true);
115+
expect(dateLocale.isDateComplete('Anything Else')).toBe(false);
86116
});
87117
});
88118
});

src/components/datepicker/dateLocaleProvider.js

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,24 @@
141141
return new Date(dateString);
142142
}
143143

144+
/**
145+
* Default function to determine whether a string makes sense to be
146+
* parsed to a Date object.
147+
*
148+
* This is very permissive and is just a basic sanity check to ensure that
149+
* things like single integers aren't able to be parsed into dates.
150+
* @param {string} dateString
151+
* @returns {boolean}
152+
*/
153+
function defaultIsDateComplete(dateString) {
154+
dateString = dateString.trim();
155+
156+
// Looks for three chunks of content (either numbers or text) separated
157+
// by delimiters.
158+
var re = /^(([a-zA-Z]{3,}|[0-9]{1,4})([ \.,]+|[\/\-])){2}([a-zA-Z]{3,}|[0-9]{1,4})$/;
159+
return re.test(dateString);
160+
}
161+
144162
/**
145163
* Default date-to-string formatter to get a month header.
146164
* @param {!Date} date
@@ -198,6 +216,7 @@
198216
dates: this.dates || defaultDates,
199217
formatDate: this.formatDate || defaultFormatDate,
200218
parseDate: this.parseDate || defaultParseDate,
219+
isDateComplete: this.isDateComplete || defaultIsDateComplete,
201220
monthHeaderFormatter: this.monthHeaderFormatter || defaultMonthHeaderFormatter,
202221
weekNumberFormatter: this.weekNumberFormatter || defaultWeekNumberFormatter,
203222
longDateFormatter: this.longDateFormatter || defaultLongDateFormatter,

src/components/datepicker/datePicker.js

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -212,9 +212,7 @@
212212

213213
self.inputElement.size = inputString.length + EXTRA_INPUT_SIZE;
214214

215-
if (self.dateUtil.isValidDate(parsedDate)) {
216-
// TODO(jelbourn): if we can detect here that `inputString` is a "complete" date,
217-
// set the ng-model value.
215+
if (self.dateUtil.isValidDate(parsedDate) && self.dateLocale.isDateComplete(inputString)) {
218216
self.date = parsedDate;
219217
self.$scope.$apply();
220218
}

0 commit comments

Comments
 (0)