Skip to content
This repository was archived by the owner on May 29, 2019. It is now read-only.

Commit c3b1431

Browse files
committedFeb 1, 2016
fix(datepicker): fix validation for M! & d!
- Fix display & validation for M! & d! Closes #5376 Fixes #5225
1 parent 48c9cd8 commit c3b1431

File tree

3 files changed

+384
-40
lines changed

3 files changed

+384
-40
lines changed
 

Diff for: ‎src/dateparser/dateparser.js

+129-34
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
angular.module('ui.bootstrap.dateparser', [])
22

3-
.service('uibDateParser', ['$log', '$locale', 'orderByFilter', function($log, $locale, orderByFilter) {
3+
.service('uibDateParser', ['$log', '$locale', 'dateFilter', 'orderByFilter', function($log, $locale, dateFilter, orderByFilter) {
44
// Pulled from https://github.com/mbostock/d3/blob/master/src/format/requote.js
55
var SPECIAL_CHARACTERS_REGEXP = /[\\\^\$\*\+\?\|\[\]\(\)\.\{\}]/g;
66

@@ -11,115 +11,164 @@ angular.module('ui.bootstrap.dateparser', [])
1111
localeId = $locale.id;
1212

1313
this.parsers = {};
14+
this.formatters = {};
1415

1516
formatCodeToRegex = [
1617
{
1718
key: 'yyyy',
1819
regex: '\\d{4}',
19-
apply: function(value) { this.year = +value; }
20+
apply: function(value) { this.year = +value; },
21+
formatter: function(date) {
22+
var _date = new Date();
23+
_date.setFullYear(Math.abs(date.getFullYear()));
24+
return dateFilter(_date, 'yyyy');
25+
}
2026
},
2127
{
2228
key: 'yy',
2329
regex: '\\d{2}',
24-
apply: function(value) { this.year = +value + 2000; }
30+
apply: function(value) { this.year = +value + 2000; },
31+
formatter: function(date) {
32+
var _date = new Date();
33+
_date.setFullYear(Math.abs(date.getFullYear()));
34+
return dateFilter(_date, 'yy');
35+
}
2536
},
2637
{
2738
key: 'y',
2839
regex: '\\d{1,4}',
29-
apply: function(value) { this.year = +value; }
40+
apply: function(value) { this.year = +value; },
41+
formatter: function(date) {
42+
var _date = new Date();
43+
_date.setFullYear(Math.abs(date.getFullYear()));
44+
return dateFilter(_date, 'y');
45+
}
3046
},
3147
{
3248
key: 'M!',
3349
regex: '0?[1-9]|1[0-2]',
34-
apply: function(value) { this.month = value - 1; }
50+
apply: function(value) { this.month = value - 1; },
51+
formatter: function(date) {
52+
var value = date.getMonth();
53+
if (/^[0-9]$/.test(value)) {
54+
return dateFilter(date, 'MM');
55+
}
56+
57+
return dateFilter(date, 'M');
58+
}
3559
},
3660
{
3761
key: 'MMMM',
3862
regex: $locale.DATETIME_FORMATS.MONTH.join('|'),
39-
apply: function(value) { this.month = $locale.DATETIME_FORMATS.MONTH.indexOf(value); }
63+
apply: function(value) { this.month = $locale.DATETIME_FORMATS.MONTH.indexOf(value); },
64+
formatter: function(date) { return dateFilter(date, 'MMMM'); }
4065
},
4166
{
4267
key: 'MMM',
4368
regex: $locale.DATETIME_FORMATS.SHORTMONTH.join('|'),
44-
apply: function(value) { this.month = $locale.DATETIME_FORMATS.SHORTMONTH.indexOf(value); }
69+
apply: function(value) { this.month = $locale.DATETIME_FORMATS.SHORTMONTH.indexOf(value); },
70+
formatter: function(date) { return dateFilter(date, 'MMM'); }
4571
},
4672
{
4773
key: 'MM',
4874
regex: '0[1-9]|1[0-2]',
49-
apply: function(value) { this.month = value - 1; }
75+
apply: function(value) { this.month = value - 1; },
76+
formatter: function(date) { return dateFilter(date, 'MM'); }
5077
},
5178
{
5279
key: 'M',
5380
regex: '[1-9]|1[0-2]',
54-
apply: function(value) { this.month = value - 1; }
81+
apply: function(value) { this.month = value - 1; },
82+
formatter: function(date) { return dateFilter(date, 'M'); }
5583
},
5684
{
5785
key: 'd!',
5886
regex: '[0-2]?[0-9]{1}|3[0-1]{1}',
59-
apply: function(value) { this.date = +value; }
87+
apply: function(value) { this.date = +value; },
88+
formatter: function(date) {
89+
var value = date.getDate();
90+
if (/^[1-9]$/.test(value)) {
91+
return dateFilter(date, 'dd');
92+
}
93+
94+
return dateFilter(date, 'd');
95+
}
6096
},
6197
{
6298
key: 'dd',
6399
regex: '[0-2][0-9]{1}|3[0-1]{1}',
64-
apply: function(value) { this.date = +value; }
100+
apply: function(value) { this.date = +value; },
101+
formatter: function(date) { return dateFilter(date, 'dd'); }
65102
},
66103
{
67104
key: 'd',
68105
regex: '[1-2]?[0-9]{1}|3[0-1]{1}',
69-
apply: function(value) { this.date = +value; }
106+
apply: function(value) { this.date = +value; },
107+
formatter: function(date) { return dateFilter(date, 'd'); }
70108
},
71109
{
72110
key: 'EEEE',
73-
regex: $locale.DATETIME_FORMATS.DAY.join('|')
111+
regex: $locale.DATETIME_FORMATS.DAY.join('|'),
112+
formatter: function(date) { return dateFilter(date, 'EEEE'); }
74113
},
75114
{
76115
key: 'EEE',
77-
regex: $locale.DATETIME_FORMATS.SHORTDAY.join('|')
116+
regex: $locale.DATETIME_FORMATS.SHORTDAY.join('|'),
117+
formatter: function(date) { return dateFilter(date, 'EEE'); }
78118
},
79119
{
80120
key: 'HH',
81121
regex: '(?:0|1)[0-9]|2[0-3]',
82-
apply: function(value) { this.hours = +value; }
122+
apply: function(value) { this.hours = +value; },
123+
formatter: function(date) { return dateFilter(date, 'HH'); }
83124
},
84125
{
85126
key: 'hh',
86127
regex: '0[0-9]|1[0-2]',
87-
apply: function(value) { this.hours = +value; }
128+
apply: function(value) { this.hours = +value; },
129+
formatter: function(date) { return dateFilter(date, 'hh'); }
88130
},
89131
{
90132
key: 'H',
91133
regex: '1?[0-9]|2[0-3]',
92-
apply: function(value) { this.hours = +value; }
134+
apply: function(value) { this.hours = +value; },
135+
formatter: function(date) { return dateFilter(date, 'H'); }
93136
},
94137
{
95138
key: 'h',
96139
regex: '[0-9]|1[0-2]',
97-
apply: function(value) { this.hours = +value; }
140+
apply: function(value) { this.hours = +value; },
141+
formatter: function(date) { return dateFilter(date, 'h'); }
98142
},
99143
{
100144
key: 'mm',
101145
regex: '[0-5][0-9]',
102-
apply: function(value) { this.minutes = +value; }
146+
apply: function(value) { this.minutes = +value; },
147+
formatter: function(date) { return dateFilter(date, 'mm'); }
103148
},
104149
{
105150
key: 'm',
106151
regex: '[0-9]|[1-5][0-9]',
107-
apply: function(value) { this.minutes = +value; }
152+
apply: function(value) { this.minutes = +value; },
153+
formatter: function(date) { return dateFilter(date, 'm'); }
108154
},
109155
{
110156
key: 'sss',
111157
regex: '[0-9][0-9][0-9]',
112-
apply: function(value) { this.milliseconds = +value; }
158+
apply: function(value) { this.milliseconds = +value; },
159+
formatter: function(date) { return dateFilter(date, 'sss'); }
113160
},
114161
{
115162
key: 'ss',
116163
regex: '[0-5][0-9]',
117-
apply: function(value) { this.seconds = +value; }
164+
apply: function(value) { this.seconds = +value; },
165+
formatter: function(date) { return dateFilter(date, 'ss'); }
118166
},
119167
{
120168
key: 's',
121169
regex: '[0-9]|[1-5][0-9]',
122-
apply: function(value) { this.seconds = +value; }
170+
apply: function(value) { this.seconds = +value; },
171+
formatter: function(date) { return dateFilter(date, 's'); }
123172
},
124173
{
125174
key: 'a',
@@ -132,7 +181,8 @@ angular.module('ui.bootstrap.dateparser', [])
132181
if (value === 'PM') {
133182
this.hours += 12;
134183
}
135-
}
184+
},
185+
formatter: function(date) { return dateFilter(date, 'a'); }
136186
},
137187
{
138188
key: 'Z',
@@ -144,38 +194,47 @@ angular.module('ui.bootstrap.dateparser', [])
144194
minutes = matches[3];
145195
this.hours += toInt(sign + hours);
146196
this.minutes += toInt(sign + minutes);
197+
},
198+
formatter: function(date) {
199+
return dateFilter(date, 'Z');
147200
}
148201
},
149202
{
150203
key: 'ww',
151-
regex: '[0-4][0-9]|5[0-3]'
204+
regex: '[0-4][0-9]|5[0-3]',
205+
formatter: function(date) { return dateFilter(date, 'ww'); }
152206
},
153207
{
154208
key: 'w',
155-
regex: '[0-9]|[1-4][0-9]|5[0-3]'
209+
regex: '[0-9]|[1-4][0-9]|5[0-3]',
210+
formatter: function(date) { return dateFilter(date, 'w'); }
156211
},
157212
{
158213
key: 'GGGG',
159-
regex: $locale.DATETIME_FORMATS.ERANAMES.join('|').replace(/\s/g, '\\s')
214+
regex: $locale.DATETIME_FORMATS.ERANAMES.join('|').replace(/\s/g, '\\s'),
215+
formatter: function(date) { return dateFilter(date, 'GGGG'); }
160216
},
161217
{
162218
key: 'GGG',
163-
regex: $locale.DATETIME_FORMATS.ERAS.join('|')
219+
regex: $locale.DATETIME_FORMATS.ERAS.join('|'),
220+
formatter: function(date) { return dateFilter(date, 'GGG'); }
164221
},
165222
{
166223
key: 'GG',
167-
regex: $locale.DATETIME_FORMATS.ERAS.join('|')
224+
regex: $locale.DATETIME_FORMATS.ERAS.join('|'),
225+
formatter: function(date) { return dateFilter(date, 'GG'); }
168226
},
169227
{
170228
key: 'G',
171-
regex: $locale.DATETIME_FORMATS.ERAS.join('|')
229+
regex: $locale.DATETIME_FORMATS.ERAS.join('|'),
230+
formatter: function(date) { return dateFilter(date, 'G'); }
172231
}
173232
];
174233
};
175234

176235
this.init();
177236

178-
function createParser(format) {
237+
function createParser(format, func) {
179238
var map = [], regex = format.split('');
180239

181240
// check for literal values
@@ -223,7 +282,8 @@ angular.module('ui.bootstrap.dateparser', [])
223282

224283
map.push({
225284
index: index,
226-
apply: data.apply,
285+
key: data.key,
286+
apply: data[func],
227287
matcher: data.regex
228288
});
229289
}
@@ -235,6 +295,41 @@ angular.module('ui.bootstrap.dateparser', [])
235295
};
236296
}
237297

298+
this.filter = function(date, format) {
299+
if (!angular.isDate(date) || isNaN(date) || !format) {
300+
return '';
301+
}
302+
303+
format = $locale.DATETIME_FORMATS[format] || format;
304+
305+
if ($locale.id !== localeId) {
306+
this.init();
307+
}
308+
309+
if (!this.formatters[format]) {
310+
this.formatters[format] = createParser(format, 'formatter');
311+
}
312+
313+
var parser = this.formatters[format],
314+
map = parser.map;
315+
316+
var _format = format;
317+
318+
return map.reduce(function(str, mapper, i) {
319+
var match = _format.match(new RegExp('(.*)' + mapper.key));
320+
if (match && angular.isString(match[1])) {
321+
str += match[1];
322+
_format = _format.replace(match[1] + mapper.key, '');
323+
}
324+
325+
if (mapper.apply) {
326+
return str + mapper.apply.call(null, date);
327+
}
328+
329+
return str;
330+
}, '');
331+
};
332+
238333
this.parse = function(input, format, baseDate) {
239334
if (!angular.isString(input) || !format) {
240335
return input;
@@ -248,7 +343,7 @@ angular.module('ui.bootstrap.dateparser', [])
248343
}
249344

250345
if (!this.parsers[format]) {
251-
this.parsers[format] = createParser(format);
346+
this.parsers[format] = createParser(format, 'apply');
252347
}
253348

254349
var parser = this.parsers[format],
@@ -336,7 +431,7 @@ angular.module('ui.bootstrap.dateparser', [])
336431
this.timezoneToOffset = timezoneToOffset;
337432
this.addDateMinutes = addDateMinutes;
338433
this.convertTimezoneToLocal = convertTimezoneToLocal;
339-
434+
340435
function toTimezone(date, timezone) {
341436
return date && timezone ? convertTimezoneToLocal(date, timezone) : date;
342437
}

0 commit comments

Comments
 (0)
This repository has been archived.