0
var Timeframe = Class.create({
0
initialize: function(element, options) {
0
this.element = $(element);
0
this.options = $H({ months: 2 }).merge(options || {});;
0
this.months = this.options.get('months');
0
this.weekdayNames = Locale.get('dayNames');
0
this.monthNames = Locale.get('monthNames');
0
this.format = this.options.get('format') || Locale.get('format');
0
this.weekOffset = this.options.get('weekOffset') || Locale.get('weekOffset');
0
previous: $H({ label: '←', element: $(this.options.get('previousButton')) }),
0
today: $H({ label: 'T', element: $(this.options.get('todayButton')) }),
0
next: $H({ label: '→', element: $(this.options.get('nextButton')) })
0
this.fields = $H({ start: $(this.options.get('startField')), end: $(this.options.get('endField')) });
0
this._buildButtons()._buildFields();
0
this.earliest = Date.parseToObject(this.options.get('earliest'));
0
this.latest = Date.parseToObject(this.options.get('latest'));
0
this.element.insert(new Element('div', { id: 'calendars_container' }));
0
this.months.times(function(month) { this.createCalendar(month) }.bind(this));
0
this.register().populate().refreshRange();
0
createCalendar: function() {
0
var calendar = new Element('table', { id: 'calendar_' + this.calendars.length, border: 0, cellspacing: 0, cellpadding: 5 });
0
calendar.insert(new Element('caption'));
0
var head = new Element('thead');
0
var row = new Element('tr');
0
this.weekdayNames.length.times(function(column) {
0
var body = new Element('tbody');
0
(6).times(function(rowNumber) {
0
var row = new Element('tr');
0
this.element.down('div#calendars_container').insert(calendar);
0
this.calendars.push(calendar);
0
this.months = this.calendars.length;
0
destroyCalendar: function() {
0
this.calendars.pop().remove();
0
this.months = this.calendars.length;
0
var month = this.date.neutral();
0
- this.months.times(function(n) {
0
+ this.months.times(function(n) {
0
var calendar = $('calendar_' + n);
0
var caption = calendar.select('caption').first();
0
caption.update(this.monthNames[month.getMonth()] + ' ' + month.getFullYear());
0
var iterator = new Date(month);
0
var offset = (iterator.getDay() - this.weekOffset) % 7;
0
var inactive = offset > 0 ? 'pre beyond' : false;
0
iterator.setDate(iterator.getDate() - 7);
0
if(iterator.getDate() > 1) inactive = 'pre beyond';
0
calendar.select('td').each(function(day) {
0
day.date = new Date(iterator); // Is this expensive (we unload these later)? We could store the epoch time instead.
0
day.update(day.date.getDate()).writeAttribute('class', inactive || 'active');
0
day.addClassName('selectable');
0
if(iterator.toString() === new Date().neutral().toString()) day.addClassName('today');
0
day.baseClass = day.readAttribute('class');
0
iterator.setDate(iterator.getDate() + 1);
0
if(iterator.getDate() == 1) inactive = inactive ? false : 'post beyond';
0
month.setMonth(month.getMonth() + 1);
0
_buildButtons: function() {
0
var buttonList = new Element('ul', { id: 'timeframe_menu' });
0
this.buttons.each(function(pair) {
0
this.clearButton = new Element('span', { className: 'clear' }).update(new Element('span').update('X'));
0
_buildFields: function() {
0
var fieldset = new Element('div', { id: 'timeframe_fields' });
0
this.fields.each(function(pair) {
0
this.parseField('start').refreshField('start').parseField('end').refreshField('end').initDate = new Date(this.date);
0
document.observe('click', this.eventClick.bind(this));
0
document.observe('mousedown', this.eventMouseDown.bind(this));
0
if(Prototype.Browser.Opera) document.observe('mousemove', this.handleMousemove.bind(this));
0
return this._registerFieldObserver('start')._registerFieldObserver('end')._disableTextSelection();
0
unregister: function() {
0
this.element.select('td').each(function(day) { day.date = day.baseClass = null; });
0
_registerFieldObserver: function(fieldName) {
0
var field = this.fields.get(fieldName);
0
field.observe('focus', function() { field.hasFocus = true; this.parseField(fieldName, true); }.bind(this));
0
new Form.Element.Observer(field, 0.2, function(element, value) { if(element.hasFocus) this.parseField(fieldName, true); }.bind(this));
0
_disableTextSelection: function() {
0
this.element.onselectstart = function() { return false; };
0
this.element.unselectable = 'on';
0
this.element.style.cursor = 'default';
0
parseField: function(fieldName, populate) {
0
var field = this.fields.get(fieldName);
0
var date = Date.parseToObject(this.fields.get(fieldName).value);
0
refreshField: function(fieldName) {
0
var field = this.fields.get(fieldName);
0
var initValue = field.value;
0
field.hasFocus = false;
0
validateField: function(fieldName, date) {
0
if((this.earliest && date < this.earliest) || (this.latest && date > this.latest))
0
eventClick: function(event) {
0
if(!event.element().ancestors) return;
0
if(el = event.findElement('a.timeframe_button'))
0
this.handleButtonClick(event, el);
0
eventMouseDown: function(event) {
0
if(!event.element().ancestors) return;
0
this.handleDateClick(el);
0
handleButtonClick: function(event, element) {
0
var movement = this.months > 1 ? this.months - 1 : 1;
0
this.populate().refreshRange();
0
this.fields.get('start').value = this.fields.get('start').defaultValue || '';
0
this.fields.get('end').value = this.fields.get('end').defaultValue || '';
0
this.date = new Date(this.initDate);
0
this.parseField('start').parseField('end');
0
handleDateClick: function(element, couldClear) {
0
this.mousedown = this.dragging = true;
0
this.getPoint(element.date);
0
getPoint: function(date) {
0
if(this.range.get('start') && this.range.get('start').toString() == date && this.range.get('end'))
0
this.startdrag = this.range.get('end');
0
eventMouseOver: function(event) {
0
this.extendRange(el.date);
0
else this.toggleClearButton(event);
0
toggleClearButton: function(event) {
0
if(event.element().ancestors && event.findElement('td.selected')) {
0
this.clearButton.hide();
0
extendRange: function(date) {
0
this.clearButton.hide();
0
if(date > this.startdrag) {
0
eventMouseUp: function(event) {
0
if(!this.dragging) return;
0
this.mousedown = false;
0
refreshRange: function() {
0
this.element.select('td').each(function(day) {
0
day.writeAttribute('class', day.baseClass);
0
- if(this.range.get('start')
this.range.get('start') <= day.date && day.date <= this.range.get('end')) {
0
+ if(this.range.get('start')
&& this.range.get('end') && this.range.get('start') <= day.date && day.date <= this.range.get('end')) {
0
var baseClass = day.hasClassName('beyond') ? 'beyond_' : day.hasClassName('today') ? 'today_' : null;
0
var state = this.stuck || this.mousedown ? 'stuck' : 'selected';
0
if(baseClass) day.addClassName(baseClass + state);
0
var day = this.getDay(), month = this.getMonth();
0
var hours = this.getHours(), minutes = this.getMinutes();
0
function pad(num) { return num.toPaddedString(2); };
0
return format.gsub(/\%([aAbBcdHImMpSwyY])/, function(part) {
0
case 'a': return Locale.get('dayNames').invoke('substring', 0, 3)[day].escapeHTML(); break;
0
return new Date(this.getFullYear(), this.getMonth(), this.getDate(), 12);
Comments
No one has commented yet.