What we're listening to:
Jared

The Album Leaf:
Into The Blue Again
Jeff

Paper Route:
Absence

Event Calendar Rails Plugin

July 23rd, 2009

For a recent project we needed to show events on a calendar. The existing Rails plugins we tried didn’t allow us to satisfactorily show multiple, overlapping events across calendar days and rows.

I found the same complaint here and began to adapt it to our needs.

I’ve extracted the result and put it on github in the hopes that others might find it useful and/or add improvements.

http://github.com/elevation/event_calendar

The above link has more details, as well as how to install and use the plugin.

Here’s the 1000 word screenshot:

Event Calendar Screenshot

Using the use_all_day option:

Event Calendar using all day option

PLEASE:

Thanks and enjoy!

  • http://rubyclub.com.ua/ Ruslan

    What do you think about add to default generation next rows
    routes.rb
    map.event '/event/:id', :controller => 'calendar', :action => 'show_event'

    #in CalendarHelper override methoddef event_calendar
    calendar event_calendar_opts do |event|
    link_to_remote(content_tag(:div, h(event.name)),
    :url => event_path(event),
    :title => "#{h(event.name)}: #{event.start_at} to #{event.end_at}",
    :href => event_path(event)
    )
    end
    end

  • http://rubyclub.com.ua/ Ruslan

    What do you think about add to default generation next rows
    routes.rb
    map.event '/event/:id', :controller => 'calendar', :action => 'show_event'

    #in CalendarHelper override method

    def event_calendar
      calendar event_calendar_opts do |event|
        link_to_remote(content_tag(:div, h(event.name)),
          :url =>  event_path(event),
          :title => "#{h(event.name)}: #{event.start_at} to #{event.end_at}",
          :href => event_path(event)
        )
      end
    end
  • http://rubyclub.com.ua/ Ruslan

    And I think need use mb_chars for correctly strip day names in multilingual projectsday_names.each do |d|
    unless d[options[:abbrev]].eql? d
    cal << %(#{d.mb_chars[options[:abbrev]]})
    else
    cal << %(#{d.mb_chars[options[:abbrev]]})
    end
    end

  • http://rubyclub.com.ua/ Ruslan

    And I think need use mb_chars for correctly strip day names in multilingual projects

    day_names.each do |d|
      unless d[options[:abbrev]].eql? d
        cal < < %(#{d.mb_chars[options[:abbrev]]})
      else
        cal << %(#{d.mb_chars[options[:abbrev]]})
      end
    end
    
  • Sean Dunn

    Thanks the quick response Jeff. I did try wrapping the start_date and end_date in getters and setters but unfortunately ran that wouldn’t work with the SQL in event_calendar.rb.

    In the end I just did a project find and replace for start_at and end_at and it so quick to do that I was kicking myself for not trying it earlier!

    Only problem I have now is that I’ve effectively forked the plugin. Oh, well.

    If I think of a more elegant solution I’ll pass it back as a patch.

  • Sean Dunn

    Thanks the quick response Jeff. I did try wrapping the start_date and end_date in getters and setters but unfortunately ran that wouldn’t work with the SQL in event_calendar.rb.

    In the end I just did a project find and replace for start_at and end_at and it so quick to do that I was kicking myself for not trying it earlier!

    Only problem I have now is that I’ve effectively forked the plugin. Oh, well.

    If I think of a more elegant solution I’ll pass it back as a patch.

  • Pingback: Event Calendar HTML Generation Rewrite | ELEVATION Dev Blog

  • Chris K

    Excellent! Thanks a lot, the calendar looks great, and was extremely easy to implement.

    Couple of issues:

    -do you know why IE 8 in both modes (compatibility and regular) misaligns the rows with day numbers? They are off by a couple of pixels to the right. Is this an easy CSS fix?
    -is it just my implementation or the events that wrap down to the next row do not have one hover effect for all days in the event? The part in one row “hovers” independently of the part in the following row.

    I can live with both of those (unless my client checks it in IE 8, then I’m screwed… LOL) so again, big THANKS, but awaiting your input. Later.

  • http://none Chris K

    Excellent! Thanks a lot, the calendar looks great, and was extremely easy to implement.

    Couple of issues:

    -do you know why IE 8 in both modes (compatibility and regular) misaligns the rows with day numbers? They are off by a couple of pixels to the right. Is this an easy CSS fix?
    -is it just my implementation or the events that wrap down to the next row do not have one hover effect for all days in the event? The part in one row “hovers” independently of the part in the following row.

    I can live with both of those (unless my client checks it in IE 8, then I’m screwed… LOL) so again, big THANKS, but awaiting your input. Later.

  • Jeff Schuil

    @Chris K

    I just checked it in IE8, and everything looks good. I’m guessing you have a CSS style adding some extra padding. Try displaying with just the event_calendar.css stylesheet and see if it looks ok. If it does, then check your other stylesheets, particularly those that set styles for td elements.

    As for the hover effect working across calendar rows… This is done in the javascript method event_select, with the default implementation using prototype for selecting elements. Make sure you have both the prototype and event_calendar.js files included in your page. (There is also a jQuery version of event_select, if that is what you prefer.)

  • http://yourelevation.com Jeff Schuil

    @Chris K

    I just checked it in IE8, and everything looks good. I’m guessing you have a CSS style adding some extra padding. Try displaying with just the event_calendar.css stylesheet and see if it looks ok. If it does, then check your other stylesheets, particularly those that set styles for td elements.

    As for the hover effect working across calendar rows… This is done in the javascript method event_select, with the default implementation using prototype for selecting elements. Make sure you have both the prototype and event_calendar.js files included in your page. (There is also a jQuery version of event_select, if that is what you prefer.)

  • Chris K

    Aaahhh… awesome, I was missing the event_calendar.js include. Now multiple rows work great.

    I’ll check my other CSSs, at least I know the problem’s on my end (although that’s weird as IE 7 shows OK).

    This is some neat piece of code – again thanks a lot, both for sharing the plugin AND the support you’ve been offering!

    Much appreciated!

  • http://none Chris K

    Aaahhh… awesome, I was missing the event_calendar.js include. Now multiple rows work great.

    I’ll check my other CSSs, at least I know the problem’s on my end (although that’s weird as IE 7 shows OK).

    This is some neat piece of code – again thanks a lot, both for sharing the plugin AND the support you’ve been offering!

    Much appreciated!

  • Lee

    I tried “script/generate event_calendar” and received:

    D:/workspace/temp/script/../config/boot.rb:20:Warning: Gem::SourceIndex#search support for String patterns is deprecated, use #find_name
    c:/ruby/lib/ruby/gems/1.8/gems/activesupport-1.4.4/lib/active_support/dependencies.rb:376:in `new_constants_in’: You have a nil object when you didn’t expect it! (NoMethodError)
    You might have expected an instance of Array.
    The error occurred while evaluating nil.empty? from c:/ruby/lib/ruby/gems/1.8/gems/activesupport-1.4.4/lib/active_support/dependencies.rb:202:in `load_file’

  • Lee

    I tried “script/generate event_calendar” and received:

    D:/workspace/temp/script/../config/boot.rb:20:Warning: Gem::SourceIndex#search support for String patterns is deprecated, use #find_name
    c:/ruby/lib/ruby/gems/1.8/gems/activesupport-1.4.4/lib/active_support/dependencies.rb:376:in `new_constants_in’: You have a nil object when you didn’t expect it! (NoMethodError)
    You might have expected an instance of Array.
    The error occurred while evaluating nil.empty? from c:/ruby/lib/ruby/gems/1.8/gems/activesupport-1.4.4/lib/active_support/dependencies.rb:202:in `load_file’

  • Jeff Schuil

    @Lee

    The plugin needs a 2.x version of Rails. From the error message, it looks like you’re running an older version.

  • http://yourelevation.com Jeff Schuil

    @Lee

    The plugin needs a 2.x version of Rails. From the error message, it looks like you’re running an older version.

  • Pingback: all day events in event calendar | ELEVATION Dev Blog

  • http://fourfourmedia.com/ Eric

    Hey.
    I am excited to use the plugin, but I am having an issue I can’t seems to resolve. I am getting the error

    undefined method `strftime’ for nil:NilClass

    /Users/eric/.gem/ruby/1.8/gems/activesupport-2.3.5/lib/active_support/whiny_nil.rb:52:in `method_missing’
    /Users/eric/Sites/rails/divott/app/helpers/calendar_helper.rb:12:in `event_calendar_opts’
    /Users/eric/Sites/rails/divott/app/helpers/calendar_helper.rb:19:in `event_calendar’
    /Users/eric/Sites/rails/divott/app/views/home/index.html.erb:12:in `_run_erb_app47views47home47index46html46erb’

  • http://fourfourmedia.com Eric

    Hey.
    I am excited to use the plugin, but I am having an issue I can’t seems to resolve. I am getting the error

    undefined method `strftime’ for nil:NilClass

    /Users/eric/.gem/ruby/1.8/gems/activesupport-2.3.5/lib/active_support/whiny_nil.rb:52:in `method_missing’
    /Users/eric/Sites/rails/divott/app/helpers/calendar_helper.rb:12:in `event_calendar_opts’
    /Users/eric/Sites/rails/divott/app/helpers/calendar_helper.rb:19:in `event_calendar’
    /Users/eric/Sites/rails/divott/app/views/home/index.html.erb:12:in `_run_erb_app47views47home47index46html46erb’

  • http://google.com/ mubashir

    Need help regarding this matter. Unable to figure out how to create new event and how to show created events on index page ??
    Thanks in advance

  • http://google.com mubashir

    Need help regarding this matter. Unable to figure out how to create new event and how to show created events on index page ??
    Thanks in advance

  • Jeff Schuil

    @Eric

    Looks like your @shown_month variable is nil. Is it being set in the controller? It should be a date object.

    @mubashir

    The plugin leaves creating events up to you. It focuses on displaying them within a calendar. At the minimum you could use a basic Rails scaffold for creating/updating/deleting events. As for showing those events, the README does a better job at explaining then I can do here.

  • http://yourelevation.com Jeff Schuil

    @Eric

    Looks like your @shown_month variable is nil. Is it being set in the controller? It should be a date object.

    @mubashir

    The plugin leaves creating events up to you. It focuses on displaying them within a calendar. At the minimum you could use a basic Rails scaffold for creating/updating/deleting events. As for showing those events, the README does a better job at explaining then I can do here.

  • http://unlock.net.au/ Ryan

    Good work on an excellent plugin and calendar!!! I would like to implement a calendar in my rails app to show a kind of time line for 4 or 5 of my models.

    As such I don’t want an “events” model, I just want to be able to build my own events collection from other models and display those items on the calendar.

    for example, I have “tasks”, “Phone calls”, “meetings” etc that I want to display.

  • http://unlock.net.au Ryan

    Good work on an excellent plugin and calendar!!! I would like to implement a calendar in my rails app to show a kind of time line for 4 or 5 of my models.

    As such I don’t want an “events” model, I just want to be able to build my own events collection from other models and display those items on the calendar.

    for example, I have “tasks”, “Phone calls”, “meetings” etc that I want to display.

  • http://www.davidrv.com/ David

    Hi Jeff,

    Nice plugin :)

    It’s working perfect but I would need multilanguage month names. I’ve I18n.yml translation files but they don’t work.

    I would like that the events names don’t hide if they are too long. Is it posible to make multiline event names.

    Thank u!

    david.

  • http://www.davidrv.com David

    Hi Jeff,

    Nice plugin :)

    It’s working perfect but I would need multilanguage month names. I’ve I18n.yml translation files but they don’t work.

    I would like that the events names don’t hide if they are too long. Is it posible to make multiline event names.

    Thank u!

    david.

  • Jeff Schuil

    @Ryan

    I think the plugin can be used towards your purposes. If you create a class that has_event_calendar, then you can call YourClass.create_event_strips(start_date, end_date, event_collection), where you’re creating the event collection from different models. The objects in that collection should just need a couple attributes like name, start_at, and end_at. Let me know how it goes!

    @David

    il8n support is on the feature list http://github.com/elevation/event_calendar/issues#issue/3. I think it would be great to have as well. Maybe I’ll work on this next.

    It isn’t currently possible to have multi-line event names. This is due to how calendar row heights are calculated. I’ll add it to the feature list, but I don’t think there is an easy/quick solution.

  • http://yourelevation.com Jeff Schuil

    @Ryan

    I think the plugin can be used towards your purposes. If you create a class that has_event_calendar, then you can call YourClass.create_event_strips(start_date, end_date, event_collection), where you’re creating the event collection from different models. The objects in that collection should just need a couple attributes like name, start_at, and end_at. Let me know how it goes!

    @David

    il8n support is on the feature list http://github.com/elevation/event_calendar/issues#issue/3. I think it would be great to have as well. Maybe I’ll work on this next.

    It isn’t currently possible to have multi-line event names. This is due to how calendar row heights are calculated. I’ll add it to the feature list, but I don’t think there is an easy/quick solution.

  • http://www.davidrv.com/ David

    Ok Jeff,

    Thanks, I will try to resolve it anyway and if I get it I will tell you. ( I would need I18n to comment your blog! hhehe) ;)

    david.

  • http://www.davidrv.com David

    Ok Jeff,

    Thanks, I will try to resolve it anyway and if I get it I will tell you. ( I would need I18n to comment your blog! hhehe) ;)

    david.

  • http://highaltitudehacking.wordpress.com/ Mike

    First I want to take a moment to thank the Elevation folks for putting the time and effort into this plugin.

    I also wanted to announce the release of a plugin that has built off of their hard work to support a different underlying model structure that gives you a little more flexibility with respect to start and end dates. For more details please check out:

    http://highaltitudehacking.wordpress.com/2010/01/11/reservation_calendar_rails_plugin/

  • http://highaltitudehacking.wordpress.com Mike

    First I want to take a moment to thank the Elevation folks for putting the time and effort into this plugin.

    I also wanted to announce the release of a plugin that has built off of their hard work to support a different underlying model structure that gives you a little more flexibility with respect to start and end dates. For more details please check out:

    http://highaltitudehacking.wordpress.com/2010/01/11/reservation_calendar_rails_plugin/

  • http://www.dinalogic.com/ RoR developer

    Hi, a very nice plugin. I managed to get I18n working for it, just try this:

    In your helper, modify the month_link function:

    def month_link(month_date)
    link_to(I18n.localize(month_date, :format => ‘%B’), {:month => month_date.month, :year => month_date.year}, :class => ‘month_link’)
    end

    and the :month_name_text from the options list:

    :month_name_text => I18n.localize(@shown_month, :format => ‘%B %Y’),

    You also need to hack the core calendar_helper.rb file in order to use the day names from your language file:

    day_names = I18n.t(‘date.day_names’)

    Hope this helps

  • http://www.dinalogic.com RoR developer

    Hi, a very nice plugin. I managed to get I18n working for it, just try this:

    In your helper, modify the month_link function:

    def month_link(month_date)
    link_to(I18n.localize(month_date, :format => ‘%B’), {:month => month_date.month, :year => month_date.year}, :class => ‘month_link’)
    end

    and the :month_name_text from the options list:

    :month_name_text => I18n.localize(@shown_month, :format => ‘%B %Y’),

    You also need to hack the core calendar_helper.rb file in order to use the day names from your language file:

    day_names = I18n.t(‘date.day_names’)

    Hope this helps

  • Jeff Schuil

    @Mike

    Glad you like the plugin. For one of our projects I used it as is to do something similar to your reservation plugin, where we had two models: Event and EventDate. An event has many event dates. The EventDate model declared has_event_calendar, thus showing each date on the calendar. It worked pretty well. It looks like your plugin formalizes this method?

  • http://yourelevation.com Jeff Schuil

    @Mike

    Glad you like the plugin. For one of our projects I used it as is to do something similar to your reservation plugin, where we had two models: Event and EventDate. An event has many event dates. The EventDate model declared has_event_calendar, thus showing each date on the calendar. It worked pretty well. It looks like your plugin formalizes this method?

  • Jeff Schuil

    @RoR developer

    Thanks for the starting point on adding localization. I’ve just updated the plugin.

  • http://yourelevation.com Jeff Schuil

    @RoR developer

    Thanks for the starting point on adding localization. I’ve just updated the plugin.

  • http://www.davidrv.com/ David

    Thx RoR developer! Nice solution.

  • http://www.davidrv.com David

    Thx RoR developer! Nice solution.

  • Charley

    Does anyone have any experience using this with conditions for the events. I set up my events to be able to be either public or private, and there are multiple users. My goal is for a logged in user to be able to see their public and private events, then be able to see other users calendars with only that users public events. Anybody have any experience with anything like that or know where I should start?

    Love the plugin by the way!!!

  • Charley

    Does anyone have any experience using this with conditions for the events. I set up my events to be able to be either public or private, and there are multiple users. My goal is for a logged in user to be able to see their public and private events, then be able to see other users calendars with only that users public events. Anybody have any experience with anything like that or know where I should start?

    Love the plugin by the way!!!

  • jeff

    hi
    thank you for your great plugin
    i wonder if it is possible to have a different look, for example the whole year, the week, a simple day and so on …
    is there a possibility ?
    thanx again!

  • jeff

    hi
    thank you for your great plugin
    i wonder if it is possible to have a different look, for example the whole year, the week, a simple day and so on …
    is there a possibility ?
    thanx again!

  • Greg

    Jeff, awesome plugin! Took me about 5 minutes to get it up in running. I have a quick question though, and maybe someone else can answer it. Right now all events are shown which is fine for starters, but I need to be able to easily supply the calendar with a custom collection of events(like only events in TX, etc.). Where would be the best place in the code to implement this? Can it be done for the controller, or would I need to modify the plugin?

    Thanks!

  • Greg

    Jeff, awesome plugin! Took me about 5 minutes to get it up in running. I have a quick question though, and maybe someone else can answer it. Right now all events are shown which is fine for starters, but I need to be able to easily supply the calendar with a custom collection of events(like only events in TX, etc.). Where would be the best place in the code to implement this? Can it be done for the controller, or would I need to modify the plugin?

    Thanks!

  • Greg

    Meh. I hacked it so it will pass a string of extra conditions down to the query in events_for_date_range.

  • Greg

    Meh. I hacked it so it will pass a string of extra conditions down to the query in events_for_date_range.