Skip to content

Commit

Permalink
Add show_header options.
Browse files Browse the repository at this point in the history
  • Loading branch information
felipediesel committed Jan 11, 2011
1 parent e52d581 commit ce7e214
Showing 1 changed file with 63 additions and 58 deletions.
121 changes: 63 additions & 58 deletions lib/event_calendar/calendar_helper.rb
@@ -1,6 +1,6 @@
module EventCalendar
module CalendarHelper

# Returns an HTML calendar which can show multiple, overlapping events across calendar days and rows.
# Customize using CSS, the below options, and by passing in a code block.
#
Expand Down Expand Up @@ -30,7 +30,7 @@ module CalendarHelper
# 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.
# :use_javascript => true # Outputs HTML with inline javascript so events spanning multiple days will be highlighted.
# If this option is false, cleaner HTML will be output, but events spanning multiple days will
# If this option is false, cleaner HTML will be output, but events spanning multiple days will
# not be highlighted correctly on hover, so it is only really useful if you know your calendar
# will only have single-day events. Defaults to true.
# :link_to_day_action => false # If controller action is passed,
Expand All @@ -47,45 +47,48 @@ module CalendarHelper
#
def calendar(options = {}, &block)
block ||= Proc.new {|d| nil}

defaults = {
:year => (Time.zone || Time).now.year,
:month => (Time.zone || Time).now.month,
:abbrev => true,
:first_day_of_week => 0,
:show_today => true,
:show_header => true,
:month_name_text => (Time.zone || Time).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,
:height => 500,
:day_names_height => 18,
:day_nums_height => 18,
:event_height => 18,
:event_margin => 1,
:event_padding_top => 2,

:use_all_day => false,
:use_javascript => true,
:link_to_day_action => false
}
options = defaults.merge options

# default month name for the given number
options[:month_name_text] ||= I18n.translate(:'date.month_names')[options[:month]]

if options[:show_header]
options[:month_name_text] ||= I18n.translate(:'date.month_names')[options[:month]]
end

# make the height calculations
# tricky since multiple events in a day could force an increase in the set height
height = options[:day_names_height]
row_heights = cal_row_heights(options)
row_heights.each do |row_height|
height += row_height
end

# the first and last days of this calendar month
if options[:dates].is_a?(Range)
first = options[:dates].begin
Expand All @@ -94,7 +97,7 @@ def calendar(options = {}, &block)
first = Date.civil(options[:year], options[:month], 1)
last = Date.civil(options[:year], options[:month], -1)
end

# create the day names array [Sunday, Monday, etc...]
day_names = []
if options[:abbrev]
Expand All @@ -105,57 +108,59 @@ def calendar(options = {}, &block)
options[:first_day_of_week].times do
day_names.push(day_names.shift)
end

# Build the HTML string
cal = ""

# outer calendar container
cal << %(<div class="ec-calendar")
cal << %(style="width: #{options[:width]}px;") if options[:width]
cal << %(>)

# table header, including the monthname and links to prev & next month
cal << %(<table class="ec-calendar-header" cellpadding="0" cellspacing="0">)
cal << %(<thead><tr>)
if options[:previous_month_text] or options[:next_month_text]
cal << %(<th colspan="2" class="ec-month-nav ec-previous-month">#{options[:previous_month_text]}</th>)
colspan = 3
else
colspan = 7
end
cal << %(<th colspan="#{colspan}" class="ec-month-name">#{options[:month_name_text]}</th>)
if options[:next_month_text]
cal << %(<th colspan="2" class="ec-month-nav ec-next-month">#{options[:next_month_text]}</th>)
if options[:show_header]
cal << %(<table class="ec-calendar-header" cellpadding="0" cellspacing="0">)
cal << %(<thead><tr>)
if options[:previous_month_text] or options[:next_month_text]
cal << %(<th colspan="2" class="ec-month-nav ec-previous-month">#{options[:previous_month_text]}</th>)
colspan = 3
else
colspan = 7
end
cal << %(<th colspan="#{colspan}" class="ec-month-name">#{options[:month_name_text]}</th>)
if options[:next_month_text]
cal << %(<th colspan="2" class="ec-month-nav ec-next-month">#{options[:next_month_text]}</th>)
end
cal << %(</tr></thead></table>)
end
cal << %(</tr></thead></table>)


# body container (holds day names and the calendar rows)
cal << %(<div class="ec-body" style="height: #{height}px;">)
# day names

# day names
cal << %(<table class="ec-day-names" style="height: #{options[:day_names_height]}px;" cellpadding="0" cellspacing="0">)
cal << %(<tbody><tr>)
day_names.each do |day_name|
cal << %(<th class="ec-day-name" title="#{day_name}">#{day_name}</th>)
end
cal << %(</tr></tbody></table>)

# container for all the calendar rows
cal << %(<div class="ec-rows" style="top: #{options[:day_names_height]}px; )
cal << %(height: #{height - options[:day_names_height]}px;">)

# initialize loop variables
first_day_of_week = beginning_of_week(first, options[:first_day_of_week])
last_day_of_week = end_of_week(first, options[:first_day_of_week])
last_day_of_cal = end_of_week(last, options[:first_day_of_week])
row_num = 0
top = 0

# go through a week at a time, until we reach the end of the month
while(last_day_of_week <= last_day_of_cal)
cal << %(<div class="ec-row" style="top: #{top}px; height: #{row_heights[row_num]}px;">)
top += row_heights[row_num]

# this weeks background table
cal << %(<table class="ec-row-bg" cellpadding="0" cellspacing="0">)
cal << %(<tbody><tr>)
Expand All @@ -164,11 +169,11 @@ def calendar(options = {}, &block)
cal << %(<td class="ec-day-bg #{today_class}">&nbsp;</td>)
end
cal << %(</tr></tbody></table>)

# calendar row
cal << %(<table class="ec-row-table" cellpadding="0" cellspacing="0">)
cal << %(<tbody>)

# day numbers row
cal << %(<tr>)
first_day_of_week.upto(last_day_of_week) do |day|
Expand All @@ -185,15 +190,15 @@ def calendar(options = {}, &block)
cal << %(</td>)
end
cal << %(</tr>)

# event rows for this day
# for each event strip, create a new table row
options[:event_strips].each do |strip|
cal << %(<tr>)
# go through through the strip, for the entries that correspond to the days of this week
strip[row_num*7, 7].each_with_index do |event, index|
day = first_day_of_week + index

if event
# get the dates of this event that fit into this week
dates = event.clip_range(first_day_of_week, last_day_of_week)
Expand All @@ -202,7 +207,7 @@ def calendar(options = {}, &block)
if dates[0] == day.to_date
# check if we should display the bg color or not
no_bg = no_event_bg?(event, options)

cal << %(<td class="ec-event-cell" colspan="#{(dates[1]-dates[0]).to_i + 1}" )
cal << %(style="padding-top: #{options[:event_margin]}px;">)
cal << %(<div class="ec-event ec-event-#{event.id} )
Expand All @@ -220,7 +225,7 @@ def calendar(options = {}, &block)
cal << %(data-event-id="#{event.id}" data-color="#{event.color}" )
end
cal << %(>)

# add a left arrow if event is clipped at the beginning
if event.start_at.to_date < dates[0]
cal << %(<div class="ec-left-arrow"></div>)
Expand All @@ -229,25 +234,25 @@ def calendar(options = {}, &block)
if event.end_at.to_date > dates[1]
cal << %(<div class="ec-right-arrow"></div>)
end

if no_bg
cal << %(<div class="ec-bullet" style="background-color: #{event.color};"></div>)
# make sure anchor text is the event color
# here b/c CSS 'inherit' color doesn't work in all browsers
cal << %(<style type="text/css">.ec-event-#{event.id} a { color: #{event.color}; }</style>)
end

if block_given?
# add the additional html that was passed as a block to this helper
cal << block.call({:event => event, :day => day.to_date, :options => options})
else
# default content in case nothing is passed in
cal << %(<a href="/events/#{event.id}" title="#{h(event.name)}">#{h(event.name)}</a>)
end

cal << %(</div></td>)
end

else
# there wasn't an event, so create an empty cell and container
cal << %(<td class="ec-event-cell ec-no-event-cell" )
Expand All @@ -261,31 +266,31 @@ def calendar(options = {}, &block)
end
cal << %(</tr>)
end

cal << %(</tbody></table>)
cal << %(</div>)

# increment the calendar row we are on, and the week
row_num += 1
first_day_of_week += 7
last_day_of_week += 7
end
cal << %(</div>)
end

cal << %(</div>)
cal << %(</div>)
cal << %(</div>)
end

# override this in your own helper for greater control
def day_link(text, date, day_action)
link_to(text, params.merge(:action => day_action, :year => date.year, :month => date.month, :day => date.day), :class => 'ec-day-link')
end

# check if we should display without a background color
def no_event_bg?(event, options)
options[:use_all_day] && !event.all_day && event.days == 0
end

# default html for displaying an event's time
# to customize: override, or do something similar, in your helper
def display_event_time(event, day)
Expand All @@ -301,9 +306,9 @@ def display_event_time(event, day)
""
end
end

private

# calculate the height of each row
# by default, it will be the height option minus the day names height,
# divided by the total number of calendar rows
Expand Down Expand Up @@ -336,29 +341,29 @@ def cal_row_heights(options)
end
row_heights
end

#
# helper methods for working with a calendar week
#

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

def end_of_week(date, start = 0)
beg = beginning_of_week(date, start)
beg + 6
end

def weekend?(date)
[0, 6].include?(date.wday)
end
Expand Down

0 comments on commit ce7e214

Please sign in to comment.