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://www.cuppadev.co.uk James

    Nice to see my code adapted as a plugin. Great work!

    Hopefully should be very useful to rails developers. :)

  • kevin

    ok, i do have a question this time. I have followed your defaults and created an event scaffold but how would i display the events and the calendar on the same page?

  • Jeff

    It looks fabulous and thank you for spending the time to create this plugin, but is there any chance that you could provide a sample application?

  • http://yourelevation.com Jeff

    @kevin

    I broke out finding events into it’s own method, so you can call it separately if you need/want to.

    In your controller, instead of the single Event.event_strips_for_month, make these three calls:

    start_d, end_d = Event.get_start_and_end_dates(@shown_month)
    @events = Event.events_for_date_range(start_d, end_d)
    @event_strips = Event.create_event_strips(start_d, end_d, @events)
    

    Then in your view you can use that @events instance variable to list the events.

    (replace ‘Event’ with your model name of course)

    @Jeff

    Putting up a sample app is on my list of things to do. I’ll update the post/github when I have something.

  • Andre

    We are new to Rails and just found your plugin. It looks awesome, but when trying to run the install nothing happens. It almost immediately goes back to a prompt, when we run the generate command it says “Couldn’t find ‘event_calendar’ generator. Any help?

  • http://yourelevation.com Jeff

    @Andre
    Interesting… so this isn’t working within your rails project?

    script/plugin install git://github.com/elevation/event_calendar.git
    

    Do you have git installed on your system? You could also try downloading the zip/tar file from github by clicking the ‘Download’ button, rename the extracted folder event_calendar, and put it in your vendor/plugins directory. You should then be able to run the event_calendar generator. Hope that helps.

  • Jeff Schuil

    @Andre
    Interesting… so this isn’t working within your rails project?

    script/plugin install git://github.com/elevation/event_calendar.git

    Do you have git installed on your system? You could also try downloading the zip/tar file from github by clicking the ‘Download’ button, rename the extracted folder event_calendar, and put it in your vendor/plugins directory. You should then be able to run the event_calendar generator. Hope that helps.

  • Andre

    We are new to Rails and just found your plugin. It looks awesome, but when trying to run the install nothing happens. It almost immediately goes back to a prompt, when we run the generate command it says “Couldn’t find ‘event_calendar’ generator. Any help?

  • Jeff

    It looks fabulous and thank you for spending the time to create this plugin, but is there any chance that you could provide a sample application?

  • http://www.cuppadev.co.uk/ James

    Nice to see my code adapted as a plugin. Great work!

    Hopefully should be very useful to rails developers. :)

  • kevin

    ok, i do have a question this time. I have followed your defaults and created an event scaffold but how would i display the events and the calendar on the same page?

  • Jeff Schuil

    @kevin

    I broke out finding events into it’s own method, so you can call it separately if you need/want to.

    In your controller, instead of the single Event.event_strips_for_month, make these three calls:

    start_d, end_d = Event.get_start_and_end_dates(@shown_month)
    @events = Event.events_for_date_range(start_d, end_d)
    @event_strips = Event.create_event_strips(start_d, end_d, @events)

    Then in your view you can use that @events instance variable to list the events.

    (replace ‘Event’ with your model name of course)

    @Jeff

    Putting up a sample app is on my list of things to do. I’ll update the post/github when I have something.

  • Diego Caliri

    I’m trying to use the plugin and I’m following the example on github and there’s a problem when calling ‘event_strips_for_month’ because that’s not defined in Event model.

    What should that method to? I will write it, but I need to know what is it supposed to do.

    Thanks in advance

    Diego

  • http://- Diego Caliri

    I’m trying to use the plugin and I’m following the example on github and there’s a problem when calling ‘event_strips_for_month’ because that’s not defined in Event model.

    What should that method to? I will write it, but I need to know what is it supposed to do.

    Thanks in advance

    Diego

  • Diego Caliri

    I have a new problem now:

    NameError in CalendarController#index

    undefined local variable or method `has_event_calendar’ for #

  • http://- Diego Caliri

    I have a new problem now:

    NameError in CalendarController#index

    undefined local variable or method `has_event_calendar’ for #

  • Jeff Schuil

    @Diego
    Are you putting the ‘has_event_calendar’ method call in your event model, or do you have it in the controller? It should be in your model…

  • http://yourelevation.com Jeff

    @Diego
    Are you putting the ‘has_event_calendar’ method call in your event model, or do you have it in the controller? It should be in your model…

  • hs

    @month = params[:month].to_i
    @year = params[:year].to_i

    @shown_month = Date.civil(@year, @month)
    start_d, end_d = Event.get_start_and_end_dates(@shown_month)
    @events = Event.events_for_date_range(start_d, end_d)
    @event_strips = Event.create_event_strips(start_d, end_d, @events)

    this is my controller. I am getting a problem with Date.civil.
    The error is

    ArgumentError (invalid date):
    C:/Ruby/lib/ruby/1.8/date.rb:727:in `civil’
    app/controllers/events_controller.rb:54:in `monthly

    Regards,
    H

  • hs

    @month = params[:month].to_i
    @year = params[:year].to_i

    @shown_month = Date.civil(@year, @month)
    start_d, end_d = Event.get_start_and_end_dates(@shown_month)
    @events = Event.events_for_date_range(start_d, end_d)
    @event_strips = Event.create_event_strips(start_d, end_d, @events)

    this is my controller. I am getting a problem with Date.civil.
    The error is

    ArgumentError (invalid date):
    C:/Ruby/lib/ruby/1.8/date.rb:727:in `civil’
    app/controllers/events_controller.rb:54:in `monthly

    Regards,
    H

  • Jeff Schuil

    @hs

    What are your @month and @year variables when you get that error? They should be integers like 8 and 2009. So: Date.civil(2009, 8) => Sat, 01 Aug 2009.

    In my example, I default the params to Time.now.month and Time.now.year in the routes file:

    map.calendar "/calendar/:year/:month", :controller => "calendar", :action => "index", :year => Time.now.year, :month => Time.now.month

  • http://yourelevation.com Jeff Schuil

    @hs

    What are your @month and @year variables when you get that error? They should be integers like 8 and 2009. So: Date.civil(2009, 8) => Sat, 01 Aug 2009.

    In my example, I default the params to Time.now.month and Time.now.year in the routes file:

    map.calendar "/calendar/:year/:month", :controller => "calendar", :action => "index", :year => Time.now.year, :month => Time.now.month

  • Mike

    I’m sorry to bug you with such a simple question but I am new to ruby and was wondering if you could help. I only want to show events that belong the the currently logged in user (current_user). How would I change this:

    def event_calendar
    calendar event_calendar_options do |event|
    #{h(event.name)}
    end
    end

    Thanks in advance for your help

  • Mike

    I’m sorry to bug you with such a simple question but I am new to ruby and was wondering if you could help. I only want to show events that belong the the currently logged in user (current_user). How would I change this:

    def event_calendar
    calendar event_calendar_options do |event|
    #{h(event.name)}
    end
    end

    Thanks in advance for your help

  • Mike

    I fixed it. I just changed:

    In my calendar_controller:

    @event_strips = Events.event_strips_for_month(@shown_month)

    to

    @event_strips = current_user.events.event_strips_for_month(@shown_month)

  • Mike

    I fixed it. I just changed:

    In my calendar_controller:

    @event_strips = Events.event_strips_for_month(@shown_month)

    to

    @event_strips = current_user.events.event_strips_for_month(@shown_month)

  • Jermaine

    I’ve been playing with this for the past couple of days and I’m very pleased.

    @Jeff Schuil: Have you thought about the design of the calendar grid itself? Currently it’s designed
    to only use 85px or 120px as the cell width (to fill up the background with either 85_bg.gif or 120_bg.gif).

    However, if you want a table width of 100%, no background image will work. Ideally you want to fill those blank spaces with plain css (borders).
    Any thoughts?

  • Jermaine

    I’ve been playing with this for the past couple of days and I’m very pleased.

    @Jeff Schuil: Have you thought about the design of the calendar grid itself? Currently it’s designed
    to only use 85px or 120px as the cell width (to fill up the background with either 85_bg.gif or 120_bg.gif).

    However, if you want a table width of 100%, no background image will work. Ideally you want to fill those blank spaces with plain css (borders).
    Any thoughts?

  • TS

    I am getting save error as @hs

    ArgumentError (invalid date)

    I checked the year and month like you had suggested and:
    My month is 0.
    my year is 0.

    If I set these variables in my controller. Then it works… but my next and prev. buttons do not.

    It seems that my variables are not initialized by the route.

    I’m hoping its something simple..(fingers crossed)

  • TS

    I am getting save error as @hs

    ArgumentError (invalid date)

    I checked the year and month like you had suggested and:
    My month is 0.
    my year is 0.

    If I set these variables in my controller. Then it works… but my next and prev. buttons do not.

    It seems that my variables are not initialized by the route.

    I’m hoping its something simple..(fingers crossed)

  • TS

    Ok so I discovered my problem!

    In routes.

    I had added the “map.calendar….” route below the default routes.

    Move the “map.calendar” route above the default routes.

  • TS

    Ok so I discovered my problem!

    In routes.

    I had added the “map.calendar….” route below the default routes.

    Move the “map.calendar” route above the default routes.

  • Jeff Schuil

    @Jermaine

    While you can set the width to be whatever you want (by changing a setting and creating a new bg image), I agree it would be ideal if the calendar could resize dynamically. (ie with a browser window resize)

    Right now each ‘event strip’ is a div placed within a single table cell that stretches across all the days of the week. The background image just gives the appearance of multiple cells. It could be re-written to produce HTML where each event strip is a table cell that spans the required number of day cells. The cells would then change width dynamically as the width of the table changed.

    Also, instead of repeating bg images for the grid, perhaps it could use another table, that has position absolute, and is just there to give the cell/day borders.

    It’s hard to describe in a comment, but those are my quick thoughts. This is on my list of things I’d like, so let me know how it goes and I’ll update the plugin if we get something working.

  • http://yourelevation.com Jeff

    @Jermaine

    While you can set the width to be whatever you want (by changing a setting and creating a new bg image), I agree it would be ideal if the calendar could resize dynamically. (ie with a browser window resize)

    Right now each ‘event strip’ is a div placed within a single table cell that stretches across all the days of the week. The background image just gives the appearance of multiple cells. It could be re-written to produce HTML where each event strip is a table cell that spans the required number of day cells. The cells would then change width dynamically as the width of the table changed.

    Also, instead of repeating bg images for the grid, perhaps it could use another table, that has position absolute, and is just there to give the cell/day borders.

    It’s hard to describe in a comment, but those are my quick thoughts. This is on my list of things I’d like, so let me know how it goes and I’ll update the plugin if we get something working.

  • Jeff

    Hi,

    I’m having a problem with the plugin. Whenever I make an event on a Friday later than 4PM(start_at 17:00:00) or so, it extends onto Saturday. I’m not sure how to resolve this, but I didn’t notice this before. I set my time zone to Pacific time in my environment.rb, but the server time is different. Could this be a problem?

    Thanks.

  • Jeff

    Hi,

    I’m having a problem with the plugin. Whenever I make an event on a Friday later than 4PM(start_at 17:00:00) or so, it extends onto Saturday. I’m not sure how to resolve this, but I didn’t notice this before. I set my time zone to Pacific time in my environment.rb, but the server time is different. Could this be a problem?

    Thanks.

  • Tom

    I really like this calendar. Thank you. I see a couple of issues. When my end date is past 8:00 PM on *Friday*, the stripe spills over to Saturday. Oddly, this is only on Friday. I originally thought it was a timezone issue since I’m using US/Eastern. But having it happen on Friday is a real puzzle.

    Also for October 2009, I get full row of empty cells at the bottom. I guess that is because the 31st falls on Saturday.

    Thanks, Really like it!

  • Tom

    I really like this calendar. Thank you. I see a couple of issues. When my end date is past 8:00 PM on *Friday*, the stripe spills over to Saturday. Oddly, this is only on Friday. I originally thought it was a timezone issue since I’m using US/Eastern. But having it happen on Friday is a real puzzle.

    Also for October 2009, I get full row of empty cells at the bottom. I guess that is because the 31st falls on Saturday.

    Thanks, Really like it!

  • Jeff Schuil

    @Jeff and @Tom

    You’re correct that it was a timezone issue. The bug only came up when the event’s end date was close to the end of the week (Friday afternoon/nights depending on the time change.) Nice find. It should now be fixed.

    I also removed the extra calendar row that was showing for the month of October. This one came up when the last day of the month was also the last day of the week (Saturday).

    Also, feel free to create an issue on github for these types of bugs, instead of a blog comment. I’ll start creating them there if they are reported here…

    Thanks, and I’m glad you like the plugin!

  • http://yourelevation.com Jeff

    @Jeff and @Tom

    You’re correct that it was a timezone issue. The bug only came up when the event’s end date was close to the end of the week (Friday afternoon/nights depending on the time change.) Nice find. It should now be fixed.

    I also removed the extra calendar row that was showing for the month of October. This one came up when the last day of the month was also the last day of the week (Saturday).

    Also, feel free to create an issue on github for these types of bugs, instead of a blog comment. I’ll start creating them there if they are reported here…

    Thanks, and I’m glad you like the plugin!

  • Larry

    Not sure why but all events show up in calendar to day early.

    i.e event datetime = 2009-10-05 00:00:00 shows up on the calendar on the 3rd.

    also is there a way to set the end_at to the same as the start_at time.
    I only need the date not the time.

    Thanks

  • Larry

    Not sure why but all events show up in calendar to day early.

    i.e event datetime = 2009-10-05 00:00:00 shows up on the calendar on the 3rd.

    also is there a way to set the end_at to the same as the start_at time.
    I only need the date not the time.

    Thanks

  • Jeff Schuil

    @Larry

    Not sure why events would show up early for you either. Maybe this is another timezone problem? I see you opened a github issue, I’ll ask for more info there…

    As for setting end_at to be the same as the start_at, you could easily do this in your event model.def end_at
    start_at
    end

    I guess this means you only want to display single day events?

    If you’re just trying to get rid of the event’s time, leaving only the date, then you should be able to replace start_at and end_at’s datetime data type with date. (ie in your event migration)

    Or just don’t display the time information.

    Another option, if you want a mix of dates and datetimes, is to add an ‘all day’ checkbox when creating an event.

  • http://yourelevation.com Jeff Schuil

    @Larry

    Not sure why events would show up early for you either. Maybe this is another timezone problem? I see you opened a github issue, I’ll ask for more info there…

    As for setting end_at to be the same as the start_at, you could easily do this in your event model.

    def end_at
      start_at
    end

    I guess this means you only want to display single day events?

    If you’re just trying to get rid of the event’s time, leaving only the date, then you should be able to replace start_at and end_at’s datetime data type with date. (ie in your event migration)

    Or just don’t display the time information.

    Another option, if you want a mix of dates and datetimes, is to add an ‘all day’ checkbox when creating an event.

  • Tom

    Just wanted to follow up with the Friday night spill over timezone issue. The updated fixed it. Thanks.

  • Tom

    Just wanted to follow up with the Friday night spill over timezone issue. The updated fixed it. Thanks.

  • steve

    This calendar is great. I’m trying to figure out how to turn the view into a popup, hopefully it won’t be too hard.

  • steve

    This calendar is great. I’m trying to figure out how to turn the view into a popup, hopefully it won’t be too hard.

  • Jeff

    Hi,

    Is there a way to change the calendar so the event title spans in the same cell, but moved down instead of having text cut off? Like “A really long title” would read as “A really lo” on the calendar.

    Also, is there a way to change the colors based on different event types? If an event was type a, is there a way to set it to a different color then type b?

    Thanks again for this wonderful plugin!

  • Jeff

    Hi,

    Is there a way to change the calendar so the event title spans in the same cell, but moved down instead of having text cut off? Like “A really long title” would read as “A really lo” on the calendar.

    Also, is there a way to change the colors based on different event types? If an event was type a, is there a way to set it to a different color then type b?

    Thanks again for this wonderful plugin!