README.md in simple_calendar-1.1.10 vs README.md in simple_calendar-2.0.0

- old
+ new

@@ -1,5 +1,7 @@ +![travis ci](https://travis-ci.org/excid3/simple_calendar.svg?branch=2.0) + Simple Calendar =============== Simple Calendar is designed to do one thing really really well: render a calendar. It lets you render a calendar of any size. Maybe you want a @@ -17,16 +19,16 @@ Installation ------------ Just add this into your Gemfile followed by a bundle install: - gem "simple_calendar", "~> 1.1.0" + gem "simple_calendar", "~> 2.0" Usage ----- -Generating calendars is extremely simple with simple_calendar in version 1.1. +Generating calendars is extremely simple with simple_calendar. The first parameter is a symbol that looks up the current date in `params`. If no date is found, it will use the current date. In these examples, we're using `:start_date` which is the default. @@ -75,31 +77,31 @@ model called Meeting, but you can add this to any model or Ruby object. Here's an example model: ```bash -rails g scaffold Meeting name starts_at:datetime +rails g scaffold Meeting name start_time:datetime ``` -We use the `has_calendar` method to tell simple_calendar how to filter -and sort the meetings on the different calendar days. This should be the -start date/time of your meeting. By default it uses `starts_at` as the -attribute name. +By default it uses `start_time` as the attribute name. -```ruby -class Meeting < ActiveRecord::Base - extend SimpleCalendar - has_calendar +**If you'd like to use another attribute other than start_time, just +pass it in as the `attribute` option** - # Or set a custom attribute for simple_calendar to sort by - # has_calendar :attribute => :your_starting_time_column_name -end +```erb +<%= month_calendar(attribute: :starts_at) do |date| %> + <%= day %> +<% end %> ``` In your controller, query for these meetings and store them in an instance -variable. We'll just load up all the meetings for this example. +variable. Normally you'll want to search for the ones that only show up +inside the calendar view (for example, you may only want to grab the events for +the current month). +We'll just load up all the meetings for this example. + ```ruby def index @meetings = Meeting.all end ``` @@ -123,17 +125,27 @@ starts_at), then all the meetings will be yielded each day. This lets you do custom filtering however you want. ## Customizing The Calendar -You can change a couple of global options that will affect how the -calendars are generated: +There are a handful of configuration options that you can use in +simple_calendar. -```ruby -Time.zone = "Central Time (US & Canada)" +### Customizing Views + +You can customize the layouts for each of the calendars by running the +generators for simple_calendar: + +```bash +rails g simple_calendar:views ``` +This will generate a folder in app/views called simple_calendar that you +edit to your heart's desire. + +### Time Zones + Setting `Time.zone` will make sure the calendar start days are correctly computed in the right timezone. You can set this globally in your `application.rb` file or if you have a User model with a time_zone attribute, you can set it on every request by using a before_filter like the following example. @@ -151,218 +163,172 @@ def set_time_zone Time.zone = current_user.time_zone end end ``` -On the other hand, you can always pass a ``ActiveSupport::TimeZone`` object as an option to avoid possible timezone pollution: -```erb -<%= calendar timezone: ActiveSupport::TimeZone.new('Taipei') do |date, events| %> -<% end %> -``` - If you want to set the time zone globally, you can set the following in `config/application.rb`: ```ruby config.time_zone = 'Central Time (US & Canada)' ``` +### Beginning Of Week + You can also change the beginning day of the week by setting `Date.beginning_of_week` in a `before_filter` just like in the previous example. If you want to set this globally, you can put this line in `config/application.rb`: ```ruby config.beginning_of_week = :sunday ``` +### Custom CSS Classes + Setting classes on the table and elements are pretty easy. -Each of the options are passed directly to the -the `content_tag` method so each of them **must** be a hash. +You can simply run the following command to install the calendar views +and then add your own helpers to the table, rows, headers, and days. -```ruby +simple_calendar comes with a handful of useful classes for each day in +the calendar that you can use: -<%= calendar table: {class: "table table-bordered"}, tr: {class: "calendar-row"}, td: {class: "day"}, do |date| %> -<% end %> -``` +```scss +.simple-calendar { + .day {} -This will set the class of `table table-bordered` on the `table` HTML -element. + .wday-0 {} + .wday-1 {} + .wday-2 {} + .wday-3 {} + .wday-4 {} + .wday-5 {} + .wday-6 {} -### Custom Day Classes + .today {} + .past {} + .future {} -`td` is an option for setting the options on the td content tag that is -generated. By default, simple_calendar renders the following classes for -any given day in a calendar: + .start-date {} + .prev-month {} + .next-month { } + .current-month {} -```ruby -td_class = ["day"] -td_class << "today" if today == current_calendar_date -td_class << "past" if today > current_calendar_date -td_class << "future" if today < current_calendar_date -td_class << "prev-month" if start_date.month != current_calendar_date.month && current_calendar_date < start_date -td_class << "next-month" if start_date.month != current_calendar_date.month && current_calendar_date > start_date -td_class << "current-month" if start_date.month == current_calendar_date.month -td_class << "wday-#{current_calendar_date.wday.to_s}" + .has-events {} +} ``` -You can set your CSS styles based upon these if you want to highlight -specific days or types of days. If you wish to override this -functionality, just set the `tr` option to a lambda that accepts two -dates and returns a hash. The hash will be passed in directly to the -content_tag options. If you wish to set a class or data attributes, just -set them as you normally would in a content_tag call. +Just paste this into a CSS file and add your styles and they will be +applied to the calendar. All of these classes are inside of the +simple-calendar class so you can scope your own classes with similar +names. -```erb -<%= month_calendar td: ->(start_date, current_calendar_date) { {class: "calendar-date", data: {day: current_calendar_date}} } do |day| %> -<% end %> -``` +### Custom Header Title And Links -This generate each day in the calendar like this: +Header and title links are easily adjusted by generating views and +modifying them inside your application. -```html -<td class="calendar-date" data-day="2014-05-11"> -</td> -``` +For example, if you'd like to use abbreviated month names, you can modify +the views from this: -Instead of writing the lambdas inline, a cleaner approach is to write a -helper that returns a lambda. You can duplicate the following example by -adding this to one of your helpers: - -```ruby -def month_calendar_td_options - ->(start_date, current_calendar_date) { - {class: "calendar-date", data: {day: current_calendar_date}} - } -end +```erb +<%= I18n.t("date.month_names")[start_date.month] %> <%= start_date.year %> ``` -And then your view would use `month_calendar_td_options` as the value. +To ```erb -<%= month_calendar td: month_calendar_td_options do |date| %> -<% end %> +<%= I18n.t("date.abbr_month_names")[start_date.month] %> <%= start_date.year %> ``` -### Custom Header Title And Links +Your calendar will now display "Sep 2015" instead of "September 2015" at +the top! :) -Each of the calendar methods will generate a header with links to the -previous and next views. The `month_calendar` also includes a header -with a title that tells you the current month and year that you are viewing. +### AJAX Calendars -To change these, you can pass in the `previous_link`, `title`, and -`next_link` options into the calendar methods. +Rendering calendars that update with AJAX is pretty simple. You'll need +to wrap your calendar in a div, overwrite the `next_link` and `previous_link` options, and setup your +controller to respond to JS requests. The response can simply replace +the HTML of the div with the newly rendered calendar. -**Use a method in your helpers to return a lambda instead of writing -them inline like these examples so your views are cleaner.** +Take a look at **[excid3/simple_calendar-ajax-example](https://github.com/excid3/simple_calendar-ajax-example)** to see how it is done. -* `title` option is a lambda that shows at the top of the calendar. For -month calendars, this is the Month and Year (May 2014) -```erb -<%= calendar title: ->(start_date) { content_tag :span, "#{I18n.t("date.month_names")[start_date.month]} #{start_date.year}", class: "calendar-title" } do |date, events| %> -<% end %> -``` +## Custom Calendars -* `previous_link` option is a standard `link_to` that is a left arrow and -with the current url having `?start_date=2014-04-30` appended to it as -a date in the previous view of the calendar. +The three main calendars available should take care of most of your +needs, but simple_calendar makes it easy to create completely custom +calendars (like maybe you only want business weeks). -```erb -<%= month_calendar previous_link: ->(param, date_range) { link_to raw("&laquo;"), {param => date_range.first - 1.day} } do |date, events| %> -<% end %> -``` +If you'd like to make a completely custom calendar, you can create a new +class that inherits from `SimpleCalendar::Calendar`. The name you give +it will correspond to the name of the template it will try to render. -* `next_link` option is a standard `link_to` that is a right arrow and -with the current url having `?start_date=2014-06-01` appended to it as -a date in the next view of the calendar. -```erb -<%= calendar next_link: ->(param, date_range) { link_to raw("&raquo;"), {param => date_range.last + 1.day} } do |date, events| %> -<% end %> +The main method you'll need to implement is the `date_range` so that +your calendar can have a custom length. + ``` +class SimpleCalendar::BusinessWeekCalendar + private -* `header` lets you add options to the header tag - -```erb -<%= calendar header: {class: "calendar-header"} do |date, events| %> -<% end %> + def date_range + beginning = start_date.beginning_of_week + 1.day + ending = start_date.end_of_week - 1.day + (beginning..ending) + end +end ``` -* `thead` allows you to customize the table headers. These are the - abbreviated day names by default (Sun Mon Tue Wed). +To render this in the view, you can do: -You can disable the `thead` line if you like by passing in `false`. - ```erb -<%= calendar thead: false do |date, events| %> +<%= SimpleCalendar::BusinessWeekCalendar.new(self).render do |date| %> + <%= day %> <% end %> ``` -* `day_names` lets you customize the day names in the `thead` row. +And this will render the +`app/views/simple_calendar/_business_week_calendar.html.erb` partial. -If you want to use full day names instead of the abbreviated ones in the -table header, you can pass in the `day_names` option which points to a -validate I18n array. +You can copy one of the existing templates to use for the partial for +your new calendar. -```erb -<%= calendar day_names: "date.day_names" do |date, events| %> -<% end %> -``` +## View Specs and Tests -Which renders: +If you're running view specs against views with calendars, you may run into route generation errors like the following: -```html -<thead> - <tr> - <th>Sunday</th> - <th>Monday</th> - <th>Tuesday</th> - <th>Wednesday</th> - </tr> -</thead> ``` - -By default we use the `date.abbr_day_names` translation to have shorter -header names. - -```erb -<%= calendar day_names: "date.abbr_day_names" do |date, events| %> -<% end %> +Failure/Error: render +ActionView::Template::Error: + No route matches {:action=>"show", :controller=>"controller_name", :start_date=>Sun, 29 Mar 2015} ``` -This renders: +If so, you can stub out the appropriate method like so (rspec 3 and up): -```html -<thead> - <tr> - <th>Sun</th> - <th>Mon</th> - <th>Tue</th> - <th>Wed</th> - </tr> -</thead> ``` +expect_any_instance_of(SimpleCalendar::Calendar).to receive(:link_to).at_least(:once).and_return("") +``` -### AJAX Calendars +With modifications as appropriate. -Rendering calendars that update with AJAX is pretty simple. You'll need -to wrap your calendar in a div, overwrite the `next_link` and `previous_link` options, and setup your -controller to respond to JS requests. The response can simply replace -the HTML of the div with the newly rendered calendar. - -Take a look at **[excid3/simple_calendar-ajax-example](https://github.com/excid3/simple_calendar-ajax-example)** to see how it is done. - ## TODO -- Multi-day events? +- Multi-day events +- Rspec tests for Calendar +- Rspec tests for MonthCalendar +- Rspec tests for WeekCalendar ## Author Chris Oliver <chris@gorails.com> [https://gorails.com](https://gorails.com) [@excid3](https://twitter.com/excid3) + +## Support + +Need help