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.location = ''; 514 calEvent.page = dw_davcal__modals.page; 515 title = LANG.plugins.davcal['create_new_event']; 516 recurringWarning = LANG.plugins.davcal['no_permission']; 517 } 518 else 519 { 520 calEvent.start = event; 521 calEvent.end = moment(event); 522 calEvent.start.hour(12); 523 calEvent.start.minute(0); 524 calEvent.end.hour(13); 525 calEvent.end.minute(0); 526 calEvent.allDay = false; 527 calEvent.recurring = false; 528 calEvent.title = ''; 529 calEvent.description = ''; 530 calEvent.location = ''; 531 calEvent.id = '0'; 532 calEvent.page = dw_davcal__modals.settings['calids'][0]['page']; 533 title = LANG.plugins.davcal['create_new_event']; 534 dialogButtons[LANG.plugins.davcal['create']] = function() { 535 if(!dw_davcal__modals.checkEvents()) 536 return; 537 538 var postArray = { }; 539 var attachArr = new Array(); 540 var pageid = jQuery("#dw_davcal__editevent_calendar option:selected").val(); 541 jQuery("input.dw_davcal__editevent, textarea.dw_davcal__editevent").each(function() { 542 if(jQuery(this).attr('type') == 'checkbox') 543 { 544 postArray[jQuery(this).prop('name')] = jQuery(this).prop('checked') ? 1 : 0; 545 } 546 else 547 { 548 postArray[jQuery(this).prop('name')] = jQuery(this).val(); 549 } 550 }); 551 jQuery('.dw_davcal__editevent_attachment_link').each(function() { 552 var attachment = jQuery(this).attr('href'); 553 if(attachment != undefined) 554 { 555 attachArr.push(attachment); 556 } 557 }); 558 postArray['attachments'] = attachArr; 559 jQuery('#dw_davcal__ajaxedit').html('<img src="'+DOKU_BASE+'lib/images/throbber.gif" alt="" width="16" height="16" />'); 560 jQuery.post( 561 DOKU_BASE + 'lib/exe/ajax.php', 562 { 563 call: 'plugin_davcal', 564 id: pageid, 565 page: dw_davcal__modals.page, 566 action: 'newEvent', 567 params: postArray, 568 sectok: JSINFO.plugin.davcal['sectok'] 569 }, 570 function(data) 571 { 572 var result = data['result']; 573 var html = data['html']; 574 jQuery('#dw_davcal__ajaxedit').html(html); 575 if(result === true) 576 { 577 jQuery('#fullCalendar').fullCalendar('refetchEvents'); 578 dw_davcal__modals.hideEditEventDialog(); 579 } 580 } 581 ); 582 }; 583 } 584 dialogButtons[LANG.plugins.davcal['cancel']] = function() { 585 dw_davcal__modals.hideEditEventDialog(); 586 }; 587 dw_davcal__modals.uid = calEvent.id; 588 dw_davcal__modals.$editEventDialog = jQuery(document.createElement('div')) 589 .dialog({ 590 autoOpen: false, 591 draggable: true, 592 // fix for dragging: http://stackoverflow.com/questions/17247486/jquery-ui-dialog-dragging-issues 593 drag: function(event, ui) { 594 var fixPix = jQuery(document).scrollTop(); 595 iObj = ui.position; 596 iObj.top = iObj.top - fixPix; 597 jQuery(this).closest(".ui-dialog").css("top", iObj.top + "px"); 598 }, 599 title: title, 600 resizable: true, 601 buttons: dialogButtons, 602 }) 603 .html( 604 '<div><table>' + 605 '<tr><td>' + LANG.plugins.davcal['calendar'] + '</td><td><select id="dw_davcal__editevent_calendar"></select></td></tr>' + 606 '<tr><td>' + LANG.plugins.davcal['title'] + '</td><td><input type="text" id="dw_davcal__eventname_edit" name="eventname" class="dw_davcal__editevent"></td></tr>' + 607 '<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>' + 608 '<tr><td>' + LANG.plugins.davcal['location'] + '</td><td><input type="text" id="dw_davcal__eventlocation_edit" name="eventlocation" class="dw_davcal__editevent"></td></tr>' + 609 '<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>' + 610 '<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>' + 611 '<tr><td colspan="2"><input type="checkbox" name="allday" id="dw_davcal__allday_edit" class="dw_davcal__editevent">' + LANG.plugins.davcal['allday'] + '</td></tr>' + 612 '<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>' + 613 '</table>' + 614 recurringWarning + 615 '<input type="hidden" name="uid" id="dw_davcal__uid_edit" class="dw_davcal__editevent">' + 616 '<input type="hidden" name="detectedtz" id="dw_davcal__tz_edit" class="dw_davcal__editevent">' + 617 '<input type="hidden" name="currenttz" id="dw_davcal__currenttz_edit" class="dw_davcal__editevent">' + 618 '</div>' + 619 '<div id="dw_davcal__ajaxedit"></div>' 620 ) 621 .parent() 622 .attr('id','dw_davcal__edit') 623 .show() 624 .appendTo('.dokuwiki:first'); 625 626 jQuery('#dw_davcal__edit').position({ 627 my: "center", 628 at: "center", 629 of: window 630 }); 631 632 // Populate calendar dropdown 633 var $dropdown = jQuery("#dw_davcal__editevent_calendar"); 634 for(var i=0; i<dw_davcal__modals.settings['calids'].length; i++) 635 { 636 var sel = ''; 637 // When creating an event, do not show read-only calendars 638 if(!edit && (dw_davcal__modals.settings['calids'][i]['write'] === false)) 639 continue; 640 if(calEvent.page == dw_davcal__modals.settings['calids'][i]['page']) 641 sel = ' selected="selected"'; 642 $dropdown.append('<option value="' + dw_davcal__modals.settings['calids'][i]['page'] + '"' + sel + '>' + dw_davcal__modals.settings['calids'][i]['name'] + '</option>'); 643 } 644 if(edit || (dw_davcal__modals.settings['calids'].length < 1)) 645 { 646 $dropdown.prop('disabled', true); 647 } 648 649 // Set up existing/predefined values 650 jQuery('#dw_davcal__tz_edit').val(dw_davcal__modals.detectedTz); 651 jQuery('#dw_davcal__currenttz_edit').val(dw_davcal__modals.currentTz); 652 jQuery('#dw_davcal__uid_edit').val(calEvent.id); 653 jQuery('#dw_davcal__eventname_edit').val(calEvent.title); 654 jQuery('#dw_davcal__eventlocation_edit').val(calEvent.location); 655 jQuery('#dw_davcal__eventfrom_edit').val(calEvent.start.format('YYYY-MM-DD')); 656 jQuery('#dw_davcal__eventfromtime_edit').val(calEvent.start.format('HH:mm')); 657 jQuery('#dw_davcal__eventdescription_edit').val(calEvent.description); 658 if(calEvent.attachments && (calEvent.attachments !== null)) 659 { 660 for(var i=0; i<calEvent.attachments.length; i++) 661 { 662 var url = calEvent.attachments[i]; 663 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>'; 664 jQuery('#dw_davcal__editevent_attachments > tbody:last').append(row); 665 666 } 667 } 668 dw_davcal__modals.attachAttachmentDeleteHandlers(); 669 jQuery('#dw_davcal__editevent_attach').on("click", function(e) 670 { 671 e.preventDefault(); 672 var url = jQuery('#dw_davcal__editevent_attachment').val(); 673 if(url == '') 674 return false; 675 jQuery('#dw_davcal__editevent_attachment').val('http://'); 676 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>'; 677 jQuery('#dw_davcal__editevent_attachments > tbody:last').append(row); 678 dw_davcal__modals.attachAttachmentDeleteHandlers(); 679 return false; 680 }); 681 if(calEvent.allDay && (calEvent.end === null)) 682 { 683 jQuery('#dw_davcal__eventto_edit').val(calEvent.start.format('YYYY-MM-DD')); 684 jQuery('#dw_davcal__eventtotime_edit').val(calEvent.start.format('HH:mm')); 685 } 686 else if(calEvent.allDay) 687 { 688 endEvent = moment(calEvent.end); 689 endEvent.subtract(1, 'days'); 690 jQuery('#dw_davcal__eventto_edit').val(endEvent.format('YYYY-MM-DD')); 691 jQuery('#dw_davcal__eventotime_edit').val(endEvent.format('HH:mm')); 692 } 693 else 694 { 695 jQuery('#dw_davcal__eventto_edit').val(calEvent.end.format('YYYY-MM-DD')); 696 jQuery('#dw_davcal__eventtotime_edit').val(calEvent.end.format('HH:mm')); 697 } 698 jQuery('#dw_davcal__allday_edit').prop('checked', calEvent.allDay); 699 700 // attach event handlers 701 jQuery('#dw_davcal__edit .ui-dialog-titlebar-close').click(function(){ 702 dw_davcal__modals.hideEditEventDialog(); 703 }); 704 jQuery('#dw_davcal__eventfrom_edit').datetimepicker({format:'YYYY-MM-DD', 705 formatDate:'YYYY-MM-DD', 706 datepicker: true, 707 timepicker: false, 708 }); 709 jQuery('#dw_davcal__eventfromtime_edit').datetimepicker({format:'HH:mm', 710 formatTime:'HH:mm', 711 datepicker: false, 712 timepicker: true, 713 step: 15}); 714 jQuery('#dw_davcal__eventto_edit').datetimepicker({format:'YYYY-MM-DD', 715 formatDate:'YYYY-MM-DD', 716 datepicker: true, 717 timepicker: false, 718 }); 719 jQuery('#dw_davcal__eventtotime_edit').datetimepicker({format:'HH:mm', 720 formatTime:'HH:mm', 721 datepicker: false, 722 timepicker: true, 723 step:15}); 724 jQuery('#dw_davcal__allday_edit').change(function() { 725 if(jQuery(this).is(":checked")) 726 { 727 jQuery('#dw_davcal__eventfromtime_edit').prop('readonly', true); 728 jQuery('#dw_davcal__eventtotime_edit').prop('readonly', true); 729 } 730 else 731 { 732 jQuery('#dw_davcal__eventfromtime_edit').prop('readonly', false); 733 jQuery('#dw_davcal__eventtotime_edit').prop('readonly', false); 734 } 735 }); 736 jQuery('#dw_davcal__allday_edit').change(); 737 }, 738 739 /** 740 * Attach handles to delete the attachments to all 'delete' links 741 */ 742 attachAttachmentDeleteHandlers: function() 743 { 744 jQuery("#dw_davcal__editevent_attachments .deleteLink").on("click", function(e) 745 { 746 e.preventDefault(); 747 var tr = jQuery(this).closest('tr'); 748 tr.css("background-color", "#FF3700"); 749 tr.fadeOut(400, function() 750 { 751 tr.remove(); 752 }); 753 return false; 754 }); 755 }, 756 757 /** 758 * Show an info/confirmation dialog 759 * @param {Object} confirm Whether a confirmation dialog (true) or an info dialog (false) is requested 760 */ 761 showDialog : function(confirm) 762 { 763 if(dw_davcal__modals.$confirmDialog) 764 return; 765 var dialogButtons = {}; 766 var title = ''; 767 if(confirm) 768 { 769 title = LANG.plugins.davcal['confirmation']; 770 var pageid = jQuery("#dw_davcal__editevent_calendar option:selected").val(); 771 dialogButtons[LANG.plugins.davcal['yes']] = function() { 772 jQuery.post( 773 DOKU_BASE + 'lib/exe/ajax.php', 774 { 775 call: 'plugin_davcal', 776 id: pageid, 777 page: dw_davcal__modals.page, 778 action: dw_davcal__modals.action, 779 params: { 780 uid: dw_davcal__modals.uid 781 }, 782 sectok: JSINFO.plugin.davcal['sectok'] 783 }, 784 function(data) 785 { 786 dw_davcal__modals.completeCb(data); 787 } 788 ); 789 dw_davcal__modals.hideDialog(); 790 }; 791 dialogButtons[LANG.plugins.davcal['cancel']] = function() { 792 dw_davcal__modals.hideDialog(); 793 }; 794 } 795 else 796 { 797 title = LANG.plugins.davcal['info']; 798 dialogButtons[LANG.plugins.davcal['ok']] = function() { 799 dw_davcal__modals.hideDialog(); 800 }; 801 } 802 dw_davcal__modals.$dialog = jQuery(document.createElement('div')) 803 .dialog({ 804 autoOpen: false, 805 draggable: true, 806 //fix for dragging: http://stackoverflow.com/questions/17247486/jquery-ui-dialog-dragging-issues 807 drag: function(event, ui) { 808 var fixPix = jQuery(document).scrollTop(); 809 iObj = ui.position; 810 iObj.top = iObj.top - fixPix; 811 jQuery(this).closest(".ui-dialog").css("top", iObj.top + "px"); 812 }, 813 title: title, 814 resizable: true, 815 buttons: dialogButtons, 816 }) 817 .html( 818 '<div>' + dw_davcal__modals.msg + '</div>' 819 ) 820 .parent() 821 .attr('id','dw_davcal__confirm') 822 .show() 823 .appendTo('.dokuwiki:first'); 824 825 jQuery('#dw_davcal__confirm').position({ 826 my: "center", 827 at: "center", 828 of: window 829 }); 830 // attach event handlers 831 jQuery('#dw_davcal__confirm .ui-dialog-titlebar-close').click(function(){ 832 dw_davcal__modals.hideDialog(); 833 }); 834 }, 835 836 /** 837 * Hide the edit event dialog 838 */ 839 hideEditEventDialog : function() { 840 dw_davcal__modals.$editEventDialog.empty(); 841 dw_davcal__modals.$editEventDialog.remove(); 842 dw_davcal__modals.$editEventDialog = null; 843 }, 844 845 /** 846 * Hide the confirm/info dialog 847 */ 848 hideDialog: function() { 849 dw_davcal__modals.$dialog.empty(); 850 dw_davcal__modals.$dialog.remove(); 851 dw_davcal__modals.$dialog = null; 852 }, 853 854 /** 855 * Hide the settings dialog 856 */ 857 hideSettingsDialog: function() { 858 dw_davcal__modals.$settingsDialog.empty(); 859 dw_davcal__modals.$settingsDialog.remove(); 860 dw_davcal__modals.$settingsDialog = null; 861 } 862}; 863