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 fullcalendar-2.4.0/lang/fr.js */ 6/* DOKUWIKI:include_once fullcalendar-2.4.0/lang/nl.js */ 7/* DOKUWIKI:include_once datetimepicker-2.4.5/jquery.datetimepicker.js */ 8/* DOKUWIKI:include_once jstz.js */ 9 10/** 11 * Initialize the DAVCal script, attaching some event handlers and triggering 12 * the initial load of the fullcalendar JS 13 */ 14jQuery(function() { 15 // Redefine functions for using moment.js with datetimepicker 16 17 Date.parseDate = function( input, format ){ 18 return moment(input,format).toDate(); 19 }; 20 Date.prototype.dateFormat = function( format ){ 21 return moment(this).format(format); 22 }; 23 24 // Attach to event links 25 var calendarpage = jQuery('#fullCalendar').data('calendarpage'); 26 if(!calendarpage) return; 27 dw_davcal__modals.page = calendarpage; 28 29 jQuery('div.fullCalendarSettings a').each(function() { 30 var $link = jQuery(this); 31 var href = $link.attr('href'); 32 if (!href) return; 33 34 $link.click( 35 function(e) { 36 dw_davcal__modals.showSettingsDialog(); 37 e.preventDefault(); 38 return ''; 39 } 40 ); 41 } 42 ); 43 44 // First, retrieve the current settings. 45 // Upon success, initialize fullcalendar. 46 var postArray = { }; 47 jQuery.post( 48 DOKU_BASE + 'lib/exe/ajax.php', 49 { 50 call: 'plugin_davcal', 51 id: dw_davcal__modals.page, 52 page: dw_davcal__modals.page, 53 action: 'getSettings', 54 params: postArray, 55 sectok: JSINFO.plugin.davcal['sectok'] 56 }, 57 function(data) 58 { 59 var result = data['result']; 60 if(result === true) 61 { 62 dw_davcal__modals.settings = data['settings']; 63 var tz = false; 64 if(data['settings']['timezone'] !== '') 65 tz = data['settings']['timezone']; 66 // Force-overwrite thhe timezone setting if requested 67 if(data['settings']['meta']['forcetimezone'] !== 'no') 68 tz = data['settings']['meta']['forcetimezone']; 69 var fcOptions = { 70 dayClick: function(date, jsEvent, view) { 71 dw_davcal__modals.showEditEventDialog(date, false); 72 }, 73 eventClick: function(calEvent, jsEvent, view) { 74 dw_davcal__modals.showEditEventDialog(calEvent, true); 75 }, 76 events: { 77 url: DOKU_BASE + 'lib/exe/ajax.php', 78 type: 'POST', 79 data: { 80 call: 'plugin_davcal', 81 action: 'getEvents', 82 id: dw_davcal__modals.page, 83 page: dw_davcal__modals.page, 84 sectok: JSINFO.plugin.davcal['sectok'] 85 }, 86 error: function() { 87 dw_davcal__modals.msg = LANG.plugins.davcal['error_retrieving_data']; 88 dw_davcal__modals.showDialog(false); 89 } 90 }, 91 header: { 92 left: 'title', 93 center: 'today prev,next', 94 right: 'month,agendaWeek,agendaDay' 95 }, 96 lang: JSINFO.plugin.davcal['language'], 97 weekNumbers: (data['settings']['weeknumbers'] == 1) ? true : false, 98 timezone: tz, 99 weekends: (data['settings']['workweek'] == 1) ? false : true, 100 firstDay: (data['settings']['monday'] == 1) ? 1 : 0, 101 defaultView: data['settings']['meta']['view'] 102 }; 103 var timeformat = data['settings']['timeformat']; 104 // Force-overwrite the user's timezone setting if requested by the calendar 105 if(data['settings']['meta']['forcetimeformat'] !== 'no') 106 timeformat = data['settings']['meta']['forcetimeformat']; 107 if(timeformat !== 'lang') 108 { 109 // If the time format is language-based, we don't need to pass 110 // the timeFormat option to fullCalendar 111 if(timeformat == '24h') 112 { 113 fcOptions.timeFormat = 'H:mm'; 114 } 115 if(timeformat == '12h') 116 { 117 fcOptions.timeFormat = 'h:mmt'; 118 } 119 } 120 for (var key in data['settings']['meta']['fcoptions']) 121 { 122 if(!data['settings']['meta']['fcoptions'].hasOwnProperty(key)) continue; 123 124 var val = data['settings']['meta']['fcoptions'][key]; 125 fcOptions[key] = val; 126 } 127 var detectedTz = jstz.determine().name(); 128 dw_davcal__modals.detectedTz = detectedTz; 129 // The current TZ value holds either the uers's selection or 130 // the force timezone value 131 dw_davcal__modals.currentTz = (tz === false) ? '' : tz; 132 // Initialize the davcal popup 133 var res = jQuery('#fullCalendar').fullCalendar(fcOptions); 134 } 135 } 136 ); 137}); 138 139/** 140 * This holds all modal windows that DAVCal uses. 141 */ 142var dw_davcal__modals = { 143 $editEventDialog: null, 144 $dialog: null, 145 $settingsDialog: null, 146 $inputDialog: null, 147 msg: null, 148 completeCb: null, 149 action: null, 150 uid: null, 151 settings: null, 152 page: null, 153 detectedTz: null, 154 currentTz: null, 155 156 /** 157 * Show the settings dialog 158 */ 159 // FIXME: Hide URLs for multi-calendar 160 showSettingsDialog : function() { 161 if(dw_davcal__modals.$settingsDialog) 162 return; 163 164 // Dialog buttons are language-dependent and defined here. 165 // Attach event handlers for save and cancel. 166 var dialogButtons = {}; 167 if(!JSINFO.plugin.davcal['disable_settings']) 168 { 169 dialogButtons[LANG.plugins.davcal['save']] = function() { 170 var postArray = { }; 171 jQuery("input[class=dw_davcal__settings], select[class=dw_davcal__settings]").each(function() { 172 if(jQuery(this).attr('type') == 'checkbox') 173 { 174 postArray[jQuery(this).prop('name')] = jQuery(this).prop('checked') ? 1 : 0; 175 } 176 else 177 { 178 postArray[jQuery(this).prop('name')] = jQuery(this).val(); 179 } 180 }); 181 jQuery('#dw_davcal__ajaxsettings').html('<img src="'+DOKU_BASE+'lib/images/throbber.gif" alt="" width="16" height="16" />'); 182 jQuery.post( 183 DOKU_BASE + 'lib/exe/ajax.php', 184 { 185 call: 'plugin_davcal', 186 id: dw_davcal__modals.page, 187 page: dw_davcal__modals.page, 188 action: 'saveSettings', 189 params: postArray, 190 sectok: JSINFO.plugin.davcal['sectok'] 191 }, 192 function(data) 193 { 194 var result = data['result']; 195 var html = data['html']; 196 jQuery('#dw_davcal__ajaxsettings').html(html); 197 if(result === true) 198 { 199 location.reload(); 200 } 201 } 202 ); 203 }; 204 } 205 dialogButtons[LANG.plugins.davcal['cancel']] = function () { 206 dw_davcal__modals.hideSettingsDialog(); 207 }; 208 209 var settingsHtml = '<div><table>'; 210 211 if(JSINFO.plugin.davcal['disable_settings'] && JSINFO.plugin.davcal['disable_sync'] && JSINFO.plugin.davcal['disable_ics']) 212 { 213 settingsHtml += LANG.plugins.davcal['nothing_to_show']; 214 } 215 216 if(!JSINFO.plugin.davcal['disable_settings']) 217 { 218 settingsHtml += '<tr><td>' + LANG.plugins.davcal['timezone'] + '</td><td><select name="timezone" id="dw_davcal__settings_timezone" class="dw_davcal__settings"></select></td></tr>' + 219 '<tr><td>' + LANG.plugins.davcal['timeformat'] + '</td><td><select name="timeformat" id="dw_davcal__settings_timeformat" class="dw_davcal__settings"></select></td></tr>' + 220 '<tr><td>' + LANG.plugins.davcal['weeknumbers'] + '</td><td><input type="checkbox" name="weeknumbers" id="dw_davcal__settings_weeknumbers" class="dw_davcal__settings"></td></tr>' + 221 '<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>' + 222 '<tr><td>' + LANG.plugins.davcal['start_monday'] + '</td><td><input type="checkbox" name="monday" id="dw_davcal__settings_monday" class="dw_davcal__settings"></td></tr>'; 223 } 224 225 if(!JSINFO.plugin.davcal['disable_sync']) 226 { 227 settingsHtml += '<tr id="dw_davcal__settings_syncurl"><td>' + LANG.plugins.davcal['sync_url'] + '</td><td><input type="text" name="syncurl" readonly="readonly" id="dw_davcal__settings_syncurl_edit" class="dw_davcal__text" value="' + dw_davcal__modals.settings['syncurl'] + '"></td></tr>'; 228 settingsHtml += '<tr id="dw_davcal__settings_principalurl"><td>' + LANG.plugins.davcal['sync_ical'] + '</td><td><input type="text" name="principalurl" readonly="readonly" id="dw_davcal__settings_principalurl_edit" class="dw_davcal__text" value="' + dw_davcal__modals.settings['principalurl'] + '"></td></tr>'; 229 } 230 231 if(!JSINFO.plugin.davcal['disable_ics']) 232 { 233 settingsHtml += '<tr id="dw_davcal__settings_privateurl"><td>' + LANG.plugins.davcal['private_url'] + '</td><td><input type="text" name="privateurl" readonly="readonly" id="dw_davcal__settings_privateurl_edit" class="dw_davcal__text" value="' + dw_davcal__modals.settings['privateurl'] + '"></td></tr>'; 234 } 235 236 settingsHtml += '</table>' + 237 '</div>' + 238 '<div id="dw_davcal__ajaxsettings"></div>'; 239 240 dw_davcal__modals.$settingsDialog = jQuery(document.createElement('div')) 241 .dialog({ 242 autoOpen: false, 243 draggable: true, 244 // fix for dragging: http://stackoverflow.com/questions/17247486/jquery-ui-dialog-dragging-issues 245 drag: function(event, ui) { 246 var fixPix = jQuery(document).scrollTop(); 247 iObj = ui.position; 248 iObj.top = iObj.top - fixPix; 249 jQuery(this).closest(".ui-dialog").css("top", iObj.top + "px"); 250 }, 251 title: LANG.plugins.davcal['settings'], 252 resizable: true, 253 buttons: dialogButtons, 254 }) 255 .html( 256 settingsHtml 257 ) 258 .parent() 259 .attr('id','dw_davcal__settings') 260 .show() 261 .appendTo('.dokuwiki:first'); 262 263 jQuery('#dw_davcal__settings').position({ 264 my: "center", 265 at: "center", 266 of: window 267 }); 268 269 // Initialize current settings 270 271 if(!JSINFO.plugin.davcal['disable_settings']) 272 { 273 var $tzdropdown = jQuery('#dw_davcal__settings_timezone'); 274 jQuery('#fullCalendarTimezoneList option').each(function() { 275 jQuery('<option />', {value: jQuery(this).val(), 276 text: jQuery(this).text()}).appendTo($tzdropdown); 277 }); 278 279 var $tfdropdown = jQuery('#dw_davcal__settings_timeformat'); 280 jQuery('<option />', {value: 'lang', text: LANG.plugins.davcal['language_specific']}).appendTo($tfdropdown); 281 jQuery('<option />', {value: '24h', text: '24h'}).appendTo($tfdropdown); 282 jQuery('<option />', {value: '12h', text: '12h'}).appendTo($tfdropdown); 283 284 if(!JSINFO.plugin.davcal['disable_sync']) 285 { 286 jQuery('#dw_davcal__settings_syncurl_edit').on('click', function() { 287 jQuery(this).select(); 288 }); 289 jQuery('#dw_davcal__settings_principalurl_edit').on('click', function() { 290 jQuery(this).select(); 291 }); 292 } 293 294 if(!JSINFO.plugin.davcal['disable_ics']) 295 { 296 jQuery('#dw_davcal__settings_privateurl_edit').on('click', function() { 297 jQuery(this).select(); 298 }); 299 } 300 301 if(dw_davcal__modals.settings) 302 { 303 if(dw_davcal__modals.settings['timeformat'] !== '') 304 jQuery('#dw_davcal__settings_timeformat').val(dw_davcal__modals.settings['timeformat']); 305 if(dw_davcal__modals.settings['timezone'] !== '') 306 jQuery('#dw_davcal__settings_timezone').val(dw_davcal__modals.settings['timezone']); 307 if(dw_davcal__modals.settings['weeknumbers'] == 1) 308 jQuery('#dw_davcal__settings_weeknumbers').prop('checked', true); 309 else 310 jQuery('#dw_davcal__settings_weeknumbers').prop('checked', false); 311 312 if(dw_davcal__modals.settings['workweek'] == 1) 313 jQuery('#dw_davcal__settings_workweek').prop('checked', true); 314 else 315 jQuery('#dw_davcal__settings_workweek').prop('checked', false); 316 317 if(dw_davcal__modals.settings['monday'] == 1) 318 jQuery('#dw_davcal__settings_monday').prop('checked', true); 319 else 320 jQuery('#dw_davcal__settings_monday').prop('checked', false); 321 if(dw_davcal__modals.settings['meta']['forcetimezone'] !== 'no') 322 jQuery('#dw_davcal__settings_timezone').prop('disabled', true); 323 if(dw_davcal__modals.settings['meta']['forcetimeformat'] !== 'no') 324 jQuery('#dw_davcal__settings_timeformat').prop('disabled', true); 325 } 326 } 327 328 // attach event handlers 329 jQuery('#dw_davcal__settings .ui-dialog-titlebar-close').click(function(){ 330 dw_davcal__modals.hideSettingsDialog(); 331 }); 332 }, 333 334 /** 335 * Sanity-check our events. 336 * 337 * @return boolean false on failure, otherwise true 338 */ 339 checkEvents : function() { 340 // Retrieve dates 341 var allDay = jQuery('#dw_davcal__allday_edit').prop('checked'); 342 var startDate = moment(jQuery('#dw_davcal__eventfrom_edit').val(), 'YYYY-MM-DD'); 343 var endDate = moment(jQuery('#dw_davcal__eventto_edit').val(), 'YYYY-MM-DD'); 344 345 // Do the checking 346 if(!allDay) 347 { 348 var startTime = moment.duration(jQuery('#dw_davcal__eventfromtime_edit').val()); 349 var endTime = moment.duration(jQuery('#dw_davcal__eventtotime_edit').val()); 350 startDate.add(startTime); 351 endDate.add(endTime); 352 } 353 if(!startDate.isValid()) 354 { 355 dw_davcal__modals.msg = LANG.plugins.davcal['start_date_invalid']; 356 dw_davcal__modals.showDialog(false); 357 return false; 358 } 359 if(!endDate.isValid()) 360 { 361 dw_davcal__modals.msg = LANG.plugins.davcal['end_date_invalid']; 362 dw_davcal__modals.showDialog(false); 363 return false; 364 } 365 if(endDate.isBefore(startDate)) 366 { 367 dw_davcal__modals.msg = LANG.plugins.davcal['end_date_before_start_date']; 368 dw_davcal__modals.showDialog(false); 369 return false; 370 } 371 if(!allDay && endDate.isSame(startDate)) 372 { 373 dw_davcal__modals.msg = LANG.plugins.davcal['end_date_is_same_as_start_date']; 374 dw_davcal__modals.showDialog(false); 375 return false; 376 } 377 return true; 378 }, 379 380 /** 381 * Show the edit event dialog, which is also used to create new events 382 * @param {Object} event The event to create, that is the date or the calEvent 383 * @param {Object} edit Whether we edit (true) or create a new event (false) 384 */ 385 showEditEventDialog : function(event, edit) { 386 if(dw_davcal__modals.$editEventDialog) 387 return; 388 389 var readonly = true; 390 for(var i=0; i<dw_davcal__modals.settings['calids'].length; i++) 391 { 392 if(edit) 393 { 394 // Use the specific calendar setting if we edit an event 395 if(event.page == dw_davcal__modals.settings['calids'][i]['page']) 396 readonly = !dw_davcal__modals.settings['calids'][i]['write']; 397 } 398 else 399 { 400 // If there is at least one writable calendar, 401 // we set readonly to false 402 if(dw_davcal__modals.settings['calids'][i]['write']) 403 readonly = false; 404 } 405 } 406 407 var title = ''; 408 var dialogButtons = {}; 409 var calEvent = []; 410 var recurringWarning = ''; 411 // Buttons are dependent on edit or create 412 // Several possibilities: 413 // 414 // 1) Somebody tries to edit, it is not recurring and not readonly -> show 415 // 2) Somebody tries to edit, it is recurring and not readonly -> message 416 // 3) Somebody tries to edit, it is readonly -> message 417 // 4) Somebody tries to create and it is readonly -> message 418 // 5) Somebody tries to create -> show 419 if(edit && (event.recurring != true) && (readonly === false)) 420 { 421 calEvent = event; 422 title = LANG.plugins.davcal['edit_event']; 423 dialogButtons[LANG.plugins.davcal['edit']] = function() { 424 if(!dw_davcal__modals.checkEvents()) 425 return; 426 var postArray = { }; 427 var attachArr = new Array(); 428 var pageid = calEvent.page; 429 430 jQuery('.dw_davcal__editevent_attachment_link').each(function() { 431 var attachment = jQuery(this).attr('href'); 432 if(attachment != undefined) 433 { 434 attachArr.push(attachment); 435 } 436 }); 437 postArray['attachments'] = attachArr; 438 jQuery("input.dw_davcal__editevent, textarea.dw_davcal__editevent").each(function() { 439 if(jQuery(this).attr('type') == 'checkbox') 440 { 441 postArray[jQuery(this).prop('name')] = jQuery(this).prop('checked') ? 1 : 0; 442 } 443 else 444 { 445 postArray[jQuery(this).prop('name')] = jQuery(this).val(); 446 } 447 }); 448 jQuery('#dw_davcal__ajaxedit').html('<img src="'+DOKU_BASE+'lib/images/throbber.gif" alt="" width="16" height="16" />'); 449 jQuery.post( 450 DOKU_BASE + 'lib/exe/ajax.php', 451 { 452 call: 'plugin_davcal', 453 id: pageid, 454 page: dw_davcal__modals.page, 455 action: 'editEvent', 456 params: postArray, 457 sectok: JSINFO.plugin.davcal['sectok'] 458 }, 459 function(data) 460 { 461 var result = data['result']; 462 var html = data['html']; 463 jQuery('#dw_davcal__ajaxedit').html(html); 464 if(result === true) 465 { 466 jQuery('#fullCalendar').fullCalendar('refetchEvents'); 467 dw_davcal__modals.hideEditEventDialog(); 468 } 469 } 470 ); 471 }; 472 dialogButtons[LANG.plugins.davcal['delete']] = function() { 473 dw_davcal__modals.action = 'deleteEvent'; 474 dw_davcal__modals.msg = LANG.plugins.davcal['really_delete_this_event']; 475 dw_davcal__modals.completeCb = function(data) { 476 var result = data['result']; 477 var html = data['html']; 478 jQuery('#dw_davcal__ajaxedit').html(html); 479 if(result === true) 480 { 481 jQuery('#fullCalendar').fullCalendar('refetchEvents'); 482 dw_davcal__modals.hideEditEventDialog(); 483 } 484 }; 485 dw_davcal__modals.showDialog(true); 486 }; 487 } 488 else if(edit && (event.recurring == true) && (readonly === false)) 489 { 490 calEvent = event; 491 title = LANG.plugins.davcal['edit_event']; 492 recurringWarning = LANG.plugins.davcal['recurring_cant_edit']; 493 } 494 else if(edit && (readonly === true)) 495 { 496 calEvent = event; 497 title = LANG.plugins.davcal['edit_event']; 498 recurringWarning = LANG.plugins.davcal['no_permission']; 499 } 500 else if(readonly === true) 501 { 502 calEvent.start = event; 503 calEvent.end = moment(event); 504 calEvent.start.hour(12); 505 calEvent.start.minute(0); 506 calEvent.end.hour(13); 507 calEvent.end.minute(0); 508 calEvent.allDay = false; 509 calEvent.recurring = false; 510 calEvent.title = ''; 511 calEvent.description = ''; 512 calEvent.id = '0'; 513 calEvent.page = dw_davcal__modals.page; 514 title = LANG.plugins.davcal['create_new_event']; 515 recurringWarning = LANG.plugins.davcal['no_permission']; 516 } 517 else 518 { 519 calEvent.start = event; 520 calEvent.end = moment(event); 521 calEvent.start.hour(12); 522 calEvent.start.minute(0); 523 calEvent.end.hour(13); 524 calEvent.end.minute(0); 525 calEvent.allDay = false; 526 calEvent.recurring = false; 527 calEvent.title = ''; 528 calEvent.description = ''; 529 calEvent.id = '0'; 530 calEvent.page = dw_davcal__modals.settings['calids'][0]['page']; 531 title = LANG.plugins.davcal['create_new_event']; 532 dialogButtons[LANG.plugins.davcal['create']] = function() { 533 if(!dw_davcal__modals.checkEvents()) 534 return; 535 536 var postArray = { }; 537 var attachArr = new Array(); 538 var pageid = jQuery("#dw_davcal__editevent_calendar option:selected").val(); 539 jQuery("input.dw_davcal__editevent, textarea.dw_davcal__editevent").each(function() { 540 if(jQuery(this).attr('type') == 'checkbox') 541 { 542 postArray[jQuery(this).prop('name')] = jQuery(this).prop('checked') ? 1 : 0; 543 } 544 else 545 { 546 postArray[jQuery(this).prop('name')] = jQuery(this).val(); 547 } 548 }); 549 jQuery('.dw_davcal__editevent_attachment_link').each(function() { 550 var attachment = jQuery(this).attr('href'); 551 if(attachment != undefined) 552 { 553 attachArr.push(attachment); 554 } 555 }); 556 postArray['attachments'] = attachArr; 557 jQuery('#dw_davcal__ajaxedit').html('<img src="'+DOKU_BASE+'lib/images/throbber.gif" alt="" width="16" height="16" />'); 558 jQuery.post( 559 DOKU_BASE + 'lib/exe/ajax.php', 560 { 561 call: 'plugin_davcal', 562 id: pageid, 563 page: dw_davcal__modals.page, 564 action: 'newEvent', 565 params: postArray, 566 sectok: JSINFO.plugin.davcal['sectok'] 567 }, 568 function(data) 569 { 570 var result = data['result']; 571 var html = data['html']; 572 jQuery('#dw_davcal__ajaxedit').html(html); 573 if(result === true) 574 { 575 jQuery('#fullCalendar').fullCalendar('refetchEvents'); 576 dw_davcal__modals.hideEditEventDialog(); 577 } 578 } 579 ); 580 }; 581 } 582 dialogButtons[LANG.plugins.davcal['cancel']] = function() { 583 dw_davcal__modals.hideEditEventDialog(); 584 }; 585 dw_davcal__modals.uid = calEvent.id; 586 dw_davcal__modals.$editEventDialog = jQuery(document.createElement('div')) 587 .dialog({ 588 autoOpen: false, 589 draggable: true, 590 // fix for dragging: http://stackoverflow.com/questions/17247486/jquery-ui-dialog-dragging-issues 591 drag: function(event, ui) { 592 var fixPix = jQuery(document).scrollTop(); 593 iObj = ui.position; 594 iObj.top = iObj.top - fixPix; 595 jQuery(this).closest(".ui-dialog").css("top", iObj.top + "px"); 596 }, 597 title: title, 598 resizable: true, 599 buttons: dialogButtons, 600 }) 601 .html( 602 '<div><table>' + 603 '<tr><td>' + LANG.plugins.davcal['calendar'] + '</td><td><select id="dw_davcal__editevent_calendar"></select></td></tr>' + 604 '<tr><td>' + LANG.plugins.davcal['title'] + '</td><td><input type="text" id="dw_davcal__eventname_edit" name="eventname" class="dw_davcal__editevent"></td></tr>' + 605 '<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>' + 606 '<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>' + 607 '<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>' + 608 '<tr><td colspan="2"><input type="checkbox" name="allday" id="dw_davcal__allday_edit" class="dw_davcal__editevent">' + LANG.plugins.davcal['allday'] + '</td></tr>' + 609 '<tr><td>' + LANG.plugins.davcal['attachments'] + '</td><td><table id="dw_davcal__editevent_attachments"><tbody><tr><td><input type="text" id="dw_davcal__editevent_attachment" value="http://"></td><td><a href="#" id="dw_davcal__editevent_attach">' + LANG.plugins.davcal['add_attachment'] + '</a></td></tr></tbody></table></td></tr>' + 610 '</table>' + 611 recurringWarning + 612 '<input type="hidden" name="uid" id="dw_davcal__uid_edit" class="dw_davcal__editevent">' + 613 '<input type="hidden" name="detectedtz" id="dw_davcal__tz_edit" class="dw_davcal__editevent">' + 614 '<input type="hidden" name="currenttz" id="dw_davcal__currenttz_edit" class="dw_davcal__editevent">' + 615 '</div>' + 616 '<div id="dw_davcal__ajaxedit"></div>' 617 ) 618 .parent() 619 .attr('id','dw_davcal__edit') 620 .show() 621 .appendTo('.dokuwiki:first'); 622 623 jQuery('#dw_davcal__edit').position({ 624 my: "center", 625 at: "center", 626 of: window 627 }); 628 629 // Populate calendar dropdown 630 var $dropdown = jQuery("#dw_davcal__editevent_calendar"); 631 for(var i=0; i<dw_davcal__modals.settings['calids'].length; i++) 632 { 633 var sel = ''; 634 // When creating an event, do not show read-only calendars 635 if(!edit && (dw_davcal__modals.settings['calids'][i]['write'] === false)) 636 continue; 637 if(calEvent.page == dw_davcal__modals.settings['calids'][i]['page']) 638 sel = ' selected="selected"'; 639 $dropdown.append('<option value="' + dw_davcal__modals.settings['calids'][i]['page'] + '"' + sel + '>' + dw_davcal__modals.settings['calids'][i]['name'] + '</option>'); 640 } 641 if(edit || (dw_davcal__modals.settings['calids'].length < 1)) 642 { 643 $dropdown.prop('disabled', true); 644 } 645 646 // Set up existing/predefined values 647 jQuery('#dw_davcal__tz_edit').val(dw_davcal__modals.detectedTz); 648 jQuery('#dw_davcal__currenttz_edit').val(dw_davcal__modals.currentTz); 649 jQuery('#dw_davcal__uid_edit').val(calEvent.id); 650 jQuery('#dw_davcal__eventname_edit').val(calEvent.title); 651 jQuery('#dw_davcal__eventfrom_edit').val(calEvent.start.format('YYYY-MM-DD')); 652 jQuery('#dw_davcal__eventfromtime_edit').val(calEvent.start.format('HH:mm')); 653 jQuery('#dw_davcal__eventdescription_edit').val(calEvent.description); 654 if(calEvent.attachments && (calEvent.attachments !== null)) 655 { 656 for(var i=0; i<calEvent.attachments.length; i++) 657 { 658 var url = calEvent.attachments[i]; 659 var row = '<tr><td><a href="' + url + '" class="dw_davcal__editevent_attachment_link">' + url + '</a></td><td><a class="deleteLink" href="#">' + LANG.plugins.davcal['delete'] + '</a></td></tr>'; 660 jQuery('#dw_davcal__editevent_attachments > tbody:last').append(row); 661 662 } 663 } 664 dw_davcal__modals.attachAttachmentDeleteHandlers(); 665 jQuery('#dw_davcal__editevent_attach').on("click", function(e) 666 { 667 e.preventDefault(); 668 var url = jQuery('#dw_davcal__editevent_attachment').val(); 669 if(url == '') 670 return false; 671 jQuery('#dw_davcal__editevent_attachment').val('http://'); 672 var row = '<tr><td><a href="' + url + '" class="dw_davcal__editevent_attachment_link">' + url + '</a></td><td><a class="deleteLink" href="#">' + LANG.plugins.davcal['delete'] + '</a></td></tr>'; 673 jQuery('#dw_davcal__editevent_attachments > tbody:last').append(row); 674 dw_davcal__modals.attachAttachmentDeleteHandlers(); 675 return false; 676 }); 677 if(calEvent.allDay && (calEvent.end === null)) 678 { 679 jQuery('#dw_davcal__eventto_edit').val(calEvent.start.format('YYYY-MM-DD')); 680 jQuery('#dw_davcal__eventtotime_edit').val(calEvent.start.format('HH:mm')); 681 } 682 else if(calEvent.allDay) 683 { 684 endEvent = moment(calEvent.end); 685 endEvent.subtract(1, 'days'); 686 jQuery('#dw_davcal__eventto_edit').val(endEvent.format('YYYY-MM-DD')); 687 jQuery('#dw_davcal__eventotime_edit').val(endEvent.format('HH:mm')); 688 } 689 else 690 { 691 jQuery('#dw_davcal__eventto_edit').val(calEvent.end.format('YYYY-MM-DD')); 692 jQuery('#dw_davcal__eventtotime_edit').val(calEvent.end.format('HH:mm')); 693 } 694 jQuery('#dw_davcal__allday_edit').prop('checked', calEvent.allDay); 695 696 // attach event handlers 697 jQuery('#dw_davcal__edit .ui-dialog-titlebar-close').click(function(){ 698 dw_davcal__modals.hideEditEventDialog(); 699 }); 700 jQuery('#dw_davcal__eventfrom_edit').datetimepicker({format:'YYYY-MM-DD', 701 formatDate:'YYYY-MM-DD', 702 datepicker: true, 703 timepicker: false, 704 }); 705 jQuery('#dw_davcal__eventfromtime_edit').datetimepicker({format:'HH:mm', 706 formatTime:'HH:mm', 707 datepicker: false, 708 timepicker: true, 709 step: 15}); 710 jQuery('#dw_davcal__eventto_edit').datetimepicker({format:'YYYY-MM-DD', 711 formatDate:'YYYY-MM-DD', 712 datepicker: true, 713 timepicker: false, 714 }); 715 jQuery('#dw_davcal__eventtotime_edit').datetimepicker({format:'HH:mm', 716 formatTime:'HH:mm', 717 datepicker: false, 718 timepicker: true, 719 step:15}); 720 jQuery('#dw_davcal__allday_edit').change(function() { 721 if(jQuery(this).is(":checked")) 722 { 723 jQuery('#dw_davcal__eventfromtime_edit').prop('readonly', true); 724 jQuery('#dw_davcal__eventtotime_edit').prop('readonly', true); 725 } 726 else 727 { 728 jQuery('#dw_davcal__eventfromtime_edit').prop('readonly', false); 729 jQuery('#dw_davcal__eventtotime_edit').prop('readonly', false); 730 } 731 }); 732 jQuery('#dw_davcal__allday_edit').change(); 733 }, 734 735 /** 736 * Attach handles to delete the attachments to all 'delete' links 737 */ 738 attachAttachmentDeleteHandlers: function() 739 { 740 jQuery("#dw_davcal__editevent_attachments .deleteLink").on("click", function(e) 741 { 742 e.preventDefault(); 743 var tr = jQuery(this).closest('tr'); 744 tr.css("background-color", "#FF3700"); 745 tr.fadeOut(400, function() 746 { 747 tr.remove(); 748 }); 749 return false; 750 }); 751 }, 752 753 /** 754 * Show an info/confirmation dialog 755 * @param {Object} confirm Whether a confirmation dialog (true) or an info dialog (false) is requested 756 */ 757 showDialog : function(confirm) 758 { 759 if(dw_davcal__modals.$confirmDialog) 760 return; 761 var dialogButtons = {}; 762 var title = ''; 763 if(confirm) 764 { 765 title = LANG.plugins.davcal['confirmation']; 766 var pageid = jQuery("#dw_davcal__editevent_calendar option:selected").val(); 767 dialogButtons[LANG.plugins.davcal['yes']] = function() { 768 jQuery.post( 769 DOKU_BASE + 'lib/exe/ajax.php', 770 { 771 call: 'plugin_davcal', 772 id: pageid, 773 page: dw_davcal__modals.page, 774 action: dw_davcal__modals.action, 775 params: { 776 uid: dw_davcal__modals.uid 777 }, 778 sectok: JSINFO.plugin.davcal['sectok'] 779 }, 780 function(data) 781 { 782 dw_davcal__modals.completeCb(data); 783 } 784 ); 785 dw_davcal__modals.hideDialog(); 786 }; 787 dialogButtons[LANG.plugins.davcal['cancel']] = function() { 788 dw_davcal__modals.hideDialog(); 789 }; 790 } 791 else 792 { 793 title = LANG.plugins.davcal['info']; 794 dialogButtons[LANG.plugins.davcal['ok']] = function() { 795 dw_davcal__modals.hideDialog(); 796 }; 797 } 798 dw_davcal__modals.$dialog = jQuery(document.createElement('div')) 799 .dialog({ 800 autoOpen: false, 801 draggable: true, 802 //fix for dragging: http://stackoverflow.com/questions/17247486/jquery-ui-dialog-dragging-issues 803 drag: function(event, ui) { 804 var fixPix = jQuery(document).scrollTop(); 805 iObj = ui.position; 806 iObj.top = iObj.top - fixPix; 807 jQuery(this).closest(".ui-dialog").css("top", iObj.top + "px"); 808 }, 809 title: title, 810 resizable: true, 811 buttons: dialogButtons, 812 }) 813 .html( 814 '<div>' + dw_davcal__modals.msg + '</div>' 815 ) 816 .parent() 817 .attr('id','dw_davcal__confirm') 818 .show() 819 .appendTo('.dokuwiki:first'); 820 821 jQuery('#dw_davcal__confirm').position({ 822 my: "center", 823 at: "center", 824 of: window 825 }); 826 // attach event handlers 827 jQuery('#dw_davcal__confirm .ui-dialog-titlebar-close').click(function(){ 828 dw_davcal__modals.hideDialog(); 829 }); 830 }, 831 832 /** 833 * Hide the edit event dialog 834 */ 835 hideEditEventDialog : function() { 836 dw_davcal__modals.$editEventDialog.empty(); 837 dw_davcal__modals.$editEventDialog.remove(); 838 dw_davcal__modals.$editEventDialog = null; 839 }, 840 841 /** 842 * Hide the confirm/info dialog 843 */ 844 hideDialog: function() { 845 dw_davcal__modals.$dialog.empty(); 846 dw_davcal__modals.$dialog.remove(); 847 dw_davcal__modals.$dialog = null; 848 }, 849 850 /** 851 * Hide the settings dialog 852 */ 853 hideSettingsDialog: function() { 854 dw_davcal__modals.$settingsDialog.empty(); 855 dw_davcal__modals.$settingsDialog.remove(); 856 dw_davcal__modals.$settingsDialog = null; 857 } 858}; 859