From 83cab23538795560cc52939c1e0fee65eb96e4fe Mon Sep 17 00:00:00 2001 From: Michael M Slusarz Date: Tue, 27 Jul 2010 02:02:51 -0600 Subject: [PATCH] Move all edit screen javascript to a static file. This started off as converting to Horde_Core_Ui_JsCalendar usage, but ended up an entire rewrite of the edit screen. --- kronolith/js/edit.js | 528 +++++++++++++++++++++++++ kronolith/lib/Event.php | 48 +-- kronolith/lib/View/EditEvent.php | 9 +- kronolith/new.php | 6 +- kronolith/search.php | 5 + kronolith/templates/edit/edit.inc | 120 +++--- kronolith/templates/edit/edit_timespan.inc | 30 +- kronolith/templates/edit/javascript.inc | 288 -------------- kronolith/templates/javascript_defs.php | 8 +- kronolith/templates/search/search_advanced.inc | 4 - kronolith/themes/screen.css | 3 + 11 files changed, 633 insertions(+), 416 deletions(-) create mode 100644 kronolith/js/edit.js delete mode 100644 kronolith/templates/edit/javascript.inc diff --git a/kronolith/js/edit.js b/kronolith/js/edit.js new file mode 100644 index 000000000..b9e02f62d --- /dev/null +++ b/kronolith/js/edit.js @@ -0,0 +1,528 @@ +/** + * edit.js - Base application logic. + * + * Copyright 2010 The Horde Project (http://www.horde.org/) + * + * See the enclosed file COPYING for license information (GPL). If you + * did not receive this file, see http://www.fsf.org/copyleft/gpl.html. + * + * @author Michael Slusarz + * @category Horde + * @package Kronolith + */ + +var KronolithEdit = +{ + calendarSelect: function(e) + { + var prefix; + + switch (e.element().identify()) { + case 'end_img': + prefix = 'end'; + break; + + case 'recur_end_img': + prefix = 'recur_end'; + break; + + case 'start_img': + prefix = 'start'; + break; + + default: + return; + } + + $(prefix + '_year').setValue(e.memo.getFullYear()); + $(prefix + '_month').setValue(e.memo.getMonth() + 1); + $(prefix + '_day').setValue(e.memo.getDate()); + + this.doAction(prefix + '_year'); + }, + + updateWday: function(p) + { + $(p + '_wday').update('(' + Horde_Calendar.fullweekdays[this.getFormDate(p).getDay()] + ')'); + }, + + getFormDate: function(p) + { + return new Date($F(p + '_year'), $F(p + '_month') - 1, $F(p + '_day')); + }, + + clickHandler: function(e) + { + if (e.isRightClick()) { + return; + } + + var elt = e.element(), + id = elt.readAttribute('id'); + + switch (id) { + case 'allday': + case 'allday_label': + this.doAction('allday'); + break; + + case 'am': + case 'am_label': + case 'pm': + case 'pm_label': + this.doAction('am'); + break; + + case 'attendees_button': + Horde.popup({ + params: Object.toQueryString({ + date: (('000' + $F('start_year')).slice(-4) + ('0' + $F('start_month')).slice(-2) + ('0' + $F('start_day')).slice(-2) + ('0' + $F('start_hour')).slice(-2) + ('0' + $F('start_min')).slice(-2) + '00'), + enddate: (('000' + $F('end_year')).slice(-4) + ('0' + $F('end_month')).slice(-2) + ('0' + $F('end_day')).slice(-2) + ('0' + $F('end_hour')).slice(-2) + ('0' + $F('end_min')).slice(-2) + '00') + }), + url: elt.readAttribute('href') + }); + e.stop(); + break; + + case 'eam': + case 'eam_label': + case 'epm': + case 'epm_label': + this.doAction('eam'); + break; + + case 'edit_current': + case 'edit_future': + $('start_year').setValue(parseInt($F('recur_ex').substr(0, 4), 10)); + $('start_month').selectedIndex = parseInt($F('recur_ex').substr(4, 2), 10) - 1; + $('start_day').selectedIndex = parseInt($F('recur_ex').substr(6, 2), 10) - 1; + + this.updateWday('start'); + this.updateEndDate(); + + $('recur_weekly_interval').adjacent('.checkbox').invoke('setValue', 0); + break; + + case 'end_img': + case 'recur_end_img': + case 'start_img': + Horde_Calendar.open(elt, this.getFormDate(id.slice(0, -4))); + e.stop(); + break; + + case 'mo': + case 'tu': + case 'we': + case 'th': + case 'fr': + case 'sa': + case 'su': + this.setInterval('recurweekly', 'recur_weekly_interval'); + this.setRecur(2); + break; + + case 'nooverwrite': + case 'yesoverwrite': + if ($F('nooverwrite')) { + $('notification_options').hide(); + } else { + $('notification_options').show(); + $('yesalarm').setValue(1); + } + break; + + case 'recurdaily': + case 'recurdaily_label': + this.setInterval('recurdaily', 'recur_daily_interval'); + break; + + case 'recurmonthday': + case 'recurmonthday_label': + this.setInterval('recurmonthday', 'recur_day_of_month_interval'); + break; + + case 'recurmonthweek': + case 'recurmonthweek_label': + this.setInterval('recurmonthweek', 'recur_week_of_month_interval'); + break; + + case 'recurnone': + this.clearFields(0); + break; + + case 'recurweekly': + case 'recurweekly_label': + this.setInterval('recurweekly', 'recur_weekly_interval'); + break; + + case 'recuryear': + case 'recuryear_label': + this.setInterval('recuryear', 'recur_yearly_interval'); + break; + + case 'recuryearday': + case 'recuryearday_label': + this.setInterval('recuryearday', 'recur_yearly_day_interval'); + break; + + case 'recuryearweekday': + case 'recuryearweekday_label': + this.setInterval('recuryearweekday', 'recur_yearly_weekday_interval'); + break; + + default: + if (elt.readAttribute('name') == 'resetButton') { + $('eventform').reset(); + this.updateWday('start'); + this.updateWday('end'); + } else { + if (!elt.match('TD')) { + elt = elt.up('TD'); + } + if (elt && elt.hasClassName('toggle')) { + elt.down().toggle().next().toggle(); + $('section' + elt.identify().substr(6)).toggle(); + } + } + break; + } + }, + + changeHandler: function(e) + { + this.doAction(e.element().readAttribute('id')); + }, + + keypressHandler: function(e) + { + switch (e.element().readAttribute('id')) { + case 'recur_daily_interval': + this.setRecur(1); + break; + + case 'recur_weekly_interval': + this.setRecur(2); + break; + + case 'recur_day_of_month_interval': + this.setRecur(3); + break; + + case 'recur_week_of_month_interval': + this.setRecur(4); + break; + + case 'recur_yearly_interval': + this.setRecur(5); + break; + + case 'recur_yearly_day_interval': + this.setRecur(6); + break; + + case 'recur_yearly_weekday_interval': + this.setRecur(7); + break; + } + }, + + doAction: function(id) + { + var endDate, endHour, duration, durHour, durMin, failed, startDate, + startHour; + + switch (id) { + case 'allday': + if ($F('allday')) { + if (KronolithVar.twentyFour) { + $('start_hour').selectedIndex = 0; + } else { + $('start_hour').selectedIndex = 11; + $('am').setValue(1); + } + $('start_min').setValue(0); + $('dur_day').setValue(1); + $('dur_hour').setValue(0); + $('dur_min').setValue(0); + } + this.updateEndDate(); + $('duration').setValue(1); + break; + + case 'am': + $('allday').setValue(0); + this.updateEndDate(); + break; + + case 'dur_day': + case 'dur_hour': + case 'dur_min': + $('allday').setValue(0); + this.updateEndDate(); + $('end').setValue(1); + break; + + case 'eam': + case 'epm': + break; + + case 'end_year': + case 'end_month': + case 'end_day': + this.updateWday('end'); + // Fall-through + + case 'end_hour': + case 'end_min': + case 'pm': + $('end').setValue(1); + + startHour = this.convertTo24Hour(parseInt($F('start_hour'), 10), 'pm'); + endHour = this.convertTo24Hour(parseInt($F('end_hour'), 10), 'epm'); + startDate = Date.UTC( + $F('start_year'), + $F('start_month') - 1, + $F('start_day'), + startHour, + $F('start_min') + ); + endDate = Date.UTC( + $F('end_year'), + $F('end_month') - 1, + $F('end_day'), + endHour, + $F('end_min') + ); + + if (endDate < startDate) { + if (KronolithVar.twentyFour && + $F('start_year') == $F('end_year') && + $F('start_month') == $F('end_month') && + $F('start_day') == $F('end_day') && + !$F('pm') && !$F('epm')) { + /* If the end hour is marked as the (default) AM, and + * the start hour is also AM, automatically default + * the end hour to PM if the date is otherwise the + * same - assume that the user wants a 9am-2pm event + * (for example), instead of throwing an error. */ + + // Toggle the end date to PM. + $('epm').checked = true; + + // Recalculate end time + endHour = this.convertTo24Hour(parseInt($F('end_hour'), 10), 'epm'); + endDate = Date.UTC( + $F('end_year'), + $F('end_month') - 1, + $F('end_day'), + endHour, + $F('end_min') + ); + } else { + alert(KronolithText.enddate_error); + endDate = startDate; + failed = true; + } + } + + duration = (endDate - startDate) / 1000; + $('dur_day').setValue(Math.floor(duration / 86400)); + duration %= 86400; + + durHour = Math.floor(duration / 3600); + duration %= 3600; + + durMin = Math.floor(duration / 60 / 5); + + $('dur_hour').selectedIndex = durHour; + $('dur_min').selectedIndex = durMin; + $('allday').setValue(false); + + if (failed) { + this.updateEndDate(); + } + break; + + case 'recur_end_year': + case 'recur_end_month': + case 'recur_end_day': + $('recur_end_type').setValue(1); + this.updateWday('recur_end'); + break; + + case 'recur_daily_interval': + this.setRecur(1); + break; + + case 'recur_weekly_interval': + this.setRecur(2); + break; + + case 'recur_day_of_month_interval': + this.setRecur(3); + break; + + case 'recur_week_of_month_interval': + this.setRecur(4); + break; + + case 'recur_yearly_interval': + this.setRecur(5); + break; + + case 'recur_yearly_day_interval': + this.setRecur(6); + break; + + case 'recur_yearly_weekday_interval': + this.setRecur(7); + break; + + case 'start_year': + case 'start_month': + case 'start_day': + this.updateWday('start'); + // Fall-through + + case 'start_hour': + case 'start_min': + $('allday').setValue(0); + this.updateEndDate(); + break; + } + }, + + updateEndDate: function() + { + var endHour, endYear, msecs, + startHour = this.convertTo24Hour(parseInt($F('start_hour'), 10), 'pm'), + startDate = new Date( + $F('start_year'), + $F('start_month') - 1, + $F('start_day'), + startHour, + $F('start_min') + ), + endDate = new Date(), + minutes = $F('dur_day') * 1440; + + minutes += $F('dur_hour') * 60; + minutes += parseInt($F('dur_min')); + msecs = minutes * 60000; + + endDate.setTime(startDate.getTime() + msecs); + + endYear = endDate.getFullYear(); + + $('end_year').setValue(endYear); + $('end_month').selectedIndex = endDate.getMonth(); + $('end_day').selectedIndex = endDate.getDate() - 1; + + endHour = endDate.getHours() + if (!KronolithVar.twentyFour) { + if (endHour < 12) { + if (endHour == 0) { + endHour = 12; + } + $('eam').setValue(1); + } else { + if (endHour > 12) { + endHour -= 12; + } + $('epm').setValue(1); + } + endHour -= 1; + } + + $('end_hour').selectedIndex = endHour; + $('end_min').selectedIndex = endDate.getMinutes() / 5; + + this.updateWday('end'); + }, + + // Converts a 12 hour based number to its 24 hour format + convertTo24Hour: function(val, elt) + { + if (KronolithVar.twentyFour) { + if ($F(elt)) { + if (val != 12) { + val += 12; + } + } else if (val == 12) { + val = 0; + } + } + + return val; + }, + + setInterval: function(elt, id) + { + if (!$F(id)) { + $(elt).setValue(1); + } + + switch (id) { + case 'recur_daily_interval': + KronolithEventForm.clearFields(1); + break; + + case 'recur_weekly_interval': + KronolithEventForm.clearFields(2); + break; + + case 'recur_day_of_month_interval': + KronolithEventForm.clearFields(3); + break; + + case 'recur_week_of_month_interval': + KronolithEventForm.clearFields(4); + break; + + case 'recur_yearly_interval': + KronolithEventForm.clearFields(5); + break; + } + }, + + setRecur: function(index) + { + document.eventform.recur[index].checked = true; + KronolithEventForm.clearFields(index); + }, + + clearFields: function(index) + { + if (index != 1) { + $('recur_daily_interval').setValue(''); + } + if (index != 2) { + $('recur_weekly_interval').setValue(''); + $('recur_weekly_interval').adjacent('.checkbox').invoke('setValue', 0); + } + if (index != 3) { + $('recur_day_of_month_interval').setValue(''); + } + if (index != 4) { + $('recur_week_of_month_interval').setValue(''); + } + if (index != 5) { + $('recur_yearly_interval').setValue(''); + } + }, + + onDomLoad: function() + { + this.updateWday('start'); + this.updateWday('end'); + this.updateWday('recur_end'); + + $('eventform').observe('click', this.clickHandler.bindAsEventListener(this)); + $('eventform').observe('change', this.changeHandler.bindAsEventListener(this)); + $('eventform').observe('keypress', this.keypressHandler.bindAsEventListener(this)); + } + +}; + +document.observe('dom:loaded', KronolithEdit.onDomLoad.bind(KronolithEdit)); +document.observe('Horde_Calendar:select', KronolithEdit.calendarSelect.bindAsEventListener(KronolithEdit)); diff --git a/kronolith/lib/Event.php b/kronolith/lib/Event.php index 4ef5718fa..b2d932de7 100644 --- a/kronolith/lib/Event.php +++ b/kronolith/lib/Event.php @@ -2364,7 +2364,7 @@ abstract class Kronolith_Event case 'start[year]': return '' . ''; case 'start[month]': @@ -2372,7 +2372,6 @@ abstract class Kronolith_Event for ($i = 1; $i < 13; ++$i) { $options[$i] = strftime('%b', mktime(1, 1, 1, $i, 1)); } - $attributes = ' onchange="' . $this->js($property) . '"'; $label = _("Start Month"); break; @@ -2381,7 +2380,6 @@ abstract class Kronolith_Event for ($i = 1; $i < 32; ++$i) { $options[$i] = $i; } - $attributes = ' onchange="' . $this->js($property) . '"'; $label = _("Start Day"); break; @@ -2392,7 +2390,6 @@ abstract class Kronolith_Event for ($i = $hour_min; $i < $hour_max; ++$i) { $options[$i] = $i; } - $attributes = ' onchange="document.eventform.whole_day.checked = false; KronolithEventForm.updateEndDate();"'; $label = _("Start Hour"); break; @@ -2402,14 +2399,13 @@ abstract class Kronolith_Event $min = sprintf('%02d', $i * 5); $options[$min] = $min; } - $attributes = ' onchange="document.eventform.whole_day.checked = false; KronolithEventForm.updateEndDate();"'; $label = _("Start Minute"); break; case 'end[year]': return '' . ''; case 'end[month]': @@ -2417,7 +2413,6 @@ abstract class Kronolith_Event for ($i = 1; $i < 13; ++$i) { $options[$i] = strftime('%b', mktime(1, 1, 1, $i, 1)); } - $attributes = ' onchange="' . $this->js($property) . '"'; $label = _("End Month"); break; @@ -2426,7 +2421,6 @@ abstract class Kronolith_Event for ($i = 1; $i < 32; ++$i) { $options[$i] = $i; } - $attributes = ' onchange="' . $this->js($property) . '"'; $label = _("End Day"); break; @@ -2439,7 +2433,6 @@ abstract class Kronolith_Event for ($i = $hour_min; $i < $hour_max; ++$i) { $options[$i] = $i; } - $attributes = ' onchange="KronolithEventForm.updateDuration(); document.eventform.end_or_dur[0].checked = true"'; $label = _("End Hour"); break; @@ -2450,7 +2443,6 @@ abstract class Kronolith_Event $min = sprintf('%02d', $i * 5); $options[$min] = $min; } - $attributes = ' onchange="KronolithEventForm.updateDuration(); document.eventform.end_or_dur[0].checked = true"'; $label = _("End Minute"); break; @@ -2458,7 +2450,7 @@ abstract class Kronolith_Event $dur = $this->getDuration(); return '' . ''; case 'dur_hour': @@ -2467,7 +2459,6 @@ abstract class Kronolith_Event for ($i = 0; $i < 24; ++$i) { $options[$i] = $i; } - $attributes = ' onchange="' . $this->js($property) . '"'; $label = _("Duration Hour"); break; @@ -2478,7 +2469,6 @@ abstract class Kronolith_Event $min = sprintf('%02d', $i * 5); $options[$min] = $min; } - $attributes = ' onchange="' . $this->js($property) . '"'; $label = _("Duration Minute"); break; @@ -2492,7 +2482,7 @@ abstract class Kronolith_Event } return '' . ''; case 'recur_end[month]': @@ -2506,7 +2496,6 @@ abstract class Kronolith_Event for ($i = 1; $i < 13; ++$i) { $options[$i] = strftime('%b', mktime(1, 1, 1, $i, 1)); } - $attributes = ' onchange="' . $this->js($property) . '"'; $label = _("Recurrence End Month"); break; @@ -2521,7 +2510,6 @@ abstract class Kronolith_Event for ($i = 1; $i < 32; ++$i) { $options[$i] = $i; } - $attributes = ' onchange="' . $this->js($property) . '"'; $label = _("Recurrence End Day"); break; } @@ -2536,34 +2524,6 @@ abstract class Kronolith_Event ''; } - public function js($property) - { - switch ($property) { - case 'start[month]': - case 'start[year]': - case 'start[day]': - case 'start': - return 'KronolithEventForm.updateWday(\'start_wday\'); document.eventform.whole_day.checked = false; KronolithEventForm.updateEndDate();'; - - case 'end[month]': - case 'end[year]': - case 'end[day]': - case 'end': - return 'KronolithEventForm.updateWday(\'end_wday\'); updateDuration(); document.eventform.end_or_dur[0].checked = true;'; - - case 'recur_end[month]': - case 'recur_end[year]': - case 'recur_end[day]': - case 'recur_end': - return 'KronolithEventForm.updateWday(\'recur_end_wday\'); document.eventform.recur_end_type[1].checked = true;'; - - case 'dur_day': - case 'dur_hour': - case 'dur_min': - return 'document.eventform.whole_day.checked = false; KronolithEventForm.updateEndDate(); document.eventform.end_or_dur[1].checked = true;'; - } - } - /** * @param array $params * diff --git a/kronolith/lib/View/EditEvent.php b/kronolith/lib/View/EditEvent.php index 5a85fbbd1..d3a1e9096 100644 --- a/kronolith/lib/View/EditEvent.php +++ b/kronolith/lib/View/EditEvent.php @@ -119,9 +119,14 @@ class Kronolith_View_EditEvent { $tags = $tagger->getTags($event->uid, 'event'); $tags = implode(',', array_values($tags)); - echo '