From 66f4022a5f8c3c37fa84b1811d796c1aae8fbd0c Mon Sep 17 00:00:00 2001 From: Jan Schneider Date: Thu, 28 May 2009 19:04:50 +0200 Subject: [PATCH] Implement (event) searching. --- kronolith/ajax.php | 36 ++++++++ kronolith/js/src/kronolith.js | 158 ++++++++++++++++++++++++++++-------- kronolith/lib/Kronolith.php | 1 + kronolith/templates/index/index.inc | 12 +-- 4 files changed, 166 insertions(+), 41 deletions(-) diff --git a/kronolith/ajax.php b/kronolith/ajax.php index 8e810b936..9f424cd59 100644 --- a/kronolith/ajax.php +++ b/kronolith/ajax.php @@ -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; diff --git a/kronolith/js/src/kronolith.js b/kronolith/js/src/kronolith.js index 0dee38a7c..3e1daf87a 100644 --- a/kronolith/js/src/kronolith.js +++ b/kronolith/js/src/kronolith.js @@ -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) { diff --git a/kronolith/lib/Kronolith.php b/kronolith/lib/Kronolith.php index 53cd5cc90..2a9b17e21 100644 --- a/kronolith/lib/Kronolith.php +++ b/kronolith/lib/Kronolith.php @@ -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)); diff --git a/kronolith/templates/index/index.inc b/kronolith/templates/index/index.inc index dbd2de051..90132b7da 100644 --- a/kronolith/templates/index/index.inc +++ b/kronolith/templates/index/index.inc @@ -102,13 +102,13 @@ -
-
-
+ -
+
-- 2.11.0