Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

jquery fullcalendar Draw a line on current time

I want to display current time in jquery full calendar while slotMinutes is 15

Calendar

Result

Below is my code for review

    $.createFullCalendarWithCurrentTime = function (selectCallback, eventsCallback, mouseOverCallback, options, eventRenderCallback, curTime) {

        var mintime = 7;
        var maxtime = 22;
        var slotsTable = undefined;
        var calendar = undefined;

        calendar = $('#calendar').fullCalendar({
            unselectAuto: false,
            header: { left: 'prev', center: 'title', right: 'next' },
            titleFormat: { week: "MMMM dd, yyyy{ - MMMM dd, yyyy}" }, // Sep 7 - 13 2009 ,
            defaultView: "agendaWeek",
            columnFormat: { week: 'dddd' },
            eventBackgroundColor: options && options["eventBackgroundColor"] ? options["eventBackgroundColor"] : "#FFEB00",
            eventBorderColor: "#FFEB00",
            eventTextColor: options && options["eventTextColor"] ? options["eventTextColor"] : "#333333",
            axisFormat: 'h(:mm) tt',
            aspectRatio: 0.1,
            buttonText: { prev: '', next: '' },
            selectable: (selectCallback != null && $.isFunction(selectCallback) ? true : false),
            selectHelper: true,
            editable: false,
            allDaySlot: false,
            slotMinutes: 15,
            minTime: 7,
            maxTime: 22,
            firstDay: 1,
            eventMouseover: mouseOverCallback,
            viewDisplay: function () {
                // Create slots table only if not created

                if (!slotsTable) {
                    // Set time
                    for (var i = 0; i < maxtime - mintime; i++) {

                        $(".fc-slot" + (i * 2 + (i * 2 + 2)) + ".fc-minor>th").html(((mintime + i) < 12 ? (mintime + i) : ((mintime + i) == 12) ? 12 : (mintime + i) % 12) + ":30 " + (mintime + i < 12 ? "am" : "pm"));
                        $(".fc-slot" + (i * 2 + (i * 2 + 2)) + ".fc-minor>th").addClass("innerHours");

                    }
                    // Set styles
                    slotsTable = $(".fc-agenda-slots").clone();
                    slotsTable.addClass("cloned");
                    slotsTable
                        .css("position", "absolute")
                        .css("top", "-12px")
                        .css("z-index", "-100");
                    $(".fc-agenda-slots th").css("visibility", "hidden");
                    slotsTable.find("td").css("visibility", "hidden");

                    // Set minimum and maximum values
                    $("#minTime").html(mintime + " am");
                    $("#maxTime").html(maxtime % 12 + " pm");

                } 

                $(".fc-agenda-slots").parent().append(slotsTable);
                $(".fc-slot0>th").html("");

                var offset = slotsTable.find(".fc-slot0>th").offset();
                $(".septimo").css("top", offset.top);
                $(".septimo").css("left", offset.left);
                $(".septimo").css("width", slotsTable.find(".fc-slot0>th").width());

                offset = slotsTable.find("tr:last-child>th").offset();
                $(".veintidos").css("top", offset.top + slotsTable.find("tr:last-child>th").height());
                $(".veintidos").css("left", offset.left);
                $(".veintidos").css("width", slotsTable.find("tr:last-child>th").width());
                try {
                    setTimeline();
                } catch (err) { }
            },
            select: selectCallback,
            events: eventsCallback,
            eventRender: eventRenderCallback
        });
        return calendar;
    };
    function setTimeline(view) {
        var parentDiv = jQuery(".fc-agenda-slots:visible").parent();
        var timeline = parentDiv.children(".timeline");
        if (timeline.length == 0) { //if timeline isn't there, add it
            timeline = jQuery("<hr>").addClass("timeline");
            parentDiv.prepend(timeline);
        }

        var curTime = new Date();

        var curCalView = jQuery("#calendar").fullCalendar('getView');
        if (curCalView.visStart < curTime && curCalView.visEnd > curTime) {
            timeline.show();
        } else {
            timeline.hide();
            return;
        }

        var curSeconds = (curTime.getHours() * 60 * 60) + (curTime.getMinutes() * 60) + curTime.getSeconds();
        var percentOfDay = curSeconds / 86400; //24 * 60 * 60 = 86400, # of seconds in a day
        var hgt = parentDiv.height();
        var topLoc = Math.floor(parentDiv.height() * percentOfDay);

        timeline.css("top", topLoc + "px");

        if (curCalView.name == "agendaWeek") { //week view, don't want the timeline to go the whole way across
            var dayCol = jQuery(".fc-today:visible");
            var left = dayCol.position().left + 1;
            var width = dayCol.width() - 2;
            timeline.css({
            //left: left + "px",
            //width: width + "px"
        });
    }
};
like image 275
Abhishek Avatar asked Feb 05 '14 11:02

Abhishek


3 Answers

If you are using 2.6.0 version or later of FullCalendar, you can use the build in nowIndicator: http://fullcalendar.io/docs/current_date/nowIndicator/

like image 172
Maksim Luzik Avatar answered Sep 20 '22 18:09

Maksim Luzik


Probably there is already an answer on SO (but I can't find it...) because I have this code snippet and demo in my jsfiddle area.

You can use a custom function to fire in viewRender event; a dashed CSS to style the added line.

Triggered when a new date-range is rendered, or when the view type switches.

Code:

function setTimeline(view) {
    var parentDiv = jQuery(".fc-agenda-slots:visible").parent();
    var timeline = parentDiv.children(".timeline");
    if (timeline.length == 0) { //if timeline isn't there, add it
        timeline = jQuery("<hr>").addClass("timeline");
        parentDiv.prepend(timeline);
    }

    var curTime = new Date();

    var curCalView = jQuery("#mycalendar").fullCalendar('getView');
    if (curCalView.visStart < curTime && curCalView.visEnd > curTime) {
        timeline.show();
    } else {
        timeline.hide();
        return;
    }

    var curSeconds = (curTime.getHours() * 60 * 60) + (curTime.getMinutes() * 60) + curTime.getSeconds();
    var percentOfDay = curSeconds / 86400; //24 * 60 * 60 = 86400, # of seconds in a day
    var topLoc = Math.floor(parentDiv.height() * percentOfDay);

    timeline.css("top", topLoc + "px");

    if (curCalView.name == "agendaWeek") { //week view, don't want the timeline to go the whole way across
        var dayCol = jQuery(".fc-today:visible");
        var left = dayCol.position().left + 1;
        var width = dayCol.width() - 2;
        timeline.css({
            left: left + "px",
            width: width + "px"
        });
    }

}

$('#mycalendar').fullCalendar({
    header: {
        left: 'prev,next today',
        center: 'title'
    },
    defaultView: 'agendaDay',
    editable: true,
    events: [{
        title: 'event1',
        start: '2014-01-07'
    }, {
        title: 'event2',
        start: '2014-01-10',
        end: '2013-05-15'
    }, {
        title: 'event3',
        start: '2014-01-13 12:30:00',
        allDay: false // will make the time show
    }],
    viewRender: function (view) {
        try {
            setTimeline();
        } catch (err) {}
    },
});

CSS:

.timeline {
    position: absolute;    
    border-top: 2px dashed red;
    width: 100%;
    margin: 0;
    padding: 0;
    z-index: 999;
}

Demo: http://jsfiddle.net/IrvinDominin/M67kv/

like image 45
Irvin Dominin Avatar answered Sep 21 '22 18:09

Irvin Dominin


Adopted to fullcalendar 2.4 versions:

    function setTimeline(view)
    {
        var curCalView = view || jQuery("#CalendarDiv").fullCalendar('getView');
        var parentDiv = jQuery(".fc-content-skeleton");
        var timeline = parentDiv.children(".timeline");
        if (timeline.length == 0) { //if timeline isn't there, add it
           timeline = jQuery("<hr>").addClass("timeline");
           parentDiv.prepend(timeline);
        }

        if ( 'agendaWeek' != curCalView.name && 'agendaDay' != curCalView.name ) {
            timeline.hide();
            return;
        }

        var curTime = moment();
//      console.log(curCalView.intervalStart.isBefore()); // returns always false ... ????
//      console.log(curCalView.start.unix());
//      console.log(curCalView.end.unix());
//      console.log(curTime.unix());

        var curSeconds = (curTime.hours() * 60 * 60) + (curTime.minutes() * 60) + curTime.seconds();
        var percentOfDay = curSeconds / 86400; //24 * 60 * 60 = 86400, # of seconds in a day
        var topLoc = Math.floor(jQuery(".fc-time-grid").height() * percentOfDay);

        timeline.css({"top":topLoc + "px",
            "left": "0px",
            "width": "100%"});

        if ( curCalView.start.unix() < curTime.unix() && curCalView.end.unix() > curTime.unix() ) {
            if ( curCalView.name == "agendaWeek") { //week view, don't want the timeline to go the whole way across
                var dayCol = jQuery(".fc-today:visible");
                var left = dayCol.position().left;
                var width = dayCol.width() - 2;
                timeline.css({
                    "left": left + "px",
                    "width": width + "px"
                });
            }
            timeline.show();
        } else {
            timeline.hide();
            return;
        }
    }

There seem to be some glitches in moment, that's why I needed to debug the entire stuff, you may delete that.

I've put the initial call in to the event eventAfterAllRender:

                // show a time indicator on time based views
                if ( ! this.eventTimer )
                    this.eventTimer = window.setInterval(function () { setTimeline(); }, 5 * 60 * 1000);
                setTimeline();
like image 27
Axel Amthor Avatar answered Sep 18 '22 18:09

Axel Amthor