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