简体   繁体   English

如何通过 FullCalendar 中的选项卡菜单将事件拖到另一个日历

[英]How to drag event to another calendar by tab menu in FullCalendar

I have a some calendars in tab container and switching by nav menu.我在标签容器中有一些日历并通过导航菜单切换。 And I would like drag event to another calendar by nav menu and when I dragging event and when nav menu switching I am losing event and getting error "Cannot read property 'isWithinClipping' of undefined".我想通过导航菜单将事件拖动到另一个日历,当我拖动事件和导航菜单切换时,我丢失事件并收到错误“无法读取未定义的属性‘isWithinClipping’”。 And when I returning to old tab I see event clone in the upper corner.当我返回旧选项卡时,我会在上角看到事件克隆。 html: html:

<div id='container'>
  <ul class="nav nav-tabs" id="myTab" role="tablist">
  <li class="nav-item" role="presentation">
    <a class="nav-link active" id="home-tab" data-toggle="tab" href="#home" role="tab" aria-controls="home" aria-selected="true">calendar 1</a>
  </li>
  <li class="nav-item" role="presentation">
    <a class="nav-link" id="profile-tab" data-toggle="tab" href="#profile" role="tab" aria-controls="profile" aria-selected="false">calendar 2</a>
  </li>
</ul>
<div class="tab-content" id="myTabContent">
  <div class="tab-pane fade show active" id="home" role="tabpanel" aria-labelledby="home-tab">
    <div id='source-calendar'></div>
  </div>
  <div class="tab-pane fade" id="profile" role="tabpanel" aria-labelledby="profile-tab">
    <div id='destination-calendar'></div>
  </div>
</div>
</div>

js code: js代码:

var srcCalendarEl = document.getElementById('source-calendar');
  var destCalendarEl = document.getElementById('destination-calendar');

  var srcCalendar = new FullCalendar.Calendar(srcCalendarEl, {
    editable: true,
    droppable: true,
    initialDate: '2020-09-12',
    events: 'https://fullcalendar.io/demo-events.json?overload-day',
    eventLeave: function(info) {
      console.log('event left!');
    }
  });

  var destCalendar = new FullCalendar.Calendar(destCalendarEl, {
    initialDate: '2020-09-12',
    editable: true,
    droppable: true, // will let it receive events!
    eventReceive: function(info) {
      console.log('event received!');
    }
  });

document.addEventListener('DOMContentLoaded', function() {
  srcCalendar.render();
  destCalendar.render();
});
  

$('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
  srcCalendar.render();
  destCalendar.render();
});

$(".nav-link").on('mouseenter', function(e){
$(this).tab('show');
})

jsfiddle提琴手

So, any body tell me how to drag event to another calendar by tab menu in FullCalendar?那么,有没有人告诉我如何通过 FullCalendar 中的选项卡菜单将事件拖动到另一个日历? Any ideas please.请有任何想法。

So, I found solution for my task, for this I chainged source code of FullCalendar (it was so difficult).所以,我为我的任务找到了解决方案,为此我链接了 FullCalendar 的源代码(这太难了)。 Need to do for first the event mirror clone must create before document body in ElementMirror class at getMirrorEl method需要首先在 getMirrorEl 方法的 ElementMirror 类中的文档主体之前创建事件镜像克隆

ElementMirror.prototype.getMirrorEl = function () {
    var sourceElRect = this.sourceElRect;
    var mirrorEl = this.mirrorEl;
    if (!mirrorEl) {
        mirrorEl = this.mirrorEl = this.sourceEl.cloneNode(true); // cloneChildren=true
        // we don't want long taps or any mouse interaction causing selection/menus.
        // would use preventSelection(), but that prevents selectstart, causing problems.
        mirrorEl.classList.add('fc-unselectable');
        mirrorEl.classList.add('fc-dragging');
        applyStyle(mirrorEl, {
            position: 'fixed',
            zIndex: this.zIndex,
            visibility: '',
            boxSizing: 'border-box',
            width: sourceElRect.right - sourceElRect.left,
            height: sourceElRect.bottom - sourceElRect.top,
            right: 'auto',
            bottom: 'auto',
            margin: 0
        });
        //this.parentNode.appendChild(mirrorEl);
        document.body.appendChild(mirrorEl); // I don't no why not event clone realy create before body?
    }
    return mirrorEl;
}

For second: when event dragging to another calendar by tab menu fullCalendar rerendering for this reason HitDragging class getting new droppableStore list but not updating offsetTrackers list.第二:当事件通过选项卡菜单 fullCalendar 重新呈现时拖动到另一个日历时,HitDragging 类获取新的 droppableStore 列表但不更新 offsetTrackers 列表。 For solution I just calling method this.prepareHits();对于解决方案,我只是调用方法 this.prepareHits(); for update:更新:

HitDragging.prototype.queryHitForOffset = function (offsetLeft, offsetTop) {
    this.prepareHits(); // for update offsetTrackers list
    var _a = this, droppableStore = _a.droppableStore, offsetTrackers = _a.offsetTrackers;
    var bestHit = null;
    for (var id in droppableStore) {
        var component = droppableStore[id].component;
        var offsetTracker = offsetTrackers[id];
        if (offsetTracker.isWithinClipping(offsetLeft, offsetTop)) {
            var originLeft = offsetTracker.computeLeft();
            var originTop = offsetTracker.computeTop();
            var positionLeft = offsetLeft - originLeft;
            var positionTop = offsetTop - originTop;
            var origRect = offsetTracker.origRect;
            var width = origRect.right - origRect.left;
            var height = origRect.bottom - origRect.top;
            if (
            // must be within the element's bounds
            positionLeft >= 0 && positionLeft < width &&
                positionTop >= 0 && positionTop < height) {
                var hit = component.queryHit(positionLeft, positionTop, width, height);
                console.log('hit', hit)
                if (hit &&
                    (
                    // make sure the hit is within activeRange, meaning it's not a deal cell
                    !component.props.dateProfile || // hack for DayTile
                        rangeContainsRange(component.props.dateProfile.activeRange, hit.dateSpan.range)) &&
                    (!bestHit || hit.layer > bestHit.layer)) {
                    // TODO: better way to re-orient rectangle
                    hit.rect.left += originLeft;
                    hit.rect.right += originLeft;
                    hit.rect.top += originTop;
                    hit.rect.bottom += originTop;
                    bestHit = hit;
                }
            }
        }
    }
    return bestHit;
};

Maybe it's not very good solution but it realy working.也许这不是很好的解决方案,但它确实有效。 I hope FullCalendar's developers will add this feature.我希望 FullCalendar 的开发者会添加这个功能。

jsfiddle提琴手

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM