1
|
/*! UIkit 2.27.1 | http://www.getuikit.com | (c) 2014 YOOtheme | MIT License */
|
2
|
// removed moment_js from core
|
3
|
// customized by tzd
|
4
|
|
5
|
(function(addon) {
|
6
|
|
7
|
var component;
|
8
|
|
9
|
if (window.UIkit) {
|
10
|
component = addon(UIkit);
|
11
|
}
|
12
|
|
13
|
if (typeof define == "function" && define.amd) {
|
14
|
define("uikit-datepicker", ["uikit"], function(){
|
15
|
return component || addon(UIkit);
|
16
|
});
|
17
|
}
|
18
|
|
19
|
})(function(UI){
|
20
|
|
21
|
"use strict";
|
22
|
|
23
|
// Datepicker
|
24
|
|
25
|
var active = false, dropdown;
|
26
|
|
27
|
UI.component('datepicker', {
|
28
|
|
29
|
defaults: {
|
30
|
mobile: false,
|
31
|
weekstart: 1,
|
32
|
i18n: {
|
33
|
months : ['January','February','March','April','May','June','July','August','September','October','November','December'],
|
34
|
weekdays : ['Sun','Mon','Tue','Wed','Thu','Fri','Sat']
|
35
|
},
|
36
|
format: "DD.MM.YYYY",
|
37
|
offsettop: 5,
|
38
|
maxDate: false,
|
39
|
minDate: false,
|
40
|
pos: 'auto',
|
41
|
addClass: '',
|
42
|
template: function(data, opts) {
|
43
|
|
44
|
var content = '', i;
|
45
|
|
46
|
content += '<div class="uk-datepicker-nav uk-clearfix">';
|
47
|
content += '<a href="" class="uk-datepicker-previous"></a>';
|
48
|
content += '<a href="" class="uk-datepicker-next"></a>';
|
49
|
|
50
|
if (UI.formSelect) {
|
51
|
|
52
|
var currentyear = (new Date()).getFullYear(), options = [], months, years, minYear, maxYear;
|
53
|
|
54
|
for (i=0;i<opts.i18n.months.length;i++) {
|
55
|
if(i==data.month) {
|
56
|
options.push('<option value="'+i+'" selected>'+opts.i18n.months[i]+'</option>');
|
57
|
} else {
|
58
|
options.push('<option value="'+i+'">'+opts.i18n.months[i]+'</option>');
|
59
|
}
|
60
|
}
|
61
|
|
62
|
months = '<span class="uk-form-select">'+ opts.i18n.months[data.month] + '<select class="update-picker-month">'+options.join('')+'</select></span>';
|
63
|
|
64
|
// --
|
65
|
|
66
|
options = [];
|
67
|
|
68
|
minYear = data.minDate ? data.minDate.year() : currentyear - 50;
|
69
|
maxYear = data.maxDate ? data.maxDate.year() : currentyear + 20;
|
70
|
|
71
|
for (i=minYear;i<=maxYear;i++) {
|
72
|
if (i == data.year) {
|
73
|
options.push('<option value="'+i+'" selected>'+i+'</option>');
|
74
|
} else {
|
75
|
options.push('<option value="'+i+'">'+i+'</option>');
|
76
|
}
|
77
|
}
|
78
|
|
79
|
years = '<span class="uk-form-select">'+ data.year + '<select class="update-picker-year">'+options.join('')+'</select></span>';
|
80
|
|
81
|
content += '<div class="uk-datepicker-heading">'+ months + ' ' + years +'</div>';
|
82
|
|
83
|
} else {
|
84
|
content += '<div class="uk-datepicker-heading">'+ opts.i18n.months[data.month] +' '+ data.year+'</div>';
|
85
|
}
|
86
|
|
87
|
content += '</div>';
|
88
|
|
89
|
content += '<table class="uk-datepicker-table">';
|
90
|
content += '<thead>';
|
91
|
for(i = 0; i < data.weekdays.length; i++) {
|
92
|
if (data.weekdays[i]) {
|
93
|
content += '<th>'+data.weekdays[i]+'</th>';
|
94
|
}
|
95
|
}
|
96
|
content += '</thead>';
|
97
|
|
98
|
content += '<tbody>';
|
99
|
for(i = 0; i < data.days.length; i++) {
|
100
|
if (data.days[i] && data.days[i].length){
|
101
|
content += '<tr>';
|
102
|
for(var d = 0; d < data.days[i].length; d++) {
|
103
|
if (data.days[i][d]) {
|
104
|
var day = data.days[i][d],
|
105
|
cls = [];
|
106
|
|
107
|
if(!day.inmonth) cls.push("uk-datepicker-table-muted");
|
108
|
if(day.selected) cls.push("uk-active");
|
109
|
if(day.disabled) cls.push('uk-datepicker-date-disabled uk-datepicker-table-muted');
|
110
|
|
111
|
content += '<td><a href="" class="'+cls.join(" ")+'" data-date="'+day.day.format()+'">'+day.day.format("D")+'</a></td>';
|
112
|
}
|
113
|
}
|
114
|
content += '</tr>';
|
115
|
}
|
116
|
}
|
117
|
content += '</tbody>';
|
118
|
|
119
|
content += '</table>';
|
120
|
|
121
|
return content;
|
122
|
}
|
123
|
},
|
124
|
|
125
|
boot: function() {
|
126
|
|
127
|
UI.$win.on("resize orientationchange", function() {
|
128
|
|
129
|
if (active) {
|
130
|
active.hide();
|
131
|
}
|
132
|
});
|
133
|
|
134
|
// init code
|
135
|
UI.$html.on("focus.datepicker.uikit", "[data-uk-datepicker]", function(e) {
|
136
|
|
137
|
var ele = UI.$(this);
|
138
|
|
139
|
if (!ele.data("datepicker")) {
|
140
|
e.preventDefault();
|
141
|
UI.datepicker(ele, UI.Utils.options(ele.attr("data-uk-datepicker")));
|
142
|
ele.trigger("focus");
|
143
|
}
|
144
|
});
|
145
|
|
146
|
UI.$html.on("click focus", '*', function(e) {
|
147
|
|
148
|
var target = UI.$(e.target);
|
149
|
|
150
|
if (active && target[0] != dropdown[0] && !target.data("datepicker") && !target.parents(".uk-datepicker:first").length) {
|
151
|
active.hide();
|
152
|
}
|
153
|
});
|
154
|
},
|
155
|
|
156
|
init: function() {
|
157
|
|
158
|
// use native datepicker on touch devices
|
159
|
if (UI.support.touch && this.element.attr('type')=='date' && !this.options.mobile) {
|
160
|
return;
|
161
|
}
|
162
|
|
163
|
var $this = this;
|
164
|
|
165
|
this.current = this.element.val() ? moment(this.element.val(), this.options.format) : moment();
|
166
|
|
167
|
this.on("click focus", function(){
|
168
|
if (active!==$this) $this.pick(this.value ? this.value:($this.options.minDate ? $this.options.minDate :''));
|
169
|
}).on("change", function(){
|
170
|
if ($this.element.val() && !moment($this.element.val(), $this.options.format).isValid()) {
|
171
|
$this.element.val(moment().format($this.options.format));
|
172
|
}
|
173
|
});
|
174
|
|
175
|
// init dropdown
|
176
|
if (!dropdown) {
|
177
|
|
178
|
dropdown = UI.$('<div class="uk-dropdown uk-datepicker '+$this.options.addClass+'"></div>');
|
179
|
|
180
|
dropdown.on("click", ".uk-datepicker-next, .uk-datepicker-previous, [data-date]", function(e){
|
181
|
|
182
|
e.stopPropagation();
|
183
|
e.preventDefault();
|
184
|
|
185
|
var ele = UI.$(this);
|
186
|
|
187
|
if (ele.hasClass('uk-datepicker-date-disabled')) return false;
|
188
|
|
189
|
if (ele.is('[data-date]')) {
|
190
|
active.current = moment(ele.data("date"));
|
191
|
active.element.val(active.current.isValid() ? active.current.format(active.options.format) : null).trigger("change");
|
192
|
dropdown.removeClass('uk-dropdown-shown');
|
193
|
setTimeout(function() {
|
194
|
dropdown.removeClass('uk-dropdown-active')
|
195
|
},280);
|
196
|
active.hide();
|
197
|
} else {
|
198
|
active.add((ele.hasClass("uk-datepicker-next") ? 1:-1), "months");
|
199
|
}
|
200
|
});
|
201
|
|
202
|
dropdown.on('change', '.update-picker-month, .update-picker-year', function(){
|
203
|
|
204
|
var select = UI.$(this);
|
205
|
active[select.is('.update-picker-year') ? 'setYear':'setMonth'](Number(select.val()));
|
206
|
});
|
207
|
|
208
|
dropdown.appendTo("body");
|
209
|
}
|
210
|
},
|
211
|
|
212
|
pick: function(initdate) {
|
213
|
|
214
|
var offset = this.element.offset(),
|
215
|
offset_left = parseInt(offset.left),
|
216
|
offset_top = parseInt(offset.top),
|
217
|
css = {
|
218
|
'left': offset_left,
|
219
|
'right': ""
|
220
|
};
|
221
|
|
222
|
this.current = isNaN(initdate) ? moment(initdate, this.options.format):moment();
|
223
|
this.initdate = this.current.format("YYYY-MM-DD");
|
224
|
|
225
|
this.update();
|
226
|
|
227
|
// check if datepicker input is in modal
|
228
|
if(($(this.element[0]).closest('.ui-dialog').length || $(this.element[0]).closest('.uk-modal').length) && !dropdown.hasClass('dropdown-modal')) {
|
229
|
dropdown.addClass('dropdown-modal');
|
230
|
}
|
231
|
|
232
|
if (UI.langdirection == 'right' || ( window.innerWidth - offset_left - dropdown.outerWidth() < 0 ) ) {
|
233
|
css.right = (window.innerWidth - (window.innerWidth - $('body').width())) - (css.left + this.element.outerWidth());
|
234
|
css.left = "";
|
235
|
}
|
236
|
|
237
|
var posTop = (offset_top - this.element.outerHeight() + this.element.height()) - this.options.offsettop - dropdown.outerHeight(),
|
238
|
posBottom = offset_top + this.element.outerHeight() + this.options.offsettop;
|
239
|
|
240
|
css.top = posBottom;
|
241
|
|
242
|
if (this.options.pos == 'top') {
|
243
|
css.top = posTop;
|
244
|
dropdown.addClass('dp-top');
|
245
|
} else if(this.options.pos == 'auto' && (window.innerHeight - posBottom - dropdown.outerHeight() + UI.$win.scrollTop() < 0 && posTop >= 0) ) {
|
246
|
css.top = posTop;
|
247
|
dropdown.addClass('dp-top');
|
248
|
}
|
249
|
|
250
|
css.minWidth = dropdown.actual('outerWidth');
|
251
|
|
252
|
dropdown.css(css).addClass('uk-dropdown-active uk-dropdown-shown');
|
253
|
|
254
|
|
255
|
this.trigger('show.uk.datepicker');
|
256
|
|
257
|
active = this;
|
258
|
},
|
259
|
|
260
|
add: function(unit, value) {
|
261
|
this.current.add(unit, value);
|
262
|
this.update();
|
263
|
},
|
264
|
|
265
|
setMonth: function(month) {
|
266
|
this.current.month(month);
|
267
|
this.update();
|
268
|
},
|
269
|
|
270
|
setYear: function(year) {
|
271
|
this.current.year(year);
|
272
|
this.update();
|
273
|
},
|
274
|
|
275
|
update: function() {
|
276
|
|
277
|
var data = this.getRows(this.current.year(), this.current.month()),
|
278
|
tpl = this.options.template(data, this.options);
|
279
|
|
280
|
dropdown.html(tpl);
|
281
|
|
282
|
this.trigger('update.uk.datepicker');
|
283
|
},
|
284
|
|
285
|
getRows: function(year, month) {
|
286
|
|
287
|
var opts = this.options,
|
288
|
now = moment().format('YYYY-MM-DD'),
|
289
|
days = [31, (year % 4 === 0 && year % 100 !== 0 || year % 400 === 0) ? 29 : 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][month],
|
290
|
before = new Date(year, month, 1, 12).getDay(),
|
291
|
data = {"month":month, "year":year,"weekdays":[],"days":[], "maxDate": false, "minDate": false},
|
292
|
row = [];
|
293
|
|
294
|
// We need these to be midday to avoid issues from DST transition protection.
|
295
|
if (opts.maxDate!==false){
|
296
|
data.maxDate = isNaN(opts.maxDate) ? moment(opts.maxDate, opts.format).startOf('day').hours(12) : moment().add(opts.maxDate, 'days').startOf('day').hours(12);
|
297
|
}
|
298
|
|
299
|
if (opts.minDate!==false){
|
300
|
data.minDate = isNaN(opts.minDate) ? moment(opts.minDate, opts.format).startOf('day').hours(12) : moment().add(opts.minDate-1, 'days').startOf('day').hours(12);
|
301
|
}
|
302
|
|
303
|
data.weekdays = (function(){
|
304
|
|
305
|
for (var i=0, arr=[]; i < 7; i++) {
|
306
|
|
307
|
var day = i + (opts.weekstart || 0);
|
308
|
|
309
|
while (day >= 7) {
|
310
|
day -= 7;
|
311
|
}
|
312
|
|
313
|
arr.push(opts.i18n.weekdays[day]);
|
314
|
}
|
315
|
|
316
|
return arr;
|
317
|
})();
|
318
|
|
319
|
if (opts.weekstart && opts.weekstart > 0) {
|
320
|
before -= opts.weekstart;
|
321
|
if (before < 0) {
|
322
|
before += 7;
|
323
|
}
|
324
|
}
|
325
|
|
326
|
var cells = days + before, after = cells;
|
327
|
|
328
|
while(after > 7) { after -= 7; }
|
329
|
|
330
|
cells += 7 - after;
|
331
|
|
332
|
var day, isDisabled, isSelected, isToday, isInMonth;
|
333
|
|
334
|
for (var i = 0, r = 0; i < cells; i++) {
|
335
|
|
336
|
day = new Date(year, month, 1 + (i - before), 12);
|
337
|
isDisabled = (data.minDate && data.minDate > day) || (data.maxDate && day > data.maxDate);
|
338
|
isInMonth = !(i < before || i >= (days + before));
|
339
|
|
340
|
day = moment(day);
|
341
|
|
342
|
isSelected = this.initdate == day.format("YYYY-MM-DD");
|
343
|
isToday = now == day.format("YYYY-MM-DD");
|
344
|
|
345
|
row.push({"selected": isSelected, "today": isToday, "disabled": isDisabled, "day":day, "inmonth":isInMonth});
|
346
|
|
347
|
if (++r === 7) {
|
348
|
data.days.push(row);
|
349
|
row = [];
|
350
|
r = 0;
|
351
|
}
|
352
|
}
|
353
|
|
354
|
return data;
|
355
|
},
|
356
|
|
357
|
hide: function() {
|
358
|
|
359
|
if (active && active === this) {
|
360
|
dropdown.removeClass('uk-dropdown-shown');
|
361
|
setTimeout(function() {
|
362
|
dropdown.removeClass('uk-dropdown-active dp-top')
|
363
|
},280);
|
364
|
active = false;
|
365
|
this.trigger('hide.uk.datepicker');
|
366
|
}
|
367
|
}
|
368
|
});
|
369
|
|
370
|
UI.Utils.moment = moment();
|
371
|
|
372
|
return UI.datepicker;
|
373
|
});
|