Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

first commit

  • Loading branch information...
commit 01acb4f5de0084059eed69a45b39d288d33bdd20 0 parents
@jeffschuil jeffschuil authored
20 MIT-LICENSE
@@ -0,0 +1,20 @@
+Copyright (c) 2009 Elevation
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
132 README
@@ -0,0 +1,132 @@
+EventCalendar
+=============
+
+Easily show multiple, overlapping events across calendar days and rows.
+
+Event calendar based off of http://www.cuppadev.co.uk/webdev/making-a-real-calendar-in-rails/ which in turn is based on CalendarHelper.
+
+After install, the "calendar" method will be available within your views.
+
+
+Install
+=======
+
+script/plugin install ssh://yourelevation.com/home/elevation/git/event_calendar.git
+
+To generate stylesheet, javascript, and sample bg grid images:
+
+script/generate event_calendar
+
+
+Example
+=======
+
+Say you have an event model, created with a migration like this:
+ create_table :events do |t|
+ t.string :name
+ t.datetime :start_at
+ t.datetime :end_at
+
+ t.timestamps
+ end
+
+At minimum needs to have the start_at and end_at fields.
+
+In addition, event can have a color field, a hex value stored as a string, which determines the color of the event.
+Or you can override the default virtual attribute on the event model, if for example, you have a calendar model that events are associated with, where each calendar has its own color.
+
+Then in your event.rb, add:
+ has_event_calendar
+
+Then if you create and hookup the calendar controller
+
+routes.rb
+
+ map.calendar "/calendar/:year/:month", :controller => "calendar", :action => "index", :year => Time.now.year, :month => Time.now.month
+
+CalendarController.rb
+
+ def index
+ @month = params[:month].to_i
+ @year = params[:year].to_i
+
+ @shown_month = Date.civil(@year, @month)
+
+ @event_strips = Event.event_strips_for_month(@shown_month)
+ end
+
+Can create helper methods, or put this directly in the view. The key is our calendar method, which takes some options.
+
+ module CalendarHelper
+ def month_link(month_date)
+ link_to(month_date.strftime("%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 => @shown_month.strftime("%B %Y"),
+ :previous_month_text => "<< " + month_link(@shown_month.last_month),
+ :next_month_text => month_link(@shown_month.next_month) + " >>"
+ }
+ end
+
+ def event_calendar
+ calendar event_calendar_options do |event|
+ "<a href='/events/#{event.id}' title=\"#{h(event.name)}\"><div>#{h(event.name)}</div></a>"
+ end
+ end
+ end
+
+Then in calendar view, simply:
+
+<%= event_calendar %>
+
+(Remember to include the stylesheet and javascript in your layout/view as well.)
+
+The default options for the calendar are:
+
+ defaults = {
+ :year => Time.now.year,
+ :month => Time.now.month,
+ :table_class => 'calendar',
+ :month_name_class => 'monthName',
+ :other_month_class => 'otherMonth',
+ :day_name_class => 'dayName',
+ :day_class => 'day',
+ :abbrev => (0..2),
+ :first_day_of_week => 0,
+ :accessible => false,
+ :show_today => true,
+ :month_name_text => Time.now.strftime("%B %Y"),
+ :previous_month_text => nil,
+ :next_month_text => nil,
+ :start => nil,
+ :event_strips => [],
+ :event_width => 85,
+ :event_height => 18,
+ :min_height => 70,
+ :event_margin => 2
+ }
+
+You can override any of these by passing your options to the calendar method.
+Note, if you change the event_width option, you will need to change the .calendar background-image in the CSS file. There are two images included for 85px and 120px.
+
+The event select color is set in the event_calendar.js file.
+
+
+TODO
+====
+
+Add tests!
+
+
+Contributors
+============
+
+Jeff Schuil
+
+Copyright (c) 2009 Elevation, released under the MIT license
23 Rakefile
@@ -0,0 +1,23 @@
+require 'rake'
+require 'rake/testtask'
+require 'rake/rdoctask'
+
+desc 'Default: run unit tests.'
+task :default => :test
+
+desc 'Test the event_calendar plugin.'
+Rake::TestTask.new(:test) do |t|
+ t.libs << 'lib'
+ t.libs << 'test'
+ t.pattern = 'test/**/*_test.rb'
+ t.verbose = true
+end
+
+desc 'Generate documentation for the event_calendar plugin.'
+Rake::RDocTask.new(:rdoc) do |rdoc|
+ rdoc.rdoc_dir = 'rdoc'
+ rdoc.title = 'EventCalendar'
+ rdoc.options << '--line-numbers' << '--inline-source'
+ rdoc.rdoc_files.include('README')
+ rdoc.rdoc_files.include('lib/**/*.rb')
+end
12 generators/event_calendar/USAGE
@@ -0,0 +1,12 @@
+Description:
+ Copies stylesheet, javascript, and sample background image files to the public folder.
+
+Example:
+ ./script/generate event_calendar
+
+ This will create:
+ public/stylesheets/event_calendar.css
+ public/javascripts/event_calendar.js
+ public/images/event_calendar
+ public/images/event_calendar/85_bg.gif
+ public/images/event_calendar/120_bg.gif
11 generators/event_calendar/event_calendar_generator.rb
@@ -0,0 +1,11 @@
+class EventCalendarGenerator < Rails::Generator::Base
+ def manifest
+ record do |m|
+ m.file "stylesheet.css", "public/stylesheets/event_calendar.css"
+ m.file "javascript.js", "public/javascripts/event_calendar.js"
+ m.directory "public/images/event_calendar"
+ m.file "85_bg.gif", "public/images/event_calendar/85_bg.gif"
+ m.file "120_bg.gif", "public/images/event_calendar/120_bg.gif"
+ end
+ end
+end
BIN  generators/event_calendar/templates/120_bg.gif
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN  generators/event_calendar/templates/85_bg.gif
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
10 generators/event_calendar/templates/javascript.js
@@ -0,0 +1,10 @@
+/* Select an entire event, for when it spans multiple rows */
+function select_event(ele, selected) {
+ ele = $(ele);
+ event_id = ele.readAttribute("event_id");
+ events = $$('.event_'+event_id);
+ events.each(function(event) {
+ if (selected) event.setStyle({ backgroundColor: '#2EAC6A' });
+ else event.setStyle({ backgroundColor: ele.readAttribute("color") });
+ });
+}
102 generators/event_calendar/templates/stylesheet.css
@@ -0,0 +1,102 @@
+/*
+ Calendar theme, based on Geoffrey Grosenbach http://nubyonrails.com
+
+ Colors:
+ Tan: ecede2
+ Turq: 003355
+ Cream: ffffdd
+*/
+
+.calendar {
+ background-image: url('/images/event_calendar/85_bg.gif');
+ background-repeat: repeat;
+ margin: auto;
+}
+
+.calendar thead {
+ background-color: white;
+}
+
+.calendar th {
+ padding-bottom: 5px;
+}
+
+th.monthName {
+ font-size: 16px;
+ font-weight: bold;
+}
+
+.dayName th {
+ font-size: 11px;
+ padding-top: 3px;
+ padding-bottom: 3px;
+ background-color: #303030;
+ color: white;
+}
+
+.otherMonth, .day, .specialDay {
+ font-size: 11px;
+ text-align: center;
+ padding: 2px 0;
+ padding-left: 1px;
+ border-right: 1px solid #d5d5d5;
+ border-bottom: 1px dotted #bbbbbb;
+}
+
+.otherMonth {
+ color: #d5d5d5;
+ background-color: white;
+}
+
+.day, .specialDay {
+ background-color: #ecede2;
+}
+.specialDay {
+ color: white;
+}
+.specialDay a, .specialDay a:visited, .specialDay a:hover {
+ color: white;
+ text-decoration: none;
+ padding: 1em;
+}
+.specialDay a:hover {
+ color: white;
+ background-color: black;
+}
+.weekendDay {
+ /* background-color: #ffffdd; */
+}
+.today{
+ background-color: #ffffdd;
+}
+
+.beginning_of_week {
+ border-left: 1px solid #d5d5d5;
+ padding-left: 0;
+}
+
+/* Event blocks */
+.events {
+ position: relative;
+ border-bottom: 1px solid #d5d5d5;
+ border-left: 1px solid #d5d5d5;
+}
+
+.event {
+ overflow: hidden;
+ text-align: left;
+ position: absolute;
+ font-size: 12px;
+ line-height: 16px;
+}
+
+.event :hover {
+ background-color: #2EAC6A;
+}
+
+.event div {
+ cursor: pointer;
+ padding-left: 6px;
+ color:#ffffff;
+ text-decoration: none;
+}
2  init.rb
@@ -0,0 +1,2 @@
+ActiveRecord::Base.extend EventCalendar::PluginMethods
+ActionView::Base.send :include, EventCalendar::CalendarHelper
1  install.rb
@@ -0,0 +1 @@
+# Install hook code here
154 lib/event_calendar.rb
@@ -0,0 +1,154 @@
+module EventCalendar
+
+ module PluginMethods
+ def has_event_calendar
+ ClassMethods.setup_event_calendar_on self
+ end
+ end
+
+ # class Methods
+ module ClassMethods
+
+ def self.setup_event_calendar_on(recipient)
+ recipient.extend ClassMethods
+ recipient.class_eval do
+ include InstanceMethods
+ end
+ end
+
+ def event_strips_for_month(shown_date)
+ strip_start, strip_end = get_start_and_end_dates(shown_date)
+
+ events = self.find(
+ :all,
+ :conditions => [
+ '((start_at >= ? OR end_at <= ?) OR
+ (end_at != NULL AND (end_at >= ? AND start_at <= ?)))',
+ strip_start, strip_end,
+ strip_start, strip_end
+ ],
+ :order => 'start_at ASC'
+ )
+
+ event_strips = create_event_strips(strip_start, strip_end, events)
+ event_strips
+ end
+
+ # Expand start and end dates to show the previous month and next month's days,
+ # that overlap with the shown months display
+ def get_start_and_end_dates(shown_date)
+ # the end of last month
+ strip_start = beginning_of_week(shown_date)
+ # the beginning of next month
+ strip_end = beginning_of_week(shown_date.next_month + 7) - 1
+ [strip_start, strip_end]
+ end
+
+ # Create the various strips that show evetns
+ def create_event_strips(strip_start, strip_end, events)
+ # create an inital event strip, with a nil entry for every day of the displayed days
+ event_strips = [[nil] * (strip_end - strip_start + 1)]
+
+ events.each do |event|
+ cur_date = event.start_at.to_date
+ end_date = event.end_at.to_date
+ cur_date, end_date = event.clip_range(strip_start, strip_end)
+ start_range = (cur_date - strip_start).to_i
+ end_range = (end_date - strip_start).to_i
+
+ # make sure the event is within our viewing range
+ if (start_range <= end_range) and (end_range > 0)
+ range = start_range..end_range
+
+ open_strip = space_in_current_strips?(event_strips, range)
+
+ if open_strip.nil?
+ # no strips open, make a new one
+ new_strip = [nil] * (strip_end - strip_start + 1)
+ range.each {|r| new_strip[r] = event}
+ event_strips << new_strip
+ else
+ # found an open strip, add this event to it
+ range.each {|r| open_strip[r] = event}
+ end
+ end
+ end
+ event_strips
+ end
+
+ def space_in_current_strips?(event_strips, range)
+ open_strip = nil
+ for strip in event_strips
+ strip_is_open = true
+ range.each do |r|
+ # overlapping events on this strip
+ if !strip[r].nil?
+ strip_is_open = false
+ break
+ end
+ end
+
+ if strip_is_open
+ open_strip = strip
+ break
+ end
+ end
+ open_strip
+ end
+
+ def days_between(first, second)
+ if first > second
+ second + (7 - first)
+ else
+ second - first
+ end
+ end
+
+ def beginning_of_week(date, start = 0)
+ days_to_beg = days_between(start, date.wday)
+ date - days_to_beg
+ end
+
+ end
+
+ # Instance Methods
+ module InstanceMethods
+ def year
+ date.year
+ end
+
+ def month
+ date.month
+ end
+
+ def day
+ date.day
+ end
+
+ def color
+ self[:color] || '#9aa4ad'
+ end
+
+ def days
+ end_at.to_date - start_at.to_date
+ end
+
+ def clip_range(start_d, end_d)
+ # Clip start date, make sure it also ends on or after the start range
+ if (start_at < start_d and end_at >= start_d)
+ clipped_start = start_d
+ else
+ clipped_start = start_at.to_date
+ end
+
+ # Clip end date
+ if (end_at > end_d)
+ clipped_end = end_d
+ else
+ clipped_end = end_at.to_date
+ end
+
+ [clipped_start, clipped_end]
+ end
+ end
+end
278 lib/event_calendar/calendar_helper.rb
@@ -0,0 +1,278 @@
+module EventCalendar
+ module CalendarHelper
+
+ # Returns an HTML calendar. In its simplest form, this method generates a plain
+ # calendar (which can then be customized using CSS).
+ # However, this may be customized in a variety of ways -- changing the default CSS
+ # classes, generating the individual day entries yourself, and so on.
+ #
+ # The following are optional, available for customizing the default behaviour:
+ # :month => Time.now.month # The month to show the calendar for. Defaults to current month.
+ # :year => Time.now.year # The year to show the calendar for. Defaults to current year.
+ # :table_class => "calendar" # The class for the <table> tag.
+ # :month_name_class => "monthName" # The class for the name of the month, at the top of the table.
+ # :other_month_class => "otherMonth" # Not implemented yet.
+ # :day_name_class => "dayName" # The class is for the names of the weekdays, at the top.
+ # :day_class => "day" # The class for the individual day number cells.
+ # This may or may not be used if you specify a block (see below).
+ # :abbrev => (0..2) # This option specifies how the day names should be abbreviated.
+ # Use (0..2) for the first three letters, (0..0) for the first, and
+ # (0..-1) for the entire name.
+ # :first_day_of_week => 0 # Renders calendar starting on Sunday. Use 1 for Monday, and so on.
+ # :accessible => true # Turns on accessibility mode. This suffixes dates within the
+ # # calendar that are outside the range defined in the <caption> with
+ # # <span class="hidden"> MonthName</span>
+ # # Defaults to false.
+ # # You'll need to define an appropriate style in order to make this disappear.
+ # # Choose your own method of hiding content appropriately.
+ #
+ # :show_today => false # Highlights today on the calendar using the CSS class 'today'.
+ # # Defaults to true.
+ # :month_name_text => nil # Displayed center in header row. Defaults to current month name from Date::MONTHNAMES hash.
+ # :previous_month_text => nil # Displayed left of the month name if set
+ # :next_month_text => nil # Displayed right of the month name if set
+ #
+ # For more customization, you can pass a code block to this method, that will get one argument, a Date object,
+ # and return a values for the individual table cells. The block can return an array, [cell_text, cell_attrs],
+ # cell_text being the text that is displayed and cell_attrs a hash containing the attributes for the <td> tag
+ # (this can be used to change the <td>'s class for customization with CSS).
+ # This block can also return the cell_text only, in which case the <td>'s class defaults to the value given in
+ # +:day_class+. If the block returns nil, the default options are used.
+ #
+ # Example usage:
+ # calendar # This generates the simplest possible calendar with the curent month and year.
+ # calendar({:year => 2005, :month => 6}) # This generates a calendar for June 2005.
+ # calendar({:table_class => "calendar_helper"}) # This generates a calendar, as
+ # # before, but the <table>'s class
+ # # is set to "calendar_helper".
+ # calendar(:abbrev => (0..-1)) # This generates a simple calendar but shows the
+ # # entire day name ("Sunday", "Monday", etc.) instead
+ # # of only the first three letters.
+ # calendar do |d| # This generates a simple calendar, but gives special days
+ # if listOfSpecialDays.include?(d) # (days that are in the array listOfSpecialDays) one CSS class,
+ # [d.mday, {:class => "specialDay"}] # "specialDay", and gives the rest of the days another CSS class,
+ # else # "normalDay". You can also use this highlight today differently
+ # [d.mday, {:class => "normalDay"}] # from the rest of the days, etc.
+ # end
+ # end
+ #
+ # An additional 'weekend' class is applied to weekend days.
+ #
+ # For consistency with the themes provided in the calendar_styles generator, use "specialDay" as the CSS class for marked days.
+ #
+ def calendar(options = {}, &block)
+ block ||= Proc.new {|d| nil}
+
+ defaults = {
+ :year => Time.now.year,
+ :month => Time.now.month,
+ :table_class => 'calendar',
+ :month_name_class => 'monthName',
+ :other_month_class => 'otherMonth',
+ :day_name_class => 'dayName',
+ :day_class => 'day',
+ :abbrev => (0..2),
+ :first_day_of_week => 0,
+ :accessible => false,
+ :show_today => true,
+ :month_name_text => Time.now.strftime("%B %Y"),
+ :previous_month_text => nil,
+ :next_month_text => nil,
+ :start => nil,
+ :event_strips => [],
+ :event_width => 85,
+ :event_height => 18,
+ :min_height => 70,
+ :event_margin => 2
+ }
+ options = defaults.merge options
+
+ options[:month_name_text] ||= Date::MONTHNAMES[options[:month]]
+
+ first = Date.civil(options[:year], options[:month], 1)
+ last = Date.civil(options[:year], options[:month], -1)
+
+ start = options[:start]
+ event_strips = options[:event_strips]
+ event_width = options[:event_width]
+ event_height = options[:event_height]
+ min_height = options[:min_height]
+ event_margin = options[:event_margin]
+
+ first_weekday = first_day_of_week(options[:first_day_of_week])
+ last_weekday = last_day_of_week(options[:first_day_of_week])
+
+ day_names = Date::DAYNAMES.dup
+ first_weekday.times do
+ day_names.push(day_names.shift)
+ end
+
+ # TODO Use some kind of builder instead of straight HTML
+ cal = %(<table class="#{options[:table_class]}" width="#{event_width*7}" border="0" cellspacing="0" cellpadding="0">)
+ cal << %(<thead><tr>)
+ if options[:previous_month_text] or options[:next_month_text]
+ cal << %(<th colspan="2">#{options[:previous_month_text]}</th>)
+ colspan=3
+ else
+ colspan=7
+ end
+ cal << %(<th colspan="#{colspan}" class="#{options[:month_name_class]}">#{options[:month_name_text]}</th>)
+ cal << %(<th colspan="2">#{options[:next_month_text]}</th>) if options[:next_month_text]
+ cal << %(</tr><tr class="#{options[:day_name_class]}">)
+ day_names.each do |d|
+ unless d[options[:abbrev]].eql? d
+ cal << "<th scope='col'><span title='#{d}'>#{d[options[:abbrev]]}</span></th>"
+ else
+ cal << "<th scope='col'>#{d[options[:abbrev]]}</th>"
+ end
+ end
+ cal << "</tr></thead><tbody><tr>"
+ #other month days, before current month
+ beginning_of_week(first, first_weekday).upto(first - 1) do |d|
+ cal << %(<td class="#{options[:other_month_class]})
+ cal << " weekendDay" if weekend?(d)
+ cal << " beginning_of_week" if d.wday == first_weekday
+ if options[:accessible]
+ cal << %(">#{d.day}<span class="hidden"> #{Date::MONTHNAMES[d.month]}</span></td>)
+ else
+ cal << %(">#{d.day}</td>)
+ end
+ end unless first.wday == first_weekday
+
+ start_row = beginning_of_week(first, first_weekday)
+ last_row = start_row
+ first.upto(last) do |cur|
+ cell_text, cell_attrs = nil#block.call(cur)
+ cell_text ||= cur.mday
+ cell_attrs ||= {:class => options[:day_class]}
+ cell_attrs[:class] += " weekendDay" if [0, 6].include?(cur.wday)
+ cell_attrs[:class] += " beginning_of_week" if cur.wday == first_weekday
+ cell_attrs[:class] += " today" if (cur == Date.today) and options[:show_today]
+ cell_attrs[:style] = "width:#{event_width-2}px;" # subtract 2 for the borders
+ cell_attrs = cell_attrs.map {|k, v| %(#{k}="#{v}") }.join(" ")
+ cal << "<td #{cell_attrs}>#{cell_text}</td>"
+
+ if cur.wday == last_weekday
+ # calendar rows events
+ content = calendar_row(event_strips,
+ event_width,
+ event_height,
+ event_margin,
+ start_row,
+ last_row..cur,
+ &block)
+ cal << "</tr>#{event_row(content, min_height, event_height, event_margin)}<tr>"
+ last_row = cur + 1
+ end
+ end
+ # other month days, after current month
+ (last + 1).upto(beginning_of_week(last + 7, first_weekday) - 1) do |d|
+ cal << %(<td class="#{options[:other_month_class]})
+ cal << " weekendDay" if weekend?(d)
+ cal << " beginning_of_week" if d.wday == first_weekday
+ cal << %(" style="width:#{event_width-2}px;)
+ if options[:accessible]
+ cal << %(">#{d.day}<span class='hidden'> #{Date::MONTHNAMES[d.mon]}</span></td>)
+ else
+ cal << %(">#{d.day}</td>)
+ end
+ end unless last.wday == last_weekday
+
+ # last calendar rows events
+ content = calendar_row(event_strips,
+ event_width,
+ event_height,
+ event_margin,
+ start_row,
+ last_row..(beginning_of_week(last + 7, first_weekday) - 1),
+ &block)
+ cal << "</tr>#{event_row(content, min_height, event_height, event_margin)}</tbody></table>"
+ end
+
+ private
+
+ def calendar_row(event_strips, event_width, event_height, event_margin, start, date_range, &block)
+ start_date = date_range.first
+ range = ((date_range.first - start).to_i)...((date_range.last - start + 1).to_i)
+ idx = -1
+
+ #print "ROW: #{date_range} [#{start}] == #{range}\n"
+
+ last_offs = 0
+ event_strips.collect do |strip|
+ idx += 1
+ range.collect do |r|
+ event = strip[r]
+
+ if !event.nil?
+ # Clip event dates (if it extends before or beyond the row)
+ dates = event.clip_range(start_date, date_range.last)
+ days_in_week = r-range.first
+ if dates[0] - start_date == days_in_week
+ # Event somewhere on this row
+ # add 2 times the number of days into the week to account for borders
+ cur_offs = (event_width*days_in_week) - 1
+ start_d = event.start_at.to_date
+ end_d = event.end_at.nil? ? start_d+1 : event.end_at.to_date+1
+ event_content(event, dates[1]-dates[0]+1, cur_offs, idx, event_width, event_height, event_margin, &block)
+ else
+ nil
+ end
+ else
+ nil
+ end
+ end.compact
+ end
+ end
+
+ def event_row(content, min_height, event_height, event_margin)
+ num_events = content.inject(0) do |sum, strip|
+ strip.blank? ? sum + 0 : sum + 1
+ end
+ event_height_total = (event_height+event_margin)*num_events + event_margin
+ height = [min_height, event_height_total].max
+ "<tr><td colspan=\"7\" class='event_row'><div class=\"events\" style=\"height:#{height}px\">#{content.join}</div><div class=\"clear\"></div></td></tr>"
+ end
+
+ def event_content(event, days, cur_offs, idx, event_width, event_height, event_margin, &block)
+ cal = ""
+ cal << "<div event_id='#{event.id}' day='#{event.start_at.day}' color='#{event.color}' "
+ cal << "class='event event_#{event.id}' "
+ cal << "style='background: #{event.color}; width: #{event_width*days}px; height: #{event_height}px; top: #{idx*(event_height+event_margin)+event_margin}px; left:#{cur_offs}px;' "
+ cal << "onmouseover='select_event(this, true);' onmouseout='select_event(this, false);' "
+ cal << "> "
+ cal << block.call(event)
+ cal << "</div>"
+ cal
+ end
+
+ def first_day_of_week(day)
+ day
+ end
+
+ def last_day_of_week(day)
+ if day > 0
+ day - 1
+ else
+ 6
+ end
+ end
+
+ def days_between(first, second)
+ if first > second
+ second + (7 - first)
+ else
+ second - first
+ end
+ end
+
+ def beginning_of_week(date, start = 1)
+ days_to_beg = days_between(start, date.wday)
+ date - days_to_beg
+ end
+
+ def weekend?(date)
+ [0, 6].include?(date.wday)
+ end
+ end
+end
4 tasks/event_calendar_tasks.rake
@@ -0,0 +1,4 @@
+# desc "Explaining what the task does"
+# task :event_calendar do
+# # Task goes here
+# end
8 test/event_calendar_test.rb
@@ -0,0 +1,8 @@
+require 'test_helper'
+
+class EventCalendarTest < ActiveSupport::TestCase
+ # Replace this with your real tests.
+ test "the truth" do
+ assert true
+ end
+end
3  test/test_helper.rb
@@ -0,0 +1,3 @@
+require 'rubygems'
+require 'active_support'
+require 'active_support/test_case'
1  uninstall.rb
@@ -0,0 +1 @@
+# Uninstall hook code here
Please sign in to comment.
Something went wrong with that request. Please try again.