Implement (event) searching.
authorJan Schneider <jan@horde.org>
Thu, 28 May 2009 17:04:50 +0000 (19:04 +0200)
committerJan Schneider <jan@horde.org>
Thu, 28 May 2009 17:09:38 +0000 (19:09 +0200)
kronolith/ajax.php
kronolith/js/src/kronolith.js
kronolith/lib/Kronolith.php
kronolith/templates/index/index.inc

index 8e810b9..9f424cd 100644 (file)
@@ -263,6 +263,42 @@ try {
         $result->deleted = true;
         break;
 
+    case 'SearchEvents':
+        $query = Horde_Serialize::unserialize(Util::getFormData('query'), Horde_Serialize::JSON);
+        if (!isset($query->start)) {
+            $query->start = new Horde_Date($_SERVER['REQUEST_TIME']);
+        }
+        if (!isset($query->end)) {
+            $query->end = null;
+        }
+        $cals   = Horde_Serialize::unserialize(Util::getFormData('cals'), Horde_Serialize::JSON);
+        $events = array();
+        foreach ($cals as $cal) {
+            if (!($kronolith_driver = getDriver($cal))) {
+                break;
+            }
+            $result = $kronolith_driver->search($query, true);
+            if (is_a($result, 'PEAR_Error')) {
+                $notification->push($result, 'horde.error');
+                break;
+            }
+            if ($result) {
+                $events[$cal] = $result;
+            }
+        }
+        $result = new stdClass;
+        $result->view = 'search';
+        $result->query = Util::getFormData('query');
+        if ($events) {
+            $result->events = $events;
+        }
+        break;
+
+    case 'SearchCalendars':
+        $result = new stdClass;
+        $result->events = 'Searched for calendars: ' . Util::getFormData('title');
+        break;
+
     case 'SaveCalPref':
         $result = true;
         break;
index 0dee38a..3e1daf8 100644 (file)
@@ -235,6 +235,58 @@ KronolithCore = {
             this.view = loc;
             break;
 
+        case 'search':
+            [ 'Day', 'Week', 'Month', 'Year', 'Tasks', 'Agenda' ].each(function(a) {
+                $('kronolithNav' + a).removeClassName('on');
+            });
+            if (this.view) {
+                $('kronolithView' + this.view.capitalize()).fade({ 'queue': 'end' });
+            }
+            var cals = [], term = locParts[1],
+                query = Object.toJSON({ 'title': term });
+            this.updateView(null, 'search', term);
+            $H(Kronolith.conf.calendars).each(function(type) {
+                $H(type.value).each(function(calendar) {
+                    if (calendar.value.show) {
+                        cals.push(type.key + '|' + calendar.key);
+                    }
+                });
+            });
+            this.startLoading('search', query, '');
+            this.doAction('Search' + locParts[0],
+                          { 'cals': cals.toJSON(), 'query': query },
+                          function(r) {
+                              // Hide spinner.
+                              this.loading--;
+                              if (!this.loading) {
+                                  $('kronolithLoading').hide();
+                              }
+                              if (r.response.view != 'search' ||
+                                  r.response.query != this.eventsLoading['search'] ||
+                                  Object.isUndefined(r.response.events)) {
+                                  return;
+                              }
+                              $H(r.response.events).each(function(calendars) {
+                                  $H(calendars.value).each(function(events) {
+                                      if (!$('kronolithAgendaDay' + events.key)) {
+                                          $('kronolithViewAgendaBody').insert(this.createAgendaDay(Date.parseExact(events.key, 'yyyyMMdd'), 0).show());
+                                      }
+                                      $H(events.value).each(function(event) {
+                                          event.value.calendar = calendars.key;
+                                          event.value.start = Date.parse(event.value.s);
+                                          event.value.end = Date.parse(event.value.e);
+                                          this._insertEvent(event, events.key, 'agenda');
+                                      }, this);
+                                  }, this);
+                              }, this);
+                          }.bind(this));
+            this.viewLoading = true;
+            $('kronolithViewAgenda').appear({ 'queue': 'end', 'afterFinish': function() { this.viewLoading = false; }.bind(this) });
+            $('kronolithLoadingagenda').insert($('kronolithLoading').remove());
+            this._addHistory(fullloc);
+            this.view = 'agenda';
+            break;
+
         case 'options':
             //this.highlightSidebar('appoptions');
             this._addHistory(loc);
@@ -249,8 +301,9 @@ KronolithCore = {
      *
      * @param Date date    The date to show in the calendar.
      * @param string view  The view that's rebuilt.
+     * @param mixed data   Any additional data that might be required.
      */
-    updateView: function(date, view)
+    updateView: function(date, view, data)
     {
         switch (view) {
         case 'day':
@@ -270,7 +323,7 @@ KronolithCore = {
                 dates = this.viewDates(date, view),
                 day = dates[0].clone();
 
-            $('kronolithViewWeek').down('caption span').setText(this.setTitle(Kronolith.text.week.interpolate({ week: date.getWeek() })));
+            $('kronolithViewWeek').down('caption span').setText(this.setTitle(Kronolith.text.week.interpolate({ 'week': date.getWeek() })));
 
             for (var i = 0; i < 7; i++) {
                 div.writeAttribute('id', 'kronolithEventsWeek' + day.dateString());
@@ -312,12 +365,17 @@ KronolithCore = {
             break;
 
         case 'agenda':
-            var tbody = $('kronolithViewAgendaBody'),
-                dates = this.viewDates(date, view),
-                day = dates[0].clone(), row;
-
-            this.setTitle(Kronolith.text.agenda + ' ' + dates[0].toString('d') + ' - ' + dates[1].toString('d'));
-            $('kronolithViewAgenda').down('caption span').setText(Kronolith.text.agenda);
+        case 'search':
+            var tbody = $('kronolithViewAgendaBody'), row;
+
+            if (view == 'agenda') {
+                var dates = this.viewDates(date, view),
+                    day = dates[0].clone();
+                this.setTitle(Kronolith.text.agenda + ' ' + dates[0].toString('d') + ' - ' + dates[1].toString('d'));
+                $('kronolithViewAgenda').down('caption span').setText(Kronolith.text.agenda);
+            } else {
+                $('kronolithViewAgenda').down('caption span').setText(this.setTitle(Kronolith.text.searching.interpolate({ 'term': data })));
+            }
 
             // Remove old rows. Maybe we should only rebuild the calendars if
             // necessary.
@@ -327,10 +385,12 @@ KronolithCore = {
                 }
             });
 
-            // Build new calendar view.
-            while (!day.isAfter(dates[1])) {
-                tbody.insert(this.createAgendaDay(day, 0).show());
-                day.next().day();
+            if (view == 'agenda') {
+                // Build new calendar view.
+                while (!day.isAfter(dates[1])) {
+                    tbody.insert(this.createAgendaDay(day, 0).show());
+                    day.next().day();
+                }
             }
             break;
         }
@@ -419,8 +479,8 @@ KronolithCore = {
     /**
      * Creates a table row for a single day in the agenda view.
      *
-     * @param Date date        The first day to show in the row.
-     * @param integer num    The number of the row.
+     * @param Date date    The first day to show in the row.
+     * @param integer num  The number of the row.
      *
      * @return Element  The element rendering a week row.
      */
@@ -436,7 +496,6 @@ KronolithCore = {
             .setText(date.toString('D'))
             .next()
             .writeAttribute('id', 'kronolithAgendaDay' + date.dateString());
-        //.writeAttribute('date', date.dateString())
 
         return row;
     },
@@ -1271,6 +1330,26 @@ KronolithCore = {
     {
         var kc = e.keyCode || e.charCode;
 
+        form = e.findElement('FORM');
+        if (form) {
+            switch (kc) {
+            case Event.KEY_RETURN:
+                switch (form.identify()) {
+                case 'kronolithEventForm':
+                    this.saveEvent();
+                    e.stop();
+                    break;
+
+                case 'kronolithSearchForm':
+                    this.go('search:' + $F('kronolithSearchContext') + ':' + $F('kronolithSearchTerm'))
+                    e.stop();
+                    break;
+                }
+                break;
+            }
+            return;
+        }
+
         switch (kc) {
         case Event.KEY_ESC:
             this._closeRedBox();
@@ -1316,26 +1395,7 @@ KronolithCore = {
                 return;
 
             case 'kronolithEventSave':
-                var cal = $F('kronolithEventCalendar'),
-                    eventid = $F('kronolithEventId'),
-                    viewDates = this.viewDates(this.date, this.view),
-                    start = viewDates[0].dateString(),
-                    end = viewDates[1].dateString();
-                this.startLoading(cal, start, end);
-                this.doAction('SaveEvent',
-                              $H($('kronolithEventForm').serialize({ 'hash': true }))
-                                  .merge({
-                                      'view': this.view,
-                                      'view_start': start,
-                                      'view_end': end
-                                  }),
-                              function(r) {
-                                  if (r.response.events && eventid) {
-                                      this._removeEvent(eventid, cal);
-                                  }
-                                  this._loadEventsCallback(r);
-                                  this._closeRedBox();
-                              }.bind(this));
+                this.saveEvent();
                 e.stop();
                 return;
 
@@ -1425,6 +1485,10 @@ KronolithCore = {
                 e.stop();
                 return;
 
+            case 'kronolithSearchButton':
+                this.go('search:' + $F('kronolithSearchContext') + ':' + $F('kronolithSearchTerm'))
+                break;
+
             case 'alertsloglink':
                 tmp = $('alertsloglink').down('A');
                 if (this.Growler.toggleLog()) {
@@ -1558,6 +1622,30 @@ KronolithCore = {
         }
     },
 
+    saveEvent: function()
+    {
+        var cal = $F('kronolithEventCalendar'),
+            eventid = $F('kronolithEventId'),
+            viewDates = this.viewDates(this.date, this.view),
+            start = viewDates[0].dateString(),
+            end = viewDates[1].dateString();
+        this.startLoading(cal, start, end);
+        this.doAction('SaveEvent',
+                      $H($('kronolithEventForm').serialize({ 'hash': true }))
+                          .merge({
+                              'view': this.view,
+                              'view_start': start,
+                              'view_end': end
+                          }),
+                      function(r) {
+                          if (r.response.events && eventid) {
+                              this._removeEvent(eventid, cal);
+                          }
+                          this._loadEventsCallback(r);
+                          this._closeRedBox();
+                      }.bind(this));
+    },
+
     _topTags: function(r)
     {
         if (!r.response.tags) {
index 53cd5cc..2a9b17e 100644 (file)
@@ -202,6 +202,7 @@ class Kronolith
             'noalerts' => _("No Alerts"),
             'week' => str_replace('%d', '#{week}', _("Week %d")),
             'agenda' => _("Agenda"),
+            'searching' => str_replace('%s', '#{term}', _("Events matching \"%s\"")),
         ));
         for ($i = 1; $i <= 12; ++$i) {
             $code['text']['month'][$i - 1] = NLS::getLangInfo(constant('MON_' . $i));
index dbd2de0..90132b7 100644 (file)
     <span><?php echo _("Search") ?></span>
   </h3>
 
-  <form action="#" method="post">
-    <input type="text" id="kronolithSearch" class="kronolithLongField" /><br />
-    <select name="q_what">
-      <option value="1"><?php echo _("Calendars") ?></option>
-      <option value="2"><?php echo _("Events") ?></option>
+  <form id="kronolithSearchForm">
+    <input type="text" id="kronolithSearchTerm" class="kronolithLongField" /><br />
+    <select id="kronolithSearchContext">
+      <option value="Events"><?php echo _("Events") ?></option>
+      <option value="Calendars"><?php echo _("Calendars") ?></option>
     </select>
-    <input type="submit" value="OK" class="button ok" /><br />
+    <input id="kronolithSearchButton" type="button" value="OK" class="button ok" /><br />
   </form>
   </div>
 </div>