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

Commit

Permalink
feat(calendar): Add date completion detection
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
Michael Chen authored and jelbourn committed Aug 13, 2015
1 parent b60bd35 commit d6457e2
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 7 deletions.
3 changes: 0 additions & 3 deletions src/components/datepicker/calendar.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,6 @@
]).directive('mdCalendar', calendarDirective);


// PRE RELEASE
// TODO(mchen): Date "isComplete" logic

// POST RELEASE
// TODO(jelbourn): Mac Cmd + left / right == Home / End
// TODO(jelbourn): Clicking on the month label opens the month-picker.
Expand Down
32 changes: 31 additions & 1 deletion src/components/datepicker/dateLocale.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,30 @@ describe('$mdDateLocale', function() {
var dateStr = '2014-03-25';
expect(dateLocale.parseDate(dateStr)).toEqual(jasmine.any(Date));
});

it('should have default date completion detection', function() {
// Valid dates.
expect(dateLocale.isDateComplete('04/05/15')).toBe(true);
expect(dateLocale.isDateComplete('04/05/2015')).toBe(true);
expect(dateLocale.isDateComplete('4/5/2015')).toBe(true);
expect(dateLocale.isDateComplete('2015 04 05')).toBe(true);
expect(dateLocale.isDateComplete('2015-04-05')).toBe(true);
expect(dateLocale.isDateComplete('2015,04,05')).toBe(true);
expect(dateLocale.isDateComplete('2015.04.05')).toBe(true);
expect(dateLocale.isDateComplete('April 5, 2015')).toBe(true);
expect(dateLocale.isDateComplete('April 5 2015')).toBe(true);
expect(dateLocale.isDateComplete('Apr 5, 2015')).toBe(true);
expect(dateLocale.isDateComplete('Apr 5 2015')).toBe(true);
expect(dateLocale.isDateComplete('2015 Apr 5')).toBe(true);

// Invalid dates.
expect(dateLocale.isDateComplete('5')).toBe(false);
expect(dateLocale.isDateComplete('4/5')).toBe(false);
expect(dateLocale.isDateComplete('04/05')).toBe(false);
expect(dateLocale.isDateComplete('Apr 5')).toBe(false);
expect(dateLocale.isDateComplete('April 5')).toBe(false);
expect(dateLocale.isDateComplete('April 5 200000')).toBe(false);
});
});

describe('with custom values', function() {
Expand All @@ -62,11 +86,14 @@ describe('$mdDateLocale', function() {
$mdDateLocaleProvider.shortDays = fakeShortDays;
$mdDateLocaleProvider.dates = fakeDates;
$mdDateLocaleProvider.formatDate = function() {
return 'Your birthday!'
return 'Your birthday!';
};
$mdDateLocaleProvider.parseDate = function() {
return new Date(1969, 6, 16);
};
$mdDateLocaleProvider.isDateComplete = function(dateString) {
return dateString === 'The One True Date';
};
}));


Expand All @@ -83,6 +110,9 @@ describe('$mdDateLocale', function() {
expect(dateLocale.dates).toEqual(fakeDates);
expect(dateLocale.formatDate(new Date())).toEqual('Your birthday!');
expect(dateLocale.parseDate('2020-01-20')).toEqual(new Date(1969, 6, 16));
expect(dateLocale.parseDate('2020-01-20')).toEqual(new Date(1969, 6, 16));
expect(dateLocale.isDateComplete('The One True Date')).toBe(true);
expect(dateLocale.isDateComplete('Anything Else')).toBe(false);
});
});
});
19 changes: 19 additions & 0 deletions src/components/datepicker/dateLocaleProvider.js
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,24 @@
return new Date(dateString);
}

/**
* Default function to determine whether a string makes sense to be
* parsed to a Date object.
*
* This is very permissive and is just a basic sanity check to ensure that
* things like single integers aren't able to be parsed into dates.
* @param {string} dateString
* @returns {boolean}
*/
function defaultIsDateComplete(dateString) {
dateString = dateString.trim();

// Looks for three chunks of content (either numbers or text) separated
// by delimiters.
var re = /^(([a-zA-Z]{3,}|[0-9]{1,4})([ \.,]+|[\/\-])){2}([a-zA-Z]{3,}|[0-9]{1,4})$/;
return re.test(dateString);
}

/**
* Default date-to-string formatter to get a month header.
* @param {!Date} date
Expand Down Expand Up @@ -198,6 +216,7 @@
dates: this.dates || defaultDates,
formatDate: this.formatDate || defaultFormatDate,
parseDate: this.parseDate || defaultParseDate,
isDateComplete: this.isDateComplete || defaultIsDateComplete,
monthHeaderFormatter: this.monthHeaderFormatter || defaultMonthHeaderFormatter,
weekNumberFormatter: this.weekNumberFormatter || defaultWeekNumberFormatter,
longDateFormatter: this.longDateFormatter || defaultLongDateFormatter,
Expand Down
4 changes: 1 addition & 3 deletions src/components/datepicker/datePicker.js
Original file line number Diff line number Diff line change
Expand Up @@ -212,9 +212,7 @@

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

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

0 comments on commit d6457e2

Please sign in to comment.