David Dsr
David Dsr

Reputation: 347

Updating events in client side with Javascript

I would like to know if there is anyway to update a Fullcalendar event in Javascript without having to reload the page, just by clicking a link with role button. When I click on the link 'Save' the event is updated in the server side but not in the client side, and I need the event to be updated in both sides.

What I'm trying to do is edit the events of a Fullcalendar opening a modal form through eventClick.

This is the code of my javascript

function drawControl(controls) {

        $('#calendar').fullCalendar({
            editable: true,
            aspectRatio: 1,
            contentHeight: 500,
            scrollTime: '24:00:00',
            minTime: '01:00:00',
            maxTime: '24:00:00',
            defaultView: 'agendaWeek',
            header:{left:"prev,next,today",
            center:"title",
            right:"month, agendaWeek, agendaDay"},


            events: allControls(controls), 

            eventRender: function(event, element) {

                var bloodLevel=event.title

                if(bloodLevel >= 180) {
                    element.css('background-color', 'red');
                }
                else if(bloodLevel < 70) {
                    element.css('background-color', 'yellow');
                }
            },
            eventClick: function(calEvent, jsEvent, view) {
                    x=calEvent.id;
                $('#modalTitle').html(calEvent.title);
                $('#control_day_edit').val(moment(calEvent.start._i).format("DD-MM-YYYY hh:mm A/PM"));
                $('#control_level').val(calEvent.title.toString());
                    console.log(calEvent)
                    console.log(calEvent.title)
                    console.log(calEvent.start._i)
                    console.log(calEvent.id)
                $('#eventUrl').attr('href',"/users/:user_id/controls/calEvent.id/edit");
                $('#fullCalModal').modal();
                y=calEvent;

            }
})
}

});

document.getElementById('button_edit').addEventListener("click", editControl);

 function editControl(event) {
     event.preventDefault();
     console.log(y);
     console.log(x);
     var controlEdited = {
         "level": document.getElementById('control_level').value,
         "day": document.getElementById('control_day_edit').value,
         "period": document.getElementById('control_period').value,
         "id": x
    }
    $.post("/editControls", JSON.stringify(controlEdited));
    y.title = document.getElementById('control_level').value;
    y.start = moment(document.getElementById('control_day_edit').value);
    console.log(y.start);
    console.log(y);
    $('#calendar').fullCalendar('updateEvent', y);
};

Upvotes: 2

Views: 7920

Answers (1)

Michbeckable
Michbeckable

Reputation: 1891

The problem I see from your code, is that you store y=calEvent but you DO NOT change the properties of this event directly. You have to do a manipulation on the start moment object like y.start.add(1, 'minute'); and then notify fullCalendar of the change with the updateEvent function.

Generally you have two options for updating events:

  1. Refetch events in the fullCalendar EventSource.
  2. Update the modified event directly.

The first option is brute force. FullCalendar offers the method .fullCalendar( 'refetchEvents' ) which fetches ALL events from ALL sources of the underlying fullCalendar. A possible implementation is to provide events in a source that accesses the sever via JSON feed, or an event generating function that can make a request to the server as well. First store the event changes on the server side and than refetch events.

The second option is more direct. Basically you can handle changes in the eventClick function like this:

eventClick = function(event, jsEvent, view) { 

    event.start.add(1, 'days'); // modify   

    // ... store server side

    $('#calendar').fullCalendar('updateEvent', event); // notify change                         
}

You can change the event in any way you want. But you have to keep either the event object or the event id to notify fullCalendar update later. Easiest way is to keep the event object. Create an object representing the modal dialog and give the event object as parameter to it. You do not know when editing in the modal is done (by the user) so provide a callback mechanism that stores the changed event on server side and updates it in fullCalendar:

eventClick = function(event, jsEvent, view) { 

    var myModal = new Modal(event, event.title, ...); // modify 
    var editWaitFor = myModal.getEditWaitFor();  // give a callback mechanism e.g. jQuery Deferred
    myModal.modal();

    $.when(editWaitFor).then(function() {        // wait for editing

        // ... store in database etc. 
        StoreServerSide(event, ...);    // store and maybe validate

        $('#calendar').fullCalendar('updateEvent', event); // notify change                                                         

    }, function() {
        event.Revert(); // edit not successful, or no change
    });             
}

I think your approach should be more object oriented. Give the event to your modal and change it there. Then store the change on server side and may be validate the change before storing it. Afterwards notify the fullCalendar. I would avoid storing values with jQuery by #id and getting them later with document.getElementById - just encapsulate needed data in objects and work with this objects.

FullCalendar.js gives you a basic javascript prototype for a dialog, that it uses to show all events after a click on the "more events" link:

function Popover(options) {
    this.options = options || {};
}

Search for this in the fullCalendar.js to see the full prototype specs. You can extend this to give a dialog for editing.

Upvotes: 2

Related Questions