KronolithCore = {
// Vars used and defaulting to null/false:
// DMenu, Growler, inAjaxCallback, is_logout,
- // daySizes, viewLoading, groupLoading, freeBusy, colorPicker
+ // daySizes, viewLoading, groupLoading, freeBusy, colorPicker, duration
view: '',
ecache: $H(),
$('kronolithEventStartDate').setValue(d.toString(Kronolith.conf.date_format));
$('kronolithEventStartTime').setValue(d.toString(Kronolith.conf.time_format));
d.add(1).hour();
+ this.duration = 60;
$('kronolithEventEndDate').setValue(d.toString(Kronolith.conf.date_format));
$('kronolithEventEndTime').setValue(d.toString(Kronolith.conf.time_format));
$('kronolithEventLinkExport').up('span').hide();
$('kronolithEventStartTime').setValue(ev.st);
$('kronolithEventEndDate').setValue(ev.ed);
$('kronolithEventEndTime').setValue(ev.et);
+ this.duration = Math.abs(Date.parse(ev.e).getTime() - Date.parse(ev.s).getTime()) / 60000;
$('kronolithEventStatus').setValue(ev.x);
$('kronolithEventDescription').setValue(ev.d);
$('kronolithEventPrivate').setValue(ev.pv);
/* Attendees */
kronolithEAttendeesAc.reset();
this.freeBusy = $H();
- $('kronolithEventStartDate').stopObserving('change');
+ if (this.attendeeStartDateHandler) {
+ this.attendeeStartDateHandler.stop();
+ }
if (!Object.isUndefined(ev.at)) {
kronolithEAttendeesAc.reset(ev.at.pluck('l'));
var table = $('kronolithEventTabAttendees').down('tbody');
if (this.fbLoading) {
$('kronolithFBLoading').show();
}
- $('kronolithEventStartDate').observe('change', function() {
+ this.attendeeStartDateHandler = $('kronolithEventStartDate').on('change', function() {
ev.at.each(function(attendee) {
this.insertFreeBusy(attendee.e);
}, this);
}
},
+ /**
+ * Returns the Date object representing the date and time specified in the
+ * event form's start or end fields.
+ *
+ * @param string what Which fields to parse, either 'start' or 'end'.
+ *
+ * @return Date The date object or null if the fields can't be parsed.
+ */
+ getDate: function(what) {
+ var dateElm, timeElm, date, time;
+ if (what == 'start') {
+ dateElm = 'kronolithEventStartDate';
+ timeElm = 'kronolithEventStartTime';
+ } else {
+ dateElm = 'kronolithEventEndDate';
+ timeElm = 'kronolithEventEndTime';
+ }
+ date = Date.parseExact($F(dateElm), Kronolith.conf.date_format)
+ || Date.parse($F(dateElm));
+ if (date) {
+ time = Date.parseExact($F(timeElm), Kronolith.conf.time_format);
+ if (!time) {
+ time = Date.parse($F(timeElm));
+ }
+ if (time) {
+ date.setHours(time.getHours());
+ date.setMinutes(time.getMinutes());
+ }
+ }
+ return date;
+ },
+
checkDate: function(e) {
var elm = e.element();
if ($F(elm)) {
},
/**
+ * Updates the end time in the event form after changing the start time.
+ */
+ updateEndTime: function() {
+ var date = this.getDate('start');
+ if (!date) {
+ return;
+ }
+ date.add(this.duration).minutes();
+ $('kronolithEventEndDate').setValue(date.toString(Kronolith.conf.date_format));
+ $('kronolithEventEndTime').setValue(date.toString(Kronolith.conf.time_format));
+ },
+
+ /**
+ * Event handler for scrolling the mouse over the date field.
+ *
+ * @param Event e The mouse event.
+ * @param string field The field name.
+ */
+ scrollDateField: function(e, field) {
+ var date = Date.parseExact($F(field), Kronolith.conf.date_format);
+ if (!date || (!e.wheelData && !e.detail)) {
+ return;
+ }
+ date.add(e.wheelData > 0 || e.detail < 0 ? 1 : -1).days();
+ $(field).setValue(date.toString(Kronolith.conf.date_format));
+ switch (field) {
+ case 'kronolithEventStartDate':
+ this.updateEndTime();
+ break;
+ case 'kronolithEventEndDate':
+ var start = this.getDate('start'), end = this.getDate('end');
+ if (start) {
+ if (start.isAfter(end)) {
+ $('kronolithEventStartDate').setValue(date.toString(Kronolith.conf.date_format));
+ $('kronolithEventStartTime').setValue($F('kronolithEventEndTime'));
+ }
+ this.duration = Math.abs(date.getTime() - start.getTime()) / 60000;
+ }
+ break;
+ }
+ },
+
+ /**
+ * Event handler for scrolling the mouse over the time field.
+ *
+ * @param Event e The mouse event.
+ * @param string field The field name.
+ */
+ scrollTimeField: function(e, field) {
+ var time = Date.parseExact($F(field), Kronolith.conf.time_format) || Date.parse($F(field)),
+ hour, minute;
+ if (!time || (!e.wheelData && !e.detail)) {
+ return;
+ }
+
+ minute = time.getMinutes();
+ if (minute % 10) {
+ if (e.wheelData > 0 || e.detail < 0) {
+ minute = (minute + 10) / 10 | 0;
+ } else {
+ minute = minute / 10 | 0;
+ }
+ minute *= 10;
+ } else {
+ minute += (e.wheelData > 0 || e.detail < 0 ? 10 : -10);
+ }
+ hour = time.getHours();
+ if (minute < 0) {
+ if (hour > 0) {
+ hour--;
+ minute = 50;
+ } else {
+ minute = 0;
+ }
+ } else if (minute >= 60) {
+ if (hour < 23) {
+ hour++;
+ minute = 0;
+ } else {
+ minute = 59;
+ }
+ }
+ time.setHours(hour);
+ time.setMinutes(minute);
+
+ $(field).setValue(time.toString(Kronolith.conf.time_format));
+ switch (field) {
+ case 'kronolithEventStartTime':
+ this.updateEndTime();
+ break;
+ case 'kronolithEventEndTime':
+ var start = this.getDate('start'), end = this.getDate('end');
+ if (start) {
+ if (start.isAfter(end)) {
+ $('kronolithEventStartDate').setValue(end.toString(Kronolith.conf.date_format));
+ $('kronolithEventStartTime').setValue($F('kronolithEventEndTime'));
+ }
+ this.duration = Math.abs(end.getTime() - start.getTime()) / 60000;
+ }
+ break;
+ }
+
+ /* Mozilla bug https://bugzilla.mozilla.org/show_bug.cgi?id=502818
+ * Need to stop or else multiple scroll events may be fired. We
+ * lose the ability to have the mousescroll bubble up, but that is
+ * more desirable than having the wrong scrolling behavior. */
+ if (Prototype.Browser.Gecko && !e.stop) {
+ Event.stop(e);
+ }
+ },
+
+ /**
* Closes a RedBox overlay, after saving its content to the body.
*/
closeRedBox: function()
$('kronolithEventStartDate', 'kronolithEventEndDate', 'kronolithTaskDueDate').compact().invoke('observe', 'blur', this.checkDate.bind(this));
$('kronolithEventStartTime', 'kronolithEventEndTime', 'kronolithTaskDueTime').compact().invoke('observe', 'blur', this.checkTime.bind(this));
+ $('kronolithEventStartDate', 'kronolithEventStartTime').invoke('observe', 'change', this.updateEndTime.bind(this));
if (Kronolith.conf.has_tasks) {
$('kronolithTaskDueDate', 'kronolithEventDueTime').compact().invoke('observe', 'focus', this.setDefaultDue.bind(this));
timeFields.push('kronolithTaskDueTime');
}
dateFields.each(function(field) {
- $(field).observe(Prototype.Browser.Gecko ? 'DOMMouseScroll' : 'mousewheel', function(e) {
- var date = Date.parseExact($F(field), Kronolith.conf.date_format);
- if (!date || (!e.wheelData && !e.detail)) {
- return;
- }
- date.add(e.wheelData > 0 || e.detail < 0 ? 1 : -1).days();
- $(field).setValue(date.toString(Kronolith.conf.date_format));
- });
- });
+ $(field).observe(Prototype.Browser.Gecko ? 'DOMMouseScroll' : 'mousewheel', this.scrollDateField.bindAsEventListener(this, field));
+ }, this);
timeFields.each(function(field) {
- $(field).observe(Prototype.Browser.Gecko ? 'DOMMouseScroll' : 'mousewheel', function(e) {
- var time = $F(field).match(/(\d+)\s*:\s*(\d+)\s*((a|p)m)?/i),
- hour, minute;
- if (!time || (!e.wheelData && !e.detail)) {
- return;
- }
-
- minute = parseInt(time[2]);
- if (minute % 10) {
- if (e.wheelData > 0 || e.detail < 0) {
- minute = (minute + 10) / 10 | 0;
- } else {
- minute = minute / 10 | 0;
- }
- minute *= 10;
- } else {
- minute += (e.wheelData > 0 || e.detail < 0 ? 10 : -10);
- }
- hour = parseInt(time[1]);
- if (minute < 0) {
- if (hour > 0) {
- hour--;
- minute = 50;
- } else {
- minute = 0;
- }
- } else if (minute >= 60) {
- if (hour < 23) {
- hour++;
- minute = 0;
- } else {
- minute = 59;
- }
- }
-
- $(field).setValue($F(field).replace(/(.*?)\d+(\s*:\s*)\d+(.*)/, '$1' + hour + ':' + minute.toPaddedString(2) + '$3'));
-
- /* Mozilla bug https://bugzilla.mozilla.org/show_bug.cgi?id=502818
- * Need to stop or else multiple scroll events may be fired. We
- * lose the ability to have the mousescroll bubble up, but that is
- * more desirable than having the wrong scrolling behavior. */
- if (Prototype.Browser.Gecko && !e.stop) {
- Event.stop(e);
- }
- });
- });
+ $(field).observe(Prototype.Browser.Gecko ? 'DOMMouseScroll' : 'mousewheel', this.scrollTimeField.bindAsEventListener(this, field));
+ }, this);
if (Horde.dhtmlHistory.initialize()) {
Horde.dhtmlHistory.addListener(this.go.bind(this));