CGI-WebToolkit
view release on metacpan or search on metacpan
t/private/javascripts/datepicker.js view on Meta::CPAN
/*
* Control.DatePicker
*
* Transforms an ordinary input textbox into an interactive date picker.
* When the textbox is clicked (or the down arrow is pressed), a calendar
* appears that the user can browse through and select a date.
*
* Features:
* - Allows user to specify a date format
* - Easy to localize
* - Customizable by CSS
*
* Written and maintained by Jeremy Jongsma (jeremy@jongsma.org)
*/
if (window.Control == undefined) Control = {};
Control.DatePicker = Class.create();
Control.DatePicker.activePicker = null;
Control.DatePicker.prototype = {
initialize: function(element, options) {
this.element = $(element);
this.i18n = new Control.DatePicker.i18n(options && options.locale ? options.locale : 'en_US');
options = this.i18n.inheritOptions(options);
options = Object.extend({
datePicker: true,
timePicker: false
}, options || {});
this.handlers = { onClick: options.onClick,
onHover: options.onHover,
onSelect: options.onSelect };
this.options = Object.extend(options || {}, {
onClick: this.pickerClicked.bind(this),
onHover: this.dateHover.bind(this),
onSelect: this.datePicked.bind(this)
});
if (this.options.timePicker && this.options.datePicker)
this.options.currentFormat = this.options.dateTimeFormat;
else if (this.options.timePicker)
this.options.currentFormat = this.options.timeFormat;
else
this.options.currentFormat = this.options.dateFormat;
// this.options.currentFormat = this.options.timePicker ? this.options.dateTimeFormat : this.options.dateFormat;
this.options.date = DateFormat.parseFormat(this.element.value, this.options.currentFormat);
// Lazy load to avoid excessive CPU usage with lots of controls on one page
this.datepicker = null;
this.originalValue = null;
this.hideTimeout = null;
if (this.options.icon) {
var cont = new Element('div', {'style': 'position: relative;'});
this.element.parentNode.replaceChild(cont, this.element);
cont.appendChild(this.element);
this.icon = new Element('img', {'src': this.options.icon, 'title': this.tr('Open calendar'), 'className': 'inputExtension'});
var padding = this.options.padding;
if (!padding) {
// No icon padding specified, default to 3px and calculate
// dynamically on image load
padding = 3;
Event.observe(this.icon, 'load', function() {
padding = parseInt(this.element.offsetHeight - this.icon.offsetHeight) / 2;
var right = (this.element.offsetParent.offsetWidth - (this.element.offsetLeft + this.element.offsetWidth) + padding) + 'px';
Element.setStyle(this.icon, {'right': right, 'top': padding + 'px'});
}.bind(this));
}
var right = (this.element.offsetParent.offsetWidth - (this.element.offsetLeft + this.element.offsetWidth) + padding) + 'px';
Element.setStyle(this.icon, {'position': 'absolute', 'right': right, 'top': padding + 'px'});
cont.appendChild(this.icon);
Event.observe(this.icon, 'click', this.togglePicker.bindAsEventListener(this));
} else {
Event.observe(this.element, 'click', this.togglePicker.bindAsEventListener(this));
}
this.hidePickerListener = this.delayedHide.bindAsEventListener(this);
Event.observe(this.element, 'keydown', this.keyHandler.bindAsEventListener(this));
Event.observe(document, 'keydown', this.docKeyHandler.bindAsEventListener(this));
this.pickerActive = false;
},
tr: function(str) {
return this.i18n.tr(str);
},
delayedHide: function(e) {
this.hideTimeout = setTimeout(this.hide.bind(this), 100);
},
pickerClicked: function() {
if (this.hideTimeout) {
clearTimeout(this.hideTimeout);
this.hideTimeout = null;
}
if (this.handlers.onClick)
this.handlers.onClick();
},
datePicked: function(date) {
this.element.value = DateFormat.format(date, this.options.currentFormat);
this.element.focus();
this.hide();
if (this.handlers.onSelect)
this.handlers.onSelect(date);
if (this.element.onchange)
this.element.onchange();
},
dateHover: function(date) {
if (this.hideTimeout) {
clearTimeout(this.hideTimeout);
this.hideTimeout = null;
}
if (this.pickerActive) {
this.element.value = DateFormat.format(date, this.options.currentFormat);
if (this.handlers.onHover)
this.handlers.onHover(date);
}
},
togglePicker: function(e) {
if (this.pickerActive) {
this.element.value = this.originalValue;
this.hide();
} else {
this.show();
}
Event.stop(e);
return false;
},
docKeyHandler: function(e) {
if (e.keyCode == Event.KEY_ESC)
if (this.pickerActive) {
this.element.value = this.originalValue;
this.hide();
}
},
keyHandler: function(e) {
switch (e.keyCode) {
case Event.KEY_ESC:
if (this.pickerActive)
this.element.value = this.originalValue;
case Event.KEY_TAB:
this.hide();
return;
case Event.KEY_DOWN:
if (!this.pickerActive) {
this.show();
Event.stop(e);
}
}
if (this.pickerActive)
return false;
},
hide: function() {
if(this.pickerActive && !this.element.disabled) {
this.datepicker.releaseKeys();
Element.remove(this.datepicker.element);
Event.stopObserving(document, 'click', this.hidePickerListener, true);
this.pickerActive = false;
Control.DatePicker.activePicker = null;
}
},
show: function () {
if (!this.pickerActive) {
if (Control.DatePicker.activePicker)
Control.DatePicker.activePicker.hide();
this.element.focus();
if (!this.datepicker)
this.datepicker = new Control.DatePickerPanel(this.options);
this.originalValue = this.element.value;
var pos = Position.positionedOffset(this.element);
t/private/javascripts/datepicker.js view on Meta::CPAN
cell.width = '14%';
cell.innerHTML = (j*6)+i+(this.options.use24hrs?0:1);
cell.onclick = this.hourClickedListener((j*6)+i+(this.options.use24hrs?0:1));
this.hourCells[(j*6)+i] = cell;
}
if (!this.options.use24hrs) {
cell = row.insertCell(i);
cell.className = 'ampm';
cell.width = '14%';
if (j) {
cell.innerHTML = this.tr('PM');
cell.onclick = this.pmClickedListener();
this.pmCell = cell;
} else {
cell.innerHTML = this.tr('AM');
cell.onclick = this.amClickedListener();
this.amCell = cell;
}
}
}
row = timeTable.insertRow(rows++);
cell = row.insertCell(0);
cell.colSpan = 6;
var hr = document.createElement('hr');
Element.setStyle(hr, {'color': '#CCCCCC', 'backgroundColor': '#CCCCCC', 'height': '1px', 'border': '0', 'marginTop': '2px', 'marginBottom': '2px', 'padding': '0'});
cell.appendChild(hr);
cell = row.insertCell(1);
for (var j = 0; j < (10/this.minInterval); ++j) {
row = timeTable.insertRow(rows++);
for (var i = 0; i < 6; ++i){
cell = row.insertCell(i);
cell.className = 'minute';
cell.width = '14%';
var minval = ((j*6+i)*this.minInterval);
if (minval < 10) minval = '0'+minval;
cell.innerHTML = ':'+minval;
cell.onclick = this.minuteClickedListener(minval);
this.minuteCells[(j*6)+i] = cell;
}
if (!this.options.use24hrs) {
cell = row.insertCell(i);
cell.width = '14%';
}
}
row = timeTable.insertRow(rows++);
cell = row.insertCell(0);
cell.style.textAlign = 'right';
cell.colSpan = 5;
cell.innerHTML = '<i>'+this.tr('Exact minutes')+':</i>';
cell = row.insertCell(1);
cell.className = 'otherminute';
var otherInput = document.createElement('input');
otherInput.type = 'text';
otherInput.maxLength = 2;
otherInput.style.width = '2em';
var inputTimeout = null;
otherInput.onkeyup = function(e) {
if (!isNaN(otherInput.value)) {
this.currentDate.setMinutes(otherInput.value);
this.dateChanged(this.currentDate);
}
}.bindAsEventListener(this);
otherInput.onkeydown = function(e) {
if (e.keyCode == Event.KEY_RETURN)
if (this.options.onSelect) this.options.onSelect(this.currentDate);
}.bindAsEventListener(this);
// Remove event key capture to allow use of arrow keys
otherInput.onfocus = this.releaseKeys.bindAsEventListener(this);
otherInput.onblur = this.captureKeys.bindAsEventListener(this);
this.otherMinutes = otherInput;
cell.appendChild(otherInput);
// Padding cell
if (!this.options.use24hrs)
cell = row.insertCell(2);
row = timeTable.insertRow(rows++);
cell = row.insertCell(0);
cell.colSpan = rowwidth;
hr = document.createElement('hr');
Element.setStyle(hr, {'color': 'gray', 'backgroundColor': 'gray', 'height': '1px', 'border': '0', 'marginTop': '3px', 'marginBottom': '3px', 'padding': '0'});
cell.appendChild(hr);
row = timeTable.insertRow(rows++);
cell = row.insertCell(0);
cell.colSpan = rowwidth;
selectButton = document.createElement('input');
selectButton.type = 'button';
if (this.options.datePicker)
selectButton.value = this.tr('Select Date and Time');
else
selectButton.value = this.tr('Select Time');
selectButton.onclick = function(e) {
this.options.onSelect && this.options.onSelect(this.currentDate);
}.bindAsEventListener(this);
cell.appendChild(selectButton);
} else {
calCont.appendChild(calTable);
}
return calCont;
},
createCalendar: function(date) {
this.currentDate = date;
this.currentDays = [];
var today = new Date();
var previousYear = new Date(date.getFullYear() - 1, date.getMonth(), 1)
var previousMonth = new Date(date.getFullYear(), date.getMonth() - 1, 1)
var nextMonth = new Date(date.getFullYear(), date.getMonth() + 1, 1)
var nextYear = new Date(date.getFullYear() + 1, date.getMonth(), 1)
var row;
( run in 0.566 second using v1.01-cache-2.11-cpan-39bf76dae61 )