with
# # MonthName
# # 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.
#
# 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 | tag
# (this can be used to change the | 's class for customization with CSS).
# This block can also return the cell_text only, in which case the | 's class defaults to the value given in
# +:day_class+. If the block returns nil, the default options are used.
#
# Example usage:
# calendar(:year => 2005, :month => 6) # This generates the simplest possible calendar.
# calendar({:year => 2005, :month => 6, :table_class => "calendar_helper"}) # This generates a calendar, as
# # before, but the 's class
# # is set to "calendar_helper".
# calendar(:year => 2005, :month => 6, :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(:year => 2005, :month => 5) 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)
raise(ArgumentError, "No year given") unless options.has_key?(:year)
raise(ArgumentError, "No month given") unless options.has_key?(:month)
block ||= Proc.new {|d| nil}
defaults = {
:table_class => 'calendar',
:month_name_class => 'monthName',
:other_month_class => 'otherMonth',
:day_name_class => 'dayName',
:day_class => 'day',
:abbrev => (0..0),
:first_day_of_week => 0,
:accessible => false,
:show_today => true
}
options = defaults.merge options
first = Date.civil(options[:year], options[:month], 1)
last = Date.civil(options[:year], options[:month], -1)
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
cal = %()
cal << %(| #{Date::MONTHNAMES[options[:month]] + ' ' + options[:year].to_s} | )
day_names.each do |d|
unless d[options[:abbrev]].eql? d
cal << "| #{d[options[:abbrev]]} | "
else
cal << "#{d[options[:abbrev]]} | "
end
end
cal << " "
beginning_of_week(first, first_weekday).upto(first - 1) do |d|
cal << %(| #{d.day} #{Date::MONTHNAMES[d.month]} | )
else
cal << %(">#{d.day})
end
end unless first.wday == first_weekday
first.upto(last) do |cur|
cell_text, cell_attrs = 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] += " today" if (cur == Date.today) and options[:show_today]
cell_attrs = cell_attrs.map {|k, v| %(#{k}="#{v}") }.join(" ")
cal << "#{cell_text} | "
cal << " " if cur.wday == last_weekday
end
(last + 1).upto(beginning_of_week(last + 7, first_weekday) - 1) do |d|
cal << %(| #{d.day} #{Date::MONTHNAMES[d.mon]} | )
else
cal << %(">#{d.day})
end
end unless last.wday == last_weekday
cal << " "
end
private
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
|