Skip to content

Instantly share code, notes, and snippets.

@nathanborror
Created September 21, 2009 05:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nathanborror/190091 to your computer and use it in GitHub Desktop.
Save nathanborror/190091 to your computer and use it in GitHub Desktop.
/**
* DatePicker
* @author Rick Hopkins
* @modified Micah Nolte, Martin Vaina, Nathan Borror
* @version 1.0
* @classDescription A date picker object for user with MooTools 1.2
* MIT-style License.
*
* Example:
* new DatePicker('date_input');
*/
var DatePicker = new Class({
Implements: [Events, Options],
options: {
onShow: function(dp) {
dp.setStyle('display', 'block');
},
onHide: function(dp) {
dp.setStyle('display', 'none');
},
prefix: 'date_picker',
month_names: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],
days_in_month: [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31],
day_names: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'],
format: 'mm/dd/yyyy',
year_start: new Date().getFullYear(),
year_range: 10,
year_order: 'asc',
offsets: {'x': 0, 'y': 0},
delay: 500
},
initialize: function(field, options) {
this.field = $(field);
if (!this.field) return false;
this.setOptions(options);
this.active = false;
if (this.field.value.length > 9) {
switch (this.options.format) {
case 'mm/dd/yyyy':
d = this.field.value.split('/');
this.year = d[2].toInt();
this.month = d[0].toInt() - 1;
this.day = d[1].toInt();
break;
case 'yyyy-mm-dd':
d = this.field.value.split('-');
this.year = d[0].toInt();
this.month = d[1].toInt() - 1;
this.day = d[2].toInt();
break;
case 'yyyy.mm.dd':
d = this.field.value.split('.');
this.year = d[0].toInt();
this.month = d[1].toInt() - 1;
this.day = d[2].toInt();
break;
case 'mm.dd.yyyy':
d = this.field.value.split('.');
this.year = d[2].toInt();
this.month = d[0].toInt() - 1;
this.day = d[1].toInt();
break;
default:
d = new Date();
this.year = d.getFullYear();
this.month = d.getMonth();
this.day = d.getDate();
break;
}
}
else {
var d = new Date();
this.year = d.getFullYear();
this.month = d.getMonth();
this.day = d.getDate();
}
this.container = new Element('div', {
'class': this.options.prefix,
'styles': {
'position': 'absolute',
'top': '0px',
'left': '0px',
'display': 'none',
'z-index': '1000'
},
'events': {
'mouseover': function() { $clear(this.timer); }.bind(this)
}
}).inject(document.body);
this.setup();
},
setup: function() {
this.field.addEvent('click', function() {
this.position();
this.build();
}.bind(this));
var destroy = this.destroy.bind(this);
this.container.addEvent('mouseleave', destroy);
},
// build calendar
build: function() {
this.container.empty();
var date = new Date();
date.setFullYear(this.year, this.month, 1);
this.year % 4 == 0 ? this.options.days_in_month[1] = 29 : this.options.days_in_month[1] = 28;
var first_day = 1 - date.getDay();
// create month select box
var month_select = new Element('select', {
'class': this.options.prefix + '_month_select'
});
for (var m = 0; m < this.options.month_names.length; m++) {
month_select.options[m] = new Option(this.options.month_names[m], m);
if (this.month == m) month_select.options[m].selected = true;
}
// create year select box
var year_select = new Element('select', {'class':this.options.prefix + '_year_select'});
i = 0;
if (this.options.year_order == 'desc') {
for (var y = this.options.year_start; y > (this.options.year_start - this.options.year_range - 1); y--) {
year_select.options[i] = new Option(y, y);
if (this.year == y) year_select.options[i].selected = true;
i++;
}
}
else {
for (var y = this.options.year_start; y < (this.options.year_start + this.options.year_range + 1); y++) {
year_select.options[i] = new Option(y, y);
if (this.year == y) year_select.options[i].selected = true;
i++;
}
}
// start creating calendar
var cal_table = new Element('table', {
'styles': {'width':'100%'}
}).inject(this.container);
var cal_table_body = new Element('tbody').inject(cal_table);
new Element('tr').adopt(new Element('td', {
'class': 'nav',
'styles': {'text-align':'center'},
'colspan':'7'
}).adopt(month_select).adopt(year_select)).inject(cal_table_body);
// create day names
var cal_day_name_row = new Element('tr').inject(cal_table_body);
for (var i = 0; i < this.options.day_names.length; i++) {
new Element('th', {
'class':'day_name',
'styles': {
'text-align': 'center',
'width': '14%'
},
'text': this.options.day_names[i].substr(0, 1)
}).inject(cal_day_name_row);
}
// create day cells
date2 = new Date();
while (first_day <= this.options.days_in_month[this.month]) {
cal_day_row = new Element('tr').inject(cal_table_body);
for (i = 0; i < 7; i++) {
if ((first_day <= this.options.days_in_month[this.month]) && (first_day > 0)) {
var cal_day_cell = new Element('td', {
'class':'day',
'styles': {
'cursor':'pointer',
'text-align':'center'
},
'axis': this.year + '-' + (this.month + 1) + '-' + first_day,
'text': first_day
}).inject(cal_day_row);
if (date2.getFullYear() == this.year && date2.getMonth() == this.month && date2.getDate() == first_day) {
cal_day_cell.addClass('current');
}
}
else {
new Element('td', {
'class':'empty',
'text': ' '
}).inject(cal_day_row);
}
first_day++;
}
}
// set onclick events for all calendar days
$$('.'+this.options.prefix+' td.day').each(function(d) {
d.onclick = function() {
ds = d.axis.split('-');
this.field.value = this.formatValue(ds[0], ds[1], ds[2]);
this.hide();
}.bind(this);
}.bind(this));
// set onchange event for month and year select boxes
month_select.onfocus = function() {
this.active = true;
}.bind(this);
month_select.onblur = function() {
this.active = false;
}.bind(this);
month_select.onchange = function() {
this.month = month_select.value.toInt();
this.year = year_select.value.toInt();
this.active = false;
this.build(this.field);
}.bind(this);
year_select.onfocus = function() {
this.active = true;
}.bind(this);
year_select.onblur = function() {
this.active = false;
}.bind(this);
year_select.onchange = function() {
this.month = month_select.value.toInt();
this.year = year_select.value.toInt();
this.active = false;
this.build(this.field);
}.bind(this);
this.show();
},
// destroy calendar
destroy: function(event) {
$clear(this.timer);
this.timer = this.hide.delay(this.options.delay, this);
},
// position calendar
position: function() {
this.coords = this.field.getCoordinates();
this.container.setStyles({
'top': (this.coords.top + this.coords.height + this.options.offsets.y) + 'px',
'left': (this.coords.left + this.options.offsets.x) + 'px',
'width': this.coords.width + 'px',
});
},
// show calendar
show: function() {
this.fireEvent('onShow', [this.container]);
},
// hide calendar
hide: function() {
if (!this.active) this.fireEvent('onHide', [this.container]);
},
// format returning date value
formatValue: function(year, month, day) {
// setup date string variable
var dateStr = '';
// check length of day
if (day < 10) day = '0' + day;
if (month < 10) month = '0' + month;
// check format and replace parts
var date_str = this.options.format.replace( /dd/i, day ).replace( /mm/i, month ).replace( /yyyy/i, year );
this.month = month.toInt() - 1;
this.year = year.toInt();
// return date string value
return date_str;
}
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment