Add lots of JS magic to make calendar usable
authorJoey Schulze <joey@infodrom.org>
Thu, 27 Jul 2017 21:08:57 +0000 (23:08 +0200)
committerJoey Schulze <joey@infodrom.org>
Sat, 6 Oct 2018 17:30:26 +0000 (19:30 +0200)
 . 2-month view
 . 1-month view
 . add comments
 . add urls
 . display, and comments and urls
 . colorise events

class/calendar.class.php
class/calendar_item.class.php [new file with mode: 0644]
class/databasetable.class.php
src/Infodrom/calendar/index.wml
src/infodrom.css

index 68ca9b8..8fc45ca 100644 (file)
@@ -6,7 +6,7 @@ class Calendar extends DatabaseTable {
   {
     $db = new Database(DBDRIVER, DBHOST, DAV_DBNAME, DBUSER, DBPASS);
 
-    parent::__construct('calendar_item', $id, $db, 'dav_id');
+    parent::__construct('calendar_item', false, $db);
   }
 
   public static function pgTimestamp($timestamp)
@@ -72,4 +72,240 @@ class Calendar extends DatabaseTable {
     return $this->db->fetchObjectList($sql);
   }
 
+  public function ajaxMonths(Array $data)
+  {
+    $monthname = array('','Jan','Feb','Mär', 'Apr','Mai','Jun','Jul','Aug','Sep','Okt','Nov','Dez');
+    $sql = sprintf("SELECT DISTINCT extract(year from dtstart) AS year,extract(month from dtstart) AS month " .
+                  "FROM calendar_item WHERE user_no = %d ORDER BY year DESC,month DESC",
+                  DAV_USER_NO);
+    $out = '';
+    $now = array(date('Y'), date('m'));
+    foreach ($this->db->fetchObjectList($sql) as $row) {
+      $out .= sprintf('<option value="%04d-%02d"%s>%s %04d</option>',
+                     $row->year, $row->month,
+                     $row->year == $now[0] && $row->month == $now[1] ? ' selected' : '',
+                     utf8_encode($monthname[$row->month]), $row->year);
+    }
+
+    return array('values' => array('thismonth' => date('Y-m')),
+                'html' => array('month' => $out));
+  }
+
+  private function getMonthData($year, $month)
+  {
+    $numdays = cal_days_in_month(CAL_GREGORIAN, $month, $year);
+
+    $areaDates = array();
+    for ($i=1; $i < 8; $i++) {
+      $date = sprintf('%04d-%02d-%02d', $year, $month, 1);
+      $sql = sprintf("SELECT dav_id FROM calendar_item WHERE user_no = %d AND dtstart::date = '%s'::date - INTERVAL '%d DAY' ORDER BY dtstart",
+                    DAV_USER_NO, $date, $i);
+      foreach ($this->fetchObjectList($sql) as $row) {
+        $item = new Calendar_Item($row->dav_id);
+       if ($item->isRegular()) continue;
+
+       foreach ($item->getDays() as $adate) {
+         if (!array_key_exists($adate, $areaDates))
+           $areaDates[$adate] = array();
+         $areaDates[$adate][] = $item;
+       }
+      }
+    }
+
+    $regDates = array();
+    for ($day=1; $day <= $numdays; $day++) {
+      $timestamp = mktime (0, 0, 0, $month, $day, $year);
+      $date = sprintf('%04d-%02d-%02d', $year, $month, $day);
+      $sql = sprintf("SELECT dav_id FROM calendar_item WHERE user_no = %d AND dtstart::date = '%s'::date ORDER BY dtstart",
+                    DAV_USER_NO, $date);
+
+      foreach ($this->fetchObjectList($sql) as $row) {
+       $item = new Calendar_Item($row->dav_id);
+
+       if (!$item->isRegular()) {
+         foreach ($item->getDays() as $adate) {
+           if (!array_key_exists($adate, $areaDates))
+             $areaDates[$adate] = array();
+           $areaDates[$adate][] = $item;
+         }
+       } else {
+         if (!array_key_exists($date, $regDates))
+           $regDates[$date] = array();
+         $regDates[$date][] = $item;
+       }
+      }
+    }
+
+    return array($areaDates, $regDates);
+  }
+
+  private function formatOneMonth($year, $month)
+  {
+    $weekday = array('', 'Mo', 'Di', 'Mi', 'Do', 'Fr', 'Sa', 'So');
+    $monthname = array('','Jan','Feb','Mär', 'Apr','Mai','Jun','Jul','Aug','Sep','Okt','Nov','Dez');
+    $numdays = cal_days_in_month(CAL_GREGORIAN, $month, $year);
+
+    $out = sprintf('<div class="head" month="%04d-%02d">%s %04d</div>',
+                  $year, $month, $monthname[intval($month)], $year);
+
+    list($areaDates, $regDates) = $this->getMonthData($year, $month);
+
+    $today = date('Y-m-d');
+    for ($day=1; $day <= $numdays; $day++) {
+      $timestamp = mktime (0, 0, 0, $month, $day, $year);
+      $date = sprintf('%04d-%02d-%02d', $year, $month, $day);
+      $items = array();
+
+      if (array_key_exists($date, $areaDates))
+       foreach ($areaDates[$date] as $item)
+         $items[] = $item->toSpan();
+
+      if (array_key_exists($date, $regDates))
+       foreach ($regDates[$date] as $item)
+         $items[] = $item->toSpan();
+
+      $class = date('N', $timestamp) == 7 ? 'sunday' : 'day';
+      if ($today == $date) $class .= ' today';
+      $kw = date('N', $timestamp) == 1 ? sprintf('<div class="kw">%d</div>', date('W', $timestamp)) : '';
+      $out .= sprintf('<div class="%s" day="%d"><div class="wday">%s</div><div class="date">%d.</div>%s%s</div>',
+                     $class,
+                     $day,
+                     $weekday[intval(date('N', $timestamp))],
+                     $day,
+                     count($items) ? implode('', $items) : '&nbsp;',
+                     $kw);
+    }
+    return $out;
+  }
+
+  public function ajaxBiMonth(Array $data)
+  {
+    list($year, $month) = explode('-', $data['month']);
+    if (!empty($data['direction'])) {
+      switch ($data['direction']) {
+      case 'prev':
+       if ($month > 1) $month--;
+       else {$year--; $month = 12;}
+       break;
+      case 'next':
+       if ($month < 12) $month++;
+       else {$year++; $month = 1;}
+       break;
+      }
+    }
+
+    $monthStr = sprintf('%04d-%02d', $year, $month);
+    $right = $this->formatOneMonth($year, $month);
+
+    if ($month < 12) $month++;
+    else {$year++; $month = 1;}
+    $left = $this->formatOneMonth($year, $month);
+
+    $out = '<div class="bimonth">';
+
+    $out .= '<div class="monthcolumn">';
+    $out .= $right;
+    $out .= '</div>';
+
+    $out .= '<div class="monthcolumn">';
+    $out .= $left;
+    $out .= '</div>';
+
+    $out .= '</div>';
+
+    return array('values' => array('thismonth' => $monthStr),
+                'html' => array('termine' => $out));
+  }
+
+  public function ajaxMonth(Array $data)
+  {
+    $monthname = array('','Januar','Februar','März', 'April','Mai','Juni','Juli','August','September','Oktober','November','Dezember');
+
+    list($year, $month) = explode('-', $data['month']);
+    if (!empty($data['direction'])) {
+      switch ($data['direction']) {
+      case 'prev':
+       if ($month > 1) $month--;
+       else {$year--; $month = 12;}
+       break;
+      case 'next':
+       if ($month < 12) $month++;
+       else {$year++; $month = 1;}
+       break;
+      }
+    }
+
+    $monthStr = sprintf('%04d-%02d', $year, $month);
+    $monthText = utf8_encode($monthname[intval($month)] . ' ' . $year);
+    $numdays = cal_days_in_month(CAL_GREGORIAN, $month, $year);
+
+    list($areaDates, $regDates) = $this->getMonthData($year, $month);
+
+    $out = '<div class="month">';
+
+    $out .= <<<EOT
+<table width="100%" cellspacing="0" border="collapse">
+<thead>
+<tr><td colspan="8" class="title">{$monthText}</td></tr>
+<tr>
+      <td width="2%">&nbsp;</td>
+      <td width="14%">Montag</td>
+      <td width="14%">Dienstag</td>
+      <td width="14%">Mittwoch</td>
+      <td width="14%">Donnerstag</td>
+      <td width="14%">Freitag</td>
+      <td width="14%">Samstag</td>
+      <td width="14%">Sonntag</td>
+</tr>
+</thead>
+<tbody>
+EOT;
+
+    $timestamp = mktime (4, 0, 0, $month, 1, $year);
+    if (date('N', $timestamp) != 1) {
+      $out .= '<tr>';
+      $out .= sprintf('<td width="2%%">%d</td>', date('W', $timestamp));
+      for ($i=1; $i < date('N', $timestamp); $i++)
+       $out .= '<td width="14%" class="empty">&nbsp;</td>';
+    }
+
+    $today = date('Y-m-d');
+    for ($day=1; $day <= $numdays; $day++) {
+      $timestamp = mktime (4, 0, 0, $month, $day, $year);
+      $date = sprintf('%04d-%02d-%02d', $year, $month, $day);
+      if (date('N', $timestamp) == 1)
+       $out .= sprintf('<tr><td width="2%%">%d</td>', date('W', $timestamp));
+
+      $items = array();
+
+      if (array_key_exists($date, $areaDates))
+       foreach ($areaDates[$date] as $item)
+         $items[] = $item->toSpan();
+
+      if (array_key_exists($date, $regDates))
+       foreach ($regDates[$date] as $item)
+         $items[] = $item->toSpan();
+
+      $out .= sprintf('<td width="14%%"><div class="day">%d</day><div>%s</div></td>',
+                     date('d', $timestamp),
+                     count($items) ? implode('<br />', $items) : '&nbsp;');
+
+      if (date('N', $timestamp) == 7)
+       $out .= '</tr>';
+    }
+
+    if (date('N', $timestamp) != 7) {
+      for ($i=date('N', $timestamp); $i < 7; $i++)
+        $out .= '<td width="14%" class="empty">&nbsp;</td>';
+      $out .= '</tr>';
+    }
+
+    $out .= '</tbody></table>';
+
+    $out .= '</div>';
+
+    return array('values' => array('thismonth' => $monthStr),
+                'html' => array('termine' => $out));
+  }
+
 }
diff --git a/class/calendar_item.class.php b/class/calendar_item.class.php
new file mode 100644 (file)
index 0000000..99f0cf1
--- /dev/null
@@ -0,0 +1,139 @@
+<?php
+
+class Calendar_Item extends DatabaseTable {
+  private $isRegular;
+  private $timespan;
+  private $timedays = array();
+
+  public function __construct($id=false)
+  {
+    $this->idcolumn = 'dav_id';
+    $db = new Database(DBDRIVER, DBHOST, DAV_DBNAME, DBUSER, DBPASS);
+
+    parent::__construct('calendar_item', $id, $db);
+  }
+
+  protected function postLoad()
+  {
+    $start = explode(' ', $this->data->dtstart);
+    $starttime = explode(':', $start[1]);
+    $end = explode(' ', $this->data->dtend);
+    $endtime = explode(':', $end[1]);
+
+    $this->isRegular = $start[0] == $end[0];
+
+    if ($this->isRegular) {
+      if ($starttime[1] == '00' && $endtime[1] == '00') {
+       if ($starttime[0] == $endtime[0])
+         $this->timespan = $starttime[0];
+       else
+         $this->timespan = $starttime[0] .'-'. $endtime[0];
+      } else {
+       $this->timespan = sprintf('%d:%02d-%d:%02d',
+                                 $starttime[0], $starttime[1],
+                                 $endtime[0], $endtime[1]);
+      }
+    } else {
+      $startTimeStamp = strtotime($start[0]) + (3*60*60);
+      $endTimeStamp = strtotime($end[0]);
+
+      while ($startTimeStamp < $endTimeStamp) {
+       $this->timeDays[] = date('Y-m-d', $startTimeStamp);
+       $startTimeStamp += (24*60*60);
+      }
+    }
+
+  }
+
+  public function isRegular()
+  {
+    return $this->isRegular;
+  }
+
+  public function timespan()
+  {
+    return $this->timespan;
+  }
+
+  public function getDays()
+  {
+    return $this->timeDays;
+  }
+
+  public function toSpan()
+  {
+    $tooltip = '';
+    if ($this->data->description)
+      $tooltip .= (strlen($tooltip)?', ':'').$this->data->description;
+    if ($this->data->location)
+      $tooltip .= (strlen($tooltip)?', ':'').'Ort: '.$this->data->location;
+
+    if (strlen($tooltip))
+      $tooltip = sprintf(' title="%s"', $tooltip);
+
+    $sql = sprintf("SELECT color FROM calendar_item_data WHERE dav_id = %d", $this->id);
+    $bgcolor = $this->fetchValue($sql);
+    if ($bgcolor) $bgcolor = sprintf(' style="background:%s;"', $bgcolor);
+
+    return sprintf('<span dav_id="%d"%s%s>%s %s</span>',
+                  $this->id,
+                  $tooltip, $bgcolor,
+                  $this->timespan(),
+                  $this->data->summary);
+  }
+
+  public function ajaxSetColor(Array $data)
+  {
+    $sql = sprintf("SELECT id FROM calendar_item_data WHERE dav_id = %d", $this->id);
+    $id = $this->fetchValue($sql);
+
+    if ($id)
+      $sql = sprintf("UPDATE calendar_item_data SET color = %s WHERE id = %d",
+                    $this->quote($data['color']), $id);
+    else
+      $sql = sprintf("INSERT INTO calendar_item_data (dav_id, color) VALUES (%d,%s)",
+                    $this->id, $this->quote($data['color']));
+
+    return $this->execute($sql);
+  }
+
+  public function ajaxLog(Array $data)
+  {
+    $title = $this->data->summary;
+    if ($this->data->location)
+      $title .= ', ' . $this->data->location;
+
+    $out = sprintf('<div class="caltitle">%s</div>', $title);
+    $out .= sprintf('<div>%s: Item created</div>', substr($this->data->created,0,16));
+    # $out .= sprintf('<div>Last modified %s</div>', $this->data->last_modified);
+
+    $sql = sprintf("SELECT name,url,comment,sys_edit,sys_user " .
+                  "FROM calendar_item_log WHERE dav_id = %d ORDER BY sys_edit", $this->id);
+    foreach ($this->fetchObjectList($sql) as $row) {
+      if (strlen($row->url))
+       $out .= sprintf('<div>%s: <a href="%s" target="_blank">%s</a></div>',
+                       substr($row->sys_edit,0,16),
+                       $row->url,
+                       $row->name ? $row->name : 'Link');
+      if (strlen($row->comment))
+       $out .= sprintf('<div>%s: %s</div>', substr($row->sys_edit,0,16), $row->comment);
+    }
+
+    return array('html' => array('log' => $out));
+  }
+
+  public function ajaxAddLog(Array $data)
+  {
+    if (!strlen($data['name']) && !strlen($data['url']) && !strlen($data['comment'])) return true;
+
+    $item = array('dav_id' => $this->id,
+                 'name' => strlen($data['name']) ? $data['name'] : NULL,
+                 'url' => strlen($data['url']) ? $data['url'] : NULL,
+                 'comment' => strlen($data['comment']) ? $data['comment'] : NULL,
+                 'sys_user' => $_SERVER['REMOTE_USER'],
+                 'sys_edit' => 'now()');
+
+    return $this->db->insertInto('calendar_item_log', $item);
+  }
+
+}
index 246d012..de2038a 100644 (file)
@@ -91,6 +91,15 @@ abstract class DatabaseTable {
     $this->db->delete($this->table, $this->idcolumn, $id === false ? $this->id : $id);
   }
 
+  public function getAttribute($attr)
+  {
+    if ($this->data === false) return NULL;
+    if (property_exists($this->data, $attr))
+      return $this->data->$attr;
+
+    return NULL;
+  }
+
   public function quote($string) { return $this->db->quote($string); }
   public function execute($sql) { return $this->db->execute($sql); }
   public function fetchValue($sql) { return $this->db->fetchValue($sql); }
index 7a71044..ceb4b41 100644 (file)
@@ -4,7 +4,12 @@
 <page func="Infodrom Oldenburg" title="Termine">
 
 <style type="text/css">
-div#termine {
+div.view {
+    float:right;
+    margin-top:-30px;
+}
+div.clear {
+    clear: both;
     margin-bottom: 10px;
 }
 table#calendar tr.row:hover {
@@ -19,8 +24,101 @@ table#calendar tr.month {
 table#calendar tr.current {
     background: orange;
 }
+div.bimonth div.monthcolumn {
+    float: left;
+    width: 50%;
+}
+div.bimonth div.head {
+    font-weight: bold;
+    border-bottom: 1px solid #ccc;
+    text-align: center;
+}
+div.bimonth div.day {
+    position: relative;
+    border-bottom: 1px solid #ccc;
+}
+div.bimonth div.sunday {
+    border-bottom: 1px solid black;
+}
+div.bimonth div.today {
+    background: #90ee90;
+}
+div.bimonth div div.wday {
+    width: 1.6em;
+    margin-right: 2px;
+    float: left;
+}
+div.bimonth div div.date {
+    width: 1.6em;
+    margin-right: 2px;
+    float: left;
+}
+div.bimonth div.kw {
+    position: absolute;
+    top: 0px;
+    right: 1px;
+    color: #999;
+}
+div.month table thead td.title {
+  background: #b0e2ff;
+}
+div.month table tbody td {
+    height: 100px;
+    vertical-align: top;
+    position: relative;
+}
+div.month table tbody td.empty {
+    background: #ddd;
+}
+div.month table tbody td span {
+    font-size: 90%;
+}
+
+div#termine span {
+    padding-left: 1px;
+    padding-right: 1px;
+}
+
+span.menu_title {
+    padding-left: 2px;
+    padding-right: 2px;
+    background: #e0e0e0;
+    font-weight: bold;
+    border-bottom: 1px solid #8f8f8f;
+    display: block;
+}
+div.menu {
+    background: #fffb71;
+    position: absolute;
+    border: 1px solid #8f8f8f;
+    z-index: 10;
+}
+span.menu {
+    padding-left: 2px;
+    padding-right: 2px;
+    display: block;
+    cursor: default;
+}
+span.menu:hover {
+    background: #96ccff;
+}
+
+div.popup_body div#log div.caltitle {
+    border-top: 0px !important;
+}
+div.popup_body div#log div {
+    margin: 0;
+    padding: 0;
+    font-size: 90%;
+    border-top: 1px solid #ccc;
+}
+div.popup_body div#log div:hover
+{
+    background: #eee;
+}
 </style>
 
+<input type="hidden" id="thismonth">
 <div id="termine">
 <table id="calendar" width="100%" class="smallfont border" cellspacing="0" summary="">
 <tr class="head">
@@ -66,13 +164,13 @@ table#calendar tr.current {
     if (strlen($kw) && $kw != $row->kw)
       $class .= ' newkw';
       
-    printf('<tr id="%d" class="%s"><td>%s</td><td>%s</td><td%s>%s</td><td>%s</td></tr>',
+    $item = new Calendar_Item($row->dav_id);
+    printf('<tr id="%d" class="%s"><td>%s</td><td>%s</td><td>%s</td><td>%s</td></tr>',
           $row->dav_id,
           $class,
           $kw != $row->kw ? $row->kw : '&nbsp;',
           Calendar::formatTimespan($row->dtstart, $row->dtend),
-          utf8_decode($tooltip),
-          utf8_decode($row->summary),
+          utf8_decode($item->toSpan()),
           utf8_decode($row->location));
     $kw = $row->kw;
   }
@@ -81,7 +179,197 @@ table#calendar tr.current {
 
 </table>
 </div>
+<div class="clear"></div>
+
+<div id="menu" class="menu" style="display:none;">
+<span class="menu_title" onmouseup="\$(this).parent().hide()">Titel</span>
+<span class="menu" onmouseup="add_comment()">Comment</span>
+<span class="menu" onmouseup="show_log()">Protocol</span>
+<span class="menu" onmouseup="colorise()">Color</span>
+<span class="menu" onmouseup="menu_close()">close</span>
+</div>
+
+<select name="colorpicker" style="display:none;">
+  <option value="#5484ed">Bold blue</option>
+  <option value="#a4bdfc">Blue</option>
+  <option value="#63b8ff">Steel blue</option>
+  <option value="#87ceeb">Sky blue</option>
+  <option value="#46d6db">Turquoise</option>
+  <option value="#7ae7bf">Light green</option>
+  <option value="#c0ff3e">Olive</option>
+  <option value="#7bd148">Green</option>
+  <option value="#51b749">Bold green</option>
+  <option value="#ffff00">Yellow</option>
+  <option value="#fbd75b">Yellow</option>
+  <option value="#ffb878">Orange</option>
+  <option value="#f4a460">Sandy brown</option>
+  <option value="#ff6a6a">IndianRed</option>
+  <option value="#ffa500">Orange</option>
+  <option value="#ff8247">Sienna</option>
+  <option value="#ff887c">Red</option>
+  <option value="#dc2127">Bold red</option>
+  <option value="#ff7f00">Dark orange</option>
+  <option value="#ee82ee">Violett</option>
+  <option value="#dbadff">Purple</option>
+  <option value="#ff00ff">Magenta</option>
+  <option value="#d4d4d4">Gray</option>
+  <option value="#e1e1e1">Gray</option>
+  <option value="#ededed">Light gray</option>
+</select>
 
+<protect><script type="text/javascript">
+function menu_close()
+{
+    $('div#menu').hide();
+}
+
+function dom_enhance()
+{
+    var html = ['<div class="view">',
+               '<button id="prev" style="display:none;">&lt;&lt;</button>',
+               '&nbsp;&nbsp;',
+               '<button id="next" style="display:none;">&gt;&gt;</button>',
+               '&nbsp;&nbsp;',
+               '<select id="month" style="display:none;">',
+               '<option value="">jetzt</option>',
+               '</select>',
+               '&nbsp;&nbsp;',
+               '<select id="view">',
+               '<option value="normal">Normal</option>',
+               '<option value="bimonth">2 Monate</option>',
+               '<option value="month">Monat</option>',
+               '</select>',
+               '</div>'];
+
+    $(html.join('')).insertAfter('h3');
+    $.invoke('Calendar/Months');
+}
+
+var logwindow = false;
+function show_log()
+{
+    menu_close()
+
+    if (!logwindow) {
+       logwindow = new Popup('Protocol', '500px', false, '<div id="log"></div>');
+       logwindow.centerPopup();
+    } else {
+       logwindow.openPopup();
+    }
+
+    $.invoke('Calendar_Item/Log', {id: $('div#menu').attr('dav_id')});
+}
+
+var commentwindow = false;
+function add_comment()
+{
+    menu_close()
+
+    if (!commentwindow) {
+       var html = ['<form id="comment">',
+                   '<input type="hidden" name="id">',
+                   '<label for="name">Name</label>',
+                   '<input name="name" style="width: 296px;">',
+                   '<label for="url">Link</label>',
+                   '<input name="url" style="width: 296px;">',
+                   '<label for="comment">Bemerkung</label>',
+                   '<textarea name="comment" style="width: 296px; height:65px;"></textarea>',
+                   '<div style="text-align: center; margin-top: 5px;"><input type="submit" value="Speichern"></div>',
+                   '</form>'];
+       commentwindow = new Popup('Bemerkung hinzufügen', '300px', false, html.join(''));
+       commentwindow.centerPopup();
+       $('form#comment input[type="submit"]').click(function(e){
+           $.invoke('Calendar_Item/AddLog', $('form#comment').serialize(), function(data){
+               commentwindow.closePopup();
+           });
+           return false;
+       });
+    } else {
+       commentwindow.openPopup();
+    }
+    $('form#comment input,form#comment textarea').not('form#comment input[type="submit"]').val('');
+    $('form#comment input[name="id"]').val($('div#menu').attr('dav_id'));
+    $('form#comment input[name="name"]').focus();
+}
+
+var incolorise = false;
+function colorise()
+{
+    menu_close()
+
+    $('select[name="colorpicker"]').simplecolorpicker({
+       picker: false
+    }).change(function(e) {
+       if (incolorise) return;
+       incolorise = true;
+
+       var color = $('select[name="colorpicker"]').val();
+       var id = $('div#menu').attr('dav_id');
+
+       $('span[dav_id="'+id+'"]').css('background-color', color);
+
+       $.invoke('Calendar_Item/SetColor', {id: id, color: color}, function(data){
+           incolorise = false;
+       });
+
+       $('select[name="colorpicker"]').simplecolorpicker('destroy');
+       $('select[name="colorpicker"]').hide();
+    });
+}
+
+function month_actions(data)
+{
+    $('#termine span').contextmenu(function(e){
+       $('select[name="colorpicker"]').simplecolorpicker('destroy');
+       $('select[name="colorpicker"]').hide();
+       $('div#menu').attr('dav_id', $(this).attr('dav_id'));
+       $('div#menu').positionOn($(this), 'center').show();
+       return false;
+    });
+
+    $('select#month').val($('#thismonth').val());
+}
+
+$(function(){
+    dom_enhance();
+    month_actions();
+    $('#view').val('normal').change(function(e){
+       if ($('#view').val() == 'normal') {
+           document.location.href = document.location.href.split('?')[0] + '?month=normal';
+       } else if ($('#view').val() == 'bimonth') {
+           $('#month,div.view button').show();
+           $.invoke('Calendar/BiMonth', {month: $('#thismonth').val()}, month_actions);
+       } else if ($('#view').val() == 'month') {
+           $('#month,div.view button').show();
+           $.invoke('Calendar/Month', {month: $('#thismonth').val()}, month_actions);
+       }
+    });
+    $('#month').change(function(e){
+       if ($('#view').val() == 'bimonth') {
+           $.invoke('Calendar/BiMonth', {month: $('#month').val()}, month_actions);
+       } else if ($('#view').val() == 'month') {
+           $.invoke('Calendar/Month', {month: $('#month').val()}, month_actions);
+       }
+
+    });
+    $('div.view button').click(function(e){
+       if ($('#view').val() == 'bimonth') {
+           $.invoke('Calendar/BiMonth',
+                    {month: $('#thismonth').val(),
+                     direction: $(this).attr('id') == 'prev' ? 'prev' : 'next'}, month_actions);
+       } else if ($('#view').val() == 'month') {
+           $.invoke('Calendar/Month',
+                    {month: $('#thismonth').val(),
+                     direction: $(this).attr('id') == 'prev' ? 'prev' : 'next'}, month_actions);
+       }
+    });
+    if (document.location.href.indexOf('month=normal') == -1) {
+       $('#view').val('bimonth');
+       $.invoke('Calendar/BiMonth', {month: '<?=date('Y-m')?>'}, month_actions);
+    }
+    $('#month,div.view button').show();
+});
+</script></protect>
 </page>
 
 # Local variables:
index ad15cbe..850eeb1 100644 (file)
@@ -154,7 +154,7 @@ input.button:hover {
  */
 div.popup {
   background: white;
-  border: 1px solid #CCC;
+  border: 1px solid #777;
   height: auto;
   position: absolute;
 }
@@ -213,6 +213,10 @@ table#fc {
   z-index: 100;
 }
 
+div.popup div.caltitle {
+    font-weight: bold;
+}
+
 /*
  * jQuery & Co.
  */