1

I have been unable to implement fullcalendar into my application and cannot find any information detailing exactly how to implement it using node, express and handlebars. I've tried multiple ways of adding fullcalendar without any luck. Other web pages in my application are working and render their information so I don't know why fullcalendar won't work after following the instructions on the website.

<!-- main.handlebars -->

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/css/bootstrap.min.css" integrity="sha384-/Y6pD6FV/Vv2HJnA6t+vslU6fwYXjCFtcEpHbNJ0lyAFsXTsjBbfaDjzALeQsN6M"
    crossorigin="anonymous">
  <link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet" integrity="sha384-wvfXpqpZZVQGK6TAh5PVlGOfQNHSoD2xbE+QkPxCAFlNEevoEH3Sl0sibVcOQVnN" crossorigin="anonymous">
  <!-- Page level plugin CSS-->
  <link href="vendor/datatables/dataTables.bootstrap4.css" rel="stylesheet">
  <!-- Custom styles for this template-->
  <link href="css/sb-admin.css" rel="stylesheet">
  <link href="css/style.css" rel="stylesheet">

  <!-- Link and script for calendar -->
  <link rel='stylesheet' href='../../node_modules/fullcalendar/dist/fullcalendar.css' />
  <script src='../../node_modules/jquery/dist/jquery.min.js'></script>
  <script src='../../node_modules/moment/min/moment.min.js'></script>
  <script src='../../node_modules/fullcalendar/dist/fullcalendar.js'></script>
  <script>
    $(document).ready(function() {
  
      // page is now ready, initialize the calendar...
      
      $('#calendar').fullCalendar({
      // put your options and callbacks here
        header: {
          left: 'prev, next, today',
          center: 'title',
          right: 'month,agendaWeek,agendaDay'
        },
        editable: true,
        timezone: "local",
        defaultView: "month",
        firstHour: "7",
        weekMode: "liquid"
      });
      
    });
  </script>

  <title>Workmate</title>
</head>

<body>
  {{#if user}}
    {{> _appNavbar}}
  {{else}}
    {{> _navbar}}
  {{/if}}

  <div class="container">
    {{> _msg}}
    {{> _errors}}
    {{{body}}}
  </div>

  <script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN"
    crossorigin="anonymous"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.11.0/umd/popper.min.js" integrity="sha384-b/U6ypiBEHpOf/4+1nzFpr53nxSS+GLCkfwBdFNTxtclqqenISfwAzpKaMNFNmj4"
    crossorigin="anonymous"></script>
  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/js/bootstrap.min.js" integrity="sha384-h0AbiXch4ZDo7tp9hKZ4TsHbi047NrKGLO3SEJAg45jXxnGIfYzk4Si90RDIqNm1"
    crossorigin="anonymous"></script>
</body>

</html>

After the main.handlebars I have the schedule.handlebars which should load the empty calendar.

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

I've followed the instructions on the fullcalendar website and it doesn't render the calendar on the schedule.handlebars page.

// webapp.js

//App schedules route
router.get('/schedules', ensureAuthenticated, (req, res) =>{
  res.render('webapp/schedules');
});

This is all the code I have to implement the application. Any help will be greatly appreciated as this is for my final year project in college.

Thanking you all in advance.

2 Answers2

1

Not sure if anyone would be interested, but after quite some time spent on trial & errors (lots of errors), I managed to make this work in conjunction with Handlebars.

First, I had to write a separate .js file (calendar.js) for the $(document).ready function:

$(document).ready(function() {
  // Let's make sure that this 2 little critters get loaded, otherwise fullcalendar wont work.
  $.when (
    $.getScript("/s/js/moment.min.js"),
    $.getScript("/s/calendar/fullcalendar.min.js"))
    .done(function() 
    {
      $('#calendar').fullCalendar({
        header: {
          left: 'prev,next today',
          center: 'title',
          right: 'listDay,listWeek,month'
        },

        // customize the button names,
        // otherwise they'd all just say "list"
        views: {
          listDay: { buttonText: 'list day' },
          listWeek: { buttonText: 'list week' }
        },

        defaultView: 'listWeek',
        defaultDate: '2018-03-12',
        navLinks: true, // can click day/week names to navigate views
        editable: true,
        eventLimit: true, // allow "more" link when too many events
        events: [
          {
            title: 'All Day Event',
            start: '2018-03-01'
          },
          {
            title: 'Long Event',
            start: '2018-03-07',
            end: '2018-03-10'
          },
          {
            id: 999,
            title: 'Repeating Event',
            start: '2018-03-09T16:00:00'
          },
          {
            id: 999,
            title: 'Repeating Event',
            start: '2018-03-16T16:00:00'
          },
          {
            title: 'Conference',
            start: '2018-03-11',
            end: '2018-03-13'
          },
          {
            title: 'Meeting',
            start: '2018-03-12T10:30:00',
            end: '2018-03-12T12:30:00'
          },
          {
            title: 'Lunch',
            start: '2018-03-12T12:00:00'
          },
          {
            title: 'Meeting',
            start: '2018-03-12T14:30:00'
          },
          {
            title: 'Happy Hour',
            start: '2018-03-12T17:30:00'
          },
          {
            title: 'Dinner',
            start: '2018-03-12T20:00:00'
          },
          {
            title: 'Birthday Party',
            start: '2018-03-13T07:00:00'
          },
          {
            title: 'Click for Google',
            url: 'http://google.com/',
            start: '2018-03-28'
          }
        ]
      }
    );
  }
  );
});

Then onto the Handlebars template:

<section>
<style>
    #calendar {
        max-width: 800px;
        margin: 0 auto;
    }
</style>
<div id='calendar'></div>

and finally my app.jes file looked something like this:

app.get("/", async(req, res, next) => {
try {
    let projectid = '2188'
    let users = await req.app.locals.db.getRate(projectid);
    res.render("listview", {
        title: "Calendar",
        rows: users,
        scripts: ["/js/views/calendar.js"]
    });
} catch (ex) {
    return next(ex);
}

});

There are a couple of required css files, which were linked on the master Handlebars template.

I'm sure this isn't the best way to integrate it, as I'm really new to NodeJS and overall Javascript, but after a long weekend trying to figure this out, seeing the calendar render was refreshing.

Hope this helps anyone.

cheers!

0

I can see two potential issues. You are including some local scripts like that:

<!-- Link and script for calendar -->
<link rel='stylesheet' href='../../node_modules/fullcalendar/dist/fullcalendar.css' />
<script src='../../node_modules/jquery/dist/jquery.min.js'></script>
<script src='../../node_modules/moment/min/moment.min.js'></script>
<script src='../../node_modules/fullcalendar/dist/fullcalendar.js'></script>

Do you expose the node_modules directory through express in order to be able to serve those files? Have a look here: https://expressjs.com/en/starter/static-files.html

It is not good practice though to expose the node_modules directory though, it is better if you have a building step of your application that will copy over all your libraries into a dedicated dist directory and ideally will minify and uglify them as well.

The second thing that can be problematic is the place that you include your script. It is good practice to move all the js imports inside the body just before the body closing tag (). You already defined some there. The document ready function will run but the div with the id calendar will not be there. More details here: Where should I put <script> tags in HTML markup?

Update 1

You need to be able to server the files in the node_modules (it is not a good practice though) like that:

app.use('/modules', express.static(path.join(__dirname, 'node_modules')))

And then include your script paths like that:

<link rel='stylesheet' href='/modules/fullcalendar/dist/fullcalendar.css' />
<script src='/modules/jquery/dist/jquery.min.js'></script>
<script src='/modules/moment/min/moment.min.js'></script>
<script src='/modules/fullcalendar/dist/fullcalendar.js'></script>
Stavros Zavrakas
  • 3,045
  • 1
  • 17
  • 30
  • I have a static 'public' file already, I've tried implementing it by using this method but it doesn't work that way either. Also I have moved the – Levent Arslan Nov 15 '17 at 13:31
  • can you send here the static public line of your webapp.js? – Stavros Zavrakas Nov 15 '17 at 15:27
  • app.use(express.static(path.join(__dirname, 'public'))); – Levent Arslan Nov 15 '17 at 16:00
  • @LeventArslan I did an update, please have a look above – Stavros Zavrakas Nov 15 '17 at 16:25
  • I've attempted to do that and it still isn't appearing can you have a look at the app? https://github.com/Leventarsenal/Workmate This is for my final year project in college so any help would be greatly appreciated – Levent Arslan Nov 15 '17 at 16:50
  • @LeventArslan I can't give you the solution, you have to understand first. Your pages are trying to load a bunch of js files that do not exist in your project at all. For example, in the main.handlebars there is the vendor/datatables/dataTables.bootstrap4.css that do not exist in the project at all and in the employees.handlebars all the script paths are broken and dont' exist in the project as well. Why do you have all these inclusions? – Stavros Zavrakas Nov 16 '17 at 09:30
  • @LeventArslan - Just a tip. Remove all the scripts that you don't need (I've mentioned them above). Move all your js includes of the main.handlebars at the head. There is a conflict with the jquery versions, you have to remove the jquery-3.2.1.slim.min.js. The document.ready that is initialising the calendar shouldn't happen in the main file. It must be moved to the specific file that you want to initialise the calendar. – Stavros Zavrakas Nov 16 '17 at 09:42
  • You have to study more about the response / request cycle and how the browser requests the script and the css files when is about to render the page. Find some resources and then you'll be able to understand better the issue that you have. – Stavros Zavrakas Nov 16 '17 at 09:45
  • I have my style.css file working already. I know about the response/request cycle. It's just this calendar will not work for me for some reason. Thanks for all your help anyway. I appreciate you taking time out to help me – Levent Arslan Nov 16 '17 at 11:03