mirror of
https://github.com/EGroupware/egroupware.git
synced 2024-11-29 03:13:40 +01:00
drag and drop for calendar for all those who cannot wait for cooxdoo or dojoproject :o) - it is disabled by default - if you want to use it you have to go to common preferences and enable drag and drop (last entry before template-specific settings) - just for Mozilla based browsers ATM, all other browsers get auto-disabled - it lacks a lot features, e.g. recurring events and whole day events but this will come - HAVE FUN
This commit is contained in:
parent
f3670af463
commit
a014327f05
66
calendar/inc/class.ajaxcalendar.inc.php
Normal file
66
calendar/inc/class.ajaxcalendar.inc.php
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Calendar - ajax class
|
||||||
|
*
|
||||||
|
* @link http://www.egroupware.org
|
||||||
|
* @author Christian Binder <christian.binder@freakmail.de>
|
||||||
|
* @package calendar
|
||||||
|
* @copyright (c) 2006 by Christian Binder <christian.binder@freakmail.de>
|
||||||
|
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
|
||||||
|
* @version $Id: class.ajaxcalendar.inc.php 22777 2006-11-26 20:55:00Z jaytraxx $
|
||||||
|
*/
|
||||||
|
|
||||||
|
require_once(EGW_INCLUDE_ROOT.'/calendar/inc/class.bocalupdate.inc.php');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* General object of the calendar ajax class
|
||||||
|
*
|
||||||
|
* @package calendar
|
||||||
|
* @author Christian Binder <christian.binder@freakmail.de>
|
||||||
|
* @copyright (c) 2006 by Christian Binder <christian.binder@freakmail.de>
|
||||||
|
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
|
||||||
|
*/
|
||||||
|
|
||||||
|
class ajaxcalendar {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var object $calendar object to handle events
|
||||||
|
*/
|
||||||
|
var $calendar;
|
||||||
|
|
||||||
|
function ajaxcalendar() {
|
||||||
|
$this->calendar = new bocalupdate;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* moves an event to another date/time
|
||||||
|
*
|
||||||
|
* @param string $eventID id of the event which has to be moved
|
||||||
|
* @param string $calendarOwner the owner of the calendar the event is in
|
||||||
|
* @param string $targetDateTime the datetime where the event should be moved to, format: YYYYMMDD
|
||||||
|
* @param string $targetOwner the owner of the target calendar
|
||||||
|
* @return string XML response if no error occurs
|
||||||
|
*/
|
||||||
|
function moveEvent($eventId,$calendarOwner,$targetDateTime,$targetOwner)
|
||||||
|
{
|
||||||
|
// we do not allow dragging into another users calendar ATM
|
||||||
|
if(!$calendarOwner == $targetOwner)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$event=$this->calendar->read($eventId);
|
||||||
|
$duration=$event['end']-$event['start'];
|
||||||
|
|
||||||
|
$event['start'] = $this->calendar->date2ts($targetDateTime);
|
||||||
|
$event['end'] = $event['start']+$duration;
|
||||||
|
|
||||||
|
$result=$this->calendar->update($event);
|
||||||
|
//Todo: handle the result !!!
|
||||||
|
|
||||||
|
$response =& new xajaxResponse();
|
||||||
|
$response->addRedirect($PHP_SELF);
|
||||||
|
|
||||||
|
return $response->getXML();
|
||||||
|
}
|
||||||
|
}
|
@ -233,6 +233,7 @@ class uical
|
|||||||
*/
|
*/
|
||||||
function do_header()
|
function do_header()
|
||||||
{
|
{
|
||||||
|
$GLOBALS['egw_info']['flags']['include_xajax'] = true;
|
||||||
$GLOBALS['egw']->common->egw_header();
|
$GLOBALS['egw']->common->egw_header();
|
||||||
|
|
||||||
if ($_GET['msg']) echo '<p class="redItalic" align="center">'.$this->html->htmlspecialchars($_GET['msg'])."</p>\n";
|
if ($_GET['msg']) echo '<p class="redItalic" align="center">'.$this->html->htmlspecialchars($_GET['msg'])."</p>\n";
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
/* $Id$ */
|
/* $Id$ */
|
||||||
|
|
||||||
include_once(EGW_INCLUDE_ROOT . '/calendar/inc/class.uical.inc.php');
|
include_once(EGW_INCLUDE_ROOT . '/calendar/inc/class.uical.inc.php');
|
||||||
|
include_once(EGW_INCLUDE_ROOT . '/phpgwapi/inc/class.dragdrop.inc.php');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class to generate the calendar views and the necesary widgets
|
* Class to generate the calendar views and the necesary widgets
|
||||||
@ -90,6 +91,13 @@ class uiviews extends uical
|
|||||||
*/
|
*/
|
||||||
var $use_time_grid=true;
|
var $use_time_grid=true;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dragdrop Object
|
||||||
|
*
|
||||||
|
* @var object $dragdrop;
|
||||||
|
*/
|
||||||
|
var $dragdrop;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Can we display the whole day in a timeGrid of the size of the workday and just scroll to workday start
|
* Can we display the whole day in a timeGrid of the size of the workday and just scroll to workday start
|
||||||
*
|
*
|
||||||
@ -138,6 +146,7 @@ class uiviews extends uical
|
|||||||
$this->holidays = $this->bo->read_holidays($this->year);
|
$this->holidays = $this->bo->read_holidays($this->year);
|
||||||
|
|
||||||
$this->check_owners_access();
|
$this->check_owners_access();
|
||||||
|
$this->dragdrop = new dragdrop();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -320,6 +329,10 @@ class uiviews extends uical
|
|||||||
|
|
||||||
echo $content;
|
echo $content;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// make wz_dragdrop elements work
|
||||||
|
$this->dragdrop->setJSCode();
|
||||||
|
|
||||||
return $content;
|
return $content;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -442,6 +455,10 @@ class uiviews extends uical
|
|||||||
|
|
||||||
echo $content;
|
echo $content;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// make wz_dragdrop elements work
|
||||||
|
$this->dragdrop->setJSCode();
|
||||||
|
|
||||||
return $content;
|
return $content;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -514,10 +531,17 @@ class uiviews extends uical
|
|||||||
{
|
{
|
||||||
echo $cols[0];
|
echo $cols[0];
|
||||||
}
|
}
|
||||||
|
// make wz_dragdrop elements work
|
||||||
|
$this->dragdrop->setJSCode();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return $this->timeGridWidget($this->bo->search($this->search_params),$this->cal_prefs['interval'],300);
|
$content = $this->timeGridWidget($this->bo->search($this->search_params),$this->cal_prefs['interval'],300);
|
||||||
|
|
||||||
|
// make wz_dragdrop elements work
|
||||||
|
$this->dragdrop->setJSCode();
|
||||||
|
|
||||||
|
return $content;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -791,6 +815,7 @@ class uiviews extends uical
|
|||||||
}
|
}
|
||||||
$html .= "</script>\n";
|
$html .= "</script>\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
return $html;
|
return $html;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -880,6 +905,16 @@ class uiviews extends uical
|
|||||||
|
|
||||||
if ($this->use_time_grid)
|
if ($this->use_time_grid)
|
||||||
{
|
{
|
||||||
|
// drag and drop: check if the current user has EDIT permissions on the grid
|
||||||
|
if($owner)
|
||||||
|
{
|
||||||
|
$dropPermission = $this->bo->check_perms(EGW_ACL_EDIT,0,$owner);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$dropPermission = true;
|
||||||
|
}
|
||||||
|
|
||||||
// adding divs to click on for each row / time-span
|
// adding divs to click on for each row / time-span
|
||||||
for($t = $this->scroll_to_wdstart ? 0 : $this->wd_start,$i = 1+$this->extraRows;
|
for($t = $this->scroll_to_wdstart ? 0 : $this->wd_start,$i = 1+$this->extraRows;
|
||||||
$t <= $this->wd_end || $this->scroll_to_wdstart && $t < 24*60;
|
$t <= $this->wd_end || $this->scroll_to_wdstart && $t < 24*60;
|
||||||
@ -888,20 +923,35 @@ class uiviews extends uical
|
|||||||
$linkData = array(
|
$linkData = array(
|
||||||
'menuaction' =>'calendar.uiforms.edit',
|
'menuaction' =>'calendar.uiforms.edit',
|
||||||
'date' => $day_ymd,
|
'date' => $day_ymd,
|
||||||
'hour' => floor($t / 60),
|
'hour' => sprintf("%02d",floor($t / 60)),
|
||||||
'minute' => floor($t % 60),
|
'minute' => sprintf("%02d",floor($t % 60)),
|
||||||
);
|
);
|
||||||
if ($owner) $linkData['owner'] = $owner;
|
if ($owner) $linkData['owner'] = $owner;
|
||||||
|
|
||||||
$html .= $indent."\t".'<div style="height:'. $this->rowHeight .'%; top: '. $i*$this->rowHeight .
|
$droppableDateTime = $linkData['date'] . "T" . $linkData['hour'] . $linkData['minute'];
|
||||||
|
$droppableID='drop_'.$droppableDateTime.'_O'.$owner;
|
||||||
|
|
||||||
|
$html .= $indent."\t".'<div id="' . $droppableID . '" style="height:'. $this->rowHeight .'%; top: '. $i*$this->rowHeight .
|
||||||
'%;" class="calAddEvent" onclick="'.$this->popup($GLOBALS['egw']->link('/index.php',$linkData)).';return false;"></div>'."\n";
|
'%;" class="calAddEvent" onclick="'.$this->popup($GLOBALS['egw']->link('/index.php',$linkData)).';return false;"></div>'."\n";
|
||||||
|
|
||||||
|
if($dropPermission)
|
||||||
|
{
|
||||||
|
$this->dragdrop->addDroppable(
|
||||||
|
$droppableID,
|
||||||
|
array(
|
||||||
|
'datetime'=>$droppableDateTime,
|
||||||
|
'owner'=>$owner ? $owner : $this->user,
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// displaying all event columns of the day
|
// displaying all event columns of the day
|
||||||
foreach($eventCols as $n => $eventCol)
|
foreach($eventCols as $n => $eventCol)
|
||||||
{
|
{
|
||||||
$html .= $this->eventColWidget($eventCol,!$n ? 0 : 60-10*(count($eventCols)-$n),
|
$html .= $this->eventColWidget($eventCol,!$n ? 0 : 60-10*(count($eventCols)-$n),
|
||||||
count($eventCols) == 1 ? 100 : (!$n ? 80 : 50),$indent."\t");
|
count($eventCols) == 1 ? 100 : (!$n ? 80 : 50),$indent."\t",
|
||||||
|
$owner ? $owner : $this->user);
|
||||||
}
|
}
|
||||||
$html .= $indent."</div>\n"; // calDayCol
|
$html .= $indent."</div>\n"; // calDayCol
|
||||||
|
|
||||||
@ -968,8 +1018,9 @@ class uiviews extends uical
|
|||||||
* @param int $left start of the widget
|
* @param int $left start of the widget
|
||||||
* @param int $width width of the widget
|
* @param int $width width of the widget
|
||||||
* @param string $indent string for correct indention
|
* @param string $indent string for correct indention
|
||||||
|
* @param int $owner owner of the eventCol
|
||||||
*/
|
*/
|
||||||
function eventColWidget($events,$left,$width,$indent)
|
function eventColWidget($events,$left,$width,$indent,$owner)
|
||||||
{
|
{
|
||||||
if ($this->debug > 1 || $this->debug==='eventColWidget') $this->bo->debug_message('uiviews::eventColWidget(%1,left=%2,width=%3,)',False,$events,$left,$width);
|
if ($this->debug > 1 || $this->debug==='eventColWidget') $this->bo->debug_message('uiviews::eventColWidget(%1,left=%2,width=%3,)',False,$events,$left,$width);
|
||||||
|
|
||||||
@ -977,7 +1028,7 @@ class uiviews extends uical
|
|||||||
(!$this->use_time_grid ? ' top: '.$this->rowHeight.'%;' : '').'">'."\n";
|
(!$this->use_time_grid ? ' top: '.$this->rowHeight.'%;' : '').'">'."\n";
|
||||||
foreach($events as $event)
|
foreach($events as $event)
|
||||||
{
|
{
|
||||||
$html .= $this->eventWidget($event,$width,$indent."\t");
|
$html .= $this->eventWidget($event,$width,$indent."\t",$owner);
|
||||||
}
|
}
|
||||||
$html .= $indent."</div>\n";
|
$html .= $indent."</div>\n";
|
||||||
|
|
||||||
@ -992,11 +1043,12 @@ class uiviews extends uical
|
|||||||
* @param $event array with the data of event to show
|
* @param $event array with the data of event to show
|
||||||
* @param $width int width of the widget
|
* @param $width int width of the widget
|
||||||
* @param string $indent string for correct indention
|
* @param string $indent string for correct indention
|
||||||
|
* @param int $owner owner of the calendar the event is in
|
||||||
* @param boolean $return_array=false should an array with keys(tooltip,popup,html) be returned or the complete widget as string
|
* @param boolean $return_array=false should an array with keys(tooltip,popup,html) be returned or the complete widget as string
|
||||||
* @param string $block='event_widget' template used the render the widget
|
* @param string $block='event_widget' template used the render the widget
|
||||||
* @return string/array
|
* @return string/array
|
||||||
*/
|
*/
|
||||||
function eventWidget($event,$width,$indent,$return_array=false,$block='event_widget')
|
function eventWidget($event,$width,$indent,$owner,$return_array=false,$block='event_widget')
|
||||||
{
|
{
|
||||||
if ($this->debug > 1 || $this->debug==='eventWidget') $this->bo->debug_message('uiviews::eventWidget(%1,width=%2)',False,$event,$width);
|
if ($this->debug > 1 || $this->debug==='eventWidget') $this->bo->debug_message('uiviews::eventWidget(%1,width=%2)',False,$event,$width);
|
||||||
|
|
||||||
@ -1159,10 +1211,39 @@ class uiviews extends uical
|
|||||||
{
|
{
|
||||||
$style = 'position: relative; margin-top: 3px;';
|
$style = 'position: relative; margin-top: 3px;';
|
||||||
}
|
}
|
||||||
return $indent.'<div class="calEvent'.($is_private ? 'Private' : '').
|
|
||||||
'" style="'.$style.' border-color: '.$headerbgcolor.'; background: '.$background.';"'.
|
$draggableID = 'drag_'.$event['id'].'_O'.$event['owner'].'_C'.$owner;
|
||||||
|
|
||||||
|
$html = $indent.'<div id="'.$draggableID.'" class="calEvent'.($is_private ? 'Private' : '').
|
||||||
|
'" style="'.$style.' border-color: '.$headerbgcolor.'; background: '.$background.'; z-index: 20;"'.
|
||||||
$popup.' '.$this->html->tooltip($tooltip,False,array('BorderWidth'=>0,'Padding'=>0)).
|
$popup.' '.$this->html->tooltip($tooltip,False,array('BorderWidth'=>0,'Padding'=>0)).
|
||||||
'>'."\n".$ie_fix.$html.$indent."</div>\n";
|
'>'."\n".$ie_fix.$html."\n".
|
||||||
|
$indent."</div>"."\n";
|
||||||
|
|
||||||
|
// ATM we do not support whole day events or recurring events for dragdrop
|
||||||
|
if ( $this->use_time_grid &&
|
||||||
|
$this->bo->check_perms(EGW_ACL_EDIT,$event['id']) &&
|
||||||
|
!$event['whole_day_on_top'] &&
|
||||||
|
!$event['whole_day'] &&
|
||||||
|
!$event['recur_type']
|
||||||
|
)
|
||||||
|
{
|
||||||
|
// register event as draggable
|
||||||
|
$this->dragdrop->addDraggable(
|
||||||
|
$draggableID,
|
||||||
|
array(
|
||||||
|
'eventId'=>$event['id'],
|
||||||
|
'eventOwner'=>$event['owner'],
|
||||||
|
'calendarOwner'=>$owner,
|
||||||
|
'errorImage'=>addslashes($this->html->image('phpgwapi','dialog_error',false,'style="width: 16px;"')),
|
||||||
|
'loaderImage'=>addslashes($this->html->image('phpgwapi','ajax-loader')),
|
||||||
|
),
|
||||||
|
'calendar.dragDropFunctions.dragEvent',
|
||||||
|
'calendar.dragDropFunctions.dropEvent'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $html;
|
||||||
}
|
}
|
||||||
|
|
||||||
function add_nonempty($content,$label,$one_per_line=False,$space = True)
|
function add_nonempty($content,$label,$one_per_line=False,$space = True)
|
||||||
@ -1781,11 +1862,18 @@ class uiviews extends uical
|
|||||||
{
|
{
|
||||||
$start = $this->bo->date2array($event['start']);
|
$start = $this->bo->date2array($event['start']);
|
||||||
$end = $this->bo->date2array($event['end']);
|
$end = $this->bo->date2array($event['end']);
|
||||||
if(!$start['hour'] && !$start['minute'] && $end['hour'] == 23 && $end['minute'] == 59 && $event['non_blocking'])
|
if(!$start['hour'] && !$start['minute'] && $end['hour'] == 23 && $end['minute'] == 59)
|
||||||
{
|
{
|
||||||
|
if($event['non_blocking'])
|
||||||
|
{
|
||||||
$dayEvents[$day][$num]['whole_day_on_top']=true;
|
$dayEvents[$day][$num]['whole_day_on_top']=true;
|
||||||
$this->whole_day_positions[$num]=($this->rowHeight*($num+2));
|
$this->whole_day_positions[$num]=($this->rowHeight*($num+2));
|
||||||
$extraRowsToAdd++;
|
$extraRowsToAdd++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$dayEvents[$day][$num]['whole_day']=true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// check after every day if we have to increase $this->extraRows
|
// check after every day if we have to increase $this->extraRows
|
||||||
|
65
calendar/js/dragDropFunctions.js
Normal file
65
calendar/js/dragDropFunctions.js
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
function dragEvent()
|
||||||
|
{
|
||||||
|
if(minOffset())
|
||||||
|
{
|
||||||
|
// make a snapshot of the old (original) innerHTML of the dragged event
|
||||||
|
if(!dd.obj.oldInnerHTML)
|
||||||
|
{
|
||||||
|
dd.obj.oldInnerHTML = dd.obj.div.innerHTML;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(dropTarget = dd.obj.getEltBelow())
|
||||||
|
{
|
||||||
|
var datetime = dropTarget.my_datetime;
|
||||||
|
}
|
||||||
|
|
||||||
|
// we just allow to drop within the users own calendar
|
||||||
|
// and not crossing into another calendar ATM
|
||||||
|
if(datetime && (dd.obj.my_calendarOwner == dropTarget.my_owner ))
|
||||||
|
{
|
||||||
|
dd.obj.div.innerHTML = '<div style="font-size: 1.1em; font-weight: bold; text-align: center;">' + datetime.substr(9,2) + ":" + datetime.substr(11,2) + '</div>';
|
||||||
|
} else {
|
||||||
|
|
||||||
|
dd.obj.div.innerHTML = '<div style="background-color: red; height: 100%; width: 100%; text-align: center;">' + dd.obj.my_errorImage + '</div>';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function dropEvent()
|
||||||
|
{
|
||||||
|
// minimum requirements for ajax call
|
||||||
|
if( minOffset() &&
|
||||||
|
(dropTarget = dd.obj.getEltBelow()) &&
|
||||||
|
(dropTarget.my_datetime) &&
|
||||||
|
(dd.obj.my_calendarOwner == dropTarget.my_owner)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
dd.obj.div.innerHTML = '<div style="height: 100%; width: 100%; text-align: center;">' + dd.obj.my_loaderImage + '</div>';
|
||||||
|
|
||||||
|
xajax_doXMLHTTP(
|
||||||
|
'calendar.ajaxcalendar.moveEvent',
|
||||||
|
dd.obj.my_eventId,
|
||||||
|
dd.obj.my_calendarOwner,
|
||||||
|
dropTarget.my_datetime,
|
||||||
|
dropTarget.my_owner
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// abort - move to old position and restore old innerHTML
|
||||||
|
if(dd.obj.oldInnerHTML)
|
||||||
|
{
|
||||||
|
dd.obj.div.innerHTML = dd.obj.oldInnerHTML;
|
||||||
|
}
|
||||||
|
dd.obj.moveTo(dd.obj.defx,dd.obj.defy);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function minOffset()
|
||||||
|
{
|
||||||
|
var offsetX = Math.abs(dd.obj.defx - dd.obj.x);
|
||||||
|
var offsetY = Math.abs(dd.obj.defy - dd.obj.y);
|
||||||
|
|
||||||
|
if(offsetX > 5 || offsetY > 5) { return true; }
|
||||||
|
return false;
|
||||||
|
}
|
@ -230,5 +230,14 @@
|
|||||||
'help' => 'Should this help messages shown up always, when you enter the preferences or only on request.',
|
'help' => 'Should this help messages shown up always, when you enter the preferences or only on request.',
|
||||||
'xmlrpc' => False,
|
'xmlrpc' => False,
|
||||||
'admin' => False
|
'admin' => False
|
||||||
|
),
|
||||||
|
'enable_dragdrop' => array(
|
||||||
|
'type' => 'check',
|
||||||
|
'label' => 'Enable drag and drop functionality (experimental)',
|
||||||
|
'name' => 'enable_dragdrop',
|
||||||
|
'help' => 'Enables or disables drag and drop functions in all applications. If the browser does not support '.
|
||||||
|
'drag and drop, it will be disabled automatically. This feature is experimental at the moment.',
|
||||||
|
'xmlrpc' => False,
|
||||||
|
'admin' => False
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
Loading…
Reference in New Issue
Block a user