var Clock = Class.create(JSControl, { initialize: function($super, element){ $super(element); this.sections = {}; Clock.sectionTypes.each(function(sectionType, iii){ this.sections[sectionType] = Element.select(this.element, "tbody." + Clock.sectionClassNames[iii]); this.sections[sectionType].each(function(section){ section.type = sectionType; }); }.bind(this)); var setcurrent = Element.down(this.element, "button.SetCurrent"); if (setcurrent) { Event.observe(setcurrent, "click", this.OnSetCurrent.bind(this)); Event.observe(setcurrent, "keydown", this.OnSetCurrent.bind(this)); } var table = Element.down(this.element, "table"); Event.observe(table, "click", this.onclick.bindAsEventListener(this)); this.focusable_ = Element.select(table, "tbody"); this.focusable_.each(function(element){ Event.observe(element, "focus", this.focusSection.bind(this).curry(element)); Event.observe(element, "blur", this.focusSection.bind(this).curry(null)); Event.observe(element, "keydown", this.onkeydown.bindAsEventListener(this)); }, this); if (setcurrent) this.focusable_.push(setcurrent); }, OnSetCurrent: function(event) { if (event.ctrlKey || event.altKey) return; if(event.type=="keydown") { var key = event.which || event.keyCode; switch(key) { case Event.KEY_RETURN: break; default: return; } } this.SetValue(ATime.Current()); this.onchange(); this.finalize(); Event.stop(event); return false; }, updateSiblingValue: function(section){ var isExt = Element.hasClassName(section, "Ext"); var val = Clock.getSectionValue(section); if (section.type != "h"){ if (isExt) val = Math.floor(val / 5) * 5; var sibling = Element[isExt ? "previous" : "next"](section); Clock.selectSectionCell(sibling, Clock.getCellBySectionAndValue(sibling, val)); } }, isExt: function(section){ return section && Element.hasClassName(section, "Ext"); }, hasExt: function(section){ return section && section.type != "h" && !this.isExt(section); }, isFocused: function(section){ return section && Element.hasClassName(section, "Focused"); }, toggleSectionExt: function(section){ if (!this.isExt(section) && !this.hasExt(section)) return null; Element.setStyle(section, {"display": "none"}); var sibling = Element[Element.hasClassName(section, "Ext") ? "previous" : "next"](section); Element.setStyle(sibling, {"display": ""}); if (this.isFocused(section)) sibling.focus(); return sibling; }, finalize: function(){ new AEvent("FINALIZE", {}, this); }, onclick: function(event){ var section = Event.findElement(event, "tbody"); if (!section || !Element.descendantOf(section, this.element)) return; var tr = Event.findElement(event, "tr"); if (!tr || !Element.hasClassName(tr, "ChangeView")){ var td = Event.findElement(event, "td"); if (!td) return; if (Element.hasClassName(td, "SimpleCell")){ Clock.selectSectionCell(section, td); this.updateSiblingValue(section); new AEvent("CLICK", {}, this); if (section.type == "s" || section.type == "m" && !this.sections["s"].collect(Element.visible).any()) this.finalize(); }else if (Element.hasClassName(td, "Period")){ Clock.selectSectionPeriod(section, td); new AEvent("CLICK", {}, this); } }else this.toggleSectionExt(section); this.onchange(); }, onkeydown: function(event){ if (!event) return; var keyCode = event.which || event.keyCode; if (event.ctrlKey && [Event.KEY_RIGHT, Event.KEY_LEFT, Event.KEY_UP, Event.KEY_DOWN].include(keyCode)){ if ([Event.KEY_UP, Event.KEY_DOWN].include(keyCode)) this.toggleAMPM(this.getActiveSection()); return; } switch (keyCode){ case Event.KEY_RIGHT: this.selectOtherCell("right"); break; case Event.KEY_LEFT: this.selectOtherCell("left"); break; case Event.KEY_UP: this.selectOtherCell("up"); break; case Event.KEY_DOWN: this.selectOtherCell("down"); break; case Event.KEY_ESC: this.finalize(); break; case Event.KEY_RETURN: if (this.isButton(this.focusedSection)) Event.fire(this.focusedSection, "click"); else this.finalize(); break; case 32: if (this.isButton(this.focusedSection)) Event.fire(this.focusedSection, "click"); else if (this.focusedSection){ var button = this.getChangeViewButton(this.focusedSection); if (button) Event.fire(button, "click"); } break; default: switch (String.fromCharCode(keyCode)){ case "a": case "A": this.setAMPM("AM"); break; case "p": case "P": this.setAMPM("PM"); break; default: return; } } Event.stop(event); }, toggleAMPM: function(section){ if (section && Clock.isAMPMsection(section)) this.setAMPM(Clock.getSectionPeriod(section) == "AM" ? "PM" : "AM"); }, selectValue: function(sectionType, val){ this.sections[sectionType].each(function(section, iii){ var section_value = val; if (sectionType == "h" && Clock.isAMPMsection(section)){ var ampm = TimeInput.toAMPM(val); section_value = ampm["value"]; Clock.selectSectionPeriod(section, Clock.getCellBySectionAndValue(section, ampm["period"])); }else if (sectionType != "h" && !this.isExt(section)) section_value = Math.floor(val / 5) * 5; Clock.selectSectionCell(section, Clock.getCellBySectionAndValue(section, section_value)); }, this); }, SetValue: function(time){ this.selectValue("h", isNaN(time.hh) ? 0 : time.hh); this.selectValue("m", isNaN(time.mm) ? 0 : time.mm); this.selectValue("s", isNaN(time.ss) ? 0 : time.ss); }, Value: function(){ var time = Clock.sectionTypes.collect(function(sectionType){ var result = 0; this.sections[sectionType].each(function(section){ if (Element.visible(section)) result = Clock.getSectionValue(section); }) return result; }.bind(this)); return new ATime(time[0], time[1], time[2]); }, SetSectionsVisibility: function(array){ array.each(function(ind, iii){ this.sections[Clock.sectionTypes[iii]].each(function(section, jjj){ Element.setStyle(section, {"display": jjj == ind ? "" : "none"}); }); }.bind(this)); }, isSection: function(element){ return element && Element.match(element, "tbody"); }, isVisibleSection: function(element){ return this.isSection(element) && Element.visible(element); }, isChangeViewButton: function(element){ return element && Element.match(element, "tr.ChangeView"); }, getChangeViewButton: function(element){ return element ? Element.down(element, "tr.ChangeView") : null; }, isButton: function(element){ return this.isChangeViewButton(element); }, focusedSection: null, setAMPM: function(val){ var currentSection = this.getActiveSection(); if (!currentSection || Clock.getSectionPeriod(currentSection) == val) return; Clock.selectSectionPeriod(currentSection, Clock.getCellBySectionAndValue(currentSection, val)); this.onchange(); }, getActiveSection: function(){ return this.isVisibleSection(this.focusedSection) ? this.focusedSection : null; }, focusSection: function(section){ if (section == this.focusedSection) return; if (this.focusedSection){ Element.removeClassName(this.focusedSection, "Focused"); this.focusedSection = null; } if (section){ Element.addClassName(section, "Focused"); if (typeof section.focus == "function") section.focus(); this.focusedSection = section; } }, selectOtherCell: function(direction){ var currentSection = this.getActiveSection(); if (!currentSection) return; var currentCell = currentSection.selectedCell; var nextCell = null; var currentRow = currentCell ? Element.up(currentCell, "tr") : null; var rows = Element.select(currentSection, "tr.SimpleRow"); var firstRow = rows.first(); var lastRow = rows.last(); var next_row_real = currentRow ? Element.next(currentRow, "tr.SimpleRow") : null; var nextRow = next_row_real || firstRow; var prev_row_real = currentRow ? Element.previous(currentRow, "tr.SimpleRow") : null; var prevRow = prev_row_real || lastRow; switch (direction){ case "right": var next_cell_real = currentCell ? Element.next(currentCell, "td.SimpleCell") : null; nextCell = next_cell_real || Element.down(nextRow, "td.SimpleCell"); if (currentCell && !next_cell_real && !next_row_real) this.toggleAMPM(currentSection); break; case "left": var prev_cell_real = currentCell ? Element.previous(currentCell, "td.SimpleCell") : null; nextCell = prev_cell_real || Element.select(prevRow, "td.SimpleCell").last(); if (currentCell && !prev_cell_real && !prev_row_real) this.toggleAMPM(currentSection); break; case "up": nextCell = (currentCell ? Element.select(prevRow, "td.SimpleCell")[Element.select(currentRow, "td.SimpleCell").indexOf(currentCell)] : null) || Element.select(prevRow, "td.SimpleCell").last(); if (currentCell && !prev_row_real) this.toggleAMPM(currentSection); break; case "down": nextCell = (currentCell ? Element.select(nextRow, "td.SimpleCell")[Element.select(currentRow, "td.SimpleCell").indexOf(currentCell)] : null) || Element.down(nextRow, "td.SimpleCell"); if (currentCell && !next_row_real) this.toggleAMPM(currentSection); } if (nextCell) Clock.selectSectionCell(currentSection, nextCell); if (nextCell != currentCell){ this.updateSiblingValue(currentSection); this.onchange(); } }, SetTabOrder: function(tabbase){ this.focusable_.each(function(element){ element.tabIndex = tabbase++; }); return tabbase; } }); Clock.sectionTypes = ["h", "m", "s"]; Clock.sectionClassNames = ["Hour", "Minute", "Second"]; Clock.makeSelected = function(element, add){ Element[add ? "addClassName" : "removeClassName"](element, "Selected"); } Clock.selectSectionCell = function(section, cell){ if (section.selectedCell){ Clock.makeSelected(section.selectedCell, false); section.selectedCell = null; } if (!cell) return; Clock.makeSelected(cell, true); section.selectedCell = cell; } Clock.isAMPMsection = function(section){ return section && Element.hasClassName(section, "AMPM"); } Clock.selectSectionPeriod = function(section, cell){ if (section.selectedPeriod){ Clock.makeSelected(section.selectedPeriod, false); section.selectedPeriod = null; } if (!cell) return; Clock.makeSelected(cell, true); section.selectedPeriod = cell; } Clock.getSectionPeriod = function(section){ if (!section || !section.selectedPeriod) return ""; return section.selectedPeriod.getAttribute("value"); } Clock.getSectionValue = function(section){ if (!section.selectedCell) return 0; var val = parseInt(section.selectedCell.getAttribute("value"), 10); return Clock.isAMPMsection(section) ?// TimeInput.to24H({ "value": val, "period": Clock.getSectionPeriod(section) }) : val; } Clock.getCellBySectionAndValue = function(section, val){ return Element.select(section, "td").find(function(element){ return element.getAttribute("value") == String(val); }); } var BigCalendarAndClock = Class.create({ initialize: function (id, timeShift) { this.calendarBlock = $(id); // this.calendarBlock = Element.down(this.root, ".BigCalendarAndClock"); if (!this.calendarBlock) return; this.timeShift = timeShift || 0; var day = Element.down(this.calendarBlock, ".Day"); var dayname = Element.down(this.calendarBlock, ".Dayname"); var time = Element.down(this.calendarBlock, ".Time"); var hours = this.calendarBlock.down(".Hours"); var minutes = this.calendarBlock.down(".Minutes"); var month = Element.down(this.calendarBlock, ".Month"); var year = Element.down(this.calendarBlock, ".Year"); var clockHrs = this.calendarBlock.down('.ClockHours'); var clockMin = this.calendarBlock.down('.ClockMinutes'); if (!day || !dayname) return; var updateTime = function () { var date = new Date(); date.setMilliseconds(this.timeShift + date.getMilliseconds()); if (time) { hours.update(date.getHours().toPaddedString(2)); minutes.update(date.getMinutes().toPaddedString(2)); //time.update(date.getHours().toPaddedString(2) + ":" + date.getMinutes().toPaddedString(2)); } this.updateClockPart(clockHrs, ((date.getHours() + date.getMinutes() / 60.) % 12.) / 12.); this.updateClockPart(clockMin, date.getMinutes() / 60.); if (typeof (this.lastUpdateDate) != "undefined" && date.getDate() == this.lastUpdateDate.getDate()) return; this.lastUpdateDate = date; day.update(date.getDate()); month.update(DateInput.of_monthname[1 + date.getMonth()]); dayname.update(DateInput.daynames[date.getDay()]); year.update(date.getFullYear()); } .bind(this); updateTime(); new PeriodicalExecuter(updateTime, 10); }, updateClockPart: function (element, value) { var frameCount = 15; var row = parseInt(value * 4.); var frameN = parseInt((value * 4. - row) * frameCount); if (row == 1) frameN = frameCount - frameN; else if (row == 2) { row = 3; frameN = frameCount - frameN; } else if (row == 3) { row = 2; } else if (row == 4) row = 0; var e = $(element); e.setStyle({ backgroundPosition: (-frameN * e.offsetWidth) + "px " + (-row * e.offsetHeight) + "px" }); } });