Module: EventCalendar::CalendarHelper
- Defined in:
- lib/event_calendar/calendar_helper.rb
Instance Method Summary collapse
-
#calendar(options = {}, &block) ⇒ Object
Returns an HTML calendar which can show multiple, overlapping events across calendar days and rows.
-
#day_link(text, date, day_action) ⇒ Object
override this in your own helper for greater control.
-
#display_event_time(event, day) ⇒ Object
default html for displaying an event’s time to customize: override, or do something similar, in your helper for instance, you may want to add localization.
-
#no_event_bg?(event, options) ⇒ Boolean
check if we should display without a background color.
Instance Method Details
#calendar(options = {}, &block) ⇒ Object
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.
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. :dates => (start_date .. end_date) # Show specific range of days. Defaults to :year, :month. :abbrev => true # Abbreviate day names. Reads from the abbr_day_names key in the localization file. :first_day_of_week => 0 # Renders calendar starting on Sunday. Use 1 for Monday, and so on. :show_today => true # Highlights today on the calendar using CSS class. :show_header => true # Show the calendar’s header. (month name, next, & previous links) :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 :event_strips => [] # An array of arrays, encapsulating the event rows on the calendar
:width => nil # Width of the calendar, if none is set then it will stretch the container’s width :height => 500 # Approx minimum total height of the calendar (excluding the header).
Height could get added if a day has too many event's to fit.
:day_names_height => 18 # Height of the day names table (included in the above ‘height’ option) :day_nums_height => 18 # Height of the day numbers tables (included in the ‘height’ option) :event_height => 18 # Height of an individual event row :event_margin => 1 # Spacing of the event rows :event_padding_top => 1 # Padding on the top of the event rows (increase to move text down)
:use_all_day => false # 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.
: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
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,
the day number will be a link. Override the day_link method for greater customization.
For more customization, you can pass a code block to this method The varibles you have to work with in this block are passed in an agruments hash: :event => The event to be displayed. :day => The day the event is displayed on. Usually the first day of the event, or the first day of the week,
if the event spans a calendar row.
:options => All the calendar options in use. (User defined and defaults merged.)
For example usage, see README.
49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 |
# File 'lib/event_calendar/calendar_helper.rb', line 49 def calendar( = {}, &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, :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 } = defaults.merge # default month name for the given number if [:show_header] [:month_name_text] ||= I18n.translate(:'date.month_names')[[:month]] end # make the height calculations # tricky since multiple events in a day could force an increase in the set height height = [:day_names_height] row_heights = cal_row_heights() row_heights.each do |row_height| height += row_height end # the first and last days of this calendar month if [:dates].is_a?(Range) first = [:dates].begin last = [:dates].end else first = Date.civil([:year], [:month], 1) last = Date.civil([:year], [:month], -1) end # create the day names array [Sunday, Monday, etc...] day_names = [] if [:abbrev] day_names.concat(I18n.translate(:'date.abbr_day_names')) else day_names.concat(I18n.translate(:'date.day_names')) end [: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: #{[:width]}px;") if [:width] cal << %(>) # table header, including the monthname and links to prev & next month if [:show_header] cal << %(<table class="ec-calendar-header" cellpadding="0" cellspacing="0">) cal << %(<thead><tr>) if [:previous_month_text] or [:next_month_text] cal << %(<th colspan="2" class="ec-month-nav ec-previous-month">#{[:previous_month_text]}</th>) colspan = 3 else colspan = 7 end cal << %(<th colspan="#{colspan}" class="ec-month-name">#{[:month_name_text]}</th>) if [:next_month_text] cal << %(<th colspan="2" class="ec-month-nav ec-next-month">#{[:next_month_text]}</th>) end cal << %(</tr></thead></table>) end # body container (holds day names and the calendar rows) cal << %(<div class="ec-body" style="height: #{height}px;">) # day names cal << %(<table class="ec-day-names" style="height: #{[: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: #{[:day_names_height]}px; ) cal << %(height: #{height - [:day_names_height]}px;">) # initialize loop variables first_day_of_week = beginning_of_week(first, [:first_day_of_week]) last_day_of_week = end_of_week(first, [:first_day_of_week]) last_day_of_cal = end_of_week(last, [: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>) first_day_of_week.upto(first_day_of_week+6) do |day| today_class = (day == Date.today) ? "ec-today-bg" : "" other_month_class = (day < first) || (day > last) ? 'ec-other-month-bg' : '' cal << %(<td class="ec-day-bg #{today_class} #{other_month_class}"> </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| cal << %(<td class="ec-day-header ) cal << %(ec-today-header ) if [:show_today] and (day == Date.today) cal << %(ec-other-month-header ) if (day < first) || (day > last) cal << %(ec-weekend-day-header) if weekend?(day) cal << %(" style="height: #{[:day_nums_height]}px;">) if [:link_to_day_action] cal << day_link(day.day, day, [:link_to_day_action]) else cal << %(#{day.day}) end cal << %(</td>) end cal << %(</tr>) # event rows for this day # for each event strip, create a new table row [: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) # if the event (after it has been clipped) starts on this date, # then create a new cell that spans the number of days if dates[0] == day.to_date # check if we should display the bg color or not no_bg = no_event_bg?(event, ) class_name = event.class.name.tableize.singularize cal << %(<td class="ec-event-cell" colspan="#{(dates[1]-dates[0]).to_i + 1}" ) cal << %(style="padding-top: #{[:event_margin]}px;">) cal << %(<div class="ec-event ec-#{class_name}-#{event.id} ) if no_bg cal << %(ec-event-no-bg" ) cal << %(style="color: #{event.color}; ) else cal << %(ec-event-bg" ) cal << %(style="background-color: #{event.color}; ) end cal << %(padding-top: #{[:event_padding_top]}px; ) cal << %(height: #{[:event_height] - [:event_padding_top]}px;" ) if [:use_javascript] # custom attributes needed for javascript event highlighting cal << %(data-event-id="#{event.id}" data-event-class="#{class_name}" 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>) end # add a right arrow if event is clipped at the end 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-#{class_name}-#{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 => }) else # default content in case nothing is passed in cal << %(<a href="/#{class_name.pluralize}/#{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" ) cal << %(style="padding-top: #{[:event_margin]}px;">) cal << %(<div class="ec-event" ) cal << %(style="padding-top: #{[:event_padding_top]}px; ) cal << %(height: #{[:event_height] - [:event_padding_top]}px;" ) cal << %(>) cal << %( </div></td>) end 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>) cal << %(</div>) cal << %(</div>) end |
#day_link(text, date, day_action) ⇒ Object
override this in your own helper for greater control
289 290 291 |
# File 'lib/event_calendar/calendar_helper.rb', line 289 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 |
#display_event_time(event, day) ⇒ Object
default html for displaying an event’s time to customize: override, or do something similar, in your helper for instance, you may want to add localization
301 302 303 304 305 306 307 308 309 310 311 312 313 |
# File 'lib/event_calendar/calendar_helper.rb', line 301 def display_event_time(event, day) time = event.start_at if !event.all_day and time.to_date == day # try to make it display as short as possible format = (time.min == 0) ? "%l" : "%l:%M" t = time.strftime(format) am_pm = time.strftime("%p") == "PM" ? "p" : "" t += am_pm %(<span class="ec-event-time">#{t}</span>) else "" end end |
#no_event_bg?(event, options) ⇒ Boolean
check if we should display without a background color
294 295 296 |
# File 'lib/event_calendar/calendar_helper.rb', line 294 def no_event_bg?(event, ) [:use_all_day] && !event.all_day && event.days == 0 end |