Подтвердить что ты не робот

Fullcalendar текущая линия времени в режиме просмотра недели и дня

Я понимаю, что в соответствии с этим вопросом билет на google code http://code.google.com/p/fullcalendar/issues/detail?id=143, что есть плавучие плавающие вокруг, однако я не могу найти его.

Мне интересно, знает ли кто, как показать красную сплошную линию в текущее время в календаре

4b9b3361

Ответ 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"
        });
    }

}

И затем в настройке:

viewDisplay: function(view) {
        try {
            setTimeline();
        } catch(err) {}
    },

и в css:

.timeline {
    position: absolute;
    left: 59px;
    border: none;
    border-top: 1px solid red;
    width: 100%;
    margin: 0;
    padding: 0;
    z-index: 999;
}

Только пробовал это на недельном просмотре, так как все, что я использую.

Удачи.

Edit:

Чтобы получить временную шкалу для обновления в течение дня, вы можете попробовать что-то подобное в viewDisplay:

viewDisplay: function(view) {
            if(first){
                first = false;
            }else {
                window.clearInterval(timelineInterval);
            }
            timelineInterval = window.setInterval(setTimeline, 300000);
            try {
                setTimeline();
            } catch(err) {}
        },

Вам нужно будет установить first = true в верхней части тега. Это перемещает временную шкалу каждые 300 секунд = 5 минут. Вы можете опустить его, если вам нужно его более плавное.

Ответ 2

Решение Magnus Winter работает очень хорошо, но оно не учитывает варианты fullcalender minTime и maxTime. Если они установлены, временная шкала неуместна.

Чтобы исправить это, замените определение curSeconds и percentOfDay в коде Magnus Winter следующим образом:

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

Отличное решение, накопило все изменения в потоке, чтобы заставить это работать для fullcalendar-2.1.0-beta1 и внес некоторые незначительные изменения, чтобы он работал у меня.

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);
}

Мои изменения

Пришлось изменить

var parentDiv = jQuery(".fc-agenda-slots:visible").parent();

to

var parentDiv = jQuery(".fc-slats:visible").parent();

В противном случае временная шкала вообще не будет отображаться. Guess Full Calendar изменил это.


Тогда у меня возникла проблема с левой позицией строки в дневном режиме, поэтому я изменил

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

to

var timeCol = $('.fc-time:visible');
timeline.css({top: topLoc + "px", left: (timeCol.outerWidth(true))+"px"});

Также ширина временной шкалы в повестке дняWeek вышла неправильно, поэтому я изменил

var width = dayCol.width() - 2;

к

var width = dayCol.width() + 1;

Не понимаю, почему это было, просто изменил его, чтобы он выглядел правильно.

Ответ 5

Мартин Пабст сделал хороший момент, но он не работает, если вы установите минимальное и максимальное время в виде строк (например, "07:30" ).

Чтобы решить это:

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);
}

И замените его определения на:

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

Удивительное решение, помогло мне многое, спасибо всем! Это изменения, необходимые для того, чтобы это решение работало с новым FullCalendar v2.

Измените строку: if (curCalView.visStart < curTime && curCalView.visEnd > curTime) {

To: if (curCalView.intervalStart < curTime && curCalView.intervalEnd > curTime) {

И предпочитаем использовать: viewRender: function(view) {

вместо: viewDisplay: function(view) {

Ответ 7

Я придумал это решение для версии 2.3.2. Он основан на предыдущих примерах.

    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

Чтобы он работал с версией 2.2.7 при использовании пользовательских минут min и max, я добавил

var slotsDiv  = $('.fc-slats:visible');

перед линией

var parentDiv = $('.fc-slats:visible').parent();

и изменил строку

var topLoc = Math.floor(parentDiv.height() * percentOfDay);

к

var topLoc = Math.floor(slotsDiv.height() * percentOfDay);

Таким образом, функция использует правильную высоту div для вычисления положения временной шкалы.