2

I have a calendar using FullCalendar, which is going to be used as a reservation system for a small massage salon.

Instead of showing all events including it's data to the website visitor, I want existing events to be not-clickable, while being grayed out without showing it's text so visitors just get an unavailable/available slots effect.

I have tried to find a solution on the internet but without any luck. My code to reproduce my situation:

<div id='calendar'></div>

<script>
 $('#calendar').fullCalendar({
         events: [
        {
            title  : 'event1',
            start  : '2019-03-20'
        },
        {
            title  : 'event2',
            start  : '2019-03-15',
            end    : '2019-03-18'
        }
    ],
 })
</script>

I'm almost sure I have to use viewRender, I just don't know how. Hope any of you guys is able to help me out.

http://jsfiddle.net/24973uey/7/

Tim Hef
  • 83
  • 1
  • 8
  • If you want to highlight unavailable slots, without showing any information about them, feeding them to fullCalendar as [Background events](https://fullcalendar.io/docs/background-events) might be a good way to achieve that. And of course if things like the title are private to the person who created the event, then when showing those events to other users, don't include the real title in your event feed (because even if it's not shown on screen, it would be visible in the browser's Developer Tools to those who know where to look). – ADyson Mar 22 '19 at 11:02

1 Answers1

1

you can do this with eventRender like this.

Edit: other possibilities with eventRender

$(function() {
  $('#calendar').fullCalendar({
 events: [
  {
   title  : 'event1',
   start  : '2019-03-20'
  },
  {
   title  : 'event2',
   start  : '2019-03-15',
   end    : '2019-03-18'
  }
 ],
 eventRender: function(event, element) {
  /* the following block will mark days with event
  // get container
  var container = element.closest('.fc-content');
  if ((typeof event.start != 'undefined') && (event.start!=null)) {
   // create new instance of date start to iterate
   var dcurr = new Date(event.start);
   var dend = (typeof event.end != 'undefined') && (event.end!=null)? event.end : event.start;
   // paint date cell
   while(dcurr<=dend){
    var strDate = dcurr.getFullYear()+'-'+('0'+(dcurr.getMonth()+1)).slice(-2)+'-'+('0'+dcurr.getDate()).slice(-2);
    // get cell reference & set background
    $('td[data-date="'+strDate+'"]',container).css('background-color','#ccc');
    // iterate next date
    dcurr.setDate(dcurr.getDate()+1);
   }
  }
  // prevent this event to be displayed on table
  return false;
  */
  
  // the following block will change event block style only 
  element.css({backgroundColor:'#ccc',border:'1px solid #999'});
  $('.fc-event-title',element).html('');
   }
  });
});
<link type="text/css" rel="stylesheet" href="http://cdnjs.cloudflare.com/ajax/libs/fullcalendar/1.6.4/fullcalendar.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script type="text/javascript" src="http://cdnjs.cloudflare.com/ajax/libs/fullcalendar/1.6.4/fullcalendar.min.js"></script>

<div id="calendar">

</div>

Edit :

another scenario : unclickable date when there is an event. (I'm using latest fullCalendar on this example)

  $(function() {
    var cal = new FullCalendar.Calendar($('#calendar')[0], {
   events: [
    {
     title  : '',
     start  : '2019-03-20'
    },
    {
     title  : '',
     start  : '2019-03-15',
     end    : '2019-03-18'
    }
   ],
   plugins: [ 'dayGrid','interaction' ],
   dateClick:function(info) {
        // check class we've set on eventRender
    if(!$(info.dayEl).hasClass('hasEvent')) {
     alert(info.dateStr)
    }
   },
   eventRender: function(info) {
    if ((typeof info.event.start != 'undefined') && (info.event.start!=null)) {
     var container = info.el.closest('.fc-content');
     // create new instance of date start to iterate
     var dcurr = new Date(info.event.start);
     var dend = (typeof info.event.end != 'undefined') && (info.event.end!=null)? info.event.end : info.event.start;
     // paint date cell
     while(dcurr<=dend){
      var strDate = dcurr.getFullYear()+'-'+('0'+(dcurr.getMonth()+1)).slice(-2)+'-'+('0'+dcurr.getDate()).slice(-2);
      // get cell reference & add class to mark it
      $('td[data-date="'+strDate+'"]',container).addClass('hasEvent');
      // iterate next date
      dcurr.setDate(dcurr.getDate()+1);
     }
    }
    $(info.el).css({backgroundColor:'#ccc',border:'1px solid #999'});
   }
    });
    cal.render();
  });
 <link type="text/css" rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fullcalendar/core@4.0.1/main.min.css">
 <link type="text/css" rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fullcalendar/daygrid@4.0.1/main.min.css">
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
 <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/@fullcalendar/core@4.0.1/main.min.js"></script>
 <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/@fullcalendar/daygrid@4.0.1/main.min.js"></script>
 <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/@fullcalendar/interaction@4.0.1/main.min.js"></script>
 <div id="calendar">

 </div>
scott6
  • 745
  • 6
  • 8
  • Mm, it returns Cannot read property 'closest' of undefined at element.closest('.fc-content') – Tim Hef Mar 22 '19 at 07:00
  • How does that come? – Tim Hef Mar 22 '19 at 07:39
  • @TimHef perhaps you are using different library version. fyi, i'm using version 1.6.4. If you are using current version, please check this link for more info for eventRender: https://fullcalendar.io/docs/eventRender – scott6 Mar 22 '19 at 08:27
  • Thanks for your help by the way, I made it work. But it is color marking the full day instead of only the events. So if a day has a event it's fully gray? – Tim Hef Mar 22 '19 at 09:15
  • @TimHef: sorry for my missperception.. please see my updated answer, is that what you are looking for? :) – scott6 Mar 22 '19 at 09:31
  • @TimHef : or if you're just want to play with styling, you can do this with pure css like `.fc-event {background: #ccc !important; }` and set all of your event title to empty string to hide its text – scott6 Mar 22 '19 at 09:46
  • Almost, I managed to hide the events using the last 2 lines of your code, thanks. The only thing left is that they should not be clickable, at the moment I can still click them. Sorry for bothering so much, I really really appriciate your help! – Tim Hef Mar 22 '19 at 09:47
  • I rather do it within the plugin itself, it's so end users can have the unavailable/available slots experience.. – Tim Hef Mar 22 '19 at 09:48
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/190488/discussion-between-tim-hef-and-scott6). – Tim Hef Mar 22 '19 at 10:06
  • @TimHef: i'm not seeing any action when i click an event above (run code snippet above). are you using `eventClick` on your fullCalendar object? if so, you can remove it :) – scott6 Mar 22 '19 at 10:08