Implemented basic search functionality; to be completed...
This commit is contained in:
parent
d17ca4a5ca
commit
79439a8934
8 changed files with 122 additions and 21 deletions
|
@ -33,6 +33,8 @@ function rcube_calendar(settings)
|
|||
this.dismiss_link = null;
|
||||
this.selected_event = null;
|
||||
this.selected_calendar = null;
|
||||
this.search_request = null;
|
||||
this.search_source = null;
|
||||
this.eventcount = [];
|
||||
|
||||
|
||||
|
@ -684,6 +686,76 @@ function rcube_calendar(settings)
|
|||
}
|
||||
};
|
||||
|
||||
|
||||
/*** event searching ***/
|
||||
|
||||
// execute search
|
||||
this.quicksearch = function()
|
||||
{
|
||||
if (rcmail.gui_objects.qsearchbox) {
|
||||
var q = rcmail.gui_objects.qsearchbox.value;
|
||||
if (q != '') {
|
||||
var id = 'search-'+q;
|
||||
var fc = $(fcselector);
|
||||
var sources = [];
|
||||
|
||||
for (var sid in this.calendars) {
|
||||
if (this.calendars[sid] && this.calendars[sid].active) {
|
||||
fc.fullCalendar('removeEventSource', this.calendars[sid]);
|
||||
sources.push(sid);
|
||||
}
|
||||
}
|
||||
id += '@'+sources.join(',');
|
||||
|
||||
// just refetch events if query didn't change
|
||||
if (this.search_request == id) {
|
||||
fc.fullCalendar('refetchEvents');
|
||||
return;
|
||||
}
|
||||
// remove old search results
|
||||
else if (this.search_source) {
|
||||
fc.fullCalendar('removeEventSource', this.search_source);
|
||||
}
|
||||
else {
|
||||
this.default_view = fc.fullCalendar('getView').name;
|
||||
}
|
||||
|
||||
// replace event source from fullcalendar
|
||||
this.search_request = id;
|
||||
this.search_source = {
|
||||
url: "./?_task=calendar&_action=search_events&q="+escape(q)+'&source='+escape(sources.join(',')),
|
||||
editable: false
|
||||
};
|
||||
|
||||
fc.fullCalendar('option', 'smartSections', false);
|
||||
fc.fullCalendar('addEventSource', this.search_source);
|
||||
fc.fullCalendar('changeView', 'list');
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// reset search and get back to normal event listing
|
||||
this.reset_quicksearch = function()
|
||||
{
|
||||
$(rcmail.gui_objects.qsearchbox).val('');
|
||||
if (this.search_request) {
|
||||
// restore original event sources and view mode from fullcalendar
|
||||
var fc = $(fcselector);
|
||||
fc.fullCalendar('option', 'smartSections', true);
|
||||
fc.fullCalendar('removeEventSource', this.search_source);
|
||||
for (var sid in this.calendars) {
|
||||
if (this.calendars[sid] && this.calendars[sid].active)
|
||||
fc.fullCalendar('addEventSource', this.calendars[sid]);
|
||||
}
|
||||
console.log(this.default_view);
|
||||
if (this.default_view)
|
||||
fc.fullCalendar('changeView', this.default_view);
|
||||
|
||||
this.search_request = this.search_source = null;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/*** startup code ***/
|
||||
|
||||
// create list of event sources AKA calendars
|
||||
|
@ -698,8 +770,10 @@ function rcube_calendar(settings)
|
|||
id: id
|
||||
}, cal);
|
||||
|
||||
if ((active = ($.inArray(String(id), settings.hidden_calendars) < 0)))
|
||||
if ((active = ($.inArray(String(id), settings.hidden_calendars) < 0))) {
|
||||
this.calendars[id].active = true;
|
||||
event_sources.push(this.calendars[id]);
|
||||
}
|
||||
|
||||
// init event handler on calendar list checkbox
|
||||
if ((li = rcmail.get_folder_li(id, 'rcmlical'))) {
|
||||
|
@ -709,21 +783,29 @@ function rcube_calendar(settings)
|
|||
var action;
|
||||
if (this.checked) {
|
||||
action = 'addEventSource';
|
||||
me.calendars[id].active = true;
|
||||
settings.hidden_calendars = $.map(settings.hidden_calendars, function(v){ return v == id ? null : v; });
|
||||
}
|
||||
else {
|
||||
action = 'removeEventSource';
|
||||
me.calendars[id].active = false;
|
||||
settings.hidden_calendars.push(id);
|
||||
}
|
||||
$(fcselector).fullCalendar(action, me.calendars[id]);
|
||||
rcmail.save_pref({ name:'hidden_calendars', value:settings.hidden_calendars.join(',') });
|
||||
// just trigger search again (don't save prefs?)
|
||||
if (me.search_request) {
|
||||
me.quicksearch();
|
||||
}
|
||||
else { // add/remove event source
|
||||
$(fcselector).fullCalendar(action, me.calendars[id]);
|
||||
rcmail.save_pref({ name:'hidden_calendars', value:settings.hidden_calendars.join(',') });
|
||||
}
|
||||
}
|
||||
}).data('id', id).get(0).checked = active;
|
||||
|
||||
$(li).click(function(e){
|
||||
var id = $(this).data('id');
|
||||
rcmail.select_folder(id, me.selected_calendar, 'rcmlical');
|
||||
rcmail.enable_command('calendar-edit','calendar-remove', true);
|
||||
rcmail.enable_command('calendar-edit','calendar-remove', !me.calendars[id].readonly);
|
||||
me.selected_calendar = id;
|
||||
}).data('id', id);
|
||||
}
|
||||
|
@ -1046,8 +1128,10 @@ window.rcmail && rcmail.addEventListener('init', function(evt) {
|
|||
rcmail.register_command('calendar-edit', function(){ cal.calendar_edit_dialog(cal.calendars[cal.selected_calendar]); }, false);
|
||||
rcmail.register_command('calendar-remove', function(){ cal.calendar_remove(cal.calendars[cal.selected_calendar]); }, false);
|
||||
|
||||
// export events
|
||||
// search and export events
|
||||
rcmail.register_command('export', function(){ rcmail.goto_url('export_events', { source:cal.selected_calendar }); }, true);
|
||||
rcmail.register_command('search', function(){ cal.quicksearch(); }, true);
|
||||
rcmail.register_command('reset-search', function(){ cal.reset_quicksearch(); }, true);
|
||||
|
||||
// register callback commands
|
||||
rcmail.addEventListener('plugin.display_alarms', function(alarms){ cal.display_alarms(alarms); });
|
||||
|
|
|
@ -138,6 +138,7 @@ class calendar extends rcube_plugin
|
|||
$this->register_handler('plugin.snooze_select', array($this->ui, 'snooze_select'));
|
||||
$this->register_handler('plugin.recurrence_form', array($this->ui, 'recurrence_form'));
|
||||
$this->register_handler('plugin.edit_recurring_warning', array($this->ui, 'recurring_event_warning'));
|
||||
$this->register_handler('plugin.searchform', array($this->rc->output, 'search_form')); // use generic method from rcube_template
|
||||
|
||||
$this->rc->output->set_env('calendar_settings', $this->load_settings());
|
||||
$this->rc->output->add_label('low','normal','high');
|
||||
|
@ -457,12 +458,13 @@ class calendar extends rcube_plugin
|
|||
*/
|
||||
function search_events()
|
||||
{
|
||||
$events = $this->driver->load_events(
|
||||
$events = $this->driver->search_events(
|
||||
get_input_value('start', RCUBE_INPUT_GET),
|
||||
get_input_value('end', RCUBE_INPUT_GET),
|
||||
get_input_value('q', RCUBE_INPUT_GET),
|
||||
get_input_value('source', RCUBE_INPUT_GET)
|
||||
);
|
||||
echo $this->encode($events);
|
||||
echo $this->encode($events, true);
|
||||
exit;
|
||||
}
|
||||
|
||||
|
@ -586,7 +588,7 @@ class calendar extends rcube_plugin
|
|||
* @param array Events as array
|
||||
* @return string JSON encoded events
|
||||
*/
|
||||
function encode($events)
|
||||
function encode($events, $addcss = false)
|
||||
{
|
||||
$json = array();
|
||||
foreach ($events as $event) {
|
||||
|
@ -601,7 +603,7 @@ class calendar extends rcube_plugin
|
|||
'end' => date('c', $event['end']), // ISO 8601 date (added in PHP 5)
|
||||
'description' => $event['description'],
|
||||
'location' => $event['location'],
|
||||
'className' => 'cat-' . asciiwords($event['categories'], true),
|
||||
'className' => ($addcss ? 'fc-event-cal-'.asciiwords($event['calendar'], true).' ' : '') . 'cat-' . asciiwords($event['categories'], true),
|
||||
'allDay' => ($event['all_day'] == 1)?true:false,
|
||||
) + $event;
|
||||
}
|
||||
|
|
|
@ -597,7 +597,7 @@ class database_driver extends calendar_driver
|
|||
*
|
||||
* @see Driver:load_events()
|
||||
*/
|
||||
public function load_events($start, $end, $calendars = null)
|
||||
public function load_events($start, $end, $calendars = null, $sql_add = '')
|
||||
{
|
||||
if (empty($calendars))
|
||||
$calendars = array_keys($this->calendars);
|
||||
|
@ -613,10 +613,12 @@ class database_driver extends calendar_driver
|
|||
$result = $this->rc->db->query(sprintf(
|
||||
"SELECT * FROM " . $this->db_events . "
|
||||
WHERE calendar_id IN (%s)
|
||||
AND start <= %s AND end >= %s",
|
||||
AND start <= %s AND end >= %s
|
||||
%s",
|
||||
join(',', $calendar_ids),
|
||||
$this->rc->db->fromunixtime($end),
|
||||
$this->rc->db->fromunixtime($start)
|
||||
$this->rc->db->fromunixtime($start),
|
||||
$sql_add
|
||||
));
|
||||
|
||||
while ($result && ($event = $this->rc->db->fetch_assoc($result))) {
|
||||
|
@ -665,7 +667,13 @@ class database_driver extends calendar_driver
|
|||
*/
|
||||
public function search_events($start, $end, $query, $calendars = null)
|
||||
{
|
||||
// compose (slow) SQL query for searching
|
||||
// FIXME: improve searching using a dedicated col and normalized values
|
||||
foreach (array('title','location','description','categories','attendees') as $col) {
|
||||
$sql_query[] = $this->rc->db->ilike($col, '%'.$query.'%');
|
||||
}
|
||||
|
||||
return $this->load_events($start, $end, $calendars, 'AND (' . join(' OR ', $sql_query) . ')');
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -106,18 +106,23 @@ class kolab_calendar
|
|||
/**
|
||||
* @param integer Event's new start (unix timestamp)
|
||||
* @param integer Event's new end (unix timestamp)
|
||||
* @param string Search query (optional)
|
||||
* @return array A list of event records
|
||||
*/
|
||||
public function list_events($start, $end)
|
||||
public function list_events($start, $end, $search = null)
|
||||
{
|
||||
// use Horde classes to compute recurring instances
|
||||
require_once 'Horde/Date/Recurrence.php';
|
||||
|
||||
$this->_fetch_events();
|
||||
|
||||
|
||||
|
||||
$events = array();
|
||||
foreach ($this->events as $id => $event) {
|
||||
// TODO: filter events by search query
|
||||
if (!empty($search)) {
|
||||
|
||||
}
|
||||
|
||||
// list events in requested time window
|
||||
if ($event['start'] <= $end && $event['end'] >= $start) {
|
||||
$events[] = $event;
|
||||
|
|
|
@ -216,9 +216,10 @@ class kolab_driver extends calendar_driver
|
|||
* @param integer Event's new start (unix timestamp)
|
||||
* @param integer Event's new end (unix timestamp)
|
||||
* @param mixed List of calendar IDs to load events from (either as array or comma-separated string)
|
||||
* @param string Search query (optional)
|
||||
* @return array A list of event records
|
||||
*/
|
||||
public function load_events($start, $end, $calendars = null)
|
||||
public function load_events($start, $end, $calendars = null, $search = null)
|
||||
{
|
||||
if ($calendars && is_string($calendars))
|
||||
$calendars = explode(',', $calendars);
|
||||
|
@ -228,7 +229,7 @@ class kolab_driver extends calendar_driver
|
|||
if ($calendars && !in_array($cid, $calendars))
|
||||
continue;
|
||||
|
||||
$events = array_merge($this->folders[$cid]->list_events($start, $end));
|
||||
$events = array_merge($this->folders[$cid]->list_events($start, $end, $search));
|
||||
}
|
||||
|
||||
return $events;
|
||||
|
@ -242,7 +243,8 @@ class kolab_driver extends calendar_driver
|
|||
*/
|
||||
public function search_events($start, $end, $query, $calendars = null)
|
||||
{
|
||||
return array();
|
||||
// delegate request to load_events()
|
||||
return $this->load_events($start, $end, $calendars, $query);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -650,8 +650,8 @@ function Calendar(element, options, eventSources) {
|
|||
if (value === undefined) {
|
||||
return options[name];
|
||||
}
|
||||
options[name] = value;
|
||||
if (name == 'height' || name == 'contentHeight' || name == 'aspectRatio') {
|
||||
options[name] = value;
|
||||
updateSize();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -622,7 +622,7 @@ table.fc-border-separate {
|
|||
.fc-view-list,
|
||||
.fc-view-table {
|
||||
border: 1px solid #ccc;
|
||||
width: 99%;
|
||||
width: auto;
|
||||
}
|
||||
|
||||
.fc-view-list .fc-list-header,
|
||||
|
|
|
@ -197,7 +197,7 @@
|
|||
|
||||
<div id="quicksearchbar">
|
||||
<roundcube:button name="searchmenulink" id="searchmenulink" image="/images/icons/glass.png" />
|
||||
<roundcube:object name="searchform" id="quicksearchbox" />
|
||||
<roundcube:object name="plugin.searchform" id="quicksearchbox" />
|
||||
<roundcube:button command="reset-search" id="searchreset" image="/images/icons/reset.gif" title="resetsearch" />
|
||||
</div>
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue