oxjs/source/Ox.UI/js/Form/DateInput.js

216 lines
7.7 KiB
JavaScript

'use strict';
/*@
Ox.DateInput <f> DateInput Element
([options[, self]]) -> <o:Ox.InputGroup> DateInput Element
options <o> Options object
format <s|short> format can be short, medium, long
value <d> date value, defaults to current date
weekday <b|false> weekday
width <o> width of individual input elements, in px
day <n> width of day input element
month <n> width of month input element
weekday <n> width of weekday input element
year <n> width of year input element
self <o> Shared private variable
change <!> triggered on change of value
@*/
Ox.DateInput = function(options, self) {
var that;
self = Ox.extend(self || {}, {
options: Ox.extend({
format: 'short',
value: Ox.formatDate(new Date(), '%F'),
weekday: false,
width: {
day: 32,
month: options && options.format == 'long' ? 80
: options && options.format == 'medium' ? 40 : 32,
weekday: options && options.format == 'long' ? 80 : 40,
year: 48
}
}, options || {})
});
self.formats = {
day: '%d',
month: self.options.format == 'short' ? '%m' :
(self.options.format == 'medium' ? '%b' : '%B'),
weekday: self.options.format == 'long' ? '%A' : '%a',
year: '%Y'
};
self.months = self.options.format == 'long' ? Ox.MONTHS : Ox.SHORT_MONTHS;
self.weekdays = self.options.format == 'long' ? Ox.WEEKDAYS : Ox.SHORT_WEEKDAYS;
self.$input = Ox.extend(self.options.weekday ? {
weekday: Ox.Input({
autocomplete: self.weekdays,
autocompleteReplace: true,
autocompleteReplaceCorrect: true,
id: 'weekday',
width: self.options.width.weekday
})
.bindEvent('autocomplete', changeWeekday)
} : {}, {
day: Ox.Input({
autocomplete: Ox.range(1, Ox.getDaysInMonth(
parseInt(Ox.formatDate(self.date, '%Y'), 10),
parseInt(Ox.formatDate(self.date, '%m'), 10)
) + 1).map(function(i) {
return self.options.format == 'short' ? Ox.pad(i, 2) : i.toString();
}),
autocompleteReplace: true,
autocompleteReplaceCorrect: true,
id: 'day',
textAlign: 'right',
width: self.options.width.day
})
.bindEvent('autocomplete', changeDay),
month: Ox.Input({
autocomplete: self.options.format == 'short' ? Ox.range(1, 13).map(function(i) {
return Ox.pad(i, 2);
}) : self.months,
autocompleteReplace: true,
autocompleteReplaceCorrect: true,
id: 'month',
textAlign: self.options.format == 'short' ? 'right' : 'left',
width: self.options.width.month
})
.bindEvent('autocomplete', changeMonthOrYear),
year: Ox.Input({
autocomplete: Ox.range(1900, 3000).concat(Ox.range(1000, 1900)).map(function(i) {
return i.toString();
}),
autocompleteReplace: true,
autocompleteReplaceCorrect: true,
id: 'year',
textAlign: 'right',
width: self.options.width.year
})
.bindEvent('autocomplete', changeMonthOrYear)
});
that = Ox.InputGroup(Ox.extend(self.options, {
id: self.options.id,
inputs: [].concat(self.options.weekday ? [
self.$input.weekday
] : [], self.options.format == 'short' ? [
self.$input.year, self.$input.month, self.$input.day
] : [
self.$input.month, self.$input.day, self.$input.year
]),
join: join,
separators: [].concat(self.options.weekday ? [
{title: self.options.format == 'short' ? '' : ',', width: 8},
] : [], self.options.format == 'short' ? [
{title: '-', width: 8}, {title: '-', width: 8}
] : [
{title: '', width: 8}, {title: ',', width: 8}
]),
split: split,
width: 0
}), self);
function changeDay() {
self.options.weekday && self.$input.weekday.value(
Ox.formatDate(new Date([
self.$input.month.value(),
self.$input.day.value(),
self.$input.year.value()
].join(' ')), self.formats.weekday)
);
self.options.value = join();
}
function changeMonthOrYear() {
var day = self.$input.day.value(),
month = self.$input.month.value(),
year = self.$input.year.value(),
days = Ox.getDaysInMonth(year, self.options.format == 'short' ? parseInt(month, 10) : month);
day = day <= days ? day : days;
//Ox.Log('Form', year, month, 'day days', day, days)
self.options.weekday && self.$input.weekday.value(
Ox.formatDate(
new Date([month, day, year].join(' ')),
self.formats.weekday
)
);
self.$input.day.options({
autocomplete: Ox.range(1, days + 1).map(function(i) {
return self.options.format == 'short' ? Ox.pad(i, 2) : i.toString();
}),
value: self.options.format == 'short' ? Ox.pad(parseInt(day, 10), 2) : day.toString()
});
self.options.value = join();
}
function changeWeekday() {
var date = getDateInWeek(
self.$input.weekday.value(),
self.$input.month.value(),
self.$input.day.value(),
self.$input.year.value()
);
self.$input.month.value(date.month);
self.$input.day.options({
autocomplete: Ox.range(1, Ox.getDaysInMonth(date.year, date.month) + 1).map(function(i) {
return self.options.format == 'short' ? Ox.pad(i, 2) : i.toString();
}),
value: date.day
});
self.$input.year.value(date.year);
self.options.value = join();
}
function getDate(value) {
return new Date(self.options.value.replace(/-/g, '/'));
}
function getDateInWeek(weekday, month, day, year) {
//Ox.Log('Form', [month, day, year].join(' '))
var date = new Date([month, day, year].join(' '));
date = Ox.getDateInWeek(date, weekday);
return {
day: Ox.formatDate(date, self.formats.day),
month: Ox.formatDate(date, self.formats.month),
year: Ox.formatDate(date, self.formats.year)
};
}
function getValues() {
var date = getDate();
return {
day: Ox.formatDate(date, self.formats.day),
month: Ox.formatDate(date, self.formats.month),
weekday: Ox.formatDate(date, self.formats.weekday),
year: Ox.formatDate(date, self.formats.year)
};
}
function join() {
return Ox.formatDate(new Date(self.options.format == 'short' ? [
self.$input.year.value(),
self.$input.month.value(),
self.$input.day.value()
].join('/') : [
self.$input.month.value(),
self.$input.day.value(),
self.$input.year.value()
].join(' ')), '%F');
}
function split() {
var values = getValues();
return [].concat(self.options.weekday ? [
values.weekday
] : [], self.options.format == 'short' ? [
values.year, values.month, values.day
] : [
values.month, values.day, values.year
]);
}
return that;
};