|
1 |
| -require 'rails2_compat' |
2 |
| - |
3 |
| -module LaterDude |
4 |
| - module CalendarHelper |
5 |
| - def calendar_for(year, month, options={}, &block) |
6 |
| - Calendar.new(year, month, options, &block).to_html |
7 |
| - end |
8 |
| - end |
9 |
| - |
10 |
| - # TODO: Maybe make output prettier? |
11 |
| - class Calendar |
12 |
| - include ActionView::Helpers::CaptureHelper |
13 |
| - include ActionView::Helpers::TagHelper |
14 |
| - include ActionView::Helpers::UrlHelper |
15 |
| - |
16 |
| - attr_accessor :output_buffer |
17 |
| - |
18 |
| - def initialize(year, month, options={}, &block) |
19 |
| - @year, @month = year, month |
20 |
| - @options = options.symbolize_keys.reverse_merge(self.class.default_calendar_options) |
21 |
| - |
22 |
| - # next_month and previous_month take precedence over next_and_previous_month |
23 |
| - @options[:next_month] ||= @options[:next_and_previous_month] |
24 |
| - @options[:previous_month] ||= @options[:next_and_previous_month] |
25 |
| - |
26 |
| - @days = Date.civil(@year, @month, 1)..Date.civil(@year, @month, -1) |
27 |
| - @block = block |
28 |
| - end |
29 |
| - |
30 |
| - def to_html |
31 |
| - content_tag(:table, :class => "#{@options[:calendar_class]}") do |
32 |
| - content_tag(:tbody, show_days)+ content_tag(:thead, "#{show_month_names}#{show_day_names}".html_safe) |
33 |
| - end |
34 |
| - end |
35 |
| - |
36 |
| - private |
37 |
| - def show_days |
38 |
| - content_tag(:tr, "#{show_previous_month}#{show_current_month}#{show_following_month}".html_safe) |
39 |
| - end |
40 |
| - |
41 |
| - def show_previous_month |
42 |
| - return if @days.first.wday == first_day_of_week # don't display anything if the first day is the first day of a week |
43 |
| - |
44 |
| - returning "" do |output| |
45 |
| - beginning_of_week(@days.first).upto(@days.first - 1) { |d| output << show_day(d) } |
46 |
| - end.html_safe |
47 |
| - end |
48 |
| - |
49 |
| - def show_current_month |
50 |
| - returning "" do |output| |
51 |
| - @days.first.upto(@days.last) { |d| output << show_day(d) } |
52 |
| - end.html_safe |
53 |
| - end |
54 |
| - |
55 |
| - def show_following_month |
56 |
| - return if @days.last.wday == last_day_of_week # don't display anything if the last day is the last day of a week |
57 |
| - |
58 |
| - returning "" do |output| |
59 |
| - (@days.last + 1).upto(beginning_of_week(@days.last + 1.week) - 1) { |d| output << show_day(d) } |
60 |
| - end.html_safe |
61 |
| - end |
62 |
| - |
63 |
| - def show_day(day) |
64 |
| - options = { :class => "day" } |
65 |
| - options[:class] << " otherMonth" if day.month != @days.first.month |
66 |
| - options[:class] << " weekend" if Calendar.weekend?(day) |
67 |
| - options[:class] << " today" if day.today? |
68 |
| - |
69 |
| - # block is only called for current month or if :yield_surrounding_days is set to true |
70 |
| - if @block && (@options[:yield_surrounding_days] || day.month == @days.first.month) |
71 |
| - content, options_from_block = Array(@block.call(day)) |
72 |
| - |
73 |
| - # passing options is optional |
74 |
| - if options_from_block.is_a?(Hash) |
75 |
| - options[:class] << " #{options_from_block.delete(:class)}" if options_from_block[:class] |
76 |
| - options.merge!(options_from_block) |
77 |
| - end |
78 |
| - else |
79 |
| - content = day.day |
80 |
| - end |
81 |
| - |
82 |
| - content = content_tag(:td, content.to_s.html_safe, options) |
83 |
| - |
84 |
| - # close table row at the end of a week and start a new one |
85 |
| - # opening and closing tag for the first and last week are included in #show_days |
86 |
| - content << "</tr><tr>".html_safe if day < @days.last && day.wday == last_day_of_week |
87 |
| - content |
88 |
| - end |
89 |
| - |
90 |
| - def beginning_of_week(day) |
91 |
| - diff = day.wday - first_day_of_week |
92 |
| - diff += 7 if first_day_of_week > day.wday # hackish ;-) |
93 |
| - day - diff |
94 |
| - end |
95 |
| - |
96 |
| - def show_month_names |
97 |
| - return if @options[:hide_month_name] |
98 |
| - |
99 |
| - content_tag(:tr, "#{previous_month}#{current_month}#{next_month}".html_safe, :class => 'month_names') |
100 |
| - end |
101 |
| - |
102 |
| - # @options[:previous_month] can either be a single value or an array containing two values. For a single value, the |
103 |
| - # value can either be a strftime compatible string or a proc. |
104 |
| - # For an array, the first value is considered to be a strftime compatible string and the second is considered to be |
105 |
| - # a proc. If the second value is not a proc then it will be ignored. |
106 |
| - def previous_month |
107 |
| - return unless @options[:previous_month] |
108 |
| - |
109 |
| - show_month(@days.first - 1.month, @options[:previous_month], :class => "previous") |
110 |
| - end |
111 |
| - |
112 |
| - # see previous_month |
113 |
| - def next_month |
114 |
| - return unless @options[:next_month] |
115 |
| - |
116 |
| - show_month(@days.first + 1.month, @options[:next_month], :class => "next") |
117 |
| - end |
118 |
| - |
119 |
| - # see previous_month and next_month |
120 |
| - def current_month |
121 |
| - colspan = @options[:previous_month] || @options[:next_month] ? 3 : 7 # span across all 7 days if previous and next month aren't shown |
122 |
| - |
123 |
| - show_month(@days.first, @options[:current_month], :colspan => colspan, :class => "current") |
124 |
| - end |
125 |
| - |
126 |
| - def show_month(month, format, options={}) |
127 |
| - options[:colspan] ||= 2 |
128 |
| - |
129 |
| - content_tag(:th, :colspan => options[:colspan], :class => "#{options[:class]} #{Date::MONTHNAMES[month.month].downcase}") do |
130 |
| - if format.kind_of?(Array) && format.size == 2 |
131 |
| - text = I18n.localize(month, :format => format.first.to_s).html_safe |
132 |
| - format.last.respond_to?(:call) ? link_to(text, format.last.call(month)) : text |
133 |
| - else |
134 |
| - format.respond_to?(:call) ? format.call(month) : I18n.localize(month, :format => format.to_s).html_safe |
135 |
| - end |
136 |
| - end |
137 |
| - end |
138 |
| - |
139 |
| - def day_names |
140 |
| - @day_names ||= @options[:use_full_day_names] ? full_day_names : abbreviated_day_names |
141 |
| - end |
142 |
| - |
143 |
| - def full_day_names |
144 |
| - @full_day_names ||= I18n.translate(:'date.day_names') |
145 |
| - end |
146 |
| - |
147 |
| - def abbreviated_day_names |
148 |
| - @abbreviated_day_names ||= I18n.translate(:'date.abbr_day_names') |
149 |
| - end |
150 |
| - |
151 |
| - def show_day_names |
152 |
| - return if @options[:hide_day_names] |
153 |
| - content_tag(:tr, :class => 'day_names') do |
154 |
| - apply_first_day_of_week(day_names).inject('') do |output, day| |
155 |
| - output << content_tag(:th, include_day_abbreviation(day), :scope => 'col', :class => Date::DAYNAMES[day_names.index(day)].downcase) |
156 |
| - end.html_safe |
157 |
| - end |
158 |
| - end |
159 |
| - |
160 |
| - # => <abbr title="Sunday">Sun</abbr> |
161 |
| - def include_day_abbreviation(day) |
162 |
| - return day if @options[:use_full_day_names] |
163 |
| - |
164 |
| - content_tag(:abbr, day, :title => full_day_names[abbreviated_day_names.index(day)]) |
165 |
| - end |
166 |
| - |
167 |
| - def apply_first_day_of_week(day_names) |
168 |
| - names = day_names.dup |
169 |
| - first_day_of_week.times { names.push(names.shift) } |
170 |
| - names |
171 |
| - end |
172 |
| - |
173 |
| - def first_day_of_week |
174 |
| - @options[:first_day_of_week] |
175 |
| - end |
176 |
| - |
177 |
| - def last_day_of_week |
178 |
| - @options[:first_day_of_week] > 0 ? @options[:first_day_of_week] - 1 : 6 |
179 |
| - end |
180 |
| - |
181 |
| - class << self |
182 |
| - def weekend?(day) |
183 |
| - [0,6].include?(day.wday) # 0 = Sunday, 6 = Saturday |
184 |
| - end |
185 |
| - |
186 |
| - def default_calendar_options |
187 |
| - { |
188 |
| - :calendar_class => "calendar", |
189 |
| - :first_day_of_week => I18n.translate(:'date.first_day_of_week', :default => "0").to_i, |
190 |
| - :hide_day_names => false, |
191 |
| - :hide_month_name => false, |
192 |
| - :use_full_day_names => false, |
193 |
| - :current_month => I18n.translate(:'date.formats.calendar_header', :default => "%B"), |
194 |
| - :next_month => false, |
195 |
| - :previous_month => false, |
196 |
| - :next_and_previous_month => false, |
197 |
| - :yield_surrounding_days => false |
198 |
| - } |
199 |
| - end |
200 |
| - end |
201 |
| - end |
202 |
| -end |
203 |
| - |
204 |
| -ActionView::Base.send(:include, LaterDude::CalendarHelper) |
| 1 | +require 'later_dude/calendar' |
| 2 | +require 'later_dude/calendar_helper' |
| 3 | +require 'later_dude/rails2_compat' |
0 commit comments