Search code examples
djangodjango-modelsdjango-adminfullcalendar-3

Using full calendar in django admin; Saving the external dragged item to a model


i have set up fullcalendar inside my admin, so i can drag timeslot on the calendar to select which date/timeslots are available for my clients to book, the calendar work perfectly, the drag items are fine, but when i put them in the calendar, it doesnt save to my model and to database.

here is the code.

model:

class Event(models.Model):
    event_name = models.CharField(max_length=255,null=True,blank=True)
    start = models.DateTimeField(null=True,blank=True)
    end = models.DateTimeField(null=True,blank=True)
    available = models.BooleanField(default=True)
    patient_name = models.CharField(max_length=60, null=True, blank=True)
    phone_number = PhoneNumberField(blank=True,null=True)

    def __unicode__(self):
        return self.event_name

html

<script>
    $(function () {

        // initialize the external events
        // -----------------------------------------------------------------

        $('#external-events .fc-event').each(function () {

            // store data so the calendar knows to render an event upon drop
            $(this).data('event', {
                title: $.trim($(this).text()), // use the element's text as the event title
                stick: true // maintain when user navigates (see docs on the renderEvent method)
            });

            // make the event draggable using jQuery UI
            $(this).draggable({
                zIndex: 999,
                revert: true, // will cause the event to go back to its
                revertDuration: 0 //  original position after the drag
            });

        });

        // initialize the calendar
        // -----------------------------------------------------------------
        $('#calendar').fullCalendar({
            eventDrop: function (event, dayDelta, minuteDelta) {
                saveMyData(event);
            },
            eventLimit: true, // for all non-agenda views
                views: {
                    agenda: {
                        eventLimit: 5 // adjust to 5 only for agendaWeek/agendaDay
                    }
                },
            buttonIcons: {
                prev: 'fa-chevron-left',
                next: 'fa-chevron-right',
            },
            themeSystem: 'bootstrap4',
            header: {
                left: false,
                center: 'title',
                right: 'prev,next today',
            },
            editable: true,
            droppable: true, // this allows things to be dropped onto the calendar
            //drop: function () {
                // is the "remove after drop" checkbox checked?
            //  if ($('#drop-remove').is(':checked')) {
                    // if so, remove the element from the "Draggable Events" list
            //      $(this).remove();
            //  }
            //}
        });

    });
</script>

<style>
    html,
    body {
        margin: 0;
        padding: 0;
        font-family: "Lucida Grande", Helvetica, Arial, Verdana, sans-serif;
        font-size: 14px;
    }

    #external-events {
        width: 150px;
        padding: 0 10px;
        border: 1px solid #ccc;
        background: #eee;
    }

    #external-events .fc-event {
        margin: 1em 0;
        cursor: move;
    }

    #calendar {
        max-width: 900px;
        margin: 20px auto;
    }
</style>
{% endblock %}

<div class="container">
    <div class="row calendar-row">
        <div class="col-sm-10">
            <div id='calendar-container'>
                <div id='calendar' class="fc fc-bootstrap4 fc-ltr"></div>
            </div>
        </div>
        <div class="col-sm-2">
            <div id='external-events'>
                <p>
                    <strong>Draggable Events</strong>
                </p>
                <div class="row style='z-index : 1;'">
                    <div class="col-sm-6">
                        <div class='fc-event' data-event='1' time = '08:30' data-duration='00:30'>08:30 – 09:00</div>
                        <div class='fc-event' data-event='1' time = '09:00' data-duration='00:30'>09:00 – 09:30</div>
                        <div class='fc-event' data-event='1' time = '09:30' data-duration='00:30'>09:30 – 10:00</div>
                        <div class='fc-event' data-event='1' time = '10:00' data-duration='00:30'>10:00 – 10:30</div>
                        <div class='fc-event' data-event='1' time = '10:30' data-duration='00:30'>10:30 – 11:00</div>
                        <div class='fc-event' data-event='1' time = '11:00' data-duration='00:30'>11:00 – 11:30</div>
                        <div class='fc-event' data-event='1' time = '11:30' data-duration='00:30'>11:30 – 12:00</div>
                        <div class='fc-event' data-event='1' time = '12:00' data-duration='00:30'>12:00 – 12:30</div>
                        <div class='fc-event' data-event='1' time = '12:30' data-duration='00:30'>12:30 – 13:00</div>
                        <div class='fc-event' data-event='1' time = '13:00' data-duration='00:30'>13:00 – 13:30</div>
                        <div class='fc-event' data-event='1' time = '13:30' data-duration='00:30'>13:30 – 14:00</div>
                        <div class='fc-event' data-event='1' time = '14:00' data-duration='00:30'>14:00 – 14:30</div>
                        <div class='fc-event' data-event='1' time = '14:30' data-duration='00:30'>14:30 – 15:00</div>
                    </div>
                    <div class="col-sm-6">
                        <div class='fc-event' data-event='1' time = '15:00' data-duration='00:30'>15:00 – 15:30</div>
                        <div class='fc-event' data-event='1' time = '15:30' data-duration='00:30'>15:30 – 16:00</div>
                        <div class='fc-event' data-event='1' time = '16:00' data-duration='00:30'>16:00 – 16:30</div>
                        <div class='fc-event' data-event='1' time = '16:30' data-duration='00:30'>16:30 – 17:00</div>
                        <div class='fc-event' data-event='1' time = '17:00' data-duration='00:30'>17:00 – 17:3</div>
                        <div class='fc-event' data-event='1' time = '17:30' data-duration='00:30'>17:30 – 18:00</div>
                        <div class='fc-event' data-event='1' time = '18:00' data-duration='00:30'>18:00 – 18:30</div>
                        <div class='fc-event' data-event='1' time = '18:30' data-duration='00:30'>18:30 – 19:00</div>
                        <div class='fc-event' data-event='1' time = '19:00' data-duration='00:30'>19:00 – 19:30</div>
                        <div class='fc-event' data-event='1' time = '19:30' data-duration='00:30'>19:30 – 20:00</div>
                        <div class='fc-event' data-event='1' time = '20:00' data-duration='00:30'>20:00 – 20:30</div>
                        <div class='fc-event' data-event='1' time = '20:30' data-duration='00:30'>20:30 – 21:00</div>

                    </div>

so i want to drag and drop a time on a date, and it to save to the model i read the fullcalendar docs about the json and things like that but i dont know how to do it, is there a simple way to just do it trought the model and db or maybe using serialize as json?

ej. i drag the timeslot 12:00 - 12:30 on the 01/septembre/2018, then in the db+admin, i get a new object event_name/2018-09-01T05:12:00:00/2018-09-01T05:12:30:00/null/null/null (as the 3 last field will be modified by hand)


Solution

  • According to the code you shared and to the discussion in the comments, it seems the problem resides on the following lines:

    eventDrop: function (event, dayDelta, minuteDelta) {
        saveMyData(event);
    },
    

    saveMyData is not performing its job. One possible implementation would be to make an Ajax request using Jquery (given the code you provided it seems you are using it). So the eventDrop function would look like something similar to this:

    eventDrop: function (event, dayDelta, minuteDelta) {
        // Gather the required data event, dayDelta, minuteDelta, or other
        data = {
            // and put it here
            ...,
            "csrfmiddlewaretoken": "<something" // You will also need to gather the CSRF token 
        }
    
        $.post( "/admin/<your_app>/event/add", data, function( data ) {
            // Your code when the request succeeds 
        }).fail(function() {
            // Your code when something fails
        });
    },
    

    You can read more about the jquery ajax requests here