【问题标题】:Change date range to show events in FullCalendar更改日期范围以在 FullCalendar 中显示事件
【发布时间】:2018-05-24 19:25:56
【问题描述】:

我需要能够使用“列表”视图通过 FullCalendar 设置“日期范围”。通过日期范围,我的意思是能够使用 2 个文本字段、2 个不同的日期输入,例如:

文本字段 1:2018-05-05

文本字段 2:2018-05-06

并过滤日历的内容,使用列表视图显示结果,并显示与该日期范围匹配的事件。

这是我的 FullCalendar 部分的代码:

 $('#calendar').fullCalendar({
      header: {
        left: 'prev,next today',
        center: 'title',
        right: 'listMonth, month,agendaWeek,agendaDay'
      },
      defaultView: 'listMonth',
      locale: 'fr',
      contentHeight: 600,
      navLinks: true, // can click day/week names to navigate views
      selectable: false,
      eventRender: function(event, element, view) { 
        element.find('.fc-widget-header').append("<div style='color:#fff'>Conférencier choisi</div>");
        element.find('.fc-title').append("<br/>" + event.lieu); 
        element.find('.fc-list-item-title').append("<br/>" + event.lieu); 
        element.find('.fc-list-item-title').append("<a href='" + event.lienconferencier + "'><div class='conferencier-calendrier-container'><div style='float:left;background-image:url(" + event.photoconferencier + ");width:40px;height:40px;background-size:cover;border-radius:100px;'></div><div style='float:left;padding-left:5px;font-weight:normal;'><strong>Conférencier</strong><br>" + event.conferencier + "</div></a>"); 
          return ['all', event.status].indexOf($('#filter-status').val()) >= 0 &&
             ['all', event.client].indexOf($('#filter-contact').val()) >= 0 && 
             ['all', event.conferencier].indexOf($('#filter-conferencier').val()) >= 0 &&
             ['', event.numero].indexOf($('#numero').val()) >= 0;

      },
      selectHelper: true,
      editable: false,
      eventLimit: true, // allow "more" link when too many events
      events: [
        {
          title: 'Example',
          start: '2018-05-05',
          end: '2018-05-06',
          color: '#ff0000',
          lieu: 'Montreal',
          numero: '300445',
          conferencier: 'John Doe',
          photoconferencier: 'http://www.example.com/img/profile.jpg',
          lienconferencier: 'http://www.example.com/profile/link.html',
          url: 'http://www.google.com'
        },
{
          title: 'Example2',
          start: '2018-05-08',
          end: '2018-05-010',
          color: '#ff0000',
          lieu: 'New York',
          numero: '300446',
          conferencier: 'Steve Jobs',
          photoconferencier: 'http://www.example.com/img/profile2.jpg',
          lienconferencier: 'http://www.example.com/profile/link2.html',
          url: 'http://www.apple.com'
        },
      ],
    });

这是我的文本字段代码:

<input type="text" placeholder="Date : From" id="start_date">
<input type="text" placeholder="Date : To" id="end_date">

我想我必须添加这样的内容:

$('#start_date').on('change', function () {
                $('#calendar').fullCalendar('rerenderEvents');
            });
$('#end_date').on('change', function () {
                $('#calendar').fullCalendar('rerenderEvents');
            });

但我不确定。另外,请记住还有其他过滤器。因此,代码中的“eventRender”部分包含一堆东西。所以我需要确保“dateRange”过滤器不会破坏其他过滤器。

我在 FullCalendar 的网站上阅读了有关“visibleRange”的信息,但我不明白如何根据在 2 个“日期范围”文本字段中输入的内容使其工作。我认为禁用我设置的其他视图(仅在列表视图中显示结果)也是一个好主意。

知道如何让它发挥作用吗?我有点迷失在这里。 非常感谢


编辑:

我试过这段代码:

$('#start_date').on('change', function () {
      $('#calendar').fullCalendar('changeView', 'list', {
        start: 2018-05-10,
        end: 2018-05-30
      });            
});

哪个有效。基本上,它的作用是我在 ID 为“start_date”的文本字段中输入一个新日期(它使用 datepicker 脚本,这就是我使用“on change”的原因),它将视图更改为列表视图,这很棒,并且仅显示我输入的日期之间的事件。所以为了让它充满活力,我这样做了:

$('#start_date').on('change', function () {
  var start_date = $('#start_date').val();
  var end_date = $('#end_date').val();
      $('#calendar').fullCalendar('changeView', 'list', {
        start: start_date,
        end: end_date
      });            
});

我有 2 个字段,“start_date”和“end_date”。 我认为在 FullCalendar 的 changeView 代码中设置“开始”和“结束”选项会在我每次选择新日期时自动更新,但它不起作用。事实上,它部分地起作用。如果我先输入“end_date”,然后输入“start_date”,它将过滤并完美工作,显示正确的日期范围。但在那之后,我无法通过更改字段中的日期来将其更改为另一个 dateRange。 它的行为可能是因为我的函数是“on change”,基于“#start_date”元素。所以我必须先选择 end_date,以确保它过滤并使用“结束”选项中的内容更改视图。

知道我做错了什么吗?

谢谢


编辑 2:

我尝试将功能从“更改”事件更改为“单击”,并添加“搜索”按钮。这里有2个问题。 1 - 它只工作一次。如果我进行搜索,然后更改日期,然后再次单击“#search-range”按钮,它不会执行任何操作。

2 - 当它工作时(页面加载后的第一次),例如,如果我选择从 5 月 1 日到 5 月 5 日,由于某些原因,它将显示从 5 月 1 日到 5 月 4 日的范围。这是我的代码:

$('#search-range').on('click', function () {
  var start_date = $('#start_date').val();
  var end_date = $('#end_date').val();
  $('#calendar').fullCalendar('changeView', 'list', {
        start: start_date,
        end: end_date
      });            
});

有什么想法吗? 再次感谢

【问题讨论】:

  • 您是否尝试过使用“选项”方法fullcalendar.io/docs/dynamic-options 从您的“更改”事件中动态设置 visibleRange 属性?您可能还必须将默认视图设置为“list”而不是专门的“listMonth”,因此它没有预定义的时间段。这两件事都记录在fullcalendar.io/docs/visibleRange)。我还没有测试过,我现在没有时间,但是请尝试一下并告诉我。
  • 如果你有一个动态定义的“事件”属性(例如设置为 URL 或函数,而不是静态 JS 数组),那么我认为更改可见范围会自动导致它自动重新获取事件从服务器,并给服务器新定义的日期范围的开始和结束日期,所以它可以返回正确的事件信息。所以你不应该需要手动调用 refetchEvents 我不认为 - 再次,你可以测试它。
  • 您可以通过更改“标题”选项中列出的按钮来使其他视图不可用。
  • 感谢您的帮助。我设法部分使它与“changeView”一起工作。我已经编辑了我的第一篇文章(参见“编辑”部分)。知道如何解决我剩下的问题吗?谢谢!
  • 只需在输入字段前添加一个搜索图标并通过单击该按钮来处理事件范围

标签: javascript jquery fullcalendar


【解决方案1】:

您可能正在寻找validRange option

$('#start_date').on('change', function(){
  $('#calendar').fullCalendar('option', 'validRange', {
    // Don't worry if user didn't provide *any* inputs.
    start: this.value,
    end: $('#end_date').val()
  });
});

$('#end_date').on('change', function(){
  $('#calendar').fullCalendar('option', 'validRange', {
    // Don't worry if user didn't provide *any* inputs.
    start: $('#start_date').val(),
    end: this.value
  });
});

演示:https://jsfiddle.net/8wd7sxyv/

更新

  • 现在包括结束日期。因此,如果结束日期为 2018-05-31,则包括当天的事件——默认行为最多仅包括 2018-05-30
  • 如果开始和结束日期在同一个月,则视图为listMonth;否则为listYear
  • function filterByDateRange(start_date, end_date, format) {
      var s = $.fullCalendar.moment(start_date),
          e = $.fullCalendar.moment(end_date),
          v = $('#calendar').fullCalendar('getView'),
          a, b;
    
      // Start date is invalid; set it to the start of the month.
      if (! s.isValid()) {
        b = e.isValid();
        s = b ? e.clone() : $.fullCalendar.moment();
        s.date(1);
        $('#start_date').val(s.format(format));
        a = true;
      }
      // End date is invalid; set it to the end of the month.
      if (! e.isValid()) {
        b = s.isValid();
        e = b ? s.clone() : $.fullCalendar.moment();
        e.date(e.daysInMonth());
        $('#end_date').val(e.format(format));
        a = true;
      }
    
      // Start date is after end date; set it to a day before the end date.
      if (s.isAfter(e)) {
        s = e.clone().add('-1', 'day');
        $('#start_date').val(s.format(format));
      // End date is before start date; set it to a day after the start date.
      } else if (e.isBefore(s)) {
        e = s.clone().add('1', 'day');
        $('#end_date').val(e.format(format));
      }
    
      // Add 1 day so that `end_date` is inclusive.
      e = e.isValid() ? e.add('1', 'day') : e;
    
      $('#calendar').fullCalendar('option', 'validRange', {
        start: s.isValid() ? s : null,
        end: e.isValid() ? e : null
      });
    
      a = a || s.isSame(e, 'month');
      // If months are different, switch to the year list.
      if ('listYear' !== v.name && ! a) {
        $('#calendar').fullCalendar('changeView', 'listYear');
      // Otherwise, switch back to month list, if needed.
      } else if ('listMonth' !== v.name) {
        $('#calendar').fullCalendar('changeView', 'listMonth');
      }
    }
    
    $('#start_date').on('change', function(){
      filterByDateRange(this.value, $('#end_date').val(), 'YYYY-MM-DD');
    });
    
    $('#end_date').on('change', function(){
      filterByDateRange($('#start_date').val(), this.value, 'YYYY-MM-DD');
    });
    

    演示:https://jsfiddle.net/8wd7sxyv/6/

    【讨论】:

    • 太棒了!效果很好。我遇到的唯一问题是,如果我从“5 月 4 日”到“5 月 10 日”选择,它将不会显示 5 月 10 日的事件,而只会显示 5 月 4 日到 5 月 9 日的事件。由于某些原因,“end_date”总是像负1。 FullCalendar 是这样工作的,还是我能做些什么?另外,我需要它在同一个列表中显示所有事件。现在,如果我选择多个月份,它一次只会显示一个月。谢谢!
    • "FullCalendar 是这样工作的,还是我可以用它做些什么?" - 两者都是。我已经更新了答案。希望这对你有用。 =)
    猜你喜欢
    • 2019-09-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多