使用fullcalendar.js如何显示日历的每个空白单元格上的空档时间?

时间:2019-08-06 00:55:10

标签: javascript fullcalendar fullcalendar-4

使用fullcalendar库,我想显示日历上每个空白单元格的开始时间(空单元格是下面的屏幕截图中标有红叉或红点的那个,我对日历的外观做了一些修改): full calendar screenshot 因此,我的预期输出是将日历变成时隙的按钮,当您单击单击时,您将开始预订30分钟的约会的过程,该约会将在书面时间开始(以下屏幕截图中的绿色时隙是悬停效果): expected output 阅读完整的日历文档后,我找不到任何简单的方法来完成此操作:https://fullcalendar.io/docs

子问题,我找不到在CSS中更改空单元格样式的方法。无法通过我的Chrome控制台选择元素。

document.addEventListener('DOMContentLoaded', function() {
var calendarEl = document.getElementById('calendar');

var calendar = new FullCalendar.Calendar(calendarEl, {
    columnHeaderHtml: function(date) {
        if (date.getUTCDay() === 0) {
        var date_day = "Lundi";
        }
        if (date.getUTCDay() === 1) {
        var date_day = "Mardi";
        }
        if (date.getUTCDay() === 2) {
        var date_day = "Mercredi";
        }
        if (date.getUTCDay() === 3) {
        var date_day = "Jeudi";
        }
        if (date.getUTCDay() === 4) {
        var date_day = "Vendredi";
        }
        if (date.getUTCDay() === 5) {
        var date_day = "Samedi";
        }
        if (date.getUTCDay() === 6) {
        var date_day = "Dimanche";
        }
        if(date.getMonth() === 0)
        {
        var date_month = "Jan";
        } 
        if(date.getMonth() === 1)
        {
        var date_month = "Fev";
        } 
        if(date.getMonth() === 2)
        {
        var date_month = "Mar";
        } 
        if(date.getMonth() === 3)
        {
        var date_month = "Avr";
        } 
        if(date.getMonth() === 4)
        {
        var date_month = "Mai";
        } 
        if(date.getMonth() === 5)
        {
        var date_month = "Juin";
        } 
        if(date.getMonth() === 6)
        {
        var date_month = "Juil";
        } 
        if(date.getMonth() === 7)
        {
        var date_month = "Août";
        } 
        if(date.getMonth() === 8)
        {
        var date_month = "Sept";
        } 
        if(date.getMonth() === 9)
        {
        var date_month = "Oct";
        } 
        if(date.getMonth() === 10)
        {
        var date_month = "Nov";
        } 
        if(date.getMonth() === 11)
        {
        var date_month = "Dec";
        } 

        var day_num = date.getDate();
        return '<b>'+date_day+'</b><br><small>'+day_num+" "+date_month+"</small>";

    },

    plugins: [ 'interaction', 'dayGrid', 'list', 'googleCalendar','timeGrid' ],
    selectable: true,

    defaultView: 'timeGridFourDay',
    views: {
        timeGridFourDay: {
            type: 'timeGrid',
            duration: { days: 4 },
            buttonText: '4 day'
        }
    },
    slotLabelFormat:{
        hour: 'numeric',
        minute: '2-digit',
        omitZeroMinute: true,
        meridiem: 'short'
    },

    locale:'fr',
    header: {
        left: 'prev today',
        right: 'next'
    },
    validRange: {
        start: '2019-08-05',
        end: '2019-09-05'
    },
    allDaySlot:false,
    firstDay:1,
    minTime:"08:00:00",
    maxTime:"20:00:00",

    displayEventTime: true, // don't show the time column in list view

    // THIS KEY WON'T WORK IN PRODUCTION!!!
    // To make your own Google API key, follow the directions here:
    // http://fullcalendar.io/docs/google_calendar/
    googleCalendarApiKey: 'AIzaSyAL9K2UqkCVfV0n81mDW0iEpOJSwcklfsY',

    // US Holidays
    events: 'fr.fr#holiday@group.v.calendar.google.com',

    eventClick: function(arg) {
        arg.jsEvent.preventDefault() // don't navigate in main tab

        console.log(arg);
    },

    select: function(info) {

        console.log(info)

    },

    loading: function(bool) {

    },
    eventSources: [
    {
    googleCalendarId: 'contact@vetorino.com',
    className: "gcalEvent"

    }],

    displayEventEnd:false,
    events:[
    { // this object will be "parsed" into an Event Object

    start: '2019-08-05 12:30:00', // a property!
    end: '2019-08-05 14:00:00', // a property! ** see important note below about 'e6d' **
    overlap: true,
    backgroundColor:"#F7F7F7",
    textColor:"#979797",
    classNames:"closed",
    }],
      contentHeight: "auto",






    });

    calendar.render();

 });

就我之前的屏幕截图所示,我只是设法将单元格留空,唯一可以找到一些信息的单元格是包含事件的单元格。

1 个答案:

答案 0 :(得分:0)

如上面的评论所述,在fullCalendar HTML中没有单个元素表示timeGrid视图中的特定“单元”或“插槽”。您在屏幕上看到的网格实际上是通过将多个表彼此叠加而创建的一种幻觉。

因此,为了满足您对用户能够在空闲时段中选择20分钟约会的要求,我可以看到两个主要选项。第一个是我通常建议使用的标准fullCalendar功能。第二个更像是您要的东西,但我认为这使事情变得过于复杂。

1)此选项只是将日历的空档时间设置为20分钟,然后具有阻止用户选择较长时间段的代码(由于slotDuration,它们无法选择较短的时间段)设置。这意味着他们可以单击任何空白空间,它将知道在该位置创建一个长度正确的事件。不允许用户选择已经存在事件的任何插槽。(我希望现实中的PS您将需要在添加事件之前收集更多数据,但对于演示,它会立即添加事件。)

document.addEventListener("DOMContentLoaded", function() {
  var Calendar = FullCalendar.Calendar;
  var calendarEl = document.getElementById("calendar");

  var calendar = new Calendar(calendarEl, {
    plugins: ["timeGrid", "interaction"],
    header: {
      left: "prev,next today",
      center: "title",
      right: "timeGridFourDay"
    },
    defaultView: "timeGridFourDay",
    views: {
      timeGridFourDay: {
        type: "timeGrid",
        duration: { days: 4 },
        buttonText: "4 day"
      }
    },
    slotLabelFormat: {
      hour: "numeric",
      minute: "2-digit",
      omitZeroMinute: true,
      meridiem: "short"
    },
    allDaySlot: false,
    firstDay: 1,
    minTime: "08:00:00",
    maxTime: "20:00:00",
    contentHeight: "auto",
    slotDuration: "00:20:00",
    selectable: true,
    select: function(info) {
      //console.log(info);
      calendar.addEvent({ "title": "Test", start: info.start, end: info.end })
      calendar.unselect();
    },
    selectOverlap: false,
    selectAllow: function(selectInfo) {
      var stM = moment(selectInfo.start);
      var enM = moment(selectInfo.end);
      var diff = enM.diff(stM, "minutes");
      console.log(diff);
      if (diff > 20)
      {
        return false;
      }
      return true;
    },
    events: [
      { "title": "Existing event", "start": "2019-08-08 10:00", "end": "2019-08-08 10:20"},
      { "title": "Existing event", "start": "2019-08-08 13:20", "end": "2019-08-08 13:40"},
]
  });

  calendar.render();
});

演示:https://codepen.io/ADyson82/pen/aeqJQg


2)此选项(从第二张屏幕截图中)更接近所需的UI,但实现起来有点复杂。我个人也认为,这会使您的日历显得杂乱无章,使您很难查看空闲和忙碌时段的位置,但最终由您决定如何实现它。通过添加第二个事件源(包含所有当前可用插槽的列表)来工作。然后,它们用于显示每个空闲插槽中心的开始时间。它们的颜色与现有事件的颜色不同(表明插槽繁忙),因此区分起来会容易一些。

当然,这需要您使用服务器端代码来计算数据库中所有当前可用的插槽,并使用该信息来填充第二个事件源。 (在演示中,空闲插槽数据是静态的,但是在真正的应用程序中当然不能使用。)

document.addEventListener("DOMContentLoaded", function() {
  var Calendar = FullCalendar.Calendar;
  var calendarEl = document.getElementById("calendar");

  var calendar = new Calendar(calendarEl, {
    plugins: ["timeGrid", "interaction"],
    header: {
      left: "prev,next today",
      center: "title",
      right: "timeGridFourDay"
    },
    defaultView: "timeGridFourDay",
    views: {
      timeGridFourDay: {
        type: "timeGrid",
        duration: { days: 4 },
        buttonText: "4 day"
      }
    },
    slotLabelFormat: {
      hour: "numeric",
      minute: "2-digit",
      omitZeroMinute: true,
      meridiem: "short"
    },
    allDaySlot: false,
    firstDay: 1,
    minTime: "08:00:00",
    maxTime: "20:00:00",
    contentHeight: "auto",
    slotDuration: "00:20:00",
    displayEventTime: false,
    eventClick: function(info) {
        if (info.event.extendedProps.type == "free") {
          calendar.addEvent({
            title: "Test",
            start: info.event.start,
            end: info.event.end
          });
          info.event.remove(); //delete the "free slot" event
        }
    },
    eventSources: [
      {
        id: "busy",
        events: [
          {
            title: "Existing event",
            start: "2019-08-08 10:00",
            end: "2019-08-08 10:20"
          },
          {
            title: "Existing event",
            start: "2019-08-08 13:20",
            end: "2019-08-08 13:40"
          }
        ]
      },
      {
        id: "free",
        backgroundColor: "green",
        events: [
          {
            title: "08:00",
            start: "2019-08-08 08:00",
            end: "2019-08-08 08:20",
            type: "free"
          },
          {
            title: "08:20",
            start: "2019-08-08 08:20",
            end: "2019-08-08 08:40",
            type: "free"
          },
          {
            title: "08:40",
            start: "2019-08-08 08:40",
            end: "2019-08-08 09:00",
            type: "free"
          },
          {
            title: "09:00",
            start: "2019-08-08 09:00",
            end: "2019-08-08 09:20",
            type: "free"
          },
          {
            title: "09:20",
            start: "2019-08-08 09:20",
            end: "2019-08-08 09:40",
            type: "free"
          },
          {
            title: "09:40",
            start: "2019-08-08 09:40",
            end: "2019-08-08 10:00",
            type: "free"
          },
          {
            title: "10:20",
            start: "2019-08-08 10:20",
            end: "2019-08-08 10:40",
            type: "free"
          },
          {
            title: "10:40",
            start: "2019-08-08 10:40",
            end: "2019-08-08 11:00",
            type: "free"
          },
        ]
      }
    ]
  });

  calendar.render();
});

对于这个演示,我只创建了几个“空闲”插槽(因为创建它们很繁琐),但是希望您能对如何在整个日历中看到数十个插槽有了一个想法。当然,您可以再次修改CSS以满足您的要求。

演示:https://codepen.io/ADyson82/pen/JgpNEX

(您当然可以进一步修改此CSS,以使其看起来更像您想要的外观。)

附录:这是OP的最终版本,适用于对最终产品感兴趣的任何人-基于上述建议:https://codepen.io/hugo-trial/pen/rXdajv