1/* DOKUWIKI:include_once fullcalendar-2.4.0/moment.js */ 2/* DOKUWIKI:include_once fullcalendar-2.4.0/fullcalendar.js */ 3/* DOKUWIKI:include_once fullcalendar-2.4.0/lang/de.js */ 4/* DOKUWIKI:include_once fullcalendar-2.4.0/lang/en.js */ 5/* DOKUWIKI:include_once datetimepicker-2.4.5/jquery.datetimepicker.js */ 6/* DOKUWIKI:include_once jstz.js */ 7 8/** 9 * Initialize the DAVCal script, attaching some event handlers and triggering 10 * the initial load of the fullcalendar JS 11 */ 12jQuery(function() { 13 // Redefine functions for using moment.js with datetimepicker 14 15 Date.parseDate = function( input, format ){ 16 return moment(input,format).toDate(); 17 }; 18 Date.prototype.dateFormat = function( format ){ 19 return moment(this).format(format); 20 }; 21 22 // Attach to event links 23 var calendarid = jQuery('#fullCalendar').data('calendarid'); 24 dw_davcal__modals.calid = calendarid; 25 26 jQuery('div.fullCalendarSettings a').each(function() { 27 var $link = jQuery(this); 28 var href = $link.attr('href'); 29 if (!href) return; 30 31 $link.click( 32 function(e) { 33 dw_davcal__modals.showSettingsDialog(); 34 e.preventDefault(); 35 return ''; 36 } 37 ); 38 } 39 ); 40 41 // First, retrieve the current settings. 42 // Upon success, initialize fullcalendar. 43 var postArray = { }; 44 jQuery.post( 45 DOKU_BASE + 'lib/exe/ajax.php', 46 { 47 call: 'plugin_davcal', 48 id: dw_davcal__modals.calid, 49 action: 'getSettings', 50 params: postArray 51 }, 52 function(data) 53 { 54 var result = data['result']; 55 if(result === true) 56 { 57 dw_davcal__modals.settings = data['settings']; 58 var wknum = false; 59 var tz = false; 60 var we = true; 61 var detectedTz = jstz.determine().name(); 62 dw_davcal__modals.detectedTz = detectedTz; 63 if(data['settings']['weeknumbers'] == 1) 64 wknum = true; 65 if(data['settings']['timezone'] !== '') 66 tz = data['settings']['timezone']; 67 if(data['settings']['workweek'] == 1) 68 we = false; 69 // Initialize the davcal popup 70 var res = jQuery('#fullCalendar').fullCalendar({ 71 dayClick: function(date, jsEvent, view) { 72 dw_davcal__modals.showEditEventDialog(date, false); 73 }, 74 eventClick: function(calEvent, jsEvent, view) { 75 dw_davcal__modals.showEditEventDialog(calEvent, true); 76 }, 77 events: { 78 url: DOKU_BASE + 'lib/exe/ajax.php', 79 type: 'POST', 80 data: { 81 call: 'plugin_davcal', 82 action: 'getEvents', 83 id: dw_davcal__modals.calid 84 }, 85 error: function() { 86 dw_davcal__modals.msg = LANG.plugins.davcal['error_retrieving_data']; 87 dw_davcal__modals.showDialog(false); 88 } 89 }, 90 header: { 91 left: 'title', 92 center: 'today prev,next', 93 right: 'month,agendaWeek,agendaDay' 94 }, 95 lang: JSINFO.plugin.davcal['language'], 96 weekNumbers: wknum, 97 timezone: tz, 98 weekends: we, 99 }); 100 } 101 } 102 ); 103}); 104 105/** 106 * This holds all modal windows that DAVCal uses. 107 */ 108var dw_davcal__modals = { 109 $editEventDialog: null, 110 $dialog: null, 111 $settingsDialog: null, 112 msg: null, 113 completeCb: null, 114 action: null, 115 uid: null, 116 settings: null, 117 calid: null, 118 detectedTz: null, 119 120 /** 121 * Show the settings dialog 122 */ 123 showSettingsDialog : function() { 124 if(dw_davcal__modals.$settingsDialog) 125 return; 126 127 // Dialog buttons are language-dependent and defined here. 128 // Attach event handlers for save and cancel. 129 var dialogButtons = {}; 130 dialogButtons[LANG.plugins.davcal['save']] = function() { 131 var postArray = { }; 132 jQuery("input[class=dw_davcal__settings], select[class=dw_davcal__settings]").each(function() { 133 if(jQuery(this).attr('type') == 'checkbox') 134 { 135 postArray[jQuery(this).prop('name')] = jQuery(this).prop('checked') ? 1 : 0; 136 } 137 else 138 { 139 postArray[jQuery(this).prop('name')] = jQuery(this).val(); 140 } 141 }); 142 jQuery('#dw_davcal__ajaxsettings').html('<img src="'+DOKU_BASE+'lib/images/throbber.gif" alt="" width="16" height="16" />'); 143 jQuery.post( 144 DOKU_BASE + 'lib/exe/ajax.php', 145 { 146 call: 'plugin_davcal', 147 id: dw_davcal__modals.calid, 148 action: 'saveSettings', 149 params: postArray 150 }, 151 function(data) 152 { 153 var result = data['result']; 154 var html = data['html']; 155 jQuery('#dw_davcal__ajaxsettings').html(html); 156 if(result === true) 157 { 158 location.reload(); 159 } 160 } 161 ); 162 }; 163 dialogButtons[LANG.plugins.davcal['cancel']] = function () { 164 dw_davcal__modals.hideSettingsDialog(); 165 }; 166 167 dw_davcal__modals.$settingsDialog = jQuery(document.createElement('div')) 168 .dialog({ 169 autoOpen: false, 170 draggable: true, 171 title: LANG.plugins.davcal['settings'], 172 resizable: true, 173 buttons: dialogButtons, 174 }) 175 .html( 176 '<div><table>' + 177 //'<tr><td>' + LANG.plugins.davcal['use_lang_tz'] + '</td><td><input type="checkbox" name="use_lang_tz" id="dw_davcal__settings_use_lang_tz" class="dw_davcal__settings"></td></tr>' + 178 '<tr><td>' + LANG.plugins.davcal['timezone'] + '</td><td><select name="timezone" id="dw_davcal__settings_timezone" class="dw_davcal__settings"></select></td></tr>' + 179 '<tr><td>' + LANG.plugins.davcal['weeknumbers'] + '</td><td><input type="checkbox" name="weeknumbers" id="dw_davcal__settings_weeknumbers" class="dw_davcal__settings"></td></tr>' + 180 '<tr><td>' + LANG.plugins.davcal['only_workweek'] + '</td><td><input type="checkbox" name="workweek" id="dw_davcal__settings_workweek" class="dw_davcal__settings"></td></tr>' + 181 '<tr><td>' + LANG.plugins.davcal['sync_url'] + '</td><td><input type="text" name="syncurl" readonly="readonly" id="dw_davcal__settings_syncurl" class="dw_davcal__text" value="' + dw_davcal__modals.settings['syncurl'] + '"></td></tr>' + 182 '<tr><td>' + LANG.plugins.davcal['private_url'] + '</td><td><input type="text" name="privateurl" readonly="readonly" id="dw_davcal__settings_privateurl" class="dw_davcal__text" value="' + dw_davcal__modals.settings['privateurl'] + '"></td></tr>' + 183 '</table>' + 184 '</div>' + 185 '<div id="dw_davcal__ajaxsettings"></div>' 186 ) 187 .parent() 188 .attr('id','dw_davcal__settings') 189 .show() 190 .appendTo('.dokuwiki:first'); 191 192 jQuery('#dw_davcal__settings').position({ 193 my: "center", 194 at: "center", 195 of: window 196 }); 197 198 // Initialize current settings 199 jQuery('#dw_davcal__settings_syncurl').on('click', function() { 200 jQuery(this).select(); 201 }); 202 203 jQuery('#dw_davcal__settings_privateurl').on('click', function() { 204 jQuery(this).select(); 205 }); 206 207 var $tzdropdown = jQuery('#dw_davcal__settings_timezone'); 208 jQuery('#fullCalendarTimezoneList option').each(function() { 209 jQuery('<option />', {value: jQuery(this).val(), 210 text: jQuery(this).text()}).appendTo($tzdropdown); 211 }); 212 213 if(dw_davcal__modals.settings) 214 { 215 if(dw_davcal__modals.settings['timezone'] !== '') 216 jQuery('#dw_davcal__settings_timezone').val(dw_davcal__modals.settings['timezone']); 217 if(dw_davcal__modals.settings['weeknumbers'] == 1) 218 jQuery('#dw_davcal__settings_weeknumbers').prop('checked', true); 219 else 220 jQuery('#dw_davcal__settings_weeknumbers').prop('checked', false); 221 222 if(dw_davcal__modals.settings['workweek'] == 1) 223 jQuery('#dw_davcal__settings_workweek').prop('checked', true); 224 else 225 jQuery('#dw_davcal__settings_workweek').prop('checked', false); 226 } 227 228 // attach event handlers 229 jQuery('#dw_davcal__settings .ui-dialog-titlebar-close').click(function(){ 230 dw_davcal__modals.hideSettingsDialog(); 231 }); 232 }, 233 234 /** 235 * Sanity-check our events. 236 * 237 * @return boolean false on failure, otherwise true 238 */ 239 checkEvents : function() { 240 // Retrieve dates 241 var allDay = jQuery('#dw_davcal__allday_edit').prop('checked'); 242 var startDate = moment(jQuery('#dw_davcal__eventfrom_edit').val(), 'YYYY-MM-DD'); 243 var endDate = moment(jQuery('#dw_davcal__eventto_edit').val(), 'YYYY-MM-DD'); 244 245 // Do the checking 246 if(!allDay) 247 { 248 var startTime = moment.duration(jQuery('#dw_davcal__eventfromtime_edit').val()); 249 var endTime = moment.duration(jQuery('#dw_davcal__eventtotime_edit').val()); 250 startDate.add(startTime); 251 endDate.add(endTime); 252 } 253 if(!startDate.isValid()) 254 { 255 dw_davcal__modals.msg = LANG.plugins.davcal['start_date_invalid']; 256 dw_davcal__modals.showDialog(false); 257 return false; 258 } 259 if(!endDate.isValid()) 260 { 261 dw_davcal__modals.msg = LANG.plugins.davcal['end_date_invalid']; 262 dw_davcal__modals.showDialog(false); 263 return false; 264 } 265 if(endDate.isBefore(startDate)) 266 { 267 dw_davcal__modals.msg = LANG.plugins.davcal['end_date_before_start_date']; 268 dw_davcal__modals.showDialog(false); 269 return false; 270 } 271 if(!allDay && endDate.isSame(startDate)) 272 { 273 dw_davcal__modals.msg = LANG.plugins.davcal['end_date_is_same_as_start_date']; 274 dw_davcal__modals.showDialog(false); 275 return false; 276 } 277 return true; 278 }, 279 280 /** 281 * Show the edit event dialog, which is also used to create new events 282 * @param {Object} event The event to create, that is the date or the calEvent 283 * @param {Object} edit Whether we edit (true) or create a new event (false) 284 */ 285 showEditEventDialog : function(event, edit) { 286 if(dw_davcal__modals.$editEventDialog) 287 return; 288 289 var title = ''; 290 var dialogButtons = {}; 291 var calEvent = []; 292 // Buttons are dependent on edit or create 293 if(edit) 294 { 295 calEvent = event; 296 title = LANG.plugins.davcal['edit_event']; 297 dialogButtons[LANG.plugins.davcal['edit']] = function() { 298 if(!dw_davcal__modals.checkEvents()) 299 return; 300 var postArray = { }; 301 jQuery("input.dw_davcal__editevent, textarea.dw_davcal__editevent").each(function() { 302 if(jQuery(this).attr('type') == 'checkbox') 303 { 304 postArray[jQuery(this).prop('name')] = jQuery(this).prop('checked') ? 1 : 0; 305 } 306 else 307 { 308 postArray[jQuery(this).prop('name')] = jQuery(this).val(); 309 } 310 }); 311 jQuery('#dw_davcal__ajaxedit').html('<img src="'+DOKU_BASE+'lib/images/throbber.gif" alt="" width="16" height="16" />'); 312 jQuery.post( 313 DOKU_BASE + 'lib/exe/ajax.php', 314 { 315 call: 'plugin_davcal', 316 id: dw_davcal__modals.calid, 317 action: 'editEvent', 318 params: postArray 319 }, 320 function(data) 321 { 322 var result = data['result']; 323 var html = data['html']; 324 jQuery('#dw_davcal__ajaxedit').html(html); 325 if(result === true) 326 { 327 jQuery('#fullCalendar').fullCalendar('refetchEvents'); 328 dw_davcal__modals.hideEditEventDialog(); 329 } 330 } 331 ); 332 }; 333 dialogButtons[LANG.plugins.davcal['delete']] = function() { 334 dw_davcal__modals.action = 'deleteEvent'; 335 dw_davcal__modals.msg = LANG.plugins.davcal['really_delete_this_event']; 336 dw_davcal__modals.completeCb = function(data) { 337 if(data.result == false) 338 { 339 dw_davcal__modals.msg = data.errmsg; 340 dw_davcal__modals.showDialog(false); 341 } 342 else 343 { 344 jQuery('#fullCalendar').fullCalendar('refetchEvents'); 345 dw_davcal__modals.hideEditEventDialog(); 346 } 347 }; 348 dw_davcal__modals.showDialog(true); 349 }; 350 } 351 else 352 { 353 calEvent.start = event; 354 calEvent.end = moment(event); 355 calEvent.start.hour(12); 356 calEvent.start.minute(0); 357 calEvent.end.hour(13); 358 calEvent.end.minute(0); 359 calEvent.allDay = false; 360 calEvent.title = ''; 361 calEvent.description = ''; 362 calEvent.id = '0'; 363 title = LANG.plugins.davcal['create_new_event']; 364 dialogButtons[LANG.plugins.davcal['create']] = function() { 365 if(!dw_davcal__modals.checkEvents()) 366 return; 367 368 var postArray = { }; 369 jQuery("input.dw_davcal__editevent, textarea.dw_davcal__editevent").each(function() { 370 if(jQuery(this).attr('type') == 'checkbox') 371 { 372 postArray[jQuery(this).prop('name')] = jQuery(this).prop('checked') ? 1 : 0; 373 } 374 else 375 { 376 postArray[jQuery(this).prop('name')] = jQuery(this).val(); 377 } 378 }); 379 jQuery('#dw_davcal__ajaxedit').html('<img src="'+DOKU_BASE+'lib/images/throbber.gif" alt="" width="16" height="16" />'); 380 jQuery.post( 381 DOKU_BASE + 'lib/exe/ajax.php', 382 { 383 call: 'plugin_davcal', 384 id: dw_davcal__modals.calid, 385 action: 'newEvent', 386 params: postArray 387 }, 388 function(data) 389 { 390 var result = data['result']; 391 var html = data['html']; 392 jQuery('#dw_davcal__ajaxedit').html(html); 393 if(result === true) 394 { 395 jQuery('#fullCalendar').fullCalendar('refetchEvents'); 396 dw_davcal__modals.hideEditEventDialog(); 397 } 398 } 399 ); 400 }; 401 } 402 dialogButtons[LANG.plugins.davcal['cancel']] = function() { 403 dw_davcal__modals.hideEditEventDialog(); 404 }; 405 dw_davcal__modals.uid = calEvent.id; 406 dw_davcal__modals.$editEventDialog = jQuery(document.createElement('div')) 407 .dialog({ 408 autoOpen: false, 409 draggable: true, 410 title: title, 411 resizable: true, 412 buttons: dialogButtons, 413 }) 414 .html( 415 '<div><table><tr><td>' + LANG.plugins.davcal['title'] + '</td><td><input type="text" id="dw_davcal__eventname_edit" name="eventname" class="dw_davcal__editevent"></td></tr>' + 416 '<tr><td>' + LANG.plugins.davcal['description'] + '</td><td><textarea name="eventdescription" id="dw_davcal__eventdescription_edit" class="dw_davcal__editevent dw_davcal__text"></textarea></td></tr>' + 417 '<tr><td>' + LANG.plugins.davcal['from'] + '</td><td><input type="text" name="eventfrom" id="dw_davcal__eventfrom_edit" class="dw_davcal__editevent dw_davcal__date"><input type="text" name="eventfromtime" id="dw_davcal__eventfromtime_edit" class="dw_davcal__editevent dw_davcal__time"></td></tr>' + 418 '<tr><td>' + LANG.plugins.davcal['to'] + '</td><td><input type="text" name="eventto" id="dw_davcal__eventto_edit" class="dw_davcal__editevent dw_davcal__date"><input type="text" name="eventtotime" id="dw_davcal__eventtotime_edit" class="dw_davcal__editevent dw_davcal__time"></td></tr>' + 419 '<tr><td colspan="2"><input type="checkbox" name="allday" id="dw_davcal__allday_edit" class="dw_davcal__editevent">' + LANG.plugins.davcal['allday'] + '</td></tr>' + 420 '</table>' + 421 '<input type="hidden" name="uid" id="dw_davcal__uid_edit" class="dw_davcal__editevent">' + 422 '<input type="hidden" name="detectedtz" id="dw_davcal__tz_edit" class="dw_davcal__editevent">' + 423 '</div>' + 424 '<div id="dw_davcal__ajaxedit"></div>' 425 ) 426 .parent() 427 .attr('id','dw_davcal__edit') 428 .show() 429 .appendTo('.dokuwiki:first'); 430 431 jQuery('#dw_davcal__edit').position({ 432 my: "center", 433 at: "center", 434 of: window 435 }); 436 // Set up existing/predefined values 437 jQuery('#dw_davcal__tz_edit').val(dw_davcal__modals.detectedTz); 438 jQuery('#dw_davcal__uid_edit').val(calEvent.id); 439 jQuery('#dw_davcal__eventname_edit').val(calEvent.title); 440 jQuery('#dw_davcal__eventfrom_edit').val(calEvent.start.format('YYYY-MM-DD')); 441 jQuery('#dw_davcal__eventfromtime_edit').val(calEvent.start.format('HH:mm')); 442 jQuery('#dw_davcal__eventdescription_edit').val(calEvent.description); 443 if(calEvent.allDay && (calEvent.end === null)) 444 { 445 jQuery('#dw_davcal__eventto_edit').val(calEvent.start.format('YYYY-MM-DD')); 446 jQuery('#dw_davcal__eventtotime_edit').val(calEvent.start.format('HH:mm')); 447 } 448 else if(calEvent.allDay) 449 { 450 endEvent = moment(calEvent.end); 451 endEvent.subtract(1, 'days'); 452 jQuery('#dw_davcal__eventto_edit').val(endEvent.format('YYYY-MM-DD')); 453 jQuery('#dw_davcal__eventotime_edit').val(endEvent.format('HH:mm')); 454 } 455 else 456 { 457 jQuery('#dw_davcal__eventto_edit').val(calEvent.end.format('YYYY-MM-DD')); 458 jQuery('#dw_davcal__eventtotime_edit').val(calEvent.end.format('HH:mm')); 459 } 460 jQuery('#dw_davcal__allday_edit').prop('checked', calEvent.allDay); 461 462 // attach event handlers 463 jQuery('#dw_davcal__edit .ui-dialog-titlebar-close').click(function(){ 464 dw_davcal__modals.hideEditEventDialog(); 465 }); 466 jQuery('#dw_davcal__eventfrom_edit').datetimepicker({format:'YYYY-MM-DD', 467 formatDate:'YYYY-MM-DD', 468 datepicker: true, 469 timepicker: false, 470 }); 471 jQuery('#dw_davcal__eventfromtime_edit').datetimepicker({format:'HH:mm', 472 formatTime:'HH:mm', 473 datepicker: false, 474 timepicker: true, 475 step: 15}); 476 jQuery('#dw_davcal__eventto_edit').datetimepicker({format:'YYYY-MM-DD', 477 formatDate:'YYYY-MM-DD', 478 datepicker: true, 479 timepicker: false, 480 }); 481 jQuery('#dw_davcal__eventtotime_edit').datetimepicker({format:'HH:mm', 482 formatTime:'HH:mm', 483 datepicker: false, 484 timepicker: true, 485 step:15}); 486 jQuery('#dw_davcal__allday_edit').change(function() { 487 if(jQuery(this).is(":checked")) 488 { 489 jQuery('#dw_davcal__eventfromtime_edit').prop('readonly', true); 490 jQuery('#dw_davcal__eventtotime_edit').prop('readonly', true); 491 } 492 else 493 { 494 jQuery('#dw_davcal__eventfromtime_edit').prop('readonly', false); 495 jQuery('#dw_davcal__eventtotime_edit').prop('readonly', false); 496 } 497 }); 498 jQuery('#dw_davcal__allday_edit').change(); 499 }, 500 501 /** 502 * Show an info/confirmation dialog 503 * @param {Object} confirm Whether a confirmation dialog (true) or an info dialog (false) is requested 504 */ 505 showDialog : function(confirm) 506 { 507 if(dw_davcal__modals.$confirmDialog) 508 return; 509 var dialogButtons = {}; 510 var title = ''; 511 if(confirm) 512 { 513 title = LANG.plugins.davcal['confirmation']; 514 dialogButtons[LANG.plugins.davcal['yes']] = function() { 515 jQuery.post( 516 DOKU_BASE + 'lib/exe/ajax.php', 517 { 518 call: 'plugin_davcal', 519 id: dw_davcal__modals.calid, 520 action: dw_davcal__modals.action, 521 params: { 522 uid: dw_davcal__modals.uid 523 } 524 }, 525 function(data) 526 { 527 dw_davcal__modals.completeCb(data); 528 } 529 ); 530 dw_davcal__modals.hideDialog(); 531 }; 532 dialogButtons[LANG.plugins.tagrevisions['cancel']] = function() { 533 dw_davcal__modals.hideDialog(); 534 }; 535 } 536 else 537 { 538 title = LANG.plugins.davcal['info']; 539 dialogButtons[LANG.plugins.davcal['ok']] = function() { 540 dw_davcal__modals.hideDialog(); 541 }; 542 } 543 dw_davcal__modals.$dialog = jQuery(document.createElement('div')) 544 .dialog({ 545 autoOpen: false, 546 draggable: true, 547 title: title, 548 resizable: true, 549 buttons: dialogButtons, 550 }) 551 .html( 552 '<div>' + dw_davcal__modals.msg + '</div>' 553 ) 554 .parent() 555 .attr('id','dw_davcal__confirm') 556 .show() 557 .appendTo('.dokuwiki:first'); 558 559 jQuery('#dw_davcal__confirm').position({ 560 my: "center", 561 at: "center", 562 of: window 563 }); 564 // attach event handlers 565 jQuery('#dw_davcal__confirm .ui-dialog-titlebar-close').click(function(){ 566 dw_davcal__modals.hideDialog(); 567 }); 568 }, 569 570 /** 571 * Hide the edit event dialog 572 */ 573 hideEditEventDialog : function() { 574 dw_davcal__modals.$editEventDialog.empty(); 575 dw_davcal__modals.$editEventDialog.remove(); 576 dw_davcal__modals.$editEventDialog = null; 577 }, 578 579 /** 580 * Hide the confirm/info dialog 581 */ 582 hideDialog: function() { 583 dw_davcal__modals.$dialog.empty(); 584 dw_davcal__modals.$dialog.remove(); 585 dw_davcal__modals.$dialog = null; 586 }, 587 588 /** 589 * Hide the settings dialog 590 */ 591 hideSettingsDialog: function() { 592 dw_davcal__modals.$settingsDialog.empty(); 593 dw_davcal__modals.$settingsDialog.remove(); 594 dw_davcal__modals.$settingsDialog = null; 595 } 596}; 597