Page 1

Building a shared calendar with Backbone.js and FullCalendar: A step...

http://blog.shinetech.com/2011/08/05/building-a-shared-calendar-with...

The Shine Blog

Building a shared calendar with Backbone.js and FullCalendar: A step-by-step tutorial Posted on August 5, 2011 by Ben Teese

In a prior post, I explained how Backbone.js can be used to implement cascading select boxes. However, this was pretty much just a read-only affair, and these were relatively simple HTML elements. How does Backbone fare creating, updating and deleting data via a much more complex UI component? I recently had the chance to build a shared calendar tool with Backbone and FullCalendar, a jQuery plugin for a full-sized calendar with drag-and-drop capabilities. I was quickly able to get them playing nicely with each other, and in this entry I’ll cover step-by-step what it took to get there. Introducing FullCalendar FullCalendar is a great plugin. The documentation is complete and useful, and it’s not that hard to get it going – considering everything that it is capable of. Here’s a picture of it in action:

So how do we get a screen like this up and running? Let’s assume that we’ve got a RESTful service such that if we do a GET to /events, we are returned a JSON array of objects representing events, where each event will contain properties recognized by FullCalendar, specifically: A unique id A string title A start date, encoded in ISO8601 format (for example, ’2011-08-12T09:55:03Z’) An end date, encoded in ISO8601 format A color, encoded in any of the CSS color formats (for example ‘Red’, or ‘#ff0000′)

1 sur 20

22/05/2013 08:27


Building a shared calendar with Backbone.js and FullCalendar: A step...

2 sur 20

http://blog.shinetech.com/2011/08/05/building-a-shared-calendar-with...

We’ll assume that our server has been configured with some test data. Now we can write the following HTML: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15

<html> <head> <link rel='stylesheet' type='text/css' href='stylesheets/fullcalendar.css'/> <link rel='stylesheet' type='text/css' href='stylesheets/application.css'/> <script type='text/javascript' <script type='text/javascript' <script type='text/javascript' <script type='text/javascript' <script type='text/javascript' </head> <body> <div id='calendar'></div> </body> </html>

src='javascripts/jquery-1.5.1.min.js'></script src='javascripts/fullcalendar.min.js'></script src='javascripts/underscore.js'></script> src='javascripts/backbone.js'></script> src='javascripts/application.js'></script>

And then the following application.js file: 1 2 3 4 5 6 7 8 9 10 11 12 13 14

$(function(){ $('#calendar').fullCalendar({ header: { left: 'prev,next today', center: 'title', right: 'month,basicWeek,basicDay', ignoreTimezone: false }, selectable: true, selectHelper: true, editable: true, events: 'events' }); });

Running this will give us a calendar complete with events, which FullCalendar can load itself from the back-end. Even though we included the Backbone.js files, they’re not actually being used yet. Note the setting of ignoreTimezone to false. If we don’t do this, FullCalendar will ignore any timezone information we’ve embedded in our ISO8601 dates. Bringing in Backbone Instead of having FullCalendar load the events for us, let’s have Backbone do it and then pass them to FullCalendar to render. This is going to require us to introduce a Backbone model, collection and view: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16

$(function(){ var Event = Backbone.Model.extend(); var Events = Backbone.Collection.extend({ model: Event, url: 'events' }); var EventsView = Backbone.View.extend({ initialize: function(){ _.bindAll(this); this.collection.bind('reset', this.addAll); }, render: function() { this.el.fullCalendar({

22/05/2013 08:27


Building a shared calendar with Backbone.js and FullCalendar: A step...

3 sur 20

17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36

http://blog.shinetech.com/2011/08/05/building-a-shared-calendar-with...

header: { left: 'prev,next today', center: 'title', right: 'month,basicWeek,basicDay', ignoreTimezone: false }, selectable: true, selectHelper: true, editable: true }); }, addAll: function(){ this.el.fullCalendar('addEventSource', this.collection.toJSON()); } }); var events = new Events(); new EventsView({el: $("#calendar"), collection: events}).render(); events.fetch(); });

All of the action happens at the end. We create an events collection, and then a view that’s going to mediate between the collection and the calendar element in the DOM. This view registers itself to receive ‘reset’ events from the collection. Next, we render the view immediately, which pops the calendar on the page. At this stage however, the calendar will have nothing in it. Finally, we call events.fetch(), which causes Backbone to fetch the events from our back-end service and populate the collection with them. The collection then triggers a ‘reset’ event, which is detected by the view. The view then adds the events to the calendar as an event source, which will automatically cause the events to be displayed on the calendar. Note that the Events collection is not what’s passed into the calendar – instead we convert it to a plain array of JSON objects. Things like the id, title etc will only be available on each Event model via the get() function, whereas FullCalendar expects to be able to access them directly as properties. Fortunately, Backbone provides us with the toJSON method to do this transformation for us. Let’s start a dialog FullCalendar lets us detect when a period of time has been selected on the calendar. Let’s detect that event, and utilize jQuery UI to pop-up a dialog box for filling in the event details. First we have to add to the HTML. I’ve highlighted the new lines: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20

<html> <head> <link rel='stylesheet' type='text/css' href='stylesheets/jquery-ui-1.8.13.custom.css' <link rel='stylesheet' type='text/css' href='stylesheets/fullcalendar.css'/> <link rel='stylesheet' type='text/css' href='stylesheets/application.css'/> <script type='text/javascript' <script type='text/javascript' <script type='text/javascript' <script type='text/javascript' <script type='text/javascript' <script type='text/javascript' </head> <body> <div id='calendar'></div>

src='javascripts/jquery-1.5.1.min.js'></script src='javascripts/jquery-ui-1.8.13.custom.min.js' src='javascripts/fullcalendar.min.js'></script src='javascripts/underscore.js'></script> src='javascripts/backbone.js'></script> src='javascripts/application.js'></script>

<div id='eventDialog' class='dialog ui-helper-hidden'> <form> <div> <label>Title:</label>

22/05/2013 08:27


Building a shared calendar with Backbone.js and FullCalendar: A step...

4 sur 20

21 22 23 24 25 26 27 28 29 30

http://blog.shinetech.com/2011/08/05/building-a-shared-calendar-with...

<input id='title' class="field" type="text"></input> </div> <div> <label>Color:</label> <input id='color' class="field" type="text"></input> </div> </form> </div> </body> </html>

Note that the dialog is initially hidden. We’ll get the Javascript to render it when the user selects some date range on the calendar. We’ve already done this sort of thing with the FullCalendar component, so doing it with a jQuery UI dialog should be pretty straightforward. In the interests of brevity, I’m not going to include all of the code again, only those lines that have changed, plus some context: ... var EventsView = Backbone.View.extend({ ... render: function() { this.el.fullCalendar({ header: { left: 'prev,next today', center: 'title', right: 'month,basicWeek,basicDay', ignoreTimezone: false }, selectable: true, selectHelper: true, editable: true, select: this.select }); }, ... select: function(startDate, endDate) { new EventView().render(); }, }); var EventView = Backbone.View.extend({ el: $('#eventDialog'), initialize: function() { _.bindAll(this); }, render: function() { this.el.dialog({ modal: true, title: 'New Event', buttons: {'Cancel': this.close} }); return this; }, close: function() { this.el.dialog('close'); } }); ... Now when we select a date range, we see this:

22/05/2013 08:27


Building a shared calendar with Backbone.js and FullCalendar: A step...

5 sur 20

http://blog.shinetech.com/2011/08/05/building-a-shared-calendar-with...

I agree that having to enter a color as text is kind of poxy, but that’s not why we’re here. I’ll leave it as an exercise to you, dear reader, to improve that in the final version of the source code if you want. Oh, and there’s one other thing: this code doesn’t actually save anything yet. Creating Events Getting to this point wasn’t too hard, but it’s certainly more code than we’d probably have if we didn’t use Backbone. So the question arises: This is better…how? The advantage of Backbone comes in when we start putting some logic behind this UI. Let’s start with creating an event. Firstly, let’s assume that if we do a POST to /events with JSON representing an event, it’ll save that event and return it to us – including it’s newly-set id. With this service in place, we can now do the following: ... var EventsView = Backbone.View.extend({ ... select: function(startDate, endDate) { var eventView = new EventView(); eventView.collection = this.collection; eventView.model = new Event({start: startDate, end: endDate}); eventView.render(); } }); var EventView = Backbone.View.extend({ ... render: function() { this.el.dialog({ modal: true, title: 'New Event', buttons: {'Ok': this.save, 'Cancel': this.close} }); return this; }, save: function() { this.model.set({'title': this.$('#title').val(), 'color': this.$('#color').val()}); this.collection.create(this.model, {success: this.close}); }, ... }); ...

22/05/2013 08:27


Building a shared calendar with Backbone.js and FullCalendar: A step...

6 sur 20

http://blog.shinetech.com/2011/08/05/building-a-shared-calendar-with...

}); So now when a user selects a date range, we create a new Event model object and set the start and end date on it, before passing it to dialog, along with the collection that we’re expecting to add the new model to. We’ve also added a ‘Ok’ button to the dialog. It’ll now look like this when we put some data in it:

When the user clicks the ‘Ok’ button, it populates the remaining fields of the model, saves it to the back-end, then adds it to the collection. But there’s a problem here. The new event doesn’t appear on the screen. If we refresh the page it’ll show up, but we don’t want to have to do that. Instead, let’s have our EventsView register to receive notifications when a new model is added to the collection. When it detects this notification, it’ll render the new event into the calendar: ... var EventsView = Backbone.View.extend({ initialize: function(){ _.bindAll(this); this.collection.bind('reset', this.addAll); this.collection.bind('add', this.addOne); }, ... addOne: function(event) { this.el.fullCalendar('renderEvent', event.toJSON()); } }); ... So now, as soon as we click ‘OK’ and the booking is successfully saved to the back-end, it’ll appear in the calendar:

Awesome! We’ve got two views that are interacting, but only via a collection. Something else could add an event to the same collection, and the calendar would pick it up just the same. This is one of the strengths of

22/05/2013 08:27


Building a shared calendar with Backbone.js and FullCalendar: A step...

7 sur 20

http://blog.shinetech.com/2011/08/05/building-a-shared-calendar-with...

Backbone.js. Updating Events Now letâ&#x20AC;&#x2122;s add some support for updating events. Letâ&#x20AC;&#x2122;s assume we can do a PUT request to /events/[id] (where [id] is the ID of the event that we want to update) where the payload is JSON containing the updated details for the event. Now we can then extend the existing dialog to support both creation and editing: ... var EventsView = Backbone.View.extend({ render: function() { this.el.fullCalendar({ ... select: this.select, eventClick: this.eventClick }); }, ... eventClick: function(fcEvent) { this.eventView.model = this.collection.get(fcEvent.id); this.eventView.render(); } }); var EventView = Backbone.View.extend({ ... render: function() { this.el.dialog({ modal: true, title: (this.model.isNew() ? 'New' : 'Edit') + ' Event', buttons: {'Ok': this.save, 'Cancel': this.close}, open: this.open }); return this; }, open: function() { this.$('#title').val(this.model.get('title')); this.$('#color').val(this.model.get('color')); }, save: function() { this.model.set({'title': this.$('#title').val(), 'color': this.$('#color').val()}); if (this.model.isNew()) { this.collection.create(this.model, {success: this.close}); } else { this.model.save({}, {success: this.close}); } }, ... }); Note how: We added the open function to set the title and color textfields. This has the additional benefit of clearing out the fields when creating a new event. We use the Backbone.Model.isNew() method to determine whether we are editing or creating an event. Now when we click on an event, a dialog will pop-up and we can edit the details of that event:

22/05/2013 08:27


Building a shared calendar with Backbone.js and FullCalendar: A step...

8 sur 20

http://blog.shinetech.com/2011/08/05/building-a-shared-calendar-with...

However, when we click ‘OK’, we’ll have the same problem we had earlier: the calendar won’t redisplay the new details. To fix this, we need to detect the change and update our UI. Fortunately, the collection will emit a ‘change’ event if one of its models gets changed. We can listen for this event and take action: ... var EventsView = Backbone.View.extend({ initialize: function(){ _.bindAll(this); this.collection.bind('reset', this.addAll); this.collection.bind('add', this.addOne); this.collection.bind('change', this.change); this.eventView = new EventView(); }, ... change: function(event) { var fcEvent = this.el.fullCalendar('clientEvents', event.get('id'))[0]; fcEvent.title = event.get('title'); fcEvent.color = event.get('color'); this.el.fullCalendar('updateEvent', fcEvent); } }); ... Note that we have to lookup the underlying event object in the calendar in order to update it. Fortunately, FullCalendar makes this easy for us by providing the clientEvents method to look up events by ID. Now that we’ve done this, our event will be updated in the calendar immediately:

22/05/2013 08:27


Building a shared calendar with Backbone.js and FullCalendar: A step...

9 sur 20

http://blog.shinetech.com/2011/08/05/building-a-shared-calendar-with...

It even updated the color for us! How good is that? Moving and Resizing Events Updating an event’s name and color is OK, but what’d be really cool is if we could move and resize events on the calendar. Turn’s out it’s surprisingly easy: ... var EventsView = Backbone.View.extend({ ... render: function() { this.el.fullCalendar({ ... eventClick: this.eventClick, eventDrop: this.eventDropOrResize, eventResize: this.eventDropOrResize }); }, ... eventDropOrResize: function(fcEvent) { this.collection.get(fcEvent.id).save({start: fcEvent.start, end: fcEvent.end}); } }); ... Once again, we look the element up in the collection and update the appropriate details. It’s kind of hard to demonstrate with screenshots (I’d encourage you to get the source code if you’d like to take it for a spin yourself), but I can now, for example, move our updated booking back a week and change it to a four-day event:

What’s more, if I reload the page, the booking retains in its new location and length – the updates really have been saved to the back-end! Impressive, eh? Deleting Events Whilst we’re here, we might as well allow users to delete events. Let’s assume we can do a DELETE request to /events/[id],

where [id] is the ID of the event that we want to delete. We can then add a ‘Delete’ button to the

dialog box for editing an event. Sure, it’s not the prettiest UI in the world, but we’re not being paid for our good looks here, are we? ... var EventsView = Backbone.View.extend({ initialize: function(){ ...

22/05/2013 08:27


Building a shared calendar with Backbone.js and FullCalendar: A step...

10 sur 20

http://blog.shinetech.com/2011/08/05/building-a-shared-calendar-with...

this.collection.bind('destroy', this.destroy); ... }, ... destroy: function(event) { this.el.fullCalendar('removeEvents', event.id); } }); var EventView = Backbone.View.extend({ ... render: function() { var buttons = {'Ok': this.save}; if (!this.model.isNew()) { _.extend(buttons, {'Delete': this.destroy}); } _.extend(buttons, {'Cancel': this.close}); this.el.dialog({ modal: true, title: (this.model.isNew() ? 'New' : 'Edit') + ' Event', buttons: buttons, open: this.open }); return this; }, ... destroy: function() { this.model.destroy({success: this.close}); } }); ... So now, when we click on an event, we see a ‘Delete’ button:

When we click the ‘Delete’ button, the event model is deleted on the back-end. It’s collection detects this and emits a ‘destroy’ event, which is picked up by the EventsView. It then removes the event from the calendar, which puts us back to where we started this whole post:

22/05/2013 08:27


Building a shared calendar with Backbone.js and FullCalendar: A step...

11 sur 20

http://blog.shinetech.com/2011/08/05/building-a-shared-calendar-with...

So now we’ve come full circle: creating, editing and – lastly – deleting an event. Summing Up In this post I’ve shown how Backbone.js can work quite nicely with sophisticated jQuery plugins like FullCalendar. We’ve also worked through the full lifecycle of creating, reading, updating and deleting model objects – a task that Backbone makes easy. Finally, we’ve seen how Backbone’s event-based approach can decouple models from views, which reduces spaghetti code. In my opinion, frameworks like Backbone.js will have a strong role to play in the future of web development by proving that client-side Javascript development doesn’t have to be a structureless free-for-all. The final version of the source code in this blog entry can be found here Share this:

Like this: 3 bloggers like this.

About Ben Teese I'm a Senior Consultant at Shine Technologies. You can find me on Twitter and GitHub. View all posts by Ben Teese →

This entry was posted in AJAX, Javascript and tagged backbone.js, fullcalendar, jquery. Bookmark the permalink.

35 Responses to Building a shared calendar with Backbone.js and FullCalendar: A step-by-step tutorial akismet-a59efb2d5e8c0b994fb39e2d67a207be says: August 10, 2011 at 8:52 pm

Thanks, great tutorial. I’m also using Backbone and FullCalendar in a project at the moment, both tools work well together. Reply

22/05/2013 08:27


Building a shared calendar with Backbone.js and FullCalendar: A step...

12 sur 20

http://blog.shinetech.com/2011/08/05/building-a-shared-calendar-with...

Benjamin Lowenstein says: September 26, 2011 at 5:01 pm

Found this very helpful, thank you very much. Also believe that the two are a power-combo, and this is a generally insightful example of how to cleanly integrate feature-packed jquery plugins with the structure of backbone. Reply

PlanB says: November 8, 2011 at 10:36 pm

Very good tutorial, helped me a lot! But how could i store the events in a database like MySQL? Thats would be awesome for integrating that nice calendar in a webproject Reply

Ben Teese says: November 9, 2011 at 9:51 am

@PlanB The source code at https://github.com/shinetech/BackboneJsAndFullCalendar includes a Rails project for the back-end. This project is currently using sqlite3, but could be reconfigured to use MySQL by installing the appropriate gems and changing config/database.yml to point to your MySQL instance. Reply

PlanB says: November 10, 2011 at 1:36 am

I have tryed to sort the things out but ruby isnt my language, js is still difficult enough for me to figure out how i can get it working, but thank you very much i will try to understand the project and ruby and mvc to figure it out

webdev says: November 17, 2011 at 6:53 am

Popup window doesn’t work(chrome, ff) Reply

Manuel Alzola says: November 21, 2011 at 9:00 pm

Hello, an awesome tutorial, the best one i’ve seen on backbone on par with your own ‘Cascading Select Boxes’ I’m having a problem with it. In the first iteration, when you depend entirely on fullcalendar to fetch the json data, the service gets the start date and end date of the range selected in fullcalendar, but, since putting the responsability on the Backbone collection, that information is lost. How can I make it work again? Thank you very much for your wonderful work Manuel Alzola Madrid Reply

Manuel, Madrid says: November 23, 2011 at 12:19 am

I’ve found the answer to my rather silly question. Here it is: Replace events.fetch();

22/05/2013 08:27


Building a shared calendar with Backbone.js and FullCalendar: A step...

13 sur 20

http://blog.shinetech.com/2011/08/05/building-a-shared-calendar-with...

using instead: var view = $(‘#calendar’).fullCalendar(‘getView’); console.log(‘fetch start ‘ + view.start + ‘end ‘ + view.end); events.fetch({data: {start: Number(view.start), end: Number(view.end)}}); Reply

Sachin Gulaya says: November 29, 2011 at 3:19 pm

Hi Manuel, I think the issue relates to this code: select: function(startDate, endDate) { new EventView().render(); } I replaced that code with: select: function(start, end, allDay) { // changed from startDate and endDate this.eventView.collection = this.collection; this.eventView.model = new Event({start: start, end: end, allDay: allDay}); // changed from startDate and endDate this.eventView.render(); } By changing ‘startDate’ and ‘endDate’ to ‘start’ and ‘end’ I was able to get new events to fill the correct time slot on the calendar. If you look at the selectable.html example in the full calendar demo this is how full calendar suggests to do it. Reply

Jinu Mathews says: December 2, 2011 at 3:53 pm

on clicking the ok button in the add event pop up no action is taking place. How to do it? Reply

Victor says: March 22, 2012 at 1:32 am

Jinu, did you receive an answer or were you able to figure a solution to your question? I’m having the exact same problem. The calendar loads fine but when I select one or a couple days I get the pop-up and fill out the fields fine. If I click on ‘Cancel’ the window closes but when I click on “Ok” absolutely nothing happens. The pop-up doesn’t even disappears, I have to click on ‘Cancel’. I created the files in my own folders for the project I’m working on and downloaded a working from “public” but I’m still having the same problem. I’m not a novice to web development but I am to javascript though, so any help or guidance will be very much appreciate. Thank you everyone! Reply

Scott Mise says: January 3, 2013 at 2:37 am

I am also having this issue. Any solutions?

Sachin Gulaya says: December 31, 2011 at 7:36 am

22/05/2013 08:27


Building a shared calendar with Backbone.js and FullCalendar: A step...

14 sur 20

http://blog.shinetech.com/2011/08/05/building-a-shared-calendar-with...

Hi Ben, I found a bug in this implementation and I would appreciate your help in fixing it(I’ve spent ~8 hours tracking it down so far but I’m a novice in javascript). How to recreate it: Make a new event. Then use the forward arrow button in the top left corner to forward 5 weeks. Then go back 5 weeks using the back arrow. Your existing events will be there but your new event will not show up. If you go outside the scope of your defaultView(whether its agendaWeek, agendaDay, or month) the new event disappear until you refresh the page. The events that existed when you first loaded the calendar will still be there. So far it looks like a solution will involve having fullcalendar reload the events collection from backbone using the events option : http://arshaw.com/fullcalendar/docs/event_data/events_function/ or http://arshaw.com/fullcalendar/docs/event_data /events_json_feed/ . I’ve tried a few solutions(involving events.fetch() and events.toJSON() ) but am in over my head. Hopefully you can shine some light on this? Reply

Sachin Gulaya says: January 6, 2012 at 5:23 am

Hi Ben, any chance I can get some advice on how to fix this? Reply

Sachin Gulaya says: January 7, 2012 at 5:20 am

Finally solved it and it was ridiculously simple to do. Just needed to set the renderEvent [,stick] flag to true. addOne: function(event) { this.el.fullCalendar(‘renderEvent’, event.toJSON(), true); } http://arshaw.com/fullcalendar/docs/event_rendering/renderEvent/ Reply

swihart says: March 31, 2012 at 10:26 am

Just getting started with your awesome tutorial, thanks so much for putting it together, it’s just what I needed. But one thing I had to hurdle over right at the start was how you call fullCalendar as this.el.fullCalendar. I had to make it this.$el.fullCalendar, otherwise it gave me an error (Uncaught TypeError: Object # has no method ‘fullCalendar’) because I was trying to call fullCalendar on a plain HTML element, rather than a jQuery object. I found this explained in the second paragraph here, apparently Backbone automagically creates a jQuery object of el called $el? : http://gordonkoo.com/blog/2012/03/06/backbones-hard-dependency-on-jquery.html I notice the ToDo example Backbone app is coded the way I had to make it, with an initial el: $(‘#todoapp’), later referred to as $el, which made me feel a little better that I wasn’t missing something: http://documentcloud.github.com/backbone /examples/todos/index.html Still I wonder how you got it to work without the dollar sign. Reply

juan says: April 11, 2012 at 1:08 am

22/05/2013 08:27


Building a shared calendar with Backbone.js and FullCalendar: A step...

15 sur 20

http://blog.shinetech.com/2011/08/05/building-a-shared-calendar-with...

Hi Ben, i have a error this.el.fullCalendar fullcalecar is not a function, but if use $(this.el).fullCalendar … works well, this is correct?,should replace all occurrences of this.el for $(this.el), I am newbie to javascript and I’m not sure if it is correct or not taking the correct object el:$ (“# calendar”) correctly, sorry for my English, Greetings from Argentina. Thank you very much, very good tutorial! Reply

swihart says: April 11, 2012 at 6:02 am

I had the same issue juan, I don’t know if this is due to a change in how Backbone.js works in a newer version or how else it was working for Ben, but I think it’s correct to use $(this.el) where you need to use a jQuery function (ie fullcalendar) on `el`. Reply

Juan says: April 11, 2012 at 8:38 am

Tks swihart,I resolved to using the following : initialize: function(){ _.bindAll(this); this.collection.bind(‘reset’, this.addAll); this.el=$(this.el); }, I’m not sure if it’s the right way, but it works. Thank you very much!

juan says: April 18, 2012 at 12:13 am

Hello, I have doubts on how to implement the binding between the previous and next buttons and the collection of fullcalendar and refetch the collection, and display these events in the fullcalendar, any suggestions, thank you very much! Reply

swihart says: April 18, 2012 at 2:28 am

juan — I think what you want to do is just load everything into the Collection and have no callback associated with the next / prev buttons. This way the months change instantly without waiting for the data to be sent. I load the initial month’s data quickly for a better user-experience and then subsequently load all the data (replacing the initial data). You could make the data loading more complex if needed. This is what I’m doing (in Coffeescript).. events fetch data: ‘start__gte’: {{ start }} ‘end__lt’: {{ end }} success: fetch() {{ start }} and {{ end }} are variables passed into the template from my server-side framework (Django in my case). I set `start` to the 23rd day of the previous month and `end` to the 13th day of the following month, as this covers all potential days that FullCalendar might possibly display on the initial month view. “start__gte” and “end__lt” are parameters specific to my API. In my case I’m using Django-Tastypie, which leverages to power of Django’s ORM for making queries and filtering data.

22/05/2013 08:27


Building a shared calendar with Backbone.js and FullCalendar: A step...

16 sur 20

http://blog.shinetech.com/2011/08/05/building-a-shared-calendar-with...

When that transaction is over, the Backbone passes the Collection to FullCalendar to render the initial data. I then call fetch() with no parameters, so it grabs all the data (you might want to tailor this if you have a ton of events). This replaces the existing initial data in the Collection with the complete data set. One change I made to Ben’s code is in the “addAll” function, I insert $(this.el).fullCalendar(‘removeEvents’); before the ‘addEventSource’ part, so that when I load the full data set in from the second fetch(), the events from the initial fetch() are cleared and will not be duplicated. This resulted in a very noticeable boost in initial page loading, and the user doesn’t even realize data continues to load in the background. Hope that helps! Reply

juan says: April 18, 2012 at 10:35 pm

Thank you very much!! I tell you my solution, which will improve based on your proposal, two events associated with the prev and next buttons respectively, and thus go to the server to bring events to the days when the calendar is being shown: events: { ‘click. fc-button-next’, ‘fetch_events’ ‘click. fc-button-prev’, ‘fetch_events’ } fetch_events: function () { var start = this. $ el.fullCalendar (‘getView’). visStart; var end = this. $ el.fullCalendar (‘getView’). visEnd; this. $ el.fullCalendar (“removeEvents”); this.collection.reset (); this.collection.fetch ({data: {start: start, end: end}}); this.addAll (); } now see how to improve this with your proposal, of course thank you very much! Reply

juan says: April 24, 2012 at 11:49 pm

Hi, I’m having problems when saving a new event, giving me error: fcEvent is undefined…. fcEvent.title = event.get(‘title’); EventsView around: change: function (event) { // Lookup the model that has the ID of the event and update its attributes this.el.fullCalendar fcEvent = var (‘clientEvents’ event.get (‘id’)) [0]; event.get fcEvent.title = (‘title’); event.get fcEvent.color = (‘color’); this.el.fullCalendar (‘UpdateEvent’, fcEvent); } on change method to fix this, add the following option “wait: true” in the create eventView.save then is: save: function () { this.model.set ({ ‘title’: this. $ (‘# title’). val (), ‘color’: this. $ (‘# color’). val () }); if (this.model.isNew ()) { this.collection.create (this.model, { success: this.close, wait: true / / this lets wait for the server to save the event and return! }); Else {}

22/05/2013 08:27


Building a shared calendar with Backbone.js and FullCalendar: A step...

17 sur 20

http://blog.shinetech.com/2011/08/05/building-a-shared-calendar-with...

this.model.save ({}, { success: this.close }); } This event is found and updated, after being saved on the server. Hope this helps you, Greetings! Reply

John says: November 15, 2012 at 8:21 pm

Hi Juan, this doesn’t works for me. can you please help Reply

victor says: October 29, 2012 at 7:25 pm

hi, I have post a question to over stack overflow, can you help me? http://stackoverflow.com/questions/13115828/fullcalander-in-android-simulator Reply

Mohammed Abdulla says: November 10, 2012 at 4:09 am

Hi there, I’m getting an error that when I add a new event it updates the text of an existing event with the newly created events title. Furthermore when I click on the newly created event I get the error message this.model is undefined. Any ideas anyone? Reply

John says: November 15, 2012 at 8:14 pm

I am having the same issue. did you get the solution? Reply

John says: November 15, 2012 at 8:13 pm

When a freshly created event is clicked I am getting the error this.model is undefined. but after a refresh it works fine. the problem is the id doesn’t gets added to the event. can anyone please help me with that? Reply

seventhsense says: January 26, 2013 at 11:38 pm

I got a same problem. I don’t solve this yet. But I got a small hint. try this.. addOne: function(event) {

22/05/2013 08:27


Building a shared calendar with Backbone.js and FullCalendar: A step...

18 sur 20

http://blog.shinetech.com/2011/08/05/building-a-shared-calendar-with...

console.log event console.log event.toJSON() this.el.fullCalendar(‘renderEvent’, event.toJSON()); } The event Object have a correct id. But after toJSON() method, event.toJSON()’s id turned to be undefined. I have no idea to solve this yet. Reply

seventhsense says: January 27, 2013 at 9:30 am

At last I got a solution about this problem. Just add option {wait: true} when create. All work well now. http://stackoverflow.com/questions/11628076/backbone-js-getting-id-from-collection-create

Adrian says: November 24, 2012 at 10:30 am

Hey Ben. That was an awesome tut. I know I’m a year late but it was tres useful just the same. I began Backbone a month ago and have a few apps under my belt but for some reason, I still feel overwhelmed with the possibilities, especially when I come across some ingenious use of it that I didn’t think of myself Anyway, my problem today is FullCalendar itself. I need the CSS for selected days altered. I successfully added className ‘fc-selected’ to any selected day which took care of my background colour changes for that selected cell. Thinking that I was home free and only needed to change ‘color’ for the text, i was surprised that it didn’t work and only way later did I realize that the date events are not in the date cell but absolutely positioned above and outside of it. Here is where I need your help. How can I target the DOM of those events on selecting a date in the calendar? Reply

Ben Teese says: December 7, 2012 at 7:44 am

Hi Adrian, I haven’t done much work customizing the CSS for FullCalendar, but my colleague Greg Gross has. Greg suggests: “I’ve had a similar problem in the past. The way I handled it was to override the eventRender function (http://arshaw.com/fullcalendar/docs/event_rendering/eventRender/) when initialising my full calendar instance. If you return false from that method, it won’t do it’s default event rendering. You can find the table cell with jQuery and render whatever you want in there. eventRender: function(event, element, view) { var cell = view.dateCell(event.start); var $row = $(‘.fc-content table > tbody > tr:eq(‘ + cell.row + ‘)’); var $cell = $row.find(‘td:eq(‘ + cell.col + ‘)’); var $content = $cell.find(‘.fc-day-content > div’); // render whatever you want in $content return false; } This method worked for me, but it may have other consequences down the road, so you’ll have to try it out and see if it works for you.”

22/05/2013 08:27


Building a shared calendar with Backbone.js and FullCalendar: A step...

19 sur 20

http://blog.shinetech.com/2011/08/05/building-a-shared-calendar-with...

Hope this helps. Cheers, Ben Reply

victor says: November 27, 2012 at 12:22 pm

hi, I have test at chrome’s extension, window resizer with 320 X 480, its seem not fits perfectly, some is short some is taller if got event. how to make it fits perfectly on every mobile device? I have post this question to over stack overflow, can you help me? thanks http://stackoverflow.com/questions/13511957/fullcalendar-does-not-fit-perfectly-on-mobile Reply

x4f4r says: April 9, 2013 at 6:09 pm

Hi I am following this tutorial. I am having problem with showing events on calendar. I have following code var EventsView = Backbone.View.extend({ initialize: function () { _.bindAll(this); this.collection.bind(‘reset’, this.addAll); }, render: function () { this.$el.fullCalendar({ header: { left: ‘prev, next today’, center: ‘title’, right: ‘agendaWeek,agendaDay’, ignoreTimezone: false }, defaultView: ‘agendaWeek’, selectable: true, selectHelper: true, editable: true }); return this; }, addAll: function () { this.el.fullCalendar(‘addEventSource’, this.collection.toJSON()); } }); I have a complete question below http://stackoverflow.com/questions/15893859/events-are-not-shown-on-calendar-using-jquery-plugin-fullcalendar Reply

Pingback: Events are not shown on calendar using jquery plugin fullCalendar | BlogoSfera

22/05/2013 08:27


Building a shared calendar with Backbone.js and FullCalendar: A step...

20 sur 20

http://blog.shinetech.com/2011/08/05/building-a-shared-calendar-with...

Shine Technologies Theme: Customized Twenty Ten

Blog at WordPress.com.

22/05/2013 08:27

Fullcalendarandbackbone