var Time = Class.create({ initialize: function(x, y) { if (x instanceof ADate) { this.adate=x; this.atime=y; // ATime or TimePoint return; } // otherwise x is a string, y is not defined if (!x) { // both arguments are not initialized this.setNull(); return; } this.parseTime(x); }, parseTime: function(sTime) { var d=new ADate(); d.fromISOpart(sTime); this.adate=d; var t=new ATime(); t.FromISO(sTime); this.atime=t; }, setNull: function() { this.adate=new ADate(); this.atime=new ATime(); }, GetADate: function() { return this.adate; }, GetATime: function() { return this.atime; }, IsIncorrect: function() { return this.adate.IsIncorrect() || this.atime.IsIncorrect(); }, toString: function() { var date = this.ToDate(); return date ? date.toLocaleString() : null; }, ToDate: function(){ if (this.IsIncorrect()) return null; var date = new Date(Date.UTC(this.adate.year, this.adate.month - 1, this.adate.day, this.atime.hh, this.atime.mm, this.atime.ss)); var offs = this.atime.GetTimezoneOffset ? this.atime.GetTimezoneOffset() : 0; return offs === 0 ? date : new Date(date.getTime() + offs * 60 * 1000); }, Serialize: function(serializer) { serializer.BeginType("Time"); if (this.adate.IsIncorrect() || this.atime.IsIncorrect()) serializer.Serialize(Time.not_a_date_time); else { var offs = typeof(this.atime.GetTimezoneOffset) == "function" ? this.atime.GetTimezoneOffset() : 0; var date = new Date(Date.UTC(this.adate.GetYear(), this.adate.GetMonth() - 1, this.adate.GetDay(), // this.atime.GetHours(), this.atime.GetMinutes(), this.atime.GetSeconds()) - offs * 60 * 1000); serializer.Serialize(// date.getUTCFullYear().toPaddedString(4)+ (date.getUTCMonth() + 1).toPaddedString(2)+ date.getUTCDate().toPaddedString(2)+ "T"+ date.getUTCHours().toPaddedString(2)+ date.getUTCMinutes().toPaddedString(2)+ date.getUTCSeconds().toPaddedString(2) +"Z"); } serializer.EndType("Time"); }, Restore: function(restorer){ this.adate=new ADate(); this.atime=new TimePoint(); restorer.BeginType("Time"); var str=restorer.Restore(); restorer.EndType("Time"); if (str==Time.not_a_date_time) return; this.adate.FromISO(str); this.atime.FromISO(str); } }); Time.not_a_date_time = "not-a-date-time"; Time.Current = function(){ return new Time(ADate.Current(), ATime.Current()); } var DateTimeInput = Class.create(JSControl, { initialize: function($super, element, params){ $super(element); this.date_input = params["date-input"]; this.time_input = params["time-input"]; this.time_first = Element.readAttribute(this.element, "order") == "TD"; if (params["button"]){ this.button_ = $(params["button"]); if (params["attrs"] && this.button_){ this.opener_ = new SIPopupOpener(this.button_, { "html": function(){ return JSControl.TransformElementAndUnwrap(params["attrs"], params.types || {}); }, "tablimit": 20, "align-id": this.ID() }); SubscribeOnEvent("CHANGE", "document", this.onCHANGE, this); SubscribeOnEvent("FINALIZE", "document", this.onFINALIZE, this); SubscribeOnEvent("CLICK", "document", this.onCHANGE, this); Event.observe(this.button_, "SI:SHOW", function(event){ if (event.memo != this.opener_) return; var elem = $(params["attrs"].htmlid); if (elem && elem.JSControl && elem.JSControl.SetValue) elem.JSControl.SetValue(this.Value()); }.bindAsEventListener(this)); } } this.params_ = params; if (this.button_) Event.observe(this.button_, "dblclick", this.setCurrent.bindAsEventListener(this)); this.value_control = Element.readAttribute(this.element, "value-control") || "signal"; this.respect_timezone_ = this.element.getAttribute("respect-timezone") == "yes"; this.defaults = { "date": "today", "time": new TimePoint(0, 0, 0) }; ["date", "time"].each(function(nam){ var val = Element.readAttribute(this.element, "default-" + nam); if (val) this.defaults[nam] = URLRestoreV(val); }, this); var awindow = AControl.GetParentWindow(this.element); if (awindow){ awindow.Subscribe("CHANGE", this.onCHANGE_AWND, this); awindow.Subscribe("WM_INIT", this.onINIT, this); } if ("signal" === this.value_control) this.inputs().each(function(elem){ Event.observe(elem, "focus", this.onfocus.bindAsEventListener(this)); Event.observe(elem, "blur", this.onblur.bindAsEventListener(this)); }, this); this.strval_ = URLSerialize(this.Value()); }, inputs: function(){ var result = []; [this.date_input, this.time_input].each(function(jscontrol){ var elem = document.getElementById(jscontrol.ID()); if (elem) result.push(elem); }, this); return result; }, onfocus: function(event){ var elem = Event.element(event); if (elem) this.set_correct(elem, true); }, onblur: function(event){ var elem = Event.element(event); if (!elem) return; var inputs = this.inputs(); if (inputs.indexOf(elem) === -1) return; var all_empty = true; for (var iii = 0; iii < inputs.length; ++iii){ var elem = inputs[iii]; var isempty = !elem.value || elem.JSControl && elem.JSControl.hintIsVisible(); if (!isempty){ all_empty = false; break; } } inputs.each(function(elem){ this.set_correct(elem, all_empty || elem.JSControl && !elem.JSControl.Value().IsIncorrect()); }, this); }, set_correct: function(elem, correct){ Element[correct ? "removeClassName" : "addClassName"](elem, "Incorrect"); }, changed: false, onCHANGE_AWND: function(aevent){ var emitter = aevent.Emitter(); if (emitter != this.date_input && emitter != this.time_input) return; if ("autofill" === this.value_control && !this.changed){ if (emitter == this.date_input && this.time_input.Value().IsIncorrect()) this.time_input.SetValue(this.defaults["time"]); else if (emitter == this.time_input && this.date_input.Value().IsIncorrect()) this.date_input.SetValue(this.defaults["date"]); this.changed = true; } this.check_change(); }, SetValue: function(dt){ if (Object.isUndefined(dt) || dt===null){ this.date_input.SetValue(null); this.time_input.SetValue(null); }else if (dt=="current"){ this.date_input.SetValue("today"); this.time_input.SetValue("current"); }else if (dt instanceof Time) { if (!dt.IsIncorrect() && dt.atime instanceof TimePoint) { if (this.respect_timezone_) { var date = dt.ToDate(); dt = new Time(// new ADate(date.getFullYear(), date.getMonth() + 1, date.getDate()),// new ATime(date.getHours(), date.getMinutes(), date.getSeconds())); } else { dt.atime=new ATime(dt.atime.hh, dt.atime.mm, dt.atime.ss); } } this.date_input.SetValue(dt.adate); this.time_input.SetValue(dt.atime); }else return; this.changed = true; this.inputs().each(function(elem){ this.set_correct(elem, true); }, this); this.strval_ = URLSerialize(this.Value()); }, Value: function(){ return new Time(this.date_input.Value(), this.time_input.Value()); }, SetAttribute: function($super, nam, val){ switch (nam){ case "title": $super(nam, val); break; case "visibility": if (["yes", "ro", "vo", "link", "no"].indexOf(val) == -1) break; if ("no" == val){ Element.setStyle(this.element, {"display": "none"}); break; }else Element.setStyle(this.element, {"display": ""}); if (this.button_) Element.setStyle(this.button_, {"display": val == "yes" ? "" : "none"}); Element[["vo", "link"].include(val) ? "addClassName" : "removeClassName"](this.element, "VO"); default: this.date_input.SetAttribute(nam, val); this.time_input.SetAttribute(nam, val); } }, SetTabOrder: function(nTabBase){ nTabBase = this.time_first ?// this.date_input.SetTabOrder(this.time_input.SetTabOrder(nTabBase)): this.time_input.SetTabOrder(this.date_input.SetTabOrder(nTabBase)); if (this.button_) this.button_.tabIndex = nTabBase++; if (this.opener_) nTabBase = this.opener_.SetTabOrder(nTabBase); return nTabBase; }, widgetID: function(){ return this.params_["attrs"].htmlid; }, onCHANGE: function(aevent){ var emitter = aevent.Emitter(); if (emitter.ID() != this.widgetID()) return; this.SetValue(emitter.Value()); this.check_change(); }, check_change: function(){ var strval = URLSerialize(this.Value()); if (!("strval_" in this) || this.strval_ != strval){ this.strval_ = strval; new AEvent("CHANGE", {}, this); } }, onFINALIZE: function(aevent){ var emitter = aevent.Emitter(); if (emitter.ID() != this.widgetID()) return; if (this.opener_) this.opener_.Hide(); new AEvent("CHANGE", {}, this); }, setCurrent: function(){ var oldval = this.Value().toString(); this.date_input.SetValue(ADate.Current()); this.time_input.SetValue(ATime.Current()); var newval = this.Value(); if (newval.toString() != oldval){ var widget = $(this.widgetID()); if (widget && widget.JSControl) widget.JSControl.SetValue(newval); this.check_change(); } }, onINIT: function(aevent){ var emitter = aevent.Emitter(); if (emitter == this.date_input || emitter == this.time_input) new AEvent("WM_INIT", {}, this); } });