<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DZone Snippets: Knewter's Code Snippets</title>
    <link>http://snippets.dzone.com/posts</link>
    <pubDate>Sat, 26 Jul 2008 20:14:20 GMT</pubDate>
    <description>DZone Snippets: Knewter's Code Snippets</description>
    <item>
      <title>week_view_helper</title>
      <link>http://snippets.dzone.com/posts/show/5206</link>
      <description>// Week view helper.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;require 'date'&lt;br /&gt;&lt;br /&gt;# Author: Josh Adams&lt;br /&gt;# This helper is based on CalendarHelper.&lt;br /&gt;# WeekViewHelper allows you to draw a databound week view calendar with fine-grained CSS formatting&lt;br /&gt;module WeekViewHelper&lt;br /&gt;  VERSION = '0.0.1'&lt;br /&gt;&lt;br /&gt;  # Returns an HTML week-view calendar. In its simplest form, this method generates a plain&lt;br /&gt;  # calendar (which can then be customized using CSS) for a given span of days.&lt;br /&gt;  # However, this may be customized in a variety of ways -- changing the default CSS&lt;br /&gt;  # classes, generating the individual day entries yourself, and so on.&lt;br /&gt;  # &lt;br /&gt;  # The following options are required:&lt;br /&gt;  #  :start_date&lt;br /&gt;  #  :end_date&lt;br /&gt;  # &lt;br /&gt;  # The following are optional, available for customizing the default behaviour:&lt;br /&gt;  #   :table_class       =&gt; "week-view"        # The class for the &lt;table&gt; tag.&lt;br /&gt;  #   :day_name_class    =&gt; "dayName"         # The class is for the names of the days, at the top.&lt;br /&gt;  #   :day_class         =&gt; "day"             # The class for the individual day number cells.&lt;br /&gt;  #                                             This may or may not be used if you specify a block (see below).&lt;br /&gt;  #   :show_today        =&gt; true              # Highlights today on the calendar using the CSS class 'today'. &lt;br /&gt;  #                                           # Defaults to true.&lt;br /&gt;  #   :previous_span_text   =&gt; nil            # Displayed left if set&lt;br /&gt;  #   :next_span_text   =&gt; nil                # Displayed right if set&lt;br /&gt;  #&lt;br /&gt;  # For more customization, you can pass a code block to this method, that will get two argument, both DateTime objects,&lt;br /&gt;  # and return a values for the individual table cells. The block can return an array, [cell_text, cell_attrs],&lt;br /&gt;  # cell_text being the text that is displayed and cell_attrs a hash containing the attributes for the &lt;td&gt; tag&lt;br /&gt;  # (this can be used to change the &lt;td&gt;'s class for customization with CSS).&lt;br /&gt;  # This block can also return the cell_text only, in which case the &lt;td&gt;'s class defaults to the value given in&lt;br /&gt;  # +:day_class+. If the block returns nil, the default options are used.&lt;br /&gt;  # &lt;br /&gt;  # Example usage:&lt;br /&gt;  #   week_view(:start_date =&gt; (Date.today - 5), :end_date =&gt; Date.today) # This generates the simplest possible week-view.&lt;br /&gt;  #   week_view(:start_date =&gt; (Date.today - 5), :end_date =&gt; Date.today, :table_class =&gt; "calendar_helper"}) # This generates a week-view, as&lt;br /&gt;  #                                                                             # before, but the &lt;table&gt;'s class&lt;br /&gt;  #                                                                             # is set to "calendar_helper".&lt;br /&gt;  #   week_view(:start_date =&gt; (Date.today - 5), :end_date =&gt; Date.today) do |s| # This generates a simple week-view, but gives special spans&lt;br /&gt;  #     if listOfSpecialSpans.include?(s)          # (spans that are in the array listOfSpecialSpans) one CSS class,&lt;br /&gt;  #       ["", {:class =&gt; "specialSpan"}]      # "specialSpan", and gives the rest of the spans another CSS class,&lt;br /&gt;  #     else                                      # "normalSpan". You can also use this to highlight the current time differently&lt;br /&gt;  #       ["", {:class =&gt; "normalSpan"}]       # from the rest of the days, etc.&lt;br /&gt;  #     end&lt;br /&gt;  #   end&lt;br /&gt;  #&lt;br /&gt;  # For consistency with the themes provided in the calendar_styles generator, use "specialSpan" as the CSS class for marked days.&lt;br /&gt;  # &lt;br /&gt;  def week_view(options = {}, &amp;block)&lt;br /&gt;    raise(ArgumentError, "No start date given")  unless options.has_key?(:start_date)&lt;br /&gt;    raise(ArgumentError, "No end date given") unless options.has_key?(:end_date)&lt;br /&gt;    span = (options[:end_date] - options[:start_date]).to_i # Get the number of days represented by the span given&lt;br /&gt;    dates = (options[:start_date]..options[:end_date])&lt;br /&gt;    start_time = 8&lt;br /&gt;    end_time   = 17&lt;br /&gt;    time_range = (start_time..end_time).to_a&lt;br /&gt;    duration = 15&lt;br /&gt;&lt;br /&gt;    block                        ||= Proc.new {|d| nil}&lt;br /&gt;    defaults = {&lt;br /&gt;      :table_class =&gt; 'week-view',&lt;br /&gt;      :day_name_class =&gt; 'dayName',&lt;br /&gt;      :day_class =&gt; 'day',&lt;br /&gt;      :show_today =&gt; true,&lt;br /&gt;      :previous_span_text =&gt; nil,&lt;br /&gt;      :next_span_text =&gt; nil&lt;br /&gt;    }&lt;br /&gt;    options = defaults.merge options&lt;br /&gt;&lt;br /&gt;		if options[:url]&lt;br /&gt;      next_start_date = options[:end_date] + 1&lt;br /&gt;      next_end_date   = next_start_date + 5&lt;br /&gt;      next_link = link_to('&gt;&gt;', url_for(options[:url].merge(:start_date =&gt; next_start_date, :end_date =&gt; next_end_date)) + options[:url_append])&lt;br /&gt;      prev_start_date = options[:start_date] - span&lt;br /&gt;      prev_end_date = options[:start_date] - 1&lt;br /&gt;      prev_link = link_to('&lt;&lt;', url_for(options[:url].merge(:start_date =&gt; prev_start_date, :end_date =&gt; prev_end_date)) + options[:url_append])&lt;br /&gt;		end&lt;br /&gt;&lt;br /&gt;    # TODO Use some kind of builder instead of straight HTML&lt;br /&gt;    cal = %(&lt;table class="#{options[:table_class]}"&gt;\n)&lt;br /&gt;    cal &lt;&lt; %(\t&lt;thead&gt;\n\t\t&lt;tr&gt;\n)&lt;br /&gt;    cal &lt;&lt; %(\t\t\t&lt;th&gt;#{dates.first.strftime("%Y")}&lt;/th&gt;\n)&lt;br /&gt;    dates.each do |d|&lt;br /&gt;      cal &lt;&lt; "\t\t\t&lt;th#{Date.today == d ? " class='today'" : ""}&gt;#{d.strftime("%A")}&lt;br /&gt;#{d.strftime("%m/%d")}&lt;/th&gt;\n"&lt;br /&gt;    end&lt;br /&gt;    cal &lt;&lt; "\t\t&lt;/tr&gt;\n\t&lt;/thead&gt;\n\t&lt;tbody&gt;\n"&lt;br /&gt;    time_range.each do |hour|&lt;br /&gt;      minutes = 0&lt;br /&gt;      print_hour = hour.to_s.rjust(2, '0')&lt;br /&gt;      4.times do |i|&lt;br /&gt;        print_minutes = minutes.to_s.rjust(2, '0')&lt;br /&gt;        cal &lt;&lt; %(\t\t&lt;tr class='m#{print_minutes} d#{duration}'&gt;\n)&lt;br /&gt;        cal &lt;&lt; %(\t\t\t&lt;th rowspan="4"&gt;&lt;h3&gt;#{hour}&lt;/h3&gt;AM&lt;/th&gt;\n) if i==0&lt;br /&gt;        options[:start_date].upto(options[:end_date]) do |d|&lt;br /&gt;          the_minutes = minutes&lt;br /&gt;          print_start_minutes = the_minutes.to_s.ljust(2, '0')&lt;br /&gt;          start_datetime_string = %(#{d.to_s(:db)}T#{print_hour}:#{print_start_minutes}:00-06:00)&lt;br /&gt;          start_datetime = DateTime.parse(start_datetime_string).to_datetime&lt;br /&gt;          end_datetime = (start_datetime + duration.minutes).to_datetime&lt;br /&gt;          range = (start_datetime...end_datetime)&lt;br /&gt;&lt;br /&gt;          # cell_attrs should return a hash.&lt;br /&gt;          cell_text, cell_attrs = block.call(range)&lt;br /&gt;          cell_text ||= ""&lt;br /&gt;          cell_attrs ||= {}&lt;br /&gt;          cell_attrs[:class] = cell_attrs[:class].to_s + " today" if Date.today == d&lt;br /&gt;          cell_attrs = cell_attrs.map {|k, v| %(#{k}="#{v}") }.join(" ")&lt;br /&gt;&lt;br /&gt;          cal &lt;&lt; "\t\t\t&lt;td #{cell_attrs}&gt;\n#{cell_text}&amp;nbsp;\t\t\t&lt;/td&gt;\n"&lt;br /&gt;        end&lt;br /&gt;        minutes += duration&lt;br /&gt;        cal &lt;&lt; %(\t\t&lt;/tr&gt;)&lt;br /&gt;      end&lt;br /&gt;    end&lt;br /&gt;    cal &lt;&lt; "\n\t&lt;/tbody&gt;\n&lt;/table&gt;"&lt;br /&gt;  end&lt;br /&gt;  &lt;br /&gt;  private&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;// Usage&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&lt;%= week_view :start_date =&gt; (Date.today - 2), :end_date =&gt; (Date.today + 2) do |range|&lt;br /&gt;      cell_text = ""&lt;br /&gt;      cell_attrs = {}&lt;br /&gt;      @events.each do |e|&lt;br /&gt;        #if range.first.to_date == e.starts_at.to_date#range.include?(e.starts_at.to_datetime)&lt;br /&gt;        if range.include?(e.starts_at.to_datetime)&lt;br /&gt;          cell_text &lt;&lt; "&lt;div class='event-container'&gt;\n"&lt;br /&gt;          if e.work_order&lt;br /&gt;            work_order_text = ""&lt;br /&gt;            work_order_text &lt;&lt; "&lt;h3&gt;" &lt;&lt; e.work_order.ticket.summary + "&lt;/h3&gt;\n"&lt;br /&gt;            work_order_text &lt;&lt; e.work_order.description&lt;br /&gt;&lt;br /&gt;            klass = ["event"]&lt;br /&gt;            klass &lt;&lt; "closed" if e.work_order.closed?&lt;br /&gt;            klass &lt;&lt; "mm" + (e.work_order.hours * 60).to_i.to_s&lt;br /&gt;&lt;br /&gt;            work_order_text = "&lt;div class='#{klass.join(" ")}'&gt;\n#{work_order_text}\n&lt;/div&gt;\n"&lt;br /&gt;            work_order_link = link_to(work_order_text, company_asset_ticket_work_order_path(e.work_order.company, e.work_order.asset, e.work_order.ticket, e.work_order))&lt;br /&gt;            cell_text &lt;&lt; work_order_link&lt;br /&gt;          end&lt;br /&gt;          cell_text &lt;&lt; "&lt;/div&gt;\n"&lt;br /&gt;        end&lt;br /&gt;      end&lt;br /&gt;      [cell_text, cell_attrs]&lt;br /&gt;    end &lt;br /&gt;-%&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;// Styles&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;table.week-view{&lt;br /&gt;  width: 100%;&lt;br /&gt;  padding: 0;&lt;br /&gt;  border-collapse: collapse;&lt;br /&gt;}&lt;br /&gt;table.week-view tbody tr th{&lt;br /&gt;  border-right: 1px solid black;&lt;br /&gt;  text-align: left;&lt;br /&gt;  padding-right: .5em;&lt;br /&gt;}&lt;br /&gt;table.week-view tbody tr th h3{&lt;br /&gt;  display: inline;&lt;br /&gt;  font-size: 3em;&lt;br /&gt;  margin: 0;&lt;br /&gt;  padding: 0;&lt;br /&gt;  background: transparent;&lt;br /&gt;  border: none;&lt;br /&gt;}&lt;br /&gt;table.week-view th{&lt;br /&gt;  background-color: #eee;&lt;br /&gt;  color: black;&lt;br /&gt;}&lt;br /&gt;table.week-view tr td{&lt;br /&gt;  border-style: solid;&lt;br /&gt;  border-width: 1px 1px 0 0;&lt;br /&gt;  width: 19%;&lt;br /&gt;  padding: 0;&lt;br /&gt;  background-color: #ffffd5;&lt;br /&gt;}&lt;br /&gt;table.week-view tr.d15 td,&lt;br /&gt;table.week-view tr.d15 th{&lt;br /&gt;  font-size: 8px;&lt;br /&gt;  height: 1em;&lt;br /&gt;  border-color: #f3e4b1 #000;&lt;br /&gt;}&lt;br /&gt;table.week-view div.event-container{&lt;br /&gt;  position: relative;&lt;br /&gt;}&lt;br /&gt;table.week-view tr td div.event{&lt;br /&gt;  padding: 2px;&lt;br /&gt;  background-color: #fff;&lt;br /&gt;  height: 2em;&lt;br /&gt;  width: 90%;&lt;br /&gt;  position: absolute;&lt;br /&gt;  top: 0;&lt;br /&gt;  left: 0;&lt;br /&gt;  border-style: solid;&lt;br /&gt;  border-color: black black black #00f;&lt;br /&gt;  border-width: .0625em .0625em .0625em .5em;&lt;br /&gt;  margin-right: .5em;&lt;br /&gt;  color: #333;&lt;br /&gt;  overflow: hidden;&lt;br /&gt;  float: left;&lt;br /&gt;}&lt;br /&gt;table.week-view tr td div.event.mm60{&lt;br /&gt;  height: 8em;&lt;br /&gt;}&lt;br /&gt;table.week-view tr td div.event.mm120{&lt;br /&gt;  height: 16em;&lt;br /&gt;}&lt;br /&gt;table.week-view tr td div.event h3{&lt;br /&gt;  margin: 0;&lt;br /&gt;  font-size: 9px;&lt;br /&gt;  color: black;&lt;br /&gt;  padding: 0;&lt;br /&gt;  border: 0;&lt;br /&gt;  background: transparent;&lt;br /&gt;}&lt;br /&gt;table.week-view tr.m00 td{&lt;br /&gt;  border-top-color: #c2b68d;&lt;br /&gt;}&lt;br /&gt;table.week-view tr.m00 th{&lt;br /&gt;  vertical-align: top;&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;</description>
      <pubDate>Sun, 09 Mar 2008 02:22:50 GMT</pubDate>
      <guid>http://snippets.dzone.com/posts/show/5206</guid>
      <author>knewter (Josh Adams)</author>
    </item>
  </channel>
</rss>
