elevation / event_calendar

Show multiple, overlapping events across calendar days and rows. Rails plugin.
http://dev.elevationblog.com/2009/7/23/event-calendar-rails-plugin
MIT License
950 stars 212 forks source link

==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 < ActiveRecord::Migration def self.up create_table :events do |t| t.string :name t.datetime :start_at t.datetime :end_at

    t.timestamps
  end
end

def self.down
  drop_table :events
end

end

At minimum we need to have start_at and end_at fields. Altnernatively, you can configure the columns to be used by passing options to has_event_calendar.

If the '--use-all-day' option is passed to the generator, it will also add a boolean all_day field. Set :start_at to be any time on the day of the event and set :all_day to true.

An event can also have a color field (any string which is a valid CSS color) which determines the color of the event. Or simply override the default virtual attribute on the model. For example, if events are associated to a calendar model, then the events can get their color from the calendar.

====app/models/event.rb

class Event < ActiveRecord::Base has_event_calendar

# To specify the columns to use call it like this:
# 
# has_event_calendar :start_at_field  => '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 < ApplicationController

def index
  @month = (params[:month] || Time.zone.now.month).to_i
  @year = (params[:year] || Time.zone.now.year).to_i

  @shown_month = Date.civil(@year, @month)

  @event_strips = Event.event_strips_for_month(@shown_month)

  # To restrict what events are included in the result you can pass additional find options like this:
  #
  # @event_strips = Event.event_strips_for_month(@shown_month, :include => :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.prev_month),
    :next_month_text => month_link(@shown_month.next_month) + " >>"
  }
end

def event_calendar
  calendar event_calendar_options do |args|
    event = args[:event]
    %(<a href="https://github.com/elevation/event_calendar/blob/master/events/#{event.id}" title="#{h(event.name)}">#{h(event.name)}</a>)
  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:

<%= event_calendar %>

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

==Notes

===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