2

I'm trying to use fullcalendar with external events. I followed the example with external events that are dragged and dropped. That's exactly what I need and the example is ok: I'm able to drag external events and drop it on the calendar. They're converted into events. But the problem is they all are 60 minutes long. I'd like to change this value but I couldn't find how to do it.

I found a lot of examples of setting durations but it's always for events and not for external drag and drop events.

Could you please help me?

Thanks

Here's my code :

document.addEventListener('DOMContentLoaded', () => {
var Draggable = FullCalendarInteraction.Draggable;

// The calendar
var calendarEl = document.getElementById('calendar-holder');
// The div containing the draggable items
var draggableEl = document.getElementById('external-events');

var calendar = new FullCalendar.Calendar(calendarEl, {
    schedulerLicenseKey: 'GPL-My-Project-Is-Open-Source',
    defaultView: 'timeGridWeek',
    editable: true,
    eventSources: [
        {
            url: "{{ path('fc_load_events') }}",
            method: "POST",
            extraParams: {
                filters: JSON.stringify({})
            },
            failure: () => {
                // alert("There was an error while fetching FullCalendar!");
            },
        },
    ],
    header: {
        left: 'prev,next today',
        center: 'title',
        //right: 'dayGridMonth,timeGridWeek,timeGridDay',
    },
    plugins: [ 'interaction', 'dayGrid', 'timeGrid' ], // https://fullcalendar.io/docs/plugin-index
    timeZone: 'UTC',
    droppable: true,
    drop: function(info) {
        info.allDay = false;
    }
});
new Draggable(draggableEl, {
    itemSelector: '.fc-event',
    eventData: function(eventEl) {
        return {
            title: eventEl.innerText,
            defaultTimedEventDuration: '03:00'
        };
    }
});

calendar.render();
new Draggable(draggableEl);

});


OK so after Adyson's answer I was able to understand and make it work a bit. I was able to retrive the duration from my item number 1 and apply this duration to the drag and dropped event. But I still have an issue because I'm only able to retrieve the information with the getDocumentById. I'm not able to retrieve anything from eventEl parameter. Here's what I did :

I added some ids to the divs, as well as some attributes, like this :

<div class="fc-event" id="event1" data-event='{ "title": "event 1", "duration": "05:00" }'>My Event 1</div>
            <div class="fc-event" id="event2" data-event='{ "title": "event 2", "duration": "03:00" }'>My Event 2</div>
            <div class="fc-event" id="event3" data-event='{ "title": "event 3", "duration": "01:00" }'>My Event 3</div>
            <div class="fc-event" id="event4" data-event='{ "title": "event 4", "duration": "02:00" }'>My Event 4</div>
            <div class="fc-event" id="event5" data-event='{ "title": "event 5", "duration": "04:00" }'>My Event 5</div>

And then I'd like to retrieve the informations but I was not able. The only thing I could do was :

                    new Draggable(containerEl, {
                    itemSelector: '.fc-event',
                    eventData: function(eventEl) {
                        var event1 = document.getElementById('event1');
                        var json_event = event1.getAttribute("data-event");
                        var event_array = JSON.parse(json_event);
                        var duration = event_array['duration'];
                        var event_title = event_array['title'];
                        return {
                            title: event_title, //eventEl.innerText,
                            duration: duration,
                        };
                    }
                });

So as you can see I'm only able to retrive a given information (first item in this case) but not the one that's being dragged and dropped.

As you can see I followed what you said and it's working great, because the event get the values that were set in the div. But here it's always div 1 because I don't know how to do.

I tried eventEl.attr('id'), (eventEl.data) but each time I'm getting an error (undefined). Could you please help me and tell me how i can get for example the value of the div id from the eventE1 ? Thanks a lot ! I'm almost there thanks to you !

user2449253
  • 103
  • 2
  • 13
  • Change this value: https://fullcalendar.io/docs/defaultTimedEventDuration – ADyson Apr 01 '20 at 07:22
  • Thanks but it's nor working... Maybe I placed it at the wrong place ? I'm going to try and copy / paste my code. – user2449253 Apr 01 '20 at 09:24
  • defaultTimedEventDuration is an option of the calendar, not the Draggable or the event. So you add it with all the other options like defaultView, editable, etc etc. – ADyson Apr 01 '20 at 09:37
  • Yes you're right, thanks, it's working now ! But I was willing to set different durations according on the events. For now I'm testing with one event that I4m drag and dropping but the next steps is to have several divs with different labels and different durations... How can I do then ? – user2449253 Apr 01 '20 at 10:38
  • I haven't tried this before but I suspect an approach like this might work: 1) put some custom property onto the `eventData` in the draggable object which tells it what the desired duration is. 2) handle the [eventReceive](https://fullcalendar.io/docs/eventReceive) callback which gives you access to the data of the dropped event. You could then access the custom property to determine the duration, and use it to update the end date of the event to where you want it. – ADyson Apr 01 '20 at 10:57
  • I wanted to post some code but it was deleted... I followed what you said but there's something I can't figure out. Without showing code it will be hard to explain... I have something like eventData: function(eventEl) {... and I don't know how to retrieve the div id from eventE1... Could you please help ? – user2449253 Apr 01 '20 at 18:35
  • What you added was deleted because you added it to the Answers section, and it's not an answer to the question. If you want to provide more info, please update your original question text. There is an "edit" button just underneath your post which allows to to update it. – ADyson Apr 01 '20 at 18:57
  • Ok got it. So I just edited my first post, but find it quite strange... Anyway, I tried to make it reusable for other people. – user2449253 Apr 01 '20 at 19:32
  • 1
    Thanks for the edit. Now, you say "as you can see I'm only able to retrive a given information (first item in this case) but not the one that's being dragged and dropped.". The event is given to you via `eventEl`. So instead of declaring `event1` and then writing `event1.getAttribute`...just write `eventEl.getAttribute` instead! – ADyson Apr 01 '20 at 22:07
  • 1
    Demo: https://codepen.io/ADyson82/pen/vYOMLmm?editors=1010 – ADyson Apr 01 '20 at 22:12
  • Thanks a lot ! I had tried .attr, .srcElement and other methods I found while googling but I hadn't tried .getAttribute !! That's exactly what was missing.Thank you very much for your help. Now I'm supposed to post the full answer to my question below ? Or isn'tit necessary ? I guess your demo contains everything :) – user2449253 Apr 02 '20 at 07:15
  • .attr is a [jQuery function](https://api.jquery.com/attr/) so it only works on jQuery objects. The equivalent native JS function is getAttribute. You had that bit right, you were just calling it on the wrong element! If you have the full solution now, you can post it below for others who might find it helpful. Then you can get upvotes for it as well. I don't mind, I gave you the idea, but you went and implemented it fully. – ADyson Apr 02 '20 at 07:34
  • I just wanted to know what to do so that other people get help and I'm not aware of good practive here :) So I'll keep it as it is, i think your demo explains it all :) I have another questions about event.moveEnd method but I don't know if I shall post it here or create a new thread. What do you think ? – user2449253 Apr 02 '20 at 07:52
  • if you have a different question you should create a new "Question" post, so more people will see it, and will be clearer and easier to follow. (Actually, asking about multiple topics in one question is considered explicitly off-topic.) – ADyson Apr 02 '20 at 08:18
  • "I'll keep it as it is,"....I disagree. Without an accepted answer, your question will not show up very often in search results, so people are far less likely to see either your work or my demo. Questions with recognised answers rate much more highly in searches. You should make an answer. If you don't want to, I will, but I think you deserve the credit really as you actually wrote 90% of the code. – ADyson Apr 02 '20 at 08:18
  • ok then, I will post the answer – user2449253 Apr 02 '20 at 08:42

1 Answers1

5

Thanks to @ADyson I was able to figure it out.

So here's the code of the external divs :

  <div id="external-events">
<p>
  <strong>Draggable Events</strong>
</p>
<div class="fc-event" id="event1" data-event='{ "title": "event 1 custom title", "duration": "05:00", "color": "#f00" }'>My Event 1</div>
<div class="fc-event" id="event2" data-event='{ "title": "event 2 other title", "duration": "03:00", "color": "#0f0" }'>My Event 2</div>
<div class="fc-event" id="event3" data-event='{ "title": "event 3 !!", "duration": "01:00", "color": "#00f" }'>My Event 3</div>
<div class="fc-event" id="event4" data-event='{ "title": "event 4 OOOH", "duration": "02:00", "color": "#ff0" }'>My Event 4</div>
<div class="fc-event" id="event5" data-event='{ "title": "event 5 YES", "duration": "04:00", "color": "#0ff" }'>My Event 5</div>
</div>

As you can see I added other attributes to be able to set custom title and color.

And here's the code for the draggable part :

    new Draggable(containerEl, {
  itemSelector: '.fc-event',
  eventData: function(eventEl) {
        var json_event = eventEl.getAttribute("data-event");
        var event_array = JSON.parse(json_event);
        var event_duration = event_array['duration'];
        var event_title = event_array['title'];
        var event_color = event_array['color'];

        return {
            title: event_title,
            duration: event_duration,
            backgroundColor: event_color,
        };
    }
});

data-event contains all the attributes and it's retrived with getAttribute method.

Thanks a lot @Adyson, I'd been struggling for days !

user2449253
  • 103
  • 2
  • 13