在fullcalendar中复制和粘贴事件

时间:2013-12-17 14:20:19

标签: javascript jquery django fullcalendar

我已经在fullcalendar中“实现”了一种复制粘贴功能,如下所示:

  1. 使用eventRender回调绑定右键单击显示上下文菜单的每个事件元素。
  2. 复制活动
  3. 使用上下文菜单将每个插槽绑定以显示粘贴功能
  4. 在菜单项上单击我通过事件的ajax(新日期和时间)发布数据,并返回事件的新json,以在日历上呈现。
  5. 为什么当你可以说完整日历已经具有可编辑的事件功能时会遇到这么多麻烦。因为(除非我弄错了)我希望用户能够复制一个事件,并将其移动到另一天(2或3或4天后),在那里他看到一个开放的插槽。它工作得很好(虽然我必须对时区和时差做一些事情,因为后端在Django中,使用TIME_ZONE)。但是,如果我尝试将其粘贴到不同的插槽中,它就不会工作了。这是一个示例代码(请不要讨厌我...)

    事件上下文菜单

    eventRender: function (event, element){
        element.bind('contextmenu', function(e){
            e.preventDefault();
            console.log('Right clicking') 
            showContextualMenu(event, element, e);
        });
    }
    
    function showContextualMenu(event,element, e){
        $("#contextual-menu").css({
            'position':'fixed',
            'top':e.clientY,
            'left':e.clientX
        }).fadeIn(500, function (){
            $(document).bind("click", function(){
                $('#contextual-menu').hide(500);
                $(document).off("click");
            });
            options = $("#contextual-menu ul").children();
            options.one('click', function (){
                console.log("Inside click");
                if ($(this).data('action')=== "move"){
                    console.log("Inside if");
                    alert("Copied event to move it");
                    copiedEvent = event; //Global variable inside on $(document).ready()...note the best implementation I know, but had to pass the event everywhere
                    paste = true; //paste is a variable telling us that there is an event wating to be pasted elswhere.
                }
            });
        });
    }        
    

    我还使用上下文菜单将议程的插槽绑定,以便用户可以右键单击插槽,如果有要在“剪贴板”中复制的事件进行复制。

    //agenda-slots right click menu creation
    var slots = $("table.fc-agenda-slots tbody").children();
    slots.bind('contextmenu', function (e){
        e.preventDefault();
        if (paste===true){
            showSlotContextualMenu($(this),e);
        }
    });
    function showSlotContextualMenu(slot,e){
        $("#contextual-menu2 li" ).unbind('click');//If user only renders the menu but doesn't click i need to unbind the click method
        var hour = parseInt(((slot.first().text()).split(":"))[0]);//hour of the slot
        var minutes = parseInt(((slot.first().text()).split(":"))[1]);//minutes of the slot
        //start = $("#calendar").fullCalendar('getDate');//date in which i am currently (case i want to paste event on different date)
        //start.setHours(hour);
        start.setMinutes(minutes);
        //end = $("#calendar").fullCalendar('getDate'); not necessary, the sever takes the duration of initial/copied event, and calculates the end time
        $("#contextual-menu2").css({
            'top':e.pageY,
            'left':e.pageX,
            'position':'absolute'
        }).fadeIn(500, function(){
            //user can click anywhere to close menu
            $(document).bind("click", function (){
                $("#contextual-menu2").hide(500);
                $(document).off("click"); 
            });
            $("#contextual-menu2 li").one("click", function(){
                //binding once every time contextual menu is shown...Dont think its the best way, please if you have advices, would love to hear them.
                if (confirm("This will move appointment with title: "+copiedEvent.title+ ". Do you want to proceed?")){
                    alert("I will save your event");
                    date = $("#calendar").fullCalendar('getDate');
                    //ajax call to save event on success event will be placed in this slot and removed from the previous one
                    $.ajax({
                        url:"/calendar/entry/move/",
                        type:"post",
                        dataType:'json',
                        data:{
                            id: copiedEvent.id,
                            start: copiedEvent.start.toGMTString(),
                            end: copiedEvent.end.toGMTString(),
                            color:copiedEvent.color,
                            csrfmiddlewaretoken:$("input[name='csrfmiddlewaretoken']").val(),
                            year: date.getFullYear(),//new year
                            month:date.getMonth(), //new month
                            day:date.getDate(),  new date
                            hour:hour, //new hour (from slot)
                            minutes:minutes //new minutes(from slot)
                        },
                        success:function (data, status, jqXHR){
                            alert("Success, You will move "+data.title+" event");
                            event = copiedEvent;
                            event.start = data['start'];
                            event.end = data['end'];
                            console.log("about to save event"+ event.id+" "+event.start+" "+event.end);
                            $("#calendar").fullCalendar('renderEvent', event);
                                paste=false;                               
                                copiedEvent=null;
    
                        }
                    });
                }
            });
        });
    
    }
    

    问题在于,当我改变一天时,例如我在12月18日复制一个事件并在12月20日将其粘贴,事件将不会呈现。警报对话框向我显示他们拥有正确的数据(日期等)仍然无法呈现事件。我没有在数据库中保存事件,我只返回json中的事件进行测试,但是如果我不改变日期并在同一天粘贴它就可以工作。似乎没有找到错误。

1 个答案:

答案 0 :(得分:0)

我工作了。但是我稍微更改了代码,以便更新copiedEvent。所以我的服务器只返回新的开始和结束日期(django),如

return HttpResponse(json.dumps(dict(start=start, end=end), cls=DjangoJSONEncoder), content_type="application/json")

和ajax调用的成功函数

function (data, status, jqXHR){
    copiedEvent.start = data.start;
    copiedEvent.end = data.end;
    $("#calendar").fullCalendar("upadateEvent", copiedEvent);
}

现在它就像一个魅力。