Showing posts with label draggable. Show all posts
Showing posts with label draggable. Show all posts

Monday, January 16, 2012

Implement drag drop events from outside in Full Calender for an ajax based data source

Introduction
With this post I will try to describe Full Calender plugin with drag and drop feature where we can drag and drop events from an Ajax based event data source outside the calender. For this to implement we need to know basics about jQuery and full calender plugin. We can get the plugin detail form this URL.

Details goes here-
CSS used in this post goes here-
   <style type='text/css'>
        body
        {
            margin-top: 40px;
            text-align: center;
            font-size: 14px;
            font-family: "Lucida Grande" ,Helvetica,Arial,Verdana,sans-serif;
        }
        #wrap
        {
            width: 1100px;
            margin: 0 auto;
        }
        #external-events
        {
            float: left;
            width: 150px;
            padding: 0 10px;
            border: 1px solid #ccc;
            background: #eee;
            text-align: left;
        }
        #external-events h4
        {
            font-size: 16px;
            margin-top: 0;
            padding-top: 1em;
        }
        .external-event
        {
            margin: 10px 0;
            padding: 2px 4px;
            background: #3366CC;
            color: #fff;
            font-size: .85em;
            cursor: pointer;
        }
        #external-events p
        {
            margin: 1.5em 0;
            font-size: 11px;
            color: #666;
        }
        #external-events p input
        {
            margin: 0;
            vertical-align: middle;
        }
        #calendar
        {
            float: right;
            width: 900px;
        }
    </style>
For this to work we need to take some CSS and JS files as a reference as follows-
    <link rel='stylesheet' type='text/css' href='http://arshaw.com/js/fullcalendar-1.5.2/fullcalendar/fullcalendar.css' />
    <link rel='stylesheet' type='text/css' href='http://arshaw.com/js/fullcalendar-1.5.2/fullcalendar/fullcalendar.print.css'
        media='print' />

    <script type='text/javascript' src='http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.7.js'></script>

    <script type='text/javascript' src='http://ajax.aspnetcdn.com/ajax/jquery.ui/1.8.9/jquery-ui.js'></script>

    <script type='text/javascript' src='http://arshaw.com/js/fullcalendar-1.5.2/fullcalendar/fullcalendar.min.js'></script>
We can implement a full calender in a div like container as follows-
    <div id='calendar'>
    </div>
            $('#calendar').fullCalendar({
                header: {
                    left: 'prev,next today',
                    center: 'title',
                    right: 'month,agendaWeek,agendaDay'
                },
                editable: true,
                droppable: true,
                drop: function(date, allDay) {
                //drop functionality goes here
                }
            });
Now the basic construct for the problem is done. Lets add a div in the page as a container and list all the events on the div using Ajax. We will now implement drag and drop such that we can drag an event form the list of events and add the events to calender by dropping it into the full calender. To list the events in a div using Ajax we can use page method like below-
    <div id='external-events'>
        <h4>
            Draggable Events</h4>
        
        <p id="events">
            <input type='checkbox' id='drop-remove' />
            <label for='drop-remove'>
                remove after drop</label>
        </p>
    </div> 
            $.ajax({
                url: "Fill draggable events area of FullCalendar.aspx/GetEvents",
                type: "POST",
                dataType: "json",
                contentType: "application/json; charset=utf-8",
                success: function(data) {
                    $(data.d).each(function(i, item) {
                        $("#events").before($("<div class='external-event'></div>").html(item.EventName));
                    });
                },
                error: function(XMLHttpRequest, textStatus, errorThrown) {
                    debugger;
                    alert(textStatus);
                }
            });
    [System.Web.Services.WebMethod]
    public static object GetEvents()
    {
        var obj = new { EventName = "My Event 1"};
        var objList = (new[] { obj }).ToList();
        objList.Add(new { EventName = "My Event 2" });
        objList.Add(new { EventName = "My Event 3" });
        objList.Add(new { EventName = "My Event 4" });
        objList.Add(new { EventName = "My Event 5" });
        objList.Add(new { EventName = "My Event 6" });
        objList.Add(new { EventName = "My Event 7" });
        return objList;
    }
In the above code we have some in memory object as event datasource. We can change to any data source as we need.
Now we need to make the event divs, constructed in the above js code, as draggable. We can do this by implementing the draggable UI plugin by modifying the success method of the Ajax call like below-
                success: function(data) {
                    $(data.d).each(function(i, item) {
                        $("#events").before($("<div class='external-event'></div>").html(item.EventName));
                    });
                    $('#external-events div.external-event').each(function() {
                        var eventObject = {
                            title: $.trim($(this).text())
                        };

                        $(this).data('eventObject', eventObject);

                        $(this).draggable({
                            zIndex: 999,
                            revert: true,
                            revertDuration: 0
                        });
                    });
                }
And finally we can implement drop functionality of the full calender plugin to accept the draggable events and we can achieve this by modifying the full calender jquery call as below-
            $('#calendar').fullCalendar({
                header: {
                    left: 'prev,next today',
                    center: 'title',
                    right: 'month,agendaWeek,agendaDay'
                },
                editable: true,
                droppable: true,
                drop: function(date, allDay) {

                    var originalEventObject = $(this).data('eventObject');

                    var copiedEventObject = $.extend({}, originalEventObject);

                    copiedEventObject.start = date;
                    copiedEventObject.allDay = allDay;

                    $('#calendar').fullCalendar('renderEvent', copiedEventObject, true);

                    if ($('#drop-remove').is(':checked')) {
                        $(this).remove();
                    }

                }
            });