问题
I understand that according to this issue ticket on google code http://code.google.com/p/fullcalendar/issues/detail?id=143 that there is a soloution floating around, however I cant seem to find it.
I am wondering if anyone knows how to show a red solid line on the current time on the calendar
回答1:
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 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"
});
}
}
And then in the setup:
viewDisplay: function(view) {
try {
setTimeline();
} catch(err) {}
},
and in the css:
.timeline {
position: absolute;
left: 59px;
border: none;
border-top: 1px solid red;
width: 100%;
margin: 0;
padding: 0;
z-index: 999;
}
Only tried this on week-view since that's all I use.
Good luck.
Edit:
To get the timeline to update during the day you could try something like this in the viewDisplay:
viewDisplay: function(view) {
if(first){
first = false;
}else {
window.clearInterval(timelineInterval);
}
timelineInterval = window.setInterval(setTimeline, 300000);
try {
setTimeline();
} catch(err) {}
},
You will need to set first=true in the top of the tag. This will move the timeline every 300 second = 5 minutes. You can lower it if you need it more smooth..
回答2:
It has been solved in the new version of FullCalendar (2.6.0)
http://fullcalendar.io/docs/current_date/nowIndicator/
$('#calendar').fullCalendar({
nowIndicator: true
});
回答3:
Magnus Winter's solution works very well, but it doesn't consider fullcalender options minTime and maxTime. If they are set then the timeline is misplaced.
To fix this replace the definition of curSeconds and percentOfDay in Magnus Winter's code with:
var curSeconds = ((curTime.getHours() - curCalView.opt("minTime")) * 60 * 60) + (curTime.getMinutes() * 60) + curTime.getSeconds();
var percentOfDay = curSeconds / ((curCalView.opt("maxTime") - curCalView.opt("minTime")) * 3600); // 60 * 60 = 3600, # of seconds in a hour
回答4:
Great solution, accumulated all the changes in the thread to get this working for fullcalendar-2.1.0-beta1 and made some minor changes so it would work for me.
var timelineInterval; $calendar.fullCalendar({ ..., viewRender: function(view) { if(typeof(timelineInterval) != 'undefined'){ window.clearInterval(timelineInterval); } timelineInterval = window.setInterval(setTimeline, 300000); try { setTimeline(); } catch(err) {} }, ... }); function setTimeline(view) { var parentDiv = $('.fc-slats:visible').parent(); var timeline = parentDiv.children(".timeline"); if (timeline.length == 0) { //if timeline isn't there, add it timeline = $("<hr>").addClass("timeline"); parentDiv.prepend(timeline); } var curTime = new Date(); var curCalView = $("#calendar").fullCalendar('getView'); if (curCalView.intervalStart < curTime && curCalView.intervalEnd > curTime) { timeline.show(); } else { timeline.hide(); return; } var calMinTimeInMinutes = strTimeToMinutes(curCalView.opt("minTime")); var calMaxTimeInMinutes = strTimeToMinutes(curCalView.opt("maxTime")); var curSeconds = (( ((curTime.getHours() * 60) + curTime.getMinutes()) - calMinTimeInMinutes) * 60) + curTime.getSeconds(); var percentOfDay = curSeconds / ((calMaxTimeInMinutes - calMinTimeInMinutes) * 60); var topLoc = Math.floor(parentDiv.height() * percentOfDay); var timeCol = $('.fc-time:visible'); timeline.css({top: topLoc + "px", left: (timeCol.outerWidth(true))+"px"}); if (curCalView.name == "agendaWeek") { //week view, don't want the timeline to go the whole way across var dayCol = $(".fc-today:visible"); var left = dayCol.position().left + 1; var width = dayCol.width() + 1; timeline.css({left: left + "px", width: width + "px"}); } } function strTimeToMinutes(str_time) { var arr_time = str_time.split(":"); var hour = parseInt(arr_time[0]); var minutes = parseInt(arr_time[1]); return((hour * 60) + minutes); }
My changes
Had to change
var parentDiv = jQuery(".fc-agenda-slots:visible").parent();
to
var parentDiv = jQuery(".fc-slats:visible").parent();
Otherwise no timeline would be rendered at all. Guess Full Calendar changed this.
Then I had an issue with the left pos of the line in day view so I changed
timeline.css("top", topLoc + "px");
to
var timeCol = $('.fc-time:visible');
timeline.css({top: topLoc + "px", left: (timeCol.outerWidth(true))+"px"});
Also the timeline width in agendaWeek came out wrong so i changed
var width = dayCol.width() - 2;
to
var width = dayCol.width() + 1;
Didn't go into why this was, just changed it so it would look right.
回答5:
Martin Pabst made a good point, but it doesn't work if you set min and max time as strings (ex. "07:30").
To solve that:
function strTimeToMinutes(str_time) {
var arr_time = str_time.split(":");
var hour = parseInt(arr_time[0]);
var minutes = parseInt(arr_time[1]);
return((hour * 60) + minutes);
}
And replace his definitions with:
var calMinTimeInMinutes = strTimeToMinutes(curCalView.opt("minTime"));
var calMaxTimeInMinutes = strTimeToMinutes(curCalView.opt("maxTime"));
var curSeconds = (( ((curTime.getHours() * 60) + curTime.getMinutes()) - calMinTimeInMinutes) * 60) + curTime.getSeconds();
var percentOfDay = curSeconds / ((calMaxTimeInMinutes - calMinTimeInMinutes) * 60);
回答6:
Awesome solution, helped me a great deal, thank you everyone! These are the changes required to get this solution working with the new FullCalendar v2.
Change the line: if (curCalView.visStart < curTime && curCalView.visEnd > curTime) {
To: if (curCalView.intervalStart < curTime && curCalView.intervalEnd > curTime) {
And prefer to use: viewRender: function(view) {
instead of: viewDisplay: function(view) {
回答7:
I came up with this solution for version 2.3.2. It is based of previous examples.
var timelineIntervalPromise;
var renderCurrentTimeline = function(view, element, anchor) {
var currentDate = moment().tz(security.currentUser.timeZone.id);
var intervalStart = view.intervalStart.clone().tz(security.currentUser.timeZone.id)
.year(view.intervalStart.year())
.month(view.intervalStart.month())
.day(view.intervalStart.day())
.time('00:00:00');
var intervalEnd = view.intervalEnd.clone().tz(security.currentUser.timeZone.id)
.year(view.intervalEnd.year())
.month(view.intervalEnd.month())
.day(view.intervalEnd.day())
.time('00:00:00');
if (view.name === 'month' || !currentDate.isBetween(intervalStart, intervalEnd)) {
return;
}
var timeGrid = element.find('.fc-time-grid');
var timeline = angular.element('<hr class="timeline" />');
timeGrid.find('hr.timeline').remove();
timeGrid.prepend(timeline);
var calMinTimeInMinutes = moment.duration(view.opt('minTime')).asMinutes();
var calMaxTimeInMinutes = moment.duration(view.opt('maxTime')).asMinutes();
var curSeconds = (( ((currentDate.hours() * 60) + currentDate.minutes()) - calMinTimeInMinutes) * 60) + currentDate.seconds();
var percentOfDay = curSeconds / ((calMaxTimeInMinutes - calMinTimeInMinutes) * 60);
var topLoc = Math.floor(timeGrid.height() * percentOfDay);
var timeCol = element.find('.fc-time:visible');
timeline.css({top: topLoc, left: timeCol.outerWidth(true)});
if (angular.isUndefined(anchor) || anchor === true) {
timeGrid.parent().scrollTop(timeline.offset().top);
}
if (view.name === 'agendaWeek') { // Week view, don't want the timeline to go the whole way across.
var dayCol = element.find('.fc-time-grid .fc-bg .fc-today');
var left = dayCol.position().left + 1;
var width = dayCol.width() + 1;
timeline.css({left: left, width: width});
}
if (angular.isDefined(timelineIntervalPromise)) {
$interval.cancel(timelineIntervalPromise);
}
timelineIntervalPromise = $interval(function() {
var view = uiCalendarConfig.calendars.eventCalendar.fullCalendar('getView');
renderCurrentTimeline(view, view.el, false);
}, 300000);
};
回答8:
To make it work with version 2.2.7 when using custom min and max time I added
var slotsDiv = $('.fc-slats:visible');
before the line
var parentDiv = $('.fc-slats:visible').parent();
and changed the line
var topLoc = Math.floor(parentDiv.height() * percentOfDay);
to
var topLoc = Math.floor(slotsDiv.height() * percentOfDay);
This way the function uses the correct div height to calculate the timeline position.
来源:https://stackoverflow.com/questions/8813454/fullcalendar-current-time-line-on-week-view-and-day-view