0

I'm currently working on a fullCalendar Project (v3, version of the template I'm using).

What I need to do is create a doc where it print all the events of the current month matching the current $_SESSION['nomeUtente'] (the current logged-in user).

e.g. If I have 2 events in March, 3 in April and 5 in May, by clicking on a button I open another link where it shows only the events on March.

My events are saved in this database: database

And this is my calendar: calendar the blue button on the bottom right is where I want to link the other page that show the events.

My issue is: I don't know how to get the events of the current month.

I tried to sketch some code in JS but I'm stuck:

function getEvents(year, month){
            var date = new Date();
            var firstDay = new Date(date.getFullYear(), date.getMonth(), 1); // print last day of prev month
            var lastDay = new Date(date.getFullYear(), date.getMonth() + 1, 0); // print last day of current month   
}

I did this code because i think from this two variables i can do something like:

if(starts > firstDay && ends <= lastDay){
       print *events of current month*
 }

If someone can help me it would be nice

Also one of my doubts is: should I use PHP or JavaScript?


Code I sketch in PHP

<?php
      require_once "../config.php";
      session_start(); 
       
        
        $thisMonth        = date("Y-m-t"); //prendere l'ultimo giorno del mese corrente
        $previousMonth    = date('Y-m-d', strtotime('last day of previous month')); //prendere l'ultimo giorno del mese passato
        $nextMonth        = date('Y-m-d', strtotime('last day of next month')); //prendere l'ultimo giorno del mese successivo
        $nomeUtente       = $_SESSION['nomeUtente'];
        $starts           = $_POST['starts'];
        $ends             = $_POST['ends'];
    
    
        if ($starts > $previousMonth && $ends <= $thisMonth){
          $sql = "SELECT * FROM assenze WHERE nomeUtente = '$nomeUtente', ename = '$ename', starts >= '$starts', ends <= '$ends' "; 
        }

I'm also undecided if the $starts, $ends and $sql are right :/


this is my calendar.js

      (function (global, factory) {
        if (typeof define === "function" && define.amd) {
            define('/App/Calendar', ['exports', 'Site', 'Config'], factory);
        } else if (typeof exports !== "undefined") {
            factory(exports, require('Site'), require('Config'));
        } else {
            var mod = {
                exports: {}
            };
            factory(mod.exports, global.Site, global.Config);
            global.AppCalendar = mod.exports;
        }
    })
    (this, function (exports, _Site2, _Config) {
        'use strict';
    
        Object.defineProperty(exports, "__esModule", {
            value: true
        });
        exports.getInstance = exports.run = exports.AppCalendar = undefined;
    
        var _Site3 = babelHelpers.interopRequireDefault(_Site2);
    
        var AppCalendar = function (_Site) {
            babelHelpers.inherits(AppCalendar, _Site);
    
            function AppCalendar() {
                babelHelpers.classCallCheck(this, AppCalendar);
                return babelHelpers.possibleConstructorReturn(this, (AppCalendar.__proto__ || Object.getPrototypeOf(AppCalendar)).apply(this, arguments));
            }
    
            babelHelpers.createClass(AppCalendar, [{
                key: 'initialize',
                value: function initialize() {
                    babelHelpers.get(AppCalendar.prototype.__proto__ || Object.getPrototypeOf(AppCalendar.prototype), 'initialize', this).call(this);
    
                    this.$actionToggleBtn = $('.site-action-toggle');
                    this.$addNewCalendarForm = $('#addNewCalendar').modal({
                        show: false
                    });
                }
            }, 
            { 
                key: 'process',
                value: function process() {
                    babelHelpers.get(AppCalendar.prototype.__proto__ || Object.getPrototypeOf(AppCalendar.prototype), 'process', this).call(this);
    
                    this.handleFullcalendar();
                    this.handleSelective();
                    this.handleAction();
                    this.handleListItem();
                    this.handleEventList();
                }
            },
    
            {
                key: 'handleFullcalendar',
                value: function handleFullcalendar() {
                    
                    var myOptions = {
                        header: {
                            left: 'today',
                            center: 'prev,title,next',
                            right: 'none'
                            //right: 'month,listWeek' <- bugged in too many ways
                        },
                        
                        buttonText:{
                            today: 'Oggi',
                            month: 'Mese',
                            week: 'Settimana',
                            day: 'Giorno',
                            list: 'Elenco'
                        },
                        
                        locale:'it',        
                        allDaySlot: false,  
                        selectable: true,
                        selectHelper: true,               
                        timeFormat: 'H(:mm)',             
                        //editable: true, permette di spostare gli eventi
                        eventLimit: true,
                        navLinks: true, //selezionando il giorno visualizza elenco eventi 
                        
                        windowResize: function windowResize(view) {
                            var width = $(window).outerWidth();
                            var options = Object.assign({}, myOptions);
    
                            options.events = view.calendar.clientEvents();
                            options.aspectRatio = width < 667 ? 0.5 : 1.35;
    
                            $('#calendar').fullCalendar('destroy');
                            $('#calendar').fullCalendar(options);
                        },
                        
                        //apre modal per aggiungere nuovo evento
                        select: function select(event) {                
                            $('#addNewEvent').modal('show');
                            $('#calendar').fullCalendar('refetchEvents',event._id)
                        },
                                                        
                        //triggherà apertura modal di #editEvent
                        eventClick: function eventClick(event) {
                            $('#editEname').val(event.title);
                            $('event.id').val(event.idAssenza);
                            $('editNomeUtente').val(event.nomeUtente);
                            $('#editDescrizione').val(event.descrizione);
                            $('#editStarts').val(event.start.toISOString());
                            $('#editEnds').val(event.end.toISOString());
                            $('#editNewEvent').modal('show').one('hidden.bs.modal', function (e) {
                                event.title = $('#editEname').val();
                                event.start = $('#editStarts').val();
                                event.end = $('#editEnds').val();
                                event.descrizione = $('#editDescrizione').val();
                                $.ajax({
                                    url: 'eventi/updateEvent.php',
                                    type: 'POST',
                                    data:  {start: event.start, _id: event.idAssenza, end: event.end, title: event.title, descrizione: event.descrizione},
                                    success: function(html){
                                        location.reload();
                                    }
                                });
                                $('#calendar').fullCalendar('updateEvent', event._id);
                            });
                        },  
    
                        /* //btn '+' verde in basso a destra
                        eventDragStart: function eventDragStart() {
                            $('.site-action').data('actionBtn').show();
                        },
                        eventDragStop: function eventDragStop() {
                            $('.site-action').data('actionBtn').hide();
                        },
                        //fine btn */
                
                        events: {                   
                            url: 'eventi/load.php', 
                            method:'POST'                                                               
                        },
                        droppable: false,
                        eventRender: function eventRender( event, element, view ) {
                            //decide il colore in base al tipo di assenza
                            if(event.title == "Normali") {
                                element.css('background-color', '#6d4c41');
                            }
                            else if(event.title == "Straordinarie") {
                                element.css('background-color', '##c0ca33');
                            }
                            else if(event.title == "Ferie") {
                                element.css('background-color', '#e53935');
                            }
                            else if(event.title == "Malattia") {
                                element.css('background-color', '#ffa000');
                            }
                            else if(event.title == "Permesso") {
                                element.css('background-color', '#9fa8da');
                            }
                            else if(event.title == "Smart Working") {
                                element.css('background-color', '#00acc1');
                            }
                            else if(event.title == "Trasferta") {
                                element.css('background-color', '#00897b');
                            }
                            else if(event.title == "Assenza non retribuita") {
                                element.css('background-color', '#546e7a');
                            }
                            else if(event.title == "Altro") {
                                element.css('background-color', '#5e35b1');
                            }
                            
                            //elimina eventi
                            if (view.name == 'listDay') {
                                element.find(".fc-list-item-time").append("<span class='closeon'>X</span>");
                            } else {
                                element.find(".fc-content").prepend("<span class='closeon'>X</span>");
                            }
                            element.find(".closeon").on('click', function() {
                                var deleteMsg = confirm("Vuoi davvero eliminare " + event.title + "?");
                                if (deleteMsg == true) {                        
                                    $.ajax({
                                        url: 'eventi/deleteEvent.php',
                                        type: 'POST',
                                        data:  {_id: event.idAssenza, nomeUtente: event.nomeUtente},
                                        success: function(html){
                                            location.reload();
                                        },
                                        error: function(html){
                                            alert("Non puoi eliminare questo evento!");
                                        }
                                    })
                                    $('#calendar').fullCalendar('removeEvents',event._id);
                                } else {
                                    ;
                                }
                            });
                            
                            //get the values from all selected checkboxes
                            var selections = [];
                            $("input[name=calendario]:checked").each(function(){
                                selections.push($(this).val());
                            });                     
                            var showEvent = false;
                            if (selections.indexOf("Ore Personali") >= 0 && event.nomeUtente == $("#nomeUtente").data('value')) showEvent = true; //show if the OP box is ticked and the event belongs to the current user
                            if (selections.indexOf("Assenze") >= 0 && event.nomeUtente != $("#nomeUtente").data('value')) showEvent = true; //show if the assenze box is ticked and the event belongs to another user                   
                            
                            /* if (event.nomeUtente == $("#nomeUtente").data('value') && event.title == 'Normali' && event.title == 'Straordinarie') showEvent = true;
                            if (event.nomeUtente != $("#nomeUtente").data('value') && event.title == 'Normali' && event.title == 'Straordinarie') showEvent = false; */
                            
                            return showEvent;
                            /* var view = $('#calendar').fullCalendar('getView');
                            alert("The view's title is " + view.title + view); */
                        }
                        
                    };
                    $('input[name=calendario]').on('change',function(){
                        $('#calendar').fullCalendar('rerenderEvents');
                    })
                    
        
                    var _options = void 0;
                    var myOptionsMobile = Object.assign({}, myOptions);
    
                    myOptionsMobile.aspectRatio = 0.5;
                    _options = $(window).outerWidth() < 667 ? myOptionsMobile : myOptions;
    
                    $('#editNewEvent').modal();
                    $('#calendar').fullCalendar(_options);
                }
            },
            {
             function getEvents(year, month){
                        var date = new Date();
                        var firstDay = new Date(date.getFullYear(), 
                       date.getMonth(), 1);
                        var lastDay = new Date(date.getFullYear(), 
                            date.getMonth() + 1, 0);
                        
                        var currentEvents = $('#calendar').fullCalendar('clientEvents').filter(event => (new Date(event.start) >= firstDay && new Date(event.end) <= lastDay));
                        
                        for(i=0; i<currentEvents.length; i++) {
                            console.log(currentEvents[i].title);
                        }
                    }
                    
}
          
            ]);
            return AppCalendar;
        }   
        (_Site3.default);
        var instance = null;
        function getInstance() {
            if (!instance) {
                instance = new AppCalendar();
            }
            return instance;
        }
    
        function run() {
            var app = getInstance();
            app.run();
        }
    
          exports.AppCalendar = AppCalendar;
          exports.run = run;
          exports.getInstance = getInstance;
          exports.default = AppCalendar;
      
    });
aim0d
  • 129
  • 7
  • I'd say it doesn't really matter whether you use PHP or JS. You can get all the currently stored events from fullCalendar and filter them, or you can run a SQL query in PHP to get them. In either case all the code needs to know is the current user ID and the requested month. If you're passing this to another page though, it might make more sense to just get the current month from fullCalendar and pass that on the querystring to the next page, then PHP can pick that up, and combine it with the username from the session to build a SQL query to get the right events, and display them in a list. – ADyson Mar 31 '22 at 10:42
  • Sounds like the solution i was looking for, but unfortunately i dont have enough knowledge to do it :/ I'm gonna try if i found somewhere to do something like this ahhaha – aim0d Mar 31 '22 at 11:58
  • Where exactly are you stuck with it? Fetching SQL data based on some parameter in the URL should be a pretty standard task, for example. Is the issue how to get the month from fullCalendar, perhaps? – ADyson Mar 31 '22 at 12:24
  • Yeah, like i know how to get parameter cause i did the load.php that, in fact, load events from the DB to my calendar. But yes. I tried also sketch something in PHP, i'm gonna load it in my question. But dont know if i did right or not – aim0d Mar 31 '22 at 12:30
  • Yes, i'm stuck in how to distinguish the singlemonth – aim0d Mar 31 '22 at 12:31
  • Well did you try reading any documentation from fullCalendar? https://fullcalendar.io/docs/v3/getView will get you the current view object whose properties you can see here: https://fullcalendar.io/docs/v3/view-object and you'll notice it includes the start and end date of the currently displayed date range, which you can then pass to your next page and your SQL query. (note that it doesn't return a month specifically, but rather a date range so that the same process will work if you're in month, week, day or some other custom view). – ADyson Mar 31 '22 at 12:34
  • `I'm also undecided if the $starts, $ends and $sql are right`...well that's what testing your code thoroughly against your requirements is for. – ADyson Mar 31 '22 at 12:35
  • **Warning:** Your code is vulnerable to SQL Injection attacks. You should use parameterised queries and prepared statements to help prevent attackers from compromising your database by using malicious input values. http://bobby-tables.com gives an explanation of the risks, as well as some examples of how to write your queries safely using PHP / mysqli. **Never** insert unsanitised data directly into your SQL. The way your code is written now, someone could easily steal, incorrectly change, or even delete your data. – ADyson Mar 31 '22 at 12:36
  • https://phpdelusions.net/mysqli also contains good examples of writing safe SQL using mysqli. See also the [mysqli documentation](https://www.php.net/manual/en/mysqli.quickstart.prepared-statements.php) and this: [How can I prevent SQL injection in PHP?](https://stackoverflow.com/questions/60174/how-can-i-prevent-sql-injection-in-php) . Parameterising your queries will also greatly reduce the risk of accidental syntax errors as a result of un-escaped or incorrectly quoted input values. If you learnt your current technique from a tutorial or book, please don't use it again. – ADyson Mar 31 '22 at 12:36
  • Right now someone could break your SQL query just with a simple `'` in one of the input fields, and that's before you even think about SQL injection attacks (because you can't guarantee someone malicious won't send your server something which isn't a date). – ADyson Mar 31 '22 at 12:37
  • oh i'm gonna fix the SQL injection. I saw the getView and it's kinda what i was looking for, now i just need to see how to also take the events – aim0d Mar 31 '22 at 12:54
  • In that scenario you don't need to take the events from fullCalendar, because you'll take them directly from your database. You pass the start and end dates to the next page via the URL, and then the PHP on the next page reads those and uses them to generate a SQL query like the one you've just added to your question. That SQL query returns the relevant events and then you can echo the data onto the page. – ADyson Mar 31 '22 at 12:58
  • oh okay, got it. Gonna work on that – aim0d Mar 31 '22 at 13:24

1 Answers1

2

This would get you your current events in JavaScript, with the dates you have setup being used to make sure we trim off anything else in memory (for if you have changed months)

function getEvents(year, month){
    var date = new Date();
    var firstDay = new Date(date.getFullYear(), date.getMonth(), 1);
    var lastDay = new Date(date.getFullYear(), date.getMonth() + 1, 0);
    
    var currentEvents = $('#calendar').fullCalendar('clientEvents').filter(event => (new Date(event.start) >= firstDay && new Date(event.end) <= lastDay));
    
    for(i=0; i<currentEvents.length; i++) {
        console.log(currentEvents[i]);
    }
}

Where calendar is the id of your FullCalendar element in the DOM.

then pick off the bits of info you want, such as title, start, end, for each entry, i.e.

currentEvents[i].title

Please change your full calendar.js to this

(function (global, factory) {
    if (typeof define === "function" && define.amd) {
        define('/App/Calendar', ['exports', 'Site', 'Config'], factory);
    } else if (typeof exports !== "undefined") {
        factory(exports, require('Site'), require('Config'));
    } else {
        var mod = {
            exports: {}
        };
        factory(mod.exports, global.Site, global.Config);
        global.AppCalendar = mod.exports;
    }
})
(this, function (exports, _Site2, _Config) {
    'use strict';

    Object.defineProperty(exports, "__esModule", {
        value: true
    });
    exports.getInstance = exports.run = exports.AppCalendar = undefined;

    var _Site3 = babelHelpers.interopRequireDefault(_Site2);

    var AppCalendar = function (_Site) {
        babelHelpers.inherits(AppCalendar, _Site);

        function AppCalendar() {
            babelHelpers.classCallCheck(this, AppCalendar);
            return babelHelpers.possibleConstructorReturn(this, (AppCalendar.__proto__ || Object.getPrototypeOf(AppCalendar)).apply(this, arguments));
        }

        babelHelpers.createClass(AppCalendar, [{
            key: 'initialize',
            value: function initialize() {
                babelHelpers.get(AppCalendar.prototype.__proto__ || Object.getPrototypeOf(AppCalendar.prototype), 'initialize', this).call(this);

                this.$actionToggleBtn = $('.site-action-toggle');
                this.$addNewCalendarForm = $('#addNewCalendar').modal({
                    show: false
                });
            }
        }, 
        { 
            key: 'process',
            value: function process() {
                babelHelpers.get(AppCalendar.prototype.__proto__ || Object.getPrototypeOf(AppCalendar.prototype), 'process', this).call(this);

                this.handleFullcalendar();
                this.handleSelective();
                this.handleAction();
                this.handleListItem();
                this.handleEventList();
            }
        },

        {
            key: 'handleFullcalendar',
            value: function handleFullcalendar() {
                
                var myOptions = {
                    header: {
                        left: 'today',
                        center: 'prev,title,next',
                        right: 'none'
                        //right: 'month,listWeek' <- bugged in too many ways
                    },
                    
                    buttonText:{
                        today: 'Oggi',
                        month: 'Mese',
                        week: 'Settimana',
                        day: 'Giorno',
                        list: 'Elenco'
                    },
                    
                    locale:'it',        
                    allDaySlot: false,  
                    selectable: true,
                    selectHelper: true,               
                    timeFormat: 'H(:mm)',             
                    //editable: true, permette di spostare gli eventi
                    eventLimit: true,
                    navLinks: true, //selezionando il giorno visualizza elenco eventi 
                    
                    windowResize: function windowResize(view) {
                        var width = $(window).outerWidth();
                        var options = Object.assign({}, myOptions);

                        options.events = view.calendar.clientEvents();
                        options.aspectRatio = width < 667 ? 0.5 : 1.35;

                        $('#calendar').fullCalendar('destroy');
                        $('#calendar').fullCalendar(options);
                    },
                    
                    //apre modal per aggiungere nuovo evento
                    select: function select(event) {                
                        $('#addNewEvent').modal('show');
                        $('#calendar').fullCalendar('refetchEvents',event._id)
                    },
                                                    
                    //triggherà apertura modal di #editEvent
                    eventClick: function eventClick(event) {
                        $('#editEname').val(event.title);
                        $('event.id').val(event.idAssenza);
                        $('editNomeUtente').val(event.nomeUtente);
                        $('#editDescrizione').val(event.descrizione);
                        $('#editStarts').val(event.start.toISOString());
                        $('#editEnds').val(event.end.toISOString());
                        $('#editNewEvent').modal('show').one('hidden.bs.modal', function (e) {
                            event.title = $('#editEname').val();
                            event.start = $('#editStarts').val();
                            event.end = $('#editEnds').val();
                            event.descrizione = $('#editDescrizione').val();
                            $.ajax({
                                url: 'eventi/updateEvent.php',
                                type: 'POST',
                                data:  {start: event.start, _id: event.idAssenza, end: event.end, title: event.title, descrizione: event.descrizione},
                                success: function(html){
                                    location.reload();
                                }
                            });
                            $('#calendar').fullCalendar('updateEvent', event._id);
                        });
                    },  

                    /* //btn '+' verde in basso a destra
                    eventDragStart: function eventDragStart() {
                        $('.site-action').data('actionBtn').show();
                    },
                    eventDragStop: function eventDragStop() {
                        $('.site-action').data('actionBtn').hide();
                    },
                    //fine btn */
            
                    events: {                   
                        url: 'eventi/load.php', 
                        method:'POST'                                                               
                    },
                    droppable: false,
                    eventRender: function eventRender( event, element, view ) {
                        //decide il colore in base al tipo di assenza
                        if(event.title == "Normali") {
                            element.css('background-color', '#6d4c41');
                        }
                        else if(event.title == "Straordinarie") {
                            element.css('background-color', '##c0ca33');
                        }
                        else if(event.title == "Ferie") {
                            element.css('background-color', '#e53935');
                        }
                        else if(event.title == "Malattia") {
                            element.css('background-color', '#ffa000');
                        }
                        else if(event.title == "Permesso") {
                            element.css('background-color', '#9fa8da');
                        }
                        else if(event.title == "Smart Working") {
                            element.css('background-color', '#00acc1');
                        }
                        else if(event.title == "Trasferta") {
                            element.css('background-color', '#00897b');
                        }
                        else if(event.title == "Assenza non retribuita") {
                            element.css('background-color', '#546e7a');
                        }
                        else if(event.title == "Altro") {
                            element.css('background-color', '#5e35b1');
                        }
                        
                        //elimina eventi
                        if (view.name == 'listDay') {
                            element.find(".fc-list-item-time").append("<span class='closeon'>X</span>");
                        } else {
                            element.find(".fc-content").prepend("<span class='closeon'>X</span>");
                        }
                        element.find(".closeon").on('click', function() {
                            var deleteMsg = confirm("Vuoi davvero eliminare " + event.title + "?");
                            if (deleteMsg == true) {                        
                                $.ajax({
                                    url: 'eventi/deleteEvent.php',
                                    type: 'POST',
                                    data:  {_id: event.idAssenza, nomeUtente: event.nomeUtente},
                                    success: function(html){
                                        location.reload();
                                    },
                                    error: function(html){
                                        alert("Non puoi eliminare questo evento!");
                                    }
                                })
                                $('#calendar').fullCalendar('removeEvents',event._id);
                            } else {
                                ;
                            }
                        });
                        
                        //get the values from all selected checkboxes
                        var selections = [];
                        $("input[name=calendario]:checked").each(function(){
                            selections.push($(this).val());
                        });                     
                        var showEvent = false;
                        if (selections.indexOf("Ore Personali") >= 0 && event.nomeUtente == $("#nomeUtente").data('value')) showEvent = true; //show if the OP box is ticked and the event belongs to the current user
                        if (selections.indexOf("Assenze") >= 0 && event.nomeUtente != $("#nomeUtente").data('value')) showEvent = true; //show if the assenze box is ticked and the event belongs to another user                   
                        
                        /* if (event.nomeUtente == $("#nomeUtente").data('value') && event.title == 'Normali' && event.title == 'Straordinarie') showEvent = true;
                        if (event.nomeUtente != $("#nomeUtente").data('value') && event.title == 'Normali' && event.title == 'Straordinarie') showEvent = false; */
                        
                        return showEvent;
                        /* var view = $('#calendar').fullCalendar('getView');
                        alert("The view's title is " + view.title + view); */
                    }
                    
                };
                $('input[name=calendario]').on('change',function(){
                    $('#calendar').fullCalendar('rerenderEvents');
                })
                
                var _options = void 0;
                var myOptionsMobile = Object.assign({}, myOptions);

                myOptionsMobile.aspectRatio = 0.5;
                _options = $(window).outerWidth() < 667 ? myOptionsMobile : myOptions;

                $('#editNewEvent').modal();
                $('#calendar').fullCalendar(_options);
            }
        }
      
        ]);
        return AppCalendar;
    }   
    (_Site3.default);
    var instance = null;
    function getInstance() {
        if (!instance) {
            instance = new AppCalendar();
        }
        return instance;
    }

    function run() {
        var app = getInstance();
        app.run();
    }

    exports.AppCalendar = AppCalendar;
    exports.run = run;
    exports.getInstance = getInstance;
    exports.default = AppCalendar;
  
});

function getEvents(year, month) {
    var date = new Date();
    var firstDay = new Date(date.getFullYear(), date.getMonth(), 1);
    var lastDay = new Date(date.getFullYear(), date.getMonth() + 1, 0);
    
    var currentEvents = $('#calendar').fullCalendar('clientEvents').filter(event => (new Date(event.start) >= firstDay && new Date(event.end) <= lastDay));
    
    for(i=0; i<currentEvents.length; i++) {
        console.log(currentEvents[i].title);
    }
}
Mike Irving
  • 1,480
  • 1
  • 12
  • 20
  • I add this code to what i wrote before, put the function in a button by onClick (maybe i did wrong, could be, i'm a noobie). but when i click on it it says "GetEvents is not defined". I actually thinks this code could help me, but i dont know what i did wrong – aim0d Mar 31 '22 at 11:57
  • @nano `GetEvents` is not the same as `getEvents`. JavaScript is case-sensitive. – ADyson Mar 31 '22 at 12:51
  • Oh, i wrote it with caps here, but in my code it's written "getEvents" – aim0d Mar 31 '22 at 12:53
  • can you share your full code @nano? `getEvents()` needs to be called after the function definition is made, and after the FullCalendar is rendered. – Mike Irving Mar 31 '22 at 13:03
  • My calendar.js i guess. I have to warned you, it is a template i'm using so it was already build, i'm just modifing the stuff i need – aim0d Mar 31 '22 at 13:12
  • Do you also need my calendar principal page? – aim0d Mar 31 '22 at 13:19
  • your `function getEvents() { ... }` code is nested within your FullCalendar setup code @nano. Move it out to the end of your script file, then run `getEvents();` in the console and it should work. – Mike Irving Mar 31 '22 at 13:52
  • I tried, it breaks my page showing just a black screen and saying "AppCalendar is not defined" and " missing : after property id" in the `function getEvents(year, month){` line – aim0d Mar 31 '22 at 14:15
  • Please change your full calendar.js for that now at the bottom of my answer @nano. – Mike Irving Mar 31 '22 at 15:21
  • I change the code – aim0d Mar 31 '22 at 15:27
  • If you copy your updated calendar.js to your question, I will update the one in my answer @nano – Mike Irving Mar 31 '22 at 15:52