Show multiple, overlapping events across calendar days and rows. Rails plugin.
Show multiple, overlapping events across calendar days and rows. Rails plugin.
==EventCalendar
Easily show multiple, overlapping events across calendar days and rows.
See http://dev.elevationblog.com/2009/7/23/event-calendar-rails-plugin for a screenshot.
After install, the "calendar" method will be available within your views.
To customize the look, modify the included stylesheet and/or change the default options.
==Install
=== Rails 2
script/plugin install git://github.com/elevation/event_calendar.git
To generate the necessary static files AND the example below:
script/generate event_calendar
=== Rails 3
As a gem:
gem install event-calendar
Add this to your Gemfile:
gem 'event-calendar', :require => 'event_calendar'
Or as a plugin:
rails plugin install git://github.com/elevation/event_calendar.git
To generate the necessary static files AND the example below:
rails generate event_calendar
=== Generator Options
script/generate event_calendar --help
--static-only: Only generate the stylesheet and javascript --use-jquery: Generate jQuery javascript --use-mootools: Generate MooTools javascript --use-all-day: Include an 'all_day' field on events, and display appropriately
You can change the default event model name (Event) and controller/view name (Calendar) by passing in two name arguments:
script/generate event_calendar EventModel ControllerName
==Generated Files
Make sure to include the stylesheet and javascript in your layout/view.
====Static files
public/stylesheets/event_calendar.css public/javascripts/event_calendar.js
Unless the --static-only option is given, the following will be generated. Names will differ if name arguments were passed to the generator.
====db/migrate/XXXX_create_events.rb
class CreateEvents 'custom_start_at', :end_at_field => 'custom_end_at' #
end
====config/routes.rb
Rails 2:
map.calendar '/calendar/:year/:month', :controller => 'calendar', :action => 'index', :requirements => {:year => /\d{4}/, :month => /\d{1,2}/}, :year => nil, :month => nil
Rails 3:
match '/calendar(/:year(/:month))' => 'calendar#index', :as => :calendar, :constraints => {:year => /\d{4}/, :month => /\d{1,2}/}
====app/controllers/calendar_controller.rb
class CalendarController :some_relation, :conditions => 'some_relations.some_column = true') #
end
end
====app/helpers/calendar_helper.rb
Some helper methods are created, but you could put this in the view. The key is our calendar method, which takes some options.
module CalendarHelper def month_link(month_date) link_to(I18n.localize(month_date, :format => "%B"), {:month => month_date.month, :year => month_date.year}) end
# custom options for this calendar
def event_calendar_options
{
:year => @year,
:month => @month,
:event_strips => @event_strips,
:month_name_text => I18n.localize(@shown_month, :format => "%B %Y"),
:previous_month_text => " month_link(@shown_month.next_month) + " >>"
}
end
def event_calendar
calendar event_calendar_options do |args|
event = args[:event]
%(#{h(event.name)})
end
end
end
Notice you can pass in a block to the calendar method. In this example I'm passing a link to the event details, and displaying the event's name. If you are using the MooTools javascript, a Tip will be created with the content of the link's title attribute for displaying additional information.
====app/views/calendar/index.html.erb
Then in calendar view, simply:
In Rails 3, use raw(event_calendar)
==Default Options
The default options for the calendar are:
defaults = { :year => Time.zone.now.year, :month => Time.zone.now.month, :abbrev => true, :first_day_of_week => 0, # See note below when setting this :show_today => true, :show_header => true, :month_name_text => Time.zone.now.strftime("%B %Y"), :previous_month_text => nil, :next_month_text => nil, :event_strips => [],
# it would be nice to have these in the CSS file
# but they are needed to perform height calculations
:width => nil,
:height => 500,
:day_names_height => 18,
:day_nums_height => 18,
:event_height => 18,
:event_margin => 1,
:event_padding_top => 1,
:use_all_day => false,
:use_javascript => true,
:link_to_day_action => false
}
You can override any of these by passing your options to the calendar method. In the above example, update the event_calendar_options helper method.
====Details
See the notes in the plugin's calendar_helper.rb for more info.
width: Optional, if none is given it will stretch to the containing element.
height: Defaults to 500px. This is the approx minimum total height of the calendar. It could be greater if a calendar row(s) need to stretch to fit additional events.
use_all_day: If set to true, will check for an 'all_day' boolean field when displaying an event. If it is an all day event, or the event is multiple days, then it will display as usual. Otherwise it will display without a background color bar.
Helper/View: :use_all_day => true
If using this option, you probably want to also show times for non-all-day events: calendar event_calendar_options do |args| event, day = args[:event], args[:day] html = %() html "day"
Route (the controller is the same as your other calendar route): map.calendar_day "/calendar/:year/:month/:day", :controller => "calendar", :action => "day"
==Notes
If you want to change the first day of the week from the default of Sunday (0), then set the new value in an instance variable and pass it to event_strips_for_month (in the controller), and to the event calendar options (in the helper/view).
Controller: @first_day_of_week = 1 @event_strips = Event.event_strips_for_month(@shown_month, @first_day_of_week)
Helper/View calendar options: :first_day_of_week => @first_day_of_week
If you need access to the events, not just the event strips, then instead of calling event_strips_for_month call these 3 methods:
start_d, end_d = Event.get_start_and_end_dates(@shown_month) # optionally pass in @first_day_of_week @events = Event.events_for_date_range(start_d, end_d) @event_strips = Event.create_event_strips(start_d, end_d, @events)
The event select color is set in the event_calendar.js file.
===ORM Support
Mongoid is supported out of the box with no additional lines of code in the model. Use the has_event_calendar method as you do with ActiveRecord.
==il8n
To localize month and day names, add the following to your localization file(s) in config/locales:
date -> formats, day_names, abbr_day_names, month_names, abbr_month_names
For example, in es.yml:
es: date: formats: default: "%e/%m/%Y"
day_names: [Domingo, Lunes, Martes, Miércoles, Jueves, Viernes, Sábado]
abbr_day_names: [Dom, Lun, Mar, Mie, Jue, Vie, Sab]
# Don't forget the nil at the beginning; there's no such thing as a 0th month
month_names: [~, Enero, Febrero, Marzo, Abril, Mayo, Junio, Julio, Agosto, Septiembre, Octubre, Noviembre, Diciembre]
abbr_month_names: [~, Ene, Feb, Mar, Abr, May, Jun, Jul, Ago, Sep, Oct, Nov, Dic]
==Contributors
== History
Copyright (c) 2009 Elevation, released under the MIT license
No open issues yet, or sync has not completed.