summaryrefslogtreecommitdiff
path: root/public/js/calendar.js
blob: ff1a4012fcac7658880be500d2a27ab62e4f29bf (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
// js/calendar.js

document.addEventListener('DOMContentLoaded', function () {
    const calendarEl = getElementOrThrow('calendar');
    const modal = getElementOrThrow('event_modal');
    let selected_start_string = null;
    const calendar = new FullCalendar.Calendar(calendarEl, {
        editable: true,
        locale: 'fr',
        //timeZone: 'local', // à modifier pour être à l'heure d'un autre pays
        initialView: 'dayGridMonth',
        headerToolbar: {
            left: 'prev,next today',
            center: 'title',
            //right: 'dayGridMonth,timeGridWeek,timeGridDay,listWeek'
            right: 'dayGridMonth,timeGridWeek,listWeek'
        },
        slotMinWidth: 70,
        defaultAllDay: false,
        // numéros de semaine
        //weekNumbers: true,
        //weekText: 's',
        // vue mois
        contentHeight: 600, // après initialisation: calendar.setOption('contentHeight', 650);
        //aspectRatio: 1.5, // après initialisation: calendar.setOption('aspectRatio', 1.8);
        // pour recalculer la taille au redimensionnement du parent, exécuter: calendar.updateSize()
        stickyHeaderDates: true, // garder les en-tête de colonnes lors du scroll
        fixedWeekCount: false, // avec false, affiche 4, 5 ou 6 semaines selon le mois
        selectable: true, // sélection de jours en cliquant dessus
        longPressDelay: 300, // 1000ms par défaut
        navLinks: true, // numéros de jour et de semaines clicables
        // vue semaine
        slotEventOverlap: true, // superposition (limitée) de deux évènements simultanés
        allDayContent: 'Journée', // texte dans la case "toute la journée"
        nowIndicator: true, // barre rouge pour maintenant
        // params en plus: https://fullcalendar.io/docs/events-json-feed
        events: 'index.php?action=get_events', // fichier PHP qui retourne les événements
        select: function (info) {
            selected_start_string = info.startStr; // variable "globale"
            hideModal();
        },
        // sélection d'une date simple sur mobile, évite des problèmes de conflit avec eventClick
        dateClick: function (info) {
            if (window.matchMedia('(pointer: coarse)').matches) {
                const end = new Date(info.date.getTime());
                calendar.view.type === 'dayGridMonth' ? end.setDate(end.getDate() + 1) : end.setMinutes(end.getMinutes() + 30);
                // vue date: la fin est une date exclue
                // vue semaine: durée de 30min par défaut
                calendar.select(info.date, end); // appeler select() avec un seul paramètre ne marche pas avec la vue "mois"
            }
        },
        //unselect: function(event, view){},
        eventClick: function (info) {
            if (!info.event.start || !info.event.end) {
                throw new Error('modale non conforme');
            }
            const modal_view = new CalendarModalView({
                mode: 'show',
                title: info.event.title,
                description: info.event.extendedProps.description,
                color: info.event.backgroundColor,
                all_day: info.event.allDay,
                start: info.event.start,
                end: info.event.end
            });
            modal.innerHTML = modal_view.getView();
            calendar.updateSize();
        },
        viewDidMount: function (_info) {
            hideModal();
            if (selected_start_string) {
                calendar.gotoDate(new Date(selected_start_string));
            }
        },
        //datesSet: function(info){}, // déclenché lorsque des dates affichées sont chargées (= comme viewDidMount + changement de date)
    });
    function hideModal() {
        modal.innerHTML = '';
        calendar.updateSize();
    }
    document.addEventListener('keydown', function (event) {
        if (event.key === 'Escape') {
            hideModal();
        }
    });
    // technique de la délégation d'événements pour utiliser un bouton ajouté dynamiquement
    document.addEventListener('click', function (event) {
        if (!event.target) {
            throw new Error('évènement click non conforme');
        }
        assertElementType(event.target, HTMLElement);
        if (event.target.classList.contains('event_close_button')) {
            hideModal();
        }
    });
    calendar.render();
});