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