inicio mail me! sindicaci;ón

Making a Real Calendar in Rails

For a while now, i have been looking at the various calendar helpers on Github. One thing stands out over all of them: they all suck.

bad_calendar

Why? well, they all implement the same basic concept – that is, they make a table containing rows for each week, and cells for each day, yielding in case the user wants to display anything other than a day number in the cell.

This is fine if all you want to do is display single-day events, but if you want to go to the next level and display multiple “all day” events it is practically impossible as the events are constrained in their table cell. Instead, another approach is needed.

good_calendar

The approach? Well, put simply the events are placed in a row below each set of day cells. Events which span more than 1 row are repeated, and a layout algorithm handles vertical placement.

Now rather than writing a whole post describing in agonising detail how to implement this approach, i thought i’d post a gist on github describing how to do it. Read it here. Any improvements? Feel free to fork. Comments? feel free to post below!

 

Update: The great guy’s over at elevation have turned this code into a plugin. So if you don’t fancy implementing this all by yourself, just use the easy to install plugin. :)

  • Jeff Schuil
    I took your example from gist, adapted it for my needs, and just extracted it to a plugin on github.

    http://dev.elevationblog.com/2009/7/23/event-ca...

    Thanks for the help!
  • John
    That's really neat and thank you for creating the plugin! However, is there a way to create links on the event strips to link to other pages? Like clicking on a strip would redirect you to another page where it listed more detailed event information?
  • James Urquhart
    Regarding the plugin, as with my original code you can customise the event view by passing a block to the calendar helper (along with the configuration options). i.e.:

    calendar event_calendar_options do |event|
    "<div>#{h(event.name)}</div>"
    end
  • James Urquhart
    Neat. Linked to from the post! :D
  • kevin
    I appreciate you efforts here but you said that your gist contains all the code that you used for an example app but where is the migrations data?
  • James Urquhart
    Kevin,

    Good point. I don't have the schema off hand, but it went something like...

    Events:
    id(int), calendar_id(int), name(string), created_by_id(int), updated_by_id(int), start_date(datetime), end_date(datetime), repeat_id(int)
    Calendar
    id(int), name(string), created_by_id(int), updated_by_id(int)

    The key bits being the Calendar and the calendar_id, start_date, end_date, and name on the Event.

    Obviously modify to suit your needs :)

    Hope that helps! :)
  • Mike
    Did you think in write a new plugin with your changes?

    Thanks
  • pimpmaster
    I just followed your GIST to the letter and got a nasty MySQL error :(

    http://pastie.textmate.org/404595
  • James Urquhart
    Apologies. I have posted a GIST which contains all the code i used in an example app, if that helps with your implementation..

    http://gist.github.com/74325
  • Tom Dickie
    I'm a complete newbie, so my apologies. Do I install calendar_plugin (topfunky's) and then copy and paste the code from the gist over the top? Specificially I'd love to know how to integrate this into my Rails app.
  • James Urquhart
    For this particular implementation, i started off with http://github.com/febuiles/cute_calendar/tree/m.... Then ended up merging most of it to my application helpers.
  • This is good. What about going the extra step and exporting it to iCal, Google Calendar, etc? Do you know of any plugins/gems/tutorials on how to go about tacking that?

    Thanks
  • James Urquhart
    For exporting to iCal, i suggest using the iCalendar gem - http://icalendar.rubyforge.org/ - which is pretty simple and straight forward to use (using an ics mime handler), especially if you use an event schema as suggested by the gist.
blog comments powered by Disqus