5

I'm using Fullcalendar (http://arshaw.com/fullcalendar) in my project. It gets events via json source.

I want to give the user option to copy one event on the calendar to other day - and I'd like to use dragging for that (well, that's the client's requirement).

But dragging seems like moving an event, not copying - is there any way to get the "copy" of an event being dragged (or copy stay in original place), so it looks like a copy operation?

I tried to copy event object in eventDragStart callback, but it didn't work.

kender
  • 85,663
  • 26
  • 103
  • 145

5 Answers5

7

Below is my solution that allows the user to hold shift key to copy events. Note that this is actually moving the original event and leaving a copy in the original position.

I started with this reference and created the following:

//Before the fullCalendar object

    var copyKey = false;
    $(document).keydown(function (e) {
        copyKey = e.shiftKey;
    }).keyup(function () {
        copyKey = false;
    });

//then inside the fullCalendar object

    eventDragStart: function (event, jsEvent, ui, view) {
        if (!copyKey) return;
        var eClone = {
            title: event.title,
            start: event.start,
            end: event.end
        };
        $('#calendar').fullCalendar('renderEvent', eClone);
    },
Pete
  • 2,393
  • 2
  • 24
  • 31
2

Try this:

eventDrop: function(event, dayDelta, minuteDelta, allDay, revertFunc, jsEvent, ui, view) {
    // Create an event object and copy at least the start date and the title from event
     var eventClone = {
         title:event.title,
         start: event.start,
         end: event.end
     };

     // Render new event with new event object
     $('#calendar').fullCalendar('renderEvent', eventClone);

     // Revert the changes in parent event. To move it back to original position
     revertFunc();
}

This is just the idea. I haven't tested this code. Please let me know how it works. Thanks

Adil Malik
  • 6,279
  • 7
  • 48
  • 77
  • You might have to use the [clone method](http://stackoverflow.com/questions/122102/what-is-the-most-efficient-way-to-clone-a-javascript-object) to create deep copies of start and end dates. But do not clone the entire event object. Because it contain _id (the id assigned by fullCalendar to each event) that might cause problems. – Adil Malik Apr 26 '12 at 13:51
2

I realise this is an old question however I found it through a search engine so the solution I ended up with could be useful to others.

I took a slightly different approach and used jQuery UI Draggable, the same way external events are set up.

An event is copied when the user drags an event with the ctrl key held down, this leaves the original event in place and creates a new event where the jQuery draggable is dropped.

  // used to track whether the user is holding the control key
  let ctrlIsPressed = false;

  function setEventsCopyable(isCopyable) {
    ctrlIsPressed = !ctrlIsPressed;
    $("#calendar").fullCalendar("option", "eventStartEditable", !isCopyable);
    $(".fc-event").draggable("option", "disabled", !isCopyable);
  }

  // set events copyable if the user is holding the control key
  $(document).keydown(function(e) {
    if (e.ctrlKey && !ctrlIsPressed) {
      setEventsCopyable(true);
    }
  });

  // if control has been released stop events being copyable
  $(document).keyup(function(e) {
    if (ctrlIsPressed) {
      setEventsCopyable(false);
    }
  });

  $("#calendar").fullCalendar({
    defaultView: "basicWeek",
    events: [
      {
        title: "Event 1",
        start: moment(),
        end: moment().add(1, "d")
      },
      {
        title: "Event 2",
        start: moment().add(1, "d"),
        end: moment().add(2, "d")
      }
    ],
    editable: true,
    droppable: true,
    eventAfterAllRender(event, element, view) {
      // make all events draggable but disable dragging
      $(".fc-event").each(function() {
        const $event = $(this);

        // store data so the calendar knows to render an event upon drop
        const event = $event.data("fcSeg").footprint.eventDef;
        $event.data("event", event);

        // make the event draggable using jQuery UI
        $event.draggable({
          disabled: true,
          helper: "clone",
          revert: true,
          revertDuration: 0,
          zIndex: 999,
          stop(event, ui) {
            // when dragging of a copied event stops we must set them
            // copyable again if the control key is still held down
            if (ctrlIsPressed) {
              setEventsCopyable(true);
            }
          }
        });
      });
    }
  });

Working Codepen.

Ally Murray
  • 599
  • 1
  • 6
  • 16
1

I managed to get around this with help of above answers :

eventDrop: function (event, delta, revertFunc) {  
                if (copyKey) {
                    var eClone = {
                        title: event.title,
                        start: event.start,
                        end: event.end,
                        id: createGuid(),
                        playlistId: event.playlistId,
                        volume: event.volume,
                        backgroundColor: event.backgroundColor,
                        allDay: false
                    }; 
                    $('#calendar').fullCalendar('renderEvent', eClone, true);

                    revertFunc();
                } 
            },
Karan Bir
  • 351
  • 4
  • 13
0

I know this is an old question, but the results I've found through my search may be useful for others

I don't know if it's possible to fix your source.

within fullcalendar.js of dragListener In the dragStart function, we see that view.hideEventsWithId(seg.footprint.eventDef.id) is a function that removes the original.

Comment it out and it will work as you want.

snieguu
  • 2,073
  • 2
  • 20
  • 39