2011-04-27 18:53:06 +02:00
/ * *
2013-10-31 15:51:19 +01:00
* EGroupware - Calendar - Javascript UI
2011-04-27 18:53:06 +02:00
*
* @ link http : //www.egroupware.org
* @ package calendar
2013-10-31 15:51:19 +01:00
* @ author Hadi Nategh < hn - AT - stylite . de >
* @ copyright ( c ) 2008 - 13 by Ralf Becker < RalfBecker - AT - outdoor - training . de >
2011-04-27 18:53:06 +02:00
* @ license http : //opensource.org/licenses/gpl-license.php GPL - GNU General Public License
* @ version $Id$
* /
2013-11-05 19:08:07 +01:00
/ * e g w : u s e s
/ e t e m p l a t e / j s / e t e m p l a t e 2 . j s
* /
2011-04-27 18:53:06 +02:00
/ * *
2013-10-31 15:51:19 +01:00
* UI for calendar
*
* @ augments AppJS
2011-04-27 18:53:06 +02:00
* /
2013-11-04 21:54:23 +01:00
app . classes . calendar = AppJS . extend (
2011-04-27 18:53:06 +02:00
{
2013-10-31 15:51:19 +01:00
/ * *
* application name
* /
appname : 'calendar' ,
2013-11-05 19:08:07 +01:00
2013-10-31 15:51:19 +01:00
/ * *
* Constructor
*
* @ memberOf app . calendar
* /
init : function ( )
2011-04-27 18:53:06 +02:00
{
2013-10-31 15:51:19 +01:00
// call parent
this . _super . apply ( this , arguments ) ;
2013-12-12 04:42:08 +01:00
2013-12-12 00:51:35 +01:00
// make calendar object available, even if not running in top window, as sidebox does
if ( window . top !== window && typeof window . top . app . calendar == 'undefined' )
{
window . top . app . calendar = this ;
}
2013-12-13 19:18:56 +01:00
//Drag_n_Drop
this . drag _n _drop ( ) ;
2013-10-31 15:51:19 +01:00
} ,
/ * *
* Destructor
* /
destroy : function ( )
2011-04-27 18:53:06 +02:00
{
2013-10-31 15:51:19 +01:00
// call parent
this . _super . apply ( this , arguments ) ;
2013-12-12 00:51:35 +01:00
// remove top window reference
if ( window . top !== window && window . top . app . calendar === this )
{
delete window . top . app . calendar ;
}
2013-10-31 15:51:19 +01:00
} ,
2011-04-27 18:53:06 +02:00
2013-10-31 15:51:19 +01:00
/ * *
* This function is called when the etemplate2 object is loaded
* and ready . If you must store a reference to the et2 object ,
* make sure to clean it up in destroy ( ) .
*
* @ param et2 etemplate2 Newly ready object
* /
et2 _ready : function ( et2 )
{
// call parent
this . _super . apply ( this , arguments ) ;
var content = this . et2 . getArrayMgr ( 'content' ) ;
if ( typeof et2 . templates [ 'calendar.list' ] != 'undefined' )
{
2014-01-24 16:50:17 +01:00
try {
// check if listview runs in an iframe --> use linkHandler to open it top-level
if ( top . egw && top != window && window . framework )
{
window . framework . linkHandler ( document . location . href + '&ajax=true' , 'calendar' ) ;
}
}
catch ( e ) {
// ignore error eg. comming because we have a top not belonging to EGroupware
}
2013-10-31 15:51:19 +01:00
this . filter _change ( ) ;
}
if ( typeof et2 . templates [ 'calendar.edit' ] != 'undefined' && typeof content . data [ 'conflicts' ] == 'undefined' )
{
$j ( document . getElementById ( 'calendar-edit_calendar-delete_series' ) ) . hide ( ) ;
//Check if it's fallback from conflict window or it's from edit window
if ( content . data [ 'button_was' ] != 'freetime' )
{
this . set _enddate _visibility ( ) ;
this . check _recur _type ( ) ;
2013-11-05 14:33:32 +01:00
this . et2 . getWidgetById ( 'recur_exception' ) . set _disabled ( typeof content . data [ 'recur_exception' ] [ 0 ] == 'undefined' ) ;
2013-10-31 15:51:19 +01:00
}
else
{
this . freetime _search ( ) ;
}
//send Syncronus ajax request to the server to unlock the on close entry
//set onbeforeunload with json request to send request when the window gets close by X button
window . onbeforeunload = function ( ) {
this . egw . json ( 'calendar.calendar_uiforms.ajax_unlock'
, [ content . data [ 'id' ] , content . data [ 'lock_token' ] ] , null , true , null , null ) . sendRequest ( true ) ;
} ;
}
//this.replace_eTemplate_onsubmit();
if ( typeof et2 . templates [ 'calendar.freetimesearch' ] != 'undefined' )
{
this . set _enddate _visibility ( ) ;
}
} ,
2014-01-24 16:50:17 +01:00
/ * *
* Link hander for jDots template to just reload our iframe , instead of reloading whole admin app
*
* @ param { String } _url
* @ return { boolean | string } true , if linkHandler took care of link , false for default processing or url to navigate to
* /
linkHandler : function ( _url )
{
if ( _url . match ( 'menuaction=calendar.calendar_uiviews.index' ) )
{
var state = this . getState ( ) ;
if ( state . view == 'listview' )
{
return _url . replace ( /menuaction=[^&]+/ , 'menuaction=calendar.calendar_uilist.listview&ajax=true' ) ;
}
}
// can not load our own index page, has to be done by framework
return false ;
} ,
2013-12-13 19:18:56 +01:00
/ * *
* Drag and Drop
*
*
* /
drag _n _drop : function ( )
{
var that = this ;
2014-01-30 19:24:24 +01:00
2013-12-13 19:18:56 +01:00
//Draggable
jQuery ( "div[id^='drag_']" ) . draggable (
2014-01-30 17:48:49 +01:00
{
2013-12-13 19:18:56 +01:00
stack : jQuery ( "div[id^='drag_']" ) ,
revert : "invalid" ,
delay : 50 ,
cursorAt : { top : 0 , left : 0 } ,
containment : ".egw_fw_content_browser_iframe" ,
scroll : true ,
opacity : . 6 ,
2014-01-07 17:09:36 +01:00
cursor : "move" ,
2013-12-13 19:18:56 +01:00
2014-01-30 17:48:49 +01:00
/ * *
* Triggered when the dragging of calEvent stoped .
*
* @ param { event } event
* @ param { Object } ui
* /
stop : function ( event , ui )
{
ui . helper . width ( oldWidth ) ;
ui . helper [ 0 ] . innerHTML = oldInnerHTML ;
2013-12-13 19:18:56 +01:00
} ,
2014-01-30 17:48:49 +01:00
/ * *
* Triggered while dragging a calEvent .
*
* @ param { event } event
* @ param { Object } ui
*
* /
drag : function ( event , ui )
2013-12-17 15:33:03 +01:00
{
2013-12-13 19:18:56 +01:00
//that.dragEvent();
} ,
2014-01-30 17:48:49 +01:00
/ * *
* Triggered when the dragging of calEvent started .
*
* @ param { event } event
* @ param { Object } ui
*
* /
start : function ( event , ui )
2013-12-17 15:33:03 +01:00
{
2014-01-30 17:48:49 +01:00
oldInnerHTML = ui . helper [ 0 ] . innerHTML ;
oldWidth = ui . helper . width ( ) ;
ui . helper . width ( jQuery ( "#calColumn" ) . width ( ) ) ;
2014-01-24 10:47:33 +01:00
}
2013-12-16 19:10:08 +01:00
} ) . resizable ( {
2014-01-30 17:48:49 +01:00
distance : 10 ,
2014-01-30 19:24:24 +01:00
2014-01-30 17:48:49 +01:00
/ * *
* Triggered when the resizable is created .
*
* @ param { event } event
* @ param { Object } ui
* /
create : function ( event , ui )
2014-01-24 13:50:20 +01:00
{
2014-01-30 17:48:49 +01:00
var resizeHelper = event . target . getAttribute ( 'data-resize' ) . split ( "|" ) [ 3 ] ;
2014-01-24 13:50:20 +01:00
if ( resizeHelper == 'WD' )
{
2014-01-27 17:03:08 +01:00
$j ( this ) . resizable ( 'destroy' ) ;
2014-01-24 13:50:20 +01:00
}
} ,
2014-01-30 17:48:49 +01:00
/ * *
* Triggered at start of resizing a calEvent
*
* @ param { event } event
* @ param { Object } ui
* /
start : function ( event , ui )
2013-12-17 15:33:03 +01:00
{
2014-01-30 17:48:49 +01:00
var resizeHelper = event . target . getAttribute ( 'data-resize' ) ;
2013-12-16 19:10:08 +01:00
var dataResize = resizeHelper . split ( "|" ) ;
var time = dataResize [ 1 ] . split ( ":" ) ;
2014-01-30 19:24:24 +01:00
2014-02-05 15:32:15 +01:00
this . dropStart = that . resizeHelper ( ui . element [ 0 ] . getBoundingClientRect ( ) . left , ui . element [ 0 ] . getBoundingClientRect ( ) . top ) ;
2014-01-30 17:48:49 +01:00
this . dropDate = dataResize [ 0 ] + "T" + time [ 0 ] + time [ 1 ] ;
//$j(this).resizable("option","containment",".calendar_calDayCol");
} ,
2014-01-29 19:44:12 +01:00
2014-01-30 17:48:49 +01:00
/ * *
* Triggered at the end of resizing the calEvent .
*
* @ param { event } event
* @ param { Object } ui
* /
stop : function ( event , ui )
{
var eventFlag = event . target . getAttribute ( 'data-resize' ) . split ( "|" ) [ 3 ] ;
var dropdate = that . cal _dnd _tZone _converter ( this . dropDate ) ;
var sT = parseInt ( ( dropdate . split ( "T" ) [ 1 ] . substr ( 0 , 2 ) * 60 ) ) + parseInt ( dropdate . split ( "T" ) [ 1 ] . substr ( 2 , 2 ) ) ;
if ( this . dropEnd != 'undefined' && this . dropEnd )
2014-01-29 19:44:12 +01:00
{
2014-01-30 17:48:49 +01:00
var eT = parseInt ( this . dropEnd . getAttribute ( 'data-date' ) . split ( "|" ) [ 1 ] * 60 ) + parseInt ( this . dropEnd . getAttribute ( 'data-date' ) . split ( "|" ) [ 2 ] ) ;
var newDuration = ( ( eT - sT ) / 60 ) * 3600 ;
that . dropEvent ( this . getAttribute ( 'id' ) , dropdate , newDuration , eventFlag ) ;
2014-01-29 19:44:12 +01:00
}
2014-01-30 17:48:49 +01:00
} ,
/ * *
* Triggered during the resize , on the drag of the resize handler
*
* @ param { event } event
* @ param { Object } ui
* /
resize : function ( event , ui )
{
this . dropEnd = that . resizeHelper ( ui . element [ 0 ] . getBoundingClientRect ( ) . left ,
ui . element [ 0 ] . getBoundingClientRect ( ) . top + ui . size . height ) ;
if ( typeof this . dropEnd != 'undefined' && this . dropEnd )
2014-01-29 19:44:12 +01:00
{
2014-01-30 17:48:49 +01:00
if ( this . dropEnd . getAttribute ( 'id' ) . match ( /drop_/g ) )
{
var dH = this . dropEnd . getAttribute ( 'data-date' ) . split ( "|" ) [ 1 ] ;
var dM = this . dropEnd . getAttribute ( 'data-date' ) . split ( "|" ) [ 2 ] ;
}
var dataResize = event . target . getAttribute ( 'data-resize' ) . split ( "|" ) ;
2014-02-03 09:27:56 +01:00
this . innerHTML = '<div style="font-size: 1.1em; text-align:center; font-weight: bold; height:100%;"><span style=" position: absolute; bottom: 0; align: center; ">' + dH + ':' + dM + '</span></div>' ;
2014-01-29 19:44:12 +01:00
}
2014-01-30 17:48:49 +01:00
else
2014-01-29 19:44:12 +01:00
{
2014-01-30 17:48:49 +01:00
this . innerHTML = '<div class="calendar_d-n-d_forbiden"></div>' ;
2014-01-29 19:44:12 +01:00
}
2013-12-17 15:33:03 +01:00
}
} ) ;
2013-12-13 19:18:56 +01:00
//Droppable
jQuery ( "div[id^='drop_']" ) . droppable (
{
2014-01-30 17:48:49 +01:00
/ * *
* Make all draggable calEvents acceptable
2014-01-30 19:24:24 +01:00
*
2014-01-30 17:48:49 +01:00
* /
2014-01-24 17:04:11 +01:00
accept : function ( )
2013-12-17 15:33:03 +01:00
{
2014-01-24 17:04:11 +01:00
return true ;
2013-12-13 19:18:56 +01:00
} ,
tolerance : 'pointer' ,
2014-01-30 17:48:49 +01:00
/ * *
* Triggered when the calEvent dropped .
*
* @ param { event } event
* @ param { Object } ui
* /
drop : function ( event , ui )
2013-12-17 15:33:03 +01:00
{
2014-01-30 17:48:49 +01:00
var dgId = ui . draggable [ 0 ] . getAttribute ( 'id' ) ;
2013-12-13 19:18:56 +01:00
var dgOwner = dgId . substring ( dgId . lastIndexOf ( "_C" ) + 2 , dgId . lastIndexOf ( "" ) ) ;
2014-01-30 17:48:49 +01:00
var dpOwner = event . target . getAttribute ( 'data-owner' ) ;
var eventFlag = ui . draggable [ 0 ] . getAttribute ( 'data-resize' ) . split ( "|" ) [ 3 ] ;
2013-12-13 19:18:56 +01:00
if ( dpOwner == null ) dpOwner = dgOwner ;
if ( dpOwner == dgOwner )
{
2014-01-30 17:48:49 +01:00
that . dropEvent ( ui . draggable [ 0 ] . id , event . target . getAttribute ( 'id' ) . substring ( event . target . getAttribute ( 'id' ) . lastIndexOf ( "drop_" ) + 5 , event . target . getAttribute ( 'id' ) . lastIndexOf ( "_O" ) ) , null , eventFlag ) ;
2013-12-13 19:18:56 +01:00
}
else
{
2014-01-30 17:48:49 +01:00
jQuery ( ui . draggable ) . draggable ( "option" , "revert" , true ) ;
2013-12-13 19:18:56 +01:00
}
} ,
2014-01-30 17:48:49 +01:00
/ * *
* Triggered when draggable calEvent is over a droppable calCell .
*
* @ param { event } event
* @ param { Object } ui
* /
over : function ( event , ui )
2013-12-17 15:33:03 +01:00
{
2014-01-30 17:48:49 +01:00
var timeDemo = event . target . id . substring ( event . target . id . lastIndexOf ( "T" ) + 1 , event . target . id . lastIndexOf ( "_O" ) ) ;
var dgId = ui . draggable [ 0 ] . getAttribute ( 'id' ) ;
2013-12-13 19:18:56 +01:00
var dgOwner = dgId . substring ( dgId . lastIndexOf ( "_C" ) + 2 , dgId . lastIndexOf ( "" ) ) ;
2014-01-30 17:48:49 +01:00
var dpOwner = event . target . getAttribute ( 'data-owner' ) ;
2013-12-13 19:18:56 +01:00
if ( dpOwner == null ) dpOwner = dgOwner ;
2014-01-24 17:04:11 +01:00
if ( dpOwner === dgOwner )
2013-12-13 19:18:56 +01:00
{
2014-01-30 17:48:49 +01:00
ui . helper [ 0 ] . innerHTML = '<div class="calendar_d-n-d_timeCounter">' + timeDemo + '</div>' ;
2013-12-13 19:18:56 +01:00
}
else
{
2014-01-30 17:48:49 +01:00
ui . helper [ 0 ] . innerHTML = '<div class="calendar_d-n-d_forbiden"></div>' ;
2013-12-13 19:18:56 +01:00
}
2014-01-24 10:47:33 +01:00
}
2013-12-13 19:18:56 +01:00
} ) ;
2014-01-06 16:36:49 +01:00
//onClick Handler for calender entries
jQuery ( "div.calendar_calEvent" ) . on ( {
click : function ( ev ) {
2014-01-17 11:28:15 +01:00
var Id = ev . currentTarget . id . replace ( /drag_/g , '' ) . split ( "_" ) [ 0 ] ;
var eventId = Id . match ( /-?\d+\.?\d*/g ) [ 0 ] ;
var appName = Id . replace ( /-?\d+\.?\d*/g , '' ) ;
2014-01-06 16:36:49 +01:00
var startDate = ev . currentTarget . getAttribute ( 'data-resize' ) . split ( "|" ) [ 0 ] ;
2014-01-24 13:50:20 +01:00
var eventFlag = ev . currentTarget . getAttribute ( 'data-resize' ) . split ( "|" ) [ 3 ] ;
if ( eventFlag != 'S' )
2014-01-06 16:36:49 +01:00
{
2014-01-17 11:28:15 +01:00
that . egw . open ( eventId , appName != "" ? appName : 'calendar' , 'edit' ) ;
2014-01-06 16:36:49 +01:00
}
else
{
2014-01-27 17:36:49 +01:00
that . edit _series ( eventId , startDate ) ;
2014-01-06 16:36:49 +01:00
}
} ,
mouseover : function ( ) {
var ttp = jQuery ( this ) . tooltip ( {
items : "[data-tooltip]" ,
content : function ( )
{
var elem = jQuery ( this ) ;
if ( elem . is ( "[data-tooltip]" ) )
return this . getAttribute ( 'data-tooltip' ) ;
} ,
track : true ,
2014-01-07 11:34:11 +01:00
open : function ( event , ui ) {
ui . tooltip . removeClass ( "ui-tooltip" ) ;
ui . tooltip . addClass ( "calendar_uitooltip" ) ;
}
2014-01-06 16:36:49 +01:00
} ) ;
ttp . tooltip ( "enable" ) ;
} ,
mousedown : function ( ) {
jQuery ( this ) . tooltip ( "disable" ) ;
}
} ) ;
2014-01-08 17:36:15 +01:00
2014-01-17 11:28:15 +01:00
//Click handler for calendar todos
jQuery ( "div.calendar_calDayTodos" ) . find ( "[data-todo^='app|']" ) . on ( {
click : function ( ev )
{
var windowSize = ev . currentTarget . getAttribute ( 'data-todo' ) . split ( "|" ) [ 1 ] ;
var link = ev . currentTarget . getAttribute ( 'href' ) ;
that . egw . open _link ( link , '_blank' , windowSize ) ;
return false ;
}
} ) ;
2014-01-08 17:36:15 +01:00
//Click Handler for calendar planner
jQuery ( "div.calendar_plannerEvent" ) . on ( {
click : function ( ev ) {
2014-01-09 10:38:55 +01:00
var eventId = ev . currentTarget . getAttribute ( 'data-date' ) . split ( "|" ) [ 1 ] ;
var startDate = ev . currentTarget . getAttribute ( 'data-date' ) . split ( "|" ) [ 0 ] ;
var recurrFlag = ev . currentTarget . getAttribute ( 'data-date' ) . split ( "|" ) [ 2 ] ;
if ( recurrFlag == "n" )
2014-01-08 17:36:15 +01:00
{
egw . open ( eventId , 'calendar' , 'edit' ) ;
}
else
{
2014-01-27 17:36:49 +01:00
that . edit _series ( eventId , startDate ) ;
2014-01-08 17:36:15 +01:00
}
} ,
mouseover : function ( ) {
var ttp = jQuery ( this ) . tooltip ( {
items : "[data-tooltip]" ,
content : function ( )
{
var elem = jQuery ( this ) ;
if ( elem . is ( "[data-tooltip]" ) )
return this . getAttribute ( 'data-tooltip' ) ;
} ,
track : true ,
open : function ( event , ui ) {
ui . tooltip . removeClass ( "ui-tooltip" ) ;
ui . tooltip . addClass ( "calendar_uitooltip" ) ;
}
} ) ;
ttp . tooltip ( "enable" ) ;
} ,
mousedown : function ( ) {
jQuery ( this ) . tooltip ( "disable" ) ;
}
} ) ;
2013-12-13 19:18:56 +01:00
//onClick Handler for calendar cells
jQuery ( "div.calendar_calAddEvent" ) . click ( function ( ev )
{
var timestamp = ev . target . getAttribute ( 'data-date' ) . split ( "|" ) ;
var owner = ev . target . getAttribute ( 'id' ) . split ( "_" ) ;
2014-01-14 18:32:01 +01:00
var ownerId = owner [ 2 ] . match ( /Ogroup/g ) ? owner [ 2 ] . replace ( /Ogroup/g , '-' ) : owner [ 2 ] . replace ( /^\D+/g , '' ) ;
if ( owner [ 2 ] . match ( /Or/g ) )
{
ownerId = 'r' + ownerId ;
}
2014-02-05 15:32:15 +01:00
that . egw . open ( null , 'calendar' , 'add' , {
date : timestamp [ 0 ] ,
hour : timestamp [ 1 ] ,
minute : timestamp [ 2 ] ,
owner : ownerId
} , '_blank' ) ;
2013-12-13 19:18:56 +01:00
} ) ;
} ,
2014-01-30 19:24:24 +01:00
2014-01-30 17:48:49 +01:00
/ * *
* Function to help calendar resizable event , to fetch the right droppable cell
*
* @ param { int } _X position left of draggable element
* @ param { int } _Y position top of draggable element
*
* @ return { jquery object | boolean } return selected jquery if not return false
* /
resizeHelper : function ( _X , _Y )
{
var drops = jQuery ( "div[id^='drop_']" ) ;
var top = Math . round ( _Y ) ;
var left = Math . round ( _X ) ;
for ( var i = 0 ; i < drops . length ; i ++ )
{
if ( top >= Math . round ( drops [ i ] . getBoundingClientRect ( ) . top )
&& top <= Math . round ( drops [ i ] . getBoundingClientRect ( ) . bottom )
&& left >= Math . round ( drops [ i ] . getBoundingClientRect ( ) . left )
&& left <= Math . round ( drops [ i ] . getBoundingClientRect ( ) . right ) )
return drops [ i ] ;
}
return false ;
} ,
2014-01-30 19:24:24 +01:00
2014-01-30 17:48:49 +01:00
/ * *
* Convert AM / PM dateTime format to 24 h
*
* @ param { string } _date dnd date format : dateTtime { am | pm } , eg . 121214 T1205 am
*
* @ return { string } 24 h format date
* /
cal _dnd _tZone _converter : function ( _date )
{
var date = _date ;
if ( _date != 'undefined' )
{
var tZone = _date . split ( 'T' ) [ 1 ] ;
if ( tZone . search ( 'am' ) > 0 )
{
tZone = tZone . replace ( ' am' , '' ) ;
var tAm = tZone . substr ( 0 , 2 ) ;
if ( tAm == '12' )
{
tZone = tZone . replace ( '12' , '00' ) ;
}
date = _date . split ( 'T' ) [ 0 ] + 'T' + tZone ;
}
if ( tZone . search ( 'pm' ) > 0 )
{
var pmTime = tZone . replace ( ' pm' , '' ) ;
var H = parseInt ( pmTime . substring ( 0 , 2 ) ) + 12 ;
pmTime = H . toString ( ) + pmTime . substr ( 2 , 2 ) ;
date = _date . split ( 'T' ) [ 0 ] + 'T' + pmTime ;
}
2013-12-13 19:18:56 +01:00
2014-01-30 17:48:49 +01:00
}
return date ;
} ,
2014-01-30 19:24:24 +01:00
2013-12-13 19:18:56 +01:00
/ * *
* DropEvent
*
* @ param { string } _id dragged event id
* @ param { array } _date array of date , hour , and minute of dropped cell
2013-12-16 19:10:08 +01:00
* @ param { string } _duration description
2014-01-24 13:50:20 +01:00
* @ param { string } _eventFlag Flag to distinguesh wheter the event is Whole Day , Series , or Single
2013-12-13 19:18:56 +01:00
* /
2014-01-24 13:50:20 +01:00
dropEvent : function ( _id , _date , _duration , _eventFlag )
2013-12-13 19:18:56 +01:00
{
var eventId = _id . substring ( _id . lastIndexOf ( "drag_" ) + 5 , _id . lastIndexOf ( "_O" ) ) ;
var calOwner = _id . substring ( _id . lastIndexOf ( "_O" ) + 2 , _id . lastIndexOf ( "_C" ) ) ;
var eventOwner = _id . substring ( _id . lastIndexOf ( "_C" ) + 2 , _id . lastIndexOf ( "" ) ) ;
2014-01-30 17:48:49 +01:00
var date = this . cal _dnd _tZone _converter ( _date ) ;
2014-01-24 13:50:20 +01:00
var moveOrder = false ;
if ( _eventFlag == 'S' )
{
et2 _dialog . show _dialog ( function ( _button _id )
{
if ( _button _id == et2 _dialog . OK _BUTTON )
{
xajax _doXMLHTTP (
'calendar.calendar_ajax.moveEvent' ,
eventId ,
calOwner ,
date ,
eventOwner ,
_duration
) ;
2014-01-30 17:55:02 +01:00
}
2014-01-24 13:50:20 +01:00
} , this . egw . lang ( "Do you really want to change the start of this series? If you do, the original series will be terminated as of today and a new series for the future reflecting your changes will be created." ) ,
this . egw . lang ( "This event is part of a series" ) , { } , et2 _dialog . BUTTONS _OK _CANCEL , et2 _dialog . WARNING _MESSAGE ) ;
}
else
{
moveOrder = true ;
}
if ( moveOrder )
{
xajax _doXMLHTTP (
'calendar.calendar_ajax.moveEvent' ,
eventId ,
calOwner ,
date ,
eventOwner ,
_duration
) ;
}
2013-12-13 19:18:56 +01:00
} ,
2014-01-30 19:24:24 +01:00
2013-10-31 15:51:19 +01:00
/ * *
* open the freetime search popup
*
2013-11-05 19:08:07 +01:00
* @ param { string } _link
2013-10-31 15:51:19 +01:00
* /
2013-11-05 19:08:07 +01:00
freetime _search _popup : function ( _link )
{
2013-10-31 15:51:19 +01:00
this . egw . open _link ( _link , 'ft_search' , '700x500' ) ;
2013-11-05 19:08:07 +01:00
} ,
2013-10-31 15:51:19 +01:00
/ * *
* send an ajax request to server to set the freetimesearch window content
*
* /
freetime _search : function ( )
2011-04-27 18:53:06 +02:00
{
2013-10-31 15:51:19 +01:00
var content = this . et2 . getArrayMgr ( 'content' ) . data ;
content [ 'start' ] = this . et2 . getWidgetById ( 'start' ) . get _value ( ) ;
content [ 'end' ] = this . et2 . getWidgetById ( 'end' ) . get _value ( ) ;
content [ 'duration' ] = this . et2 . getWidgetById ( 'duration' ) . get _value ( ) ;
var request = this . egw . json ( 'calendar.calendar_uiforms.ajax_freetimesearch' , [ content ] , null , null , null , null ) ;
request . sendRequest ( ) ;
} ,
/ * *
* Function for disabling the recur _data multiselect box
*
* /
check _recur _type : function ( )
2011-04-27 18:53:06 +02:00
{
2013-10-31 15:51:19 +01:00
var recurType = this . et2 . getWidgetById ( 'recur_type' ) ;
var recurData = this . et2 . getWidgetById ( 'recur_data' ) ;
2011-04-27 18:53:06 +02:00
2013-10-31 15:51:19 +01:00
if ( recurType && recurData )
2011-04-27 18:53:06 +02:00
{
2013-10-31 15:51:19 +01:00
recurData . set _disabled ( recurType . get _value ( ) != 2 ) ;
2011-04-27 18:53:06 +02:00
}
2013-10-31 15:51:19 +01:00
} ,
/ * *
* Show / Hide end date , for both edit and freetimesearch popups ,
* based on if "use end date" selected or not .
*
* /
set _enddate _visibility : function ( )
{
var duration = this . et2 . getWidgetById ( 'duration' ) ;
var end = this . et2 . getWidgetById ( 'end' ) ;
if ( typeof duration != 'undefined' && typeof end != 'undefined' )
2011-04-27 18:53:06 +02:00
{
2013-10-31 15:51:19 +01:00
end . set _disabled ( duration . get _value ( ) !== '' ) ;
2011-04-27 18:53:06 +02:00
}
2013-10-31 15:51:19 +01:00
} ,
2013-01-09 22:38:18 +01:00
2013-10-31 15:51:19 +01:00
/ * *
* handles actions selectbox in calendar edit popup
*
2013-11-05 19:08:07 +01:00
* @ param { mixed } _event
2014-01-24 10:47:33 +01:00
* @ param { et2 _base _widget } widget "actions selectBox" in edit popup window
2013-10-31 15:51:19 +01:00
* /
2013-11-05 19:08:07 +01:00
actions _change : function ( _event , widget )
{
2013-10-31 15:51:19 +01:00
var event = this . et2 . getArrayMgr ( 'content' ) . data ;
if ( widget )
{
var id = this . et2 . getArrayMgr ( 'content' ) . data [ 'id' ] ;
switch ( widget . get _value ( ) )
{
case 'print' :
this . egw . open _link ( 'calendar.calendar_uiforms.edit&cal_id=' + id + '&print=1' , '_blank' , '700x700' ) ;
this . et2 . _inst . submit ( ) ;
break ;
case 'mail' :
this . egw . json ( 'calendar.calendar_uiforms.ajax_custom_mail' , [ event , ! event [ 'id' ] , false ] , null , null , null , null ) . sendRequest ( ) ;
this . et2 . _inst . submit ( ) ;
break ;
case 'sendrequest' :
this . egw . json ( 'calendar.calendar_uiforms.ajax_custom_mail' , [ event , ! event [ 'id' ] , true ] , null , null , null , null ) . sendRequest ( ) ;
this . et2 . _inst . submit ( ) ;
break ;
case 'infolog' :
this . egw . open _link ( 'infolog.infolog_ui.edit&action=calendar&action_id=' + ( $j . isPlainObject ( event ) ? event [ 'id' ] : event ) , '_self' , '700x600' , 'infolog' ) ;
this . et2 . _inst . submit ( ) ;
break ;
default :
this . et2 . _inst . submit ( ) ;
}
}
2013-11-05 19:08:07 +01:00
} ,
2013-10-31 15:51:19 +01:00
/ * *
* open mail compose popup window
*
2013-11-05 19:08:07 +01:00
* @ param { Array } vars
2013-10-31 15:51:19 +01:00
* @ todo need to provide right mail compose from server to custom _mail function
* /
2013-11-05 19:08:07 +01:00
custom _mail : function ( vars )
{
2014-01-29 19:47:49 +01:00
this . egw . open _link ( this . egw . link ( "/index.php" , vars ) , '_blank' , '700x700' ) ;
2013-11-05 19:08:07 +01:00
} ,
2013-10-31 15:51:19 +01:00
/ * *
* control delete _series popup visibility
*
2014-01-24 10:47:33 +01:00
* @ param { et2 _widget } widget
2013-11-05 19:08:07 +01:00
* @ param { Array } exceptions an array contains number of exception entries
2013-10-31 15:51:19 +01:00
*
* /
2014-01-23 11:27:18 +01:00
delete _btn : function ( widget , exceptions )
2013-11-05 19:08:07 +01:00
{
var content = this . et2 . getArrayMgr ( 'content' ) . data ;
2013-10-31 15:51:19 +01:00
2013-11-05 19:08:07 +01:00
if ( exceptions )
{
2013-10-31 15:51:19 +01:00
$j ( document . getElementById ( 'calendar-edit_calendar-delete_series' ) ) . show ( ) ;
2013-11-05 19:08:07 +01:00
}
else if ( content [ 'recur_type' ] !== 0 )
{
2014-01-23 11:27:18 +01:00
et2 _dialog . confirm ( widget , 'Delete this series of recuring events' , 'Delete Series' ) ;
2013-11-05 19:08:07 +01:00
}
else
{
2014-01-23 11:27:18 +01:00
et2 _dialog . confirm ( widget , 'Delete this event' , 'Delete' ) ;
2013-11-05 19:08:07 +01:00
}
} ,
2013-10-31 15:51:19 +01:00
/ * *
* print _participants _status ( egw , widget )
* Handle to apply changes from status in print popup
*
2013-11-05 19:08:07 +01:00
* @ param { mixed } _event
* @ param { et2 _base _widget } widget widget "status" in print popup window
2013-10-31 15:51:19 +01:00
*
* /
2013-11-05 19:08:07 +01:00
print _participants _status : function ( _event , widget )
{
2013-10-31 15:51:19 +01:00
if ( widget && window . opener )
{
//Parent popup window
var editPopWindow = window . opener ;
if ( editPopWindow )
{
//Update paretn popup window
editPopWindow . etemplate2 . getByApplication ( 'calendar' ) [ 0 ] . widgetContainer . getWidgetById ( widget . id ) . set _value ( widget . get _value ( ) ) ;
}
this . et2 . _inst . submit ( ) ;
editPopWindow . opener . egw _refresh ( 'status changed' , 'calendar' ) ;
}
else if ( widget )
{
window . egw _refresh ( this . egw . lang ( 'The original popup edit window is closed! You need to close the print window and reopen the entry again.' ) , 'calendar' ) ;
}
2013-11-05 19:08:07 +01:00
} ,
2013-10-31 15:51:19 +01:00
/ * *
* Handles to select freetime , and replace the selected one on Start ,
* and End date & time in edit calendar entry popup .
*
2013-11-05 19:08:07 +01:00
* @ param { mixed } _event
* @ param { et2 _base _widget } _widget widget "select button" in freetime search popup window
2013-10-31 15:51:19 +01:00
*
* /
2013-11-05 19:08:07 +01:00
freetime _select : function ( _event , _widget )
{
2013-10-31 15:51:19 +01:00
if ( _widget )
{
var content = this . et2 . _inst . widgetContainer . getArrayMgr ( 'content' ) . data ;
// Make the Id from selected button by checking the index
var selectedId = _widget . id . match ( /^select\[([0-9])\]$/i ) [ 1 ] ;
var sTime = this . et2 . getWidgetById ( selectedId + 'start' ) ;
var eTime = this . et2 . getWidgetById ( selectedId + '[end]' ) ;
//Catches the start time from freetime content
var str = sTime . get _value ( ) ;
2013-01-09 22:45:55 +01:00
2013-10-31 15:51:19 +01:00
var end = parseInt ( str ) + parseInt ( content [ 'duration' ] ) ;
//check the parent window is still open before to try to access it
if ( window . opener )
{
var editWindowObj = window . opener . etemplate2 . getByApplication ( 'calendar' ) [ 0 ] ;
if ( typeof editWindowObj != "undefined" )
{
var startTime = editWindowObj . widgetContainer . getWidgetById ( 'start' ) ;
var endTime = editWindowObj . widgetContainer . getWidgetById ( 'end' ) ;
if ( startTime && endTime )
{
startTime . set _value ( str ) ;
endTime . set _value ( end ) ;
}
}
}
else
{
alert ( this . egw . lang ( 'The original calendar edit popup is closed!' ) ) ;
}
}
window . close ( ) ;
2013-11-05 19:08:07 +01:00
} ,
2013-10-31 15:51:19 +01:00
/ * *
* show / hide the filter of nm list in calendar listview
*
* /
filter _change : function ( )
2013-01-09 22:45:55 +01:00
{
2013-10-31 15:51:19 +01:00
var filter = this . et2 . getWidgetById ( 'filter' ) ;
var dates = this . et2 . getWidgetById ( 'calendar.list.dates' ) ;
if ( filter && dates )
2013-01-09 22:45:55 +01:00
{
2013-10-31 15:51:19 +01:00
dates . set _disabled ( filter . value !== "custom" ) ;
2013-01-09 22:45:55 +01:00
}
2013-10-31 15:51:19 +01:00
} ,
/ * *
* this function try to fix ids which are from integrated apps
*
2013-11-05 19:08:07 +01:00
* @ param { egw _action } _action
* @ param { Array } _senders
2013-10-31 15:51:19 +01:00
* /
cal _fix _app _id : function ( _action , _senders )
2013-01-09 22:38:18 +01:00
{
2013-10-31 15:51:19 +01:00
var app = 'calendar' ;
var id = _senders [ 0 ] . id ;
2013-11-04 11:23:08 +01:00
var matches = id . match ( /^(?:calendar::)?([0-9]+)(:([0-9]+))?$/ ) ;
2013-10-31 15:51:19 +01:00
if ( matches )
{
id = matches [ 1 ] ;
}
2014-01-24 10:47:33 +01:00
else
2013-10-31 15:51:19 +01:00
{
2014-01-24 10:47:33 +01:00
matches = id . match ( /^([a-z_-]+)([0-9]+)/i ) ;
if ( matches )
{
app = matches [ 1 ] ;
id = matches [ 2 ] ;
}
2013-10-31 15:51:19 +01:00
}
var backup _url = _action . data . url ;
2013-11-05 14:30:41 +01:00
_action . data . url = _action . data . url . replace ( /(\$|%24)id/ , id ) ;
_action . data . url = _action . data . url . replace ( /(\$|%24)app/ , app ) ;
2013-10-31 15:51:19 +01:00
nm _action ( _action , _senders ) ;
2013-11-05 14:30:41 +01:00
2013-10-31 15:51:19 +01:00
_action . data . url = backup _url ; // restore url
} ,
/ * *
* Open calendar entry , taking into accout the calendar integration of other apps
*
* calendar _uilist : : get _rows sets var js _calendar _integration object
*
* @ param _action
* @ param _senders
*
* /
cal _open : function ( _action , _senders )
{
var js _integration _data = this . et2 . getArrayMgr ( 'content' ) . data . nm . js _integration _data ;
var id = _senders [ 0 ] . id ;
var matches = id . match ( /^(?:calendar::)?([0-9]+):([0-9]+)$/ ) ;
var backup = _action . data ;
if ( matches )
{
this . edit _series ( matches [ 1 ] , matches [ 2 ] ) ;
return ;
}
2014-01-24 10:47:33 +01:00
matches = id . match ( /^([a-z_-]+)([0-9]+)/i ) ;
if ( matches )
2013-10-31 15:51:19 +01:00
{
var app = matches [ 1 ] ;
_action . data . url = window . egw _webserverUrl + '/index.php?' ;
var get _params = js _integration _data [ app ] . edit ;
get _params [ js _integration _data [ app ] . edit _id ] = matches [ 2 ] ;
for ( var name in get _params )
_action . data . url += name + "=" + encodeURIComponent ( get _params [ name ] ) + "&" ;
2013-01-09 22:38:18 +01:00
2014-01-24 10:47:33 +01:00
if ( js _integration _data [ app ] . edit _popup )
2013-10-31 15:51:19 +01:00
{
2014-01-24 10:47:33 +01:00
matches = js _integration _data [ app ] . edit _popup . match ( /^(.*)x(.*)$/ ) ;
if ( matches )
{
_action . data . width = matches [ 1 ] ;
_action . data . height = matches [ 2 ] ;
}
else
{
_action . data . nm _action = 'location' ;
}
2013-10-31 15:51:19 +01:00
}
}
egw . open ( id . replace ( /^calendar::/g , '' ) , 'calendar' , 'edit' ) ;
_action . data = backup ; // restore url, width, height, nm_action
} ,
2013-01-09 22:38:18 +01:00
2013-10-31 15:51:19 +01:00
/ * *
* Delete calendar entry , asking if you want to delete series or exception
*
*
* @ param _action
* @ param _senders
* /
cal _delete : function ( _action , _senders )
{
var backup = _action . data ;
var matches = false ;
2013-01-09 22:38:18 +01:00
2013-10-31 15:51:19 +01:00
// Loop so we ask if any of the selected entries is part of a series
for ( var i = 0 ; i < _senders . length ; i ++ )
2013-01-09 22:38:18 +01:00
{
2013-10-31 15:51:19 +01:00
var id = _senders [ i ] . id ;
if ( ! matches )
{
matches = id . match ( /^(?:calendar::)?([0-9]+):([0-9]+)$/ ) ;
}
}
if ( matches )
{
var id = matches [ 1 ] ;
var date = matches [ 2 ] ;
var popup = jQuery ( document . getElementById ( _action . getManager ( ) . etemplate _var _prefix + '[' + _action . id + '_popup]' ) ) ;
var row = null ;
// Cancel normal confirm
delete _action . data . confirm ;
delete _action . data . confirm _multiple ;
// nm action - show popup
nm _open _popup ( _action , _senders ) ;
if ( ! popup )
{
return ;
}
2014-01-24 10:47:33 +01:00
row = jQuery ( "#" + id + "\\:" + date ) ;
if ( row )
2013-11-05 19:08:07 +01:00
{
2013-10-31 15:51:19 +01:00
// Open at row
popup . css ( {
position : "absolute" ,
top : row . position ( ) . top + row . height ( ) - popup . height ( ) / 2 ,
left : $j ( window ) . width ( ) / 2 - popup . width ( ) / 2
} ) ;
} else {
// Open popup in the middle
popup . css ( {
position : "absolute" ,
top : $j ( window ) . height ( ) / 2 - popup . height ( ) / 2 ,
left : $j ( window ) . width ( ) / 2 - popup . width ( ) / 2
} ) ;
}
2013-01-09 22:38:18 +01:00
return ;
}
2013-10-31 15:51:19 +01:00
console . log ( _action ) ;
2013-11-05 17:02:21 +01:00
nm _action ( _action , _senders ) ;
2013-10-31 15:51:19 +01:00
_action . data = backup ; // restore url, width, height, nm_action
} ,
2014-01-23 18:15:49 +01:00
/ * *
2014-01-24 16:50:17 +01:00
* Confirmation dialog for moving a series entry
2014-01-23 18:15:49 +01:00
*
2014-01-24 16:50:17 +01:00
* @ param { object } _DOM
* @ param { et2 _widget } _button button Save | Apply
2014-01-23 18:15:49 +01:00
* /
move _edit _series : function ( _DOM , _button )
{
var content = this . et2 . getArrayMgr ( 'content' ) . data ;
var start _date = this . et2 . getWidgetById ( 'start' ) . get _value ( ) ;
var whole _day = this . et2 . getWidgetById ( 'whole_day' ) . get _value ( ) ;
var button = _button ;
var that = this ;
if ( typeof content != 'undefined' && typeof content . recur _type != 'undefined' && content . recur _type != 0 )
{
if ( content . start != start _date || content . whole _day . toString ( ) != whole _day )
{
et2 _dialog . show _dialog ( function ( _button _id )
{
if ( _button _id == et2 _dialog . OK _BUTTON )
{
that . et2 . _inst . submit ( button ) ;
}
else
{
return false ;
}
} ,
this . egw . lang ( "Do you really want to change the start of this series? If you do, the original series will be terminated as of today and a new series for the future reflecting your changes will be created." ) ,
this . egw . lang ( "This event is part of a series" ) , { } , et2 _dialog . BUTTONS _OK _CANCEL , et2 _dialog . WARNING _MESSAGE ) ;
}
else
{
return true ;
}
}
else
{
return true ;
}
} ,
2013-10-31 15:51:19 +01:00
/ * *
* Create edit exception dialog for recurrence entries
*
2013-11-05 19:08:07 +01:00
* @ param { object } event
* @ param { string } id cal _id
* @ param { integer } date timestamp
2013-10-31 15:51:19 +01:00
* /
edit _series : function ( event , id , date )
{
// Coming from list, there is no event
if ( arguments . length == 2 )
{
date = id ;
id = event ;
event = null ;
}
2013-11-05 19:08:07 +01:00
var edit _id = id ;
var edit _date = date ;
2013-10-31 15:51:19 +01:00
var that = this ;
var buttons = [
{ text : this . egw . lang ( "Edit exception" ) , id : "exception" , class : "ui-priority-primary" , "default" : true } ,
{ text : this . egw . lang ( "Edit series" ) , id : "series" } ,
2013-11-05 19:08:07 +01:00
{ text : this . egw . lang ( "Cancel" ) , id : "cancel" }
2013-10-31 15:51:19 +01:00
] ;
2013-11-05 19:08:07 +01:00
et2 _dialog . show _dialog ( function ( _button _id )
2013-10-31 15:51:19 +01:00
{
2013-11-05 19:08:07 +01:00
switch ( _button _id )
2013-10-31 15:51:19 +01:00
{
case 'exception' :
2013-11-06 09:49:29 +01:00
that . egw . open ( edit _id , 'calendar' , 'edit' , '&date=' + edit _date + '&exception=1' ) ;
2013-10-31 15:51:19 +01:00
break ;
case 'series' :
2013-11-06 09:49:29 +01:00
that . egw . open ( edit _id , 'calendar' , 'edit' , '&date=' + edit _date ) ;
2013-10-31 15:51:19 +01:00
break ;
case 'cancel' :
default :
break ;
}
2013-11-05 19:08:07 +01:00
} , this . egw . lang ( "Do you want to edit this event as an exception or the whole series?" ) ,
this . egw . lang ( "This event is part of a series" ) , { } , buttons , et2 _dialog . WARNING _MESSAGE ) ;
2013-12-05 00:28:31 +01:00
} ,
2014-01-24 10:47:33 +01:00
/ * *
* Current state , get updated via set _state method
*
* @ type object
* /
state : undefined ,
/ * *
* Method to set state for JSON requests ( jdots ajax _exec or et2 submits can NOT use egw . js script tag )
*
* @ param { object } _state
* /
set _state : function ( _state )
{
if ( typeof _state == 'object' )
{
this . state = _state ;
}
} ,
2013-12-05 00:28:31 +01:00
/ * *
* Return state object defining current view
*
* Called by favorites to query current state .
*
* @ return { object } description
* /
getState : function ( )
{
2014-01-24 10:47:33 +01:00
var state = this . state ;
2013-12-06 22:26:55 +01:00
2014-01-24 10:47:33 +01:00
if ( ! state )
{
var egw _script _tag = document . getElementById ( 'egw_script_id' ) ;
state = egw _script _tag . getAttribute ( 'data-calendar-state' ) ;
state = state ? JSON . parse ( state ) : { } ;
}
2013-12-05 01:03:13 +01:00
// we are currently in list-view
if ( this . et2 && this . et2 . getWidgetById ( 'nm' ) )
{
2013-12-06 22:26:55 +01:00
jQuery . extend ( state , this . _super . apply ( this , arguments ) ) ; // call default implementation
2013-12-05 01:03:13 +01:00
}
2013-12-05 00:28:31 +01:00
2013-12-06 22:26:55 +01:00
return state ;
2013-12-05 00:28:31 +01:00
} ,
/ * *
* Set a state previously returned by getState
*
* Called by favorites to set a state saved as favorite .
*
* @ param { object } state containing "name" attribute to be used as "favorite" GET parameter to a nextmatch
* /
setState : function ( state )
{
2013-12-06 19:24:29 +01:00
// State should be an object, not a string, but we'll parse
if ( typeof state == "string" )
{
if ( state . indexOf ( '{' ) != - 1 || state == 'null' )
{
state = JSON . parse ( state ) ;
}
}
2013-12-05 00:28:31 +01:00
// old calendar state handling on server-side (incl. switching to and from listview)
var menuaction = 'calendar.calendar_uiviews.index' ;
2013-12-12 00:51:35 +01:00
if ( typeof state . state != 'undefined' && state . state . view == 'undefined' || state . state . view == 'listview' )
2013-12-05 00:28:31 +01:00
{
2014-01-24 10:47:33 +01:00
// check if we already use et2 / are in listview
2014-01-30 19:24:24 +01:00
if ( this . et2 || etemplate2 && etemplate2 . getByApplication ( 'calendar' ) )
2014-01-24 10:47:33 +01:00
{
// current calendar-code can set regular calendar states only via a server-request :(
// --> check if we only need to set something which can be handeled by nm internally
// or we need a redirect
// ToDo: pass them via nm's get_rows call to server (eg. by passing state), so we dont need a redirect
var current _state = this . getState ( ) ;
var need _redirect = false ;
for ( var attr in current _state )
{
switch ( attr )
{
case 'cat_id' :
case 'owner' :
case 'filter' :
if ( state . state [ attr ] != current _state [ attr ] )
{
need _redirect = true ;
break ;
}
break ;
}
}
if ( ! need _redirect )
{
return this . _super . apply ( this , [ state ] ) ;
}
}
2013-12-06 19:24:29 +01:00
menuaction = 'calendar.calendar_uilist.listview' ;
2013-12-12 04:42:08 +01:00
state . state . ajax = 'true' ;
2013-12-05 00:28:31 +01:00
if ( state . name )
{
2013-12-12 04:42:08 +01:00
state . state . favorite = state . name . replace ( /[^A-Za-z0-9-_]/g , '_' ) ;
2013-12-05 00:28:31 +01:00
}
}
2014-01-30 17:55:02 +01:00
// setting internal state now, that linkHandler does not intercept switching from listview to any old view
this . state = state ;
2013-12-12 00:51:35 +01:00
var query = jQuery . extend ( { menuaction : menuaction } , state . state || { } ) ;
2013-12-12 04:42:08 +01:00
2013-12-12 00:51:35 +01:00
// prepend an owner 0, to reset all owners and not just set given resource type
if ( typeof query . owner != 'undefined' )
2013-12-05 00:28:31 +01:00
{
2013-12-12 00:51:35 +01:00
query . owner = '0,' + query . owner ;
2013-12-05 00:28:31 +01:00
}
2013-12-12 00:51:35 +01:00
2013-12-12 04:42:08 +01:00
this . egw . open _link ( this . egw . link ( '/index.php' , query ) , 'calendar' ) ;
2013-12-12 00:51:35 +01:00
// Stop the normal bubbling if this is called on click
return false ;
2013-11-05 19:08:07 +01:00
}
2013-10-31 15:51:19 +01:00
} ) ;