summaryrefslogtreecommitdiff
path: root/public/js/calendar.js
blob: a0926320e9c99208a2310d72f51d63c390195021 (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
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
// js/calendar.js

document.addEventListener('DOMContentLoaded', function(){
    const calendarEl = document.getElementById('calendar');
    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'
        },
        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 multiples
        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();
        },
        //unselect: function(event, view){},

        eventClick: function(info){
            const aside = document.querySelector('aside');
            const checked = info.event.allDay ? 'checked' : '';

            // change des objets Date en chaînes compatibles avec les input
            function formatDate(date){
                return date.getFullYear() + '-' + (date.getMonth() + 1).toString().padStart(2, '0') + '-' + date.getDate().toString().padStart(2, '0')
                    + (info.event.allDay ? '' : 'T' + date.getHours().toString().padStart(2, '0') + ':' + date.getMinutes().toString().padStart(2, '0'));
            }
            function minusOneDay(date){
                date.setDate(date.getDate() - 1); // jour de fin modifié pour ne pas faire bizarre pour l'utilisateur
                return date;
            }

            const start = formatDate(info.event.start);
            const start_date = start.split('T')[0];
            const start_hour = (info.event.allDay ? '' : '<br>à ' + start.split('T')[1]).replace(":", "h");
            const formated_start = start_date.split('-')[2] + '/' + start_date.split('-')[1] + '/' + start_date.split('-')[0] + start_hour;
            const end = formatDate(info.event.allDay ? minusOneDay(info.event.end) : info.event.end, info.event.allDay);
            const end_date = end.split('T')[0];
            const end_hour = (info.event.allDay ? '' : '<br>à ' + end.split('T')[1]).replace(":", "h");
            const formated_end = end_date.split('-')[2] + '/' + end_date.split('-')[1] + '/' + end_date.split('-')[0] + end_hour;

            let aside_content = `<div class="event" style="border-color: ` + info.event.backgroundColor +`;">
                    <h3>` + info.event.title + `</h3>
                    <p><i>` + info.event.extendedProps.description + `</i></p>`;
            if(checked && (formated_start === formated_end)){ // affichage simplifié évènement d'un jour
                aside_content = aside_content + `<p>le ` + formated_start + `</p>
                    </div>`;
            }
            else{
                aside_content = aside_content + `<p>du ` + formated_start + `</p>
                        <p>au ` + formated_end + `</p>
                    </div>`;
            }

            aside.innerHTML = aside_content;
            calendar.updateSize();
        },
        viewDidMount: function(info){ // déclenché lorsque qu'une nouvelle vue est chargée (mois, semaine...)
            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(){
        const aside = document.querySelector('aside');
        aside.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.classList.contains('event_close_button')){
            hideModal();
        }
    });

    calendar.render();
});