Skip to content

Instantly share code, notes, and snippets.

@fffergal
Forked from anonymous/gist:226040
Created November 4, 2009 16:16
Show Gist options
  • Save fffergal/226160 to your computer and use it in GitHub Desktop.
Save fffergal/226160 to your computer and use it in GitHub Desktop.
var DatePicker=Class.create({
_monthNames:['January','February','March','April','May','June','July','August','September','October','November','December'],
initialize:function() {
this._date=new Date();
this._userCallback=false;
this._monthRow=new Element('tr');
this._monthRow.insert(new Element('td',{style:'cursor:pointer;'}));
this._monthRow.insert(new Element('td',{colspan:5,style:'text-align:center;'}));
this._monthRow.insert(new Element('td',{style:'text-align:right; cursor:pointer;'}));
this._monthRow.select('td')[0].appendChild(document.createTextNode('<'));
this._monthRow.select('td')[1].appendChild(document.createTextNode(this._monthNames[this._date.getMonth()]));
this._monthRow.select('td')[2].appendChild(document.createTextNode('>'));
this._yearRow=new Element('tr');
this._yearRow.insert(new Element('td',{style:'cursor:pointer;'}));
this._yearRow.insert(new Element('td',{colspan:5,style:'text-align:center;'}));
this._yearRow.insert(new Element('td',{style:'text-align:right; cursor:pointer;'}));
this._yearRow.select('td')[0].appendChild(document.createTextNode('<'));
this._yearRow.select('td')[1].appendChild(document.createTextNode(this._date.getFullYear().toPaddedString(0)));
this._yearRow.select('td')[2].appendChild(document.createTextNode('>'));
this._pickerTable=new Element('table');
this._pickerTable.insert(new Element('tbody'));
this._pickerTable.down().insert(this._monthRow);
this._pickerTable.down().insert(new Element('tr'));
['S','M','T','W','T','F','S'].each(function(it) {
var newCell=new Element('td',{style:'text-align:center;'});
newCell.appendChild(document.createTextNode(it));
this._pickerTable.select('tr')[1].insert(newCell);
},this);
this._pickerTable.down().insert(new Element('tr'));
$R(1,7).each(function() {
var newCell=new Element('td',{style:'text-align:center;'});
newCell.appendChild(document.createTextNode('\xa0'));
this._pickerTable.select('tr')[2].insert(newCell);
},this);
$R(1,5).each(function() {
this._pickerTable.down().insert(this._pickerTable.select('tr')[2].clone(true));
},this);
this._pickerTable.down().insert(this._yearRow);
this._updateTable();
},
_daysInMonth:function() {
if (this._date.getMonth() == 0 || this._date.getMonth() == 2 || this._date.getMonth() == 4 || this._date.getMonth() == 6 || this._date.getMonth() == 7 || this._date.getMonth() == 9 || this._date.getMonth() == 11) {
return 31;
}
else if (this._date.getMonth() == 3 || this._date.getMonth() == 5 || this._date.getMonth() == 8 || this._date.getMonth() == 10) {
return 30;
}
else if (this._date.getMonth() == 1) {
if (new Date(this._date.getFullYear(),1,29).getDate() == 29) {
return 29;
}
else {
return 28;
}
}
},
_updateTable:function() {
if (this._userCallback) {
this._userCallback(this._date);
}
if (this._pickerTable.select('.highlighted')[0]) {
this._pickerTable.select('.highlighted')[0].removeClassName('highlighted');
}
this._monthRow.select('td')[1].replaceChild(document.createTextNode(this._monthNames[this._date.getMonth()]),this._monthRow.select('td')[1].firstChild);
this._yearRow.select('td')[1].replaceChild(document.createTextNode(this._date.getFullYear().toPaddedString(0)),this._yearRow.select('td')[1].firstChild);
$R(0,(new Date(this._date.getFullYear(),this._date.getMonth(),1)).getDay()-1).each(function(it) {
this._pickerTable.select('tr')[2].select('td')[it].replaceChild(document.createTextNode('\xa0'),this._pickerTable.select('tr')[2].select('td')[it].firstChild);
this._pickerTable.select('tr')[2].select('td')[it].setStyle({cursor:'auto'});
},this);
var col=(new Date(this._date.getFullYear(),this._date.getMonth(),1)).getDay();
var row=2;
var day=1;
while (day <= this._daysInMonth()) {
this._pickerTable.select('tr')[row].select('td')[col].replaceChild(document.createTextNode(day.toPaddedString(0)),this._pickerTable.select('tr')[row].select('td')[col].firstChild);
this._pickerTable.select('tr')[row].select('td')[col].setStyle({cursor:'pointer'});
if (day == this._date.getDate()) {
this._pickerTable.select('tr')[row].select('td')[col].addClassName('highlighted');
}
col++;
if (col == 7) {
col=0;
row++;
}
day++;
}
while (row < 8 && col < 7) {
this._pickerTable.select('tr')[row].select('td')[col].replaceChild(document.createTextNode('\xa0'),this._pickerTable.select('tr')[row].select('td')[col].firstChild);
this._pickerTable.select('tr')[row].select('td')[col].setStyle({cursor:'auto'});
col++;
if (col == 7) {
col=0;
row++;
}
}
},
_prevYear:function() {
this._date.setFullYear(this._date.getFullYear()-1);
this._updateTable();
},
_nextYear:function() {
this._date.setFullYear(this._date.getFullYear()+1);
this._updateTable();
},
_prevMonth:function() {
this._date.setMonth(this._date.getMonth()-1);
this._updateTable();
},
_nextMonth:function() {
this._date.setMonth(this._date.getMonth()+1);
this._updateTable();
},
_thisDay:function(instance) {
if (this.firstChild.nodeValue != '\xa0') {
instance._date.setDate(this.firstChild.nodeValue);
instance._updateTable();
}
},
beInserted:function(targetElement) {
$(targetElement).insert(this._pickerTable);
Event.observe(this._pickerTable.select('tr')[0].select('td')[0],'click',this._prevMonth.bind(this));
Event.observe(this._pickerTable.select('tr')[0].select('td')[2],'click',this._nextMonth.bind(this));
Event.observe(this._pickerTable.select('tr')[8].select('td')[0],'click',this._prevYear.bind(this));
Event.observe(this._pickerTable.select('tr')[8].select('td')[2],'click',this._nextYear.bind(this));
$R(2,7).each(function(row) {
$R(0,6).each(function(col) {
Event.observe(this._pickerTable.select('tr')[row].select('td')[col],'click',this._thisDay.curry(this));
},this);
},this);
return this._pickerTable;
},
changeCallback:function(callback) {
this._userCallback=callback;
this._userCallback(this._date);
}
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment