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