SimpleCalendar::Timeslot

This gem is an extension of the rubygem simple_calendar by Chris Oliver aka excid3. It allows for simple calendar creation in a Ruby on Rails app with an timeslot representation of events in a 24h day.

This helps to visually grasps the length of events and the time between them. In case of overlapping, the respective events are shown side-by-side. It is also possible to categorise events in buckets according to some function, then they will be shown next to one another in the 24h timeline.

Different layouts are selectable via options, just like many other ones.

All layouts support the following options:

  • event rendering can be completely controlled, the calendar provides a wrapping div around with the correct dimensions at the right place
  • responsive design which can (and should) be styled to your liking
  • turn hour grid on/off
  • set the width of the grid in px or %
  • adjust the pixel-size corresponding to one minute
  • limit the overall size of day, making part of it scroll
  • for horizontal layouts: determine the breadth of one day
  • "bucketing" of events by same value, any event function can be provided (see colums "Me" and "Mom" in image below and symbol :event_type_name in code)
  • displaying of bucket label by provided function on event
  • formating of date above day
  • formating of date in heading
  • turn current time indicator on/off, this is an invisible css-stylable div with class tscal-current-time-indicator (can be seen in examples below)
  • by default, the 24h-grid hides any overflow which is recommended not to overwrite, otherwise there might be 2-directional scrolling

Note: events are styled in the examples with the following minimalistic styles to show their outline. This is not the case when the gem is used out of the box, because it would make the style hard to overwrite because of css-predence rules.

.event-wrapper {
  border: solid 1px black;
}

Vertical layout

This layout grows vertically, and can be limited in height by option body_size_px and will then scroll. The horizontal direction is responsive. Vertical Layout

Code

<%= timeslot_calendar(events: @events,
                      layout: :vertical,
                      number_of_days: 2,
                      px_per_minute: 1.3,
                      #display_grid: true,
                      grid_width: "30px",
                      body_size_px: 600,
                      bucket_by: :event_type,
                      date_format_string: "%d.%m.%Y",
                      #date_heading_format_string: "%d.%m.%Y",
                      display_bucket_title: :event_type_name,
                      display_current_time_indicator: true
      ) do |event| %>
  <div class="timeslot-event">
    <%= event.title %>
  </div>
<% end %>

Horizontal layout

This layout is basicall the vertical one toppled over. The days grows horizontally, if it has not enough space (which is likely this direction) the day will scroll with the day and bucket headings staying fixed. Multiple days scroll together. The height per day can be adjusted as option, the events scale responsively.

One advantage over vertical layout is that the horizontal scrolling works better for mobile devices, combined with vertical scroll to scroll further down. Horizontal Layout

Code:

<%= timeslot_calendar(events: @events,
                      layout: :horizontal,
                      day_height_px: 100,
                      #...
      ) do |event| %>
    <div class="timeslot-event">
      <%= event.title %>
    </div>
  <% end %>

Horizontal - Date on top

My personal favorite: like horizontal layout, but the date is moved above the scrolling day, freeing up space. Forcibly, the scroll between days is separated (this could be restored with a javascript scroll-lock). Horizontal Layout

Code:

<%= timeslot_calendar(events: @events,
                      layout: :horizontal_date_on_top,
                      #...
      ) do |event| %>
    <div class="timeslot-event">
      <%= event.title %>
    </div>
  <% end %>

Installation

Add this line to your application's Gemfile:

gem 'simple_calendar-timeslot'

And then execute:

$ bundle install

Or install it yourself as:

$ gem install simple_calendar-timeslot

Important Then include the stylesheet in your rails app.

If you have an application.css file, include the following (before *= require_tree . and *= require_self if you want to overwrite styles with equal specificity):

*= require simple_calendar-timeslot

If you use an SCSS file (application.scss), add the following line instead:

@import 'simple_calendar-timeslot';

Usage

Include a code snipped like the one below anywhere in your .html.erb file, set @events in your calling controller to be a collection of your model object to be displayed. You can refer to the documentation on simple_calendar/Rendering_Events (thats from the gem on which this one is built on top of), the complete paragraph applies to this gem as well.

All options are optional, below you see all possible values commented out with their default value behind the colon and a short description afterwards.

Your model must implement a start_time and end_time function that returns a datetime, or you can specify alternatives as options to the call below as attribute: :my_start_time and end_attribute: :my_end_time (without the # of course).

<%= timeslot_calendar(events: @events,
                      # number_of_days: 4, 
                      # layout: :vertical, # possible values: :vertical, :horizontal, :horizontal_date_on_top
                      # px_per_minute: 0.65, # define size of one minute
                      # display_grid: true, 
                      # grid_width: "20px", # can be any valid css size px, %, em
                      # display_current_time_indicator: false, # draw a line to show the current time, stylable class: tscal-current-time-indicator
                      # body_size_px: false, # only vertical layout: set integer if your want to limit the height
                      # day_height_px: 200, # only horizontal and horizontal_date_on_top layout: set height for a day
                      # bucket_by: false, # give model function as symbol if you want to bucket events by this function (f.ex. :event_type)
                      # display_bucket_title: false,
                      # date_format_string: false,
                      # date_heading_format_string: "%B %Y",
                      # attribute: :my_start_time, # provide alternative to :start_time model function 
                      # end_attribute: :my_end_time, # provide alternative to :end_time model function 
                     ) do |event| %>
  <div class="timeslot-event">
    <%= event.title %>
  </div>
<% end %>

Customization

Style away as much as you want. This gem is mainly concerned to move the right pieces to the right place, how they look is up to you. Have a look at the generated HTML or start with these classes

  • .tscal-event-wrapper
  • .tscal-current-time-indicator
  • .tscal-hour-cell

Some words of caution: overflow is hidden for the scrolling part of the calendar, that is a div with class .buckets-wrapper. If you see your box-shadows clipped, that is probably causing it. You can of course overwrite clipping (with .timeslot-calendar .buckets-wrapper { overflow: visible; }), but then I recommend setting overflow: hidden; on .tscal-event-wrapper, otherwise you risk to see scrolling where you don't want to, when to content of the event is overflowing.

Here is an example with some basic styling

Styled calendar

Development

After checking out the repo, run bin/setup to install dependencies. Then, run rake test to run the tests. You can also run bin/console for an interactive prompt that will allow you to experiment.

To install this gem onto your local machine, run bundle exec rake install. To release a new version, update the version number in version.rb, and then run bundle exec rake release, which will create a git tag for the version, push git commits and the created tag, and push the .gem file to rubygems.org.

Contributing

I could use some help with the test suite. Bug reports and pull requests are welcome on GitHub at https://github.com/1klap/simple_calendar-timeslot.