Angularjs fullcalendar drag drop - get value of dropped object

1.7k Views Asked by At

I am dropping an external object into angular-ui-calendar using angular-dragdrop.

The external object is coming from this list:

<div class="fc-event" data-drag="true"
     jqyoui-draggable="{animate:true}"
     ng-model="test_object"
     ng-repeat="test_object in test_objects">
  Draggable - {{ test_object.name }} 
</div>

The fullcalendar is set up with:

<div id="ApptsCalendar" calendar="ApptsCalendar"
     ui-calendar="calendarOptions.calendar"
     ng-model="eventSources" data-drop="true"
     jqyoui-droppable="{multiple:true, onDrop: 'drop_function'}"
     data-jqyoui-options>
</div>

When dropped, I can process that event using fullcalendar 'drop' method with:

$scope.calendarOptions = {
    calendar: {
        editable: true,
        droppable: true,
        drop: function(date,jsEvent,ui,resourceId){
            console.log("Dropped from calendarOptions")
            console.log(resourceId);
            $scope.eventSources[0].push({
                id:5,
                title: 'dropped event (fake)',
                start:  date
            });     
        }
    }
};

or from the angular-dragdrop 'onDrop' callback to call a 'drop' function:

jqyoui-droppable="{multiple:true, onDrop: 'drop'}"

Both can trigger when I want, but neither seem to have the two pieces I need. I need to have the object value being dropped (defined in ng-model) and the date being dropped into.

Basically, I want to push the event to the the eventSources with:

$scope.eventSources[0].push({
    id:5,
    title: '...name of object...',
    start:  '...date of target dropped on...'
});

http://plnkr.co/edit/fj858Htb2FRUg5h1pucP?p=preview

3

There are 3 best solutions below

1
On BEST ANSWER

Well, one of the things you wanted is already there. It's date on which the event is dropped. You get it from the first argument of the drop function. It's a moment object (according to the docs) so you might want to use .toDate() in order to get the JS Date object.

The other thing is the value of the event which got dropped. According to the same docs page, the DOM object of the event is accessible using this inside drop function.

Now, this is a bit unconventional way (I don't see many choices here), what you can do is, with the ng-repeat iterating over event objects, you can keep an attribute with value from each object which can later be accessed inside the drop function. For example, see how I added customEventName="{{test_object.name}}" in here:

<div class="fc-event tech_draggable" data-drag="true" id="{{test_object.name}}" 
     customEventName="{{test_object.name}}" jqyoui-draggable="{animate:true}" 
     ng-model="test_object" ng-repeat="test_object in test_objects" ...>
    Draggable - {{ test_object.name }}
</div>

Then, in the drop function, that can be accessed using this.getAttribute('customEventName') like this:

$scope.calendarOptions = {
  calendar: {
    editable: true,
    droppable: true,
    drop: function(momentDate, jsEvent, ui, resourceId) {
      console.log(momentDate.toDate()) // gives JS Date object
      console.log(this.getAttribute('customEventName')); // gives event2/event3 etc.
      //... more
    }
  }
};
0
On

After some more research, I think fullcalendar has the solution already.

I can use data-event attribute in the element:

data-event='{"title":"{{ test_object.name }}"}'

With that, there is no need to even have a 'drop' function... fullcalendar natively supports drag and drop.

I can then optionally use eventReceive to handle a drop from an external resource and use eventDrop to handle an internal event move.

http://plnkr.co/edit/fj858Htb2FRUg5h1pucP?p=preview

0
On

An alternative is to make an attribute with a string representing the scope variable name:

<div ng-repeat="test_object in test_objects">
  <div class="fc-event tech_draggable" 
       data-drag="true" 
       jqyoui-draggable="{animate:true}" 
       ng-repeat="test_object in test_objects" 
       style="margin-bottom:1px;" 
       data-jqyoui-options="{helper: 'clone'}"
       scope-data-name="test_objects[{{$index}}]"
   >
    Draggable - {{ test_object.name }}
  </div>
</div>

And using $scope.$eval to get the actual object:

$scope.calendarOptions = {
    calendar: {
        editable: true,
        droppable: true,
        drop: function(date,jsEvent,ui,resourceId){
            var scopeDataName = this.getAttribute('scope-data-name');
            var data = $scope.$eval(scopeDataName);
            $scope.eventSources[1].push({ 
                id: $scope.eventSources[0].length, 
                title: `${data.name} ${data.description}`,
                start: date
            }); 
        }
    }
};

The DEMO on PLNKR