George
George

Reputation: 734

Fullcalendar using week view, navigate month by month instead of week by week

I am using fullcalendar to implement a schedule for a school where the classes are in specific days for the entire month, for example a class can be on TTH or MWF, TWTH etc.

I am trying to implement a week view but I want to navigate month by month so I don't have to display the same class every specific day on the entire month (on month view). Inspired by this question I tried to implement the following:

$('#calendar').fullCalendar({
defaultView: 'customWeek',
views: {
    customWeek: {
        type: 'week',
        duration: {months: 1}
    }
}
});

but this implementation did not force the view to start on the beginning of the month, so if I navigate through the calendar the next view will start on the second day of the month or the third, or sometimes on the last day of the previous month.

I also tried to make it work with CSS on month view so it looks like a week view:

.fc-day-top .fc-day-number{
   display: none;
}

.fc td {
  border-bottom: 0 !important;
  border-top: 0 !important;
}

.fc-head {
  border-top: 1px solid black !important;
  border-bottom: 1px solid black !important;
}
.fc-body{
  border-bottom: 1px solid black !important;
}

but I lost the time slots at the beginning of the calendar and the events are stuck at the top of it and they look bad.

calendar

So I am searching for the best approach to complete this task.

Upvotes: 1

Views: 1606

Answers (1)

Louys Patrice Bessette
Louys Patrice Bessette

Reputation: 33943

That one was fun! So the trick is to hide the .fc-week rows we don't want to see in a month view. Then, we don't have to mess with the normal navigation.

To do this, we have to target which row we want to see. I made 2 options here:

  1. The week which contains the 1st of the month
  2. The first full week (no day of previous month)

It can be "switched" in code using two booleans. It is now setted for the second option.

Feel free to ask for any question! ;)

// Switches about what to display
// Use only one of the two to true.
var FIND_first_full_week = true;
var FIND_first_day_of_month = false;


$("#calendar").fullCalendar({

  viewRender: function(){
    var ShowWeek;
    var weeks = $(".fc-week");

    // Find the first day of the month
    if(FIND_first_day_of_month){
      for(i=0;i<weeks.length;i++){
        var days = weeks.eq(i).find(".fc-day-number");
        days.each(function(){
          if( $(this).html()=="1" && !$(this).parent().is(".fc-other-month") ){
            ShowWeek = i;
          }
        });
      }
    }
    
    // Find first full week of the month (no day in past month)
    if(FIND_first_full_week){
      for(i=0;i<weeks.length;i++){
        var firstFullWeek = false;
        var dayCount=0;

        var days = weeks.eq(i).find(".fc-day-number");
        days.each(function(){
          if(!firstFullWeek){
            if( !$(this).parent().is(".fc-other-month") ){
              dayCount++;
              if(dayCount==7){
                firstFullWeek = true;
                ShowWeek = i;
                i = weeks.length;
              }
            }
          }
        });
      }
    }
    
    // Fix FullCalendar display!
    setTimeout(function(){
      weeks.not(weeks.eq(ShowWeek)).css({"display":"none"});
      var weekHeight = weeks.height();
      $(".fc-day-grid-container").css({"height":weekHeight});
    },10);
  }
});
/* Your CSS */
.fc td {
  border-bottom: 0 !important;
  border-top: 0 !important;
}

.fc-head {
  border-top: 1px solid black !important;
  border-bottom: 1px solid black !important;
}
.fc-body{
  border-bottom: 1px solid black !important;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/fullcalendar/3.4.0/fullcalendar.css" rel="stylesheet"/>

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.1/moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/fullcalendar/3.4.0/fullcalendar.min.js"></script>

<div id="calendar"></div>

Upvotes: 2

Related Questions