Skip to content
tschmidt edited this page Sep 13, 2010 · 8 revisions

This tutorial will cover examples from basic to more advanced.

Common to all examples

Once you have installed the gem, you will need to add the following to between the

… section of your layout <%= stylesheet_link_tag ‘nifty_cal/modern’ %>

This will include the ‘modern.css’ stylesheet. You can use this stylesheet as a template to create your own custom stylesheets. More options may be added later but for now this will definitely get you started.

Easy peasy

The easiest way to insert a calendar into a view is to add

<%= display_calendar %>

in the view that will display the calendar. This will insert a calendar that starts on the first day of the current month and will continue to the end of the month. In some cases this may pad the end of the month with the first few days of the following month to fill out the calendar. Some people may not like the way this looks as it is not your standard view for display a calendar. Typically you will see something like this:

Sun Mon Tue Wed Thu Fri Sat
1 2 3 4 5 6 7
8 9 10 11 12 13 14

and not something that looks like this…

Tue Wed Thu Fri Sat Sun Mon
1 2 3 4 5 6 7
8 9 10 11 12 13 14

The reason that I didn’t take this route is that the NiftyCal was not designed to show a straight up calendar. The purpose was to take advantage of some of the more advanced options and display a calendar that starts on today’s date and goes through to a set end date. This would dynamically update the view to show an ever changing format for the calendar.

More dynamic example

For this example we are going to assume that we have an application that tracks events. These events have a ‘date’ field and a ‘title’ field. The ‘date’ field will contain the date of the event and the ‘title’ field will contain (you guessed it) the title for the event. We’ve decided that we only want to see the dates that are coming up in the next 2 weeks from today. It just makes sense, right? Why would we need to know about past events? Anyway, I digress.

Here’s the setup

<%= display_calendar :start_date => Date.today, :end_date => 2.weeks.from_now(Date.today) %>

Now, you may be wondering why we added the ‘Date.today’ as an argument to ‘2.weeks.from_now’. The reason is that display_calendar is expecting Date objects. When you call ‘2.weeks.from_now’ you will actually get either a DateTime object or an ActiveSupport::TimeWithZone object. Eventually I will add in support for these situations but for now, adding the ‘Date.today’ as an arguments tells ‘2.weeks.from_now’ to return the date as a Date object.

Once you reload your page you should now see a calendar that starts on today and displays 2 weeks worth of dates. Let’s take this a step further and add the event/events that occur on a specific date. First, we will need to check and see whether the calendar date matches any Event dates. This is where passing a block to the ‘display_calendar’ method comes in handy.

<%= display_calendar :start_date => Date.today, :end_date => 2.weeks.from_now(Date.today) do |day| … end %>

What we are doing here is passing each date on the calendar into the block via the ‘day’ argument. Now, you can call this whatever you like but I find it helps to keep things simple and label things what they are, call me crazy. Now we need to get all the dates from our Events and check to see if they include the day that is currently being passed into the block.

<%= display_calendar :start_date => Date.today, :end_date => 2.weeks.from_now(Date.today) do |day| if @events.collect(&:date).include(day) … end end %>

We’re using some shorthand code here so I’ll explain what’s happening here. Basically, we are going through our events that are stored in the ‘@events’ instance variable and ‘collecting’ the ‘date’ value for each of them. Then we are checking to see if the ‘day’ that is currently being passed into the block matches any of the dates that were collected. If we find a match then we need to get all the event titles for that date and display them in some way (I’m going to use a list).

<%= display_calendar :start_date => Date.today, :end_date => 2.weeks.from_now(Date.today) do |day|
  if @events.collect(&:date).include(day)
    content = '<ol>'
    @events.each do |event|
      content << "<li>#{event.title}</li>" if event.date == day
    end
    content << '</ol>'
    content
  end
end %>

Here we are just looping through the events and adding them if they match the day. We then return the ‘content’ which will be displayed in our ‘td’ for the matching day. But what if we wanted some way to mark the day on the calendar as having an event? Well, that’s pretty simple. All you need to do is pass an array instead of just the ‘content’. The first entry in the array will be the content that you want to display, the second is a hash with a single key=value pair. The key is expected to be ‘:class’ and the value is expected to be the class name that you want the ‘td’ element to have (for those wondering, I may change this in the future but I am playing with other options that can be passed). Adding this final change will produce this code

<%= display_calendar :start_date => Date.today, :end_date => 2.weeks.from_now(Date.today) do |day|
  if @events.collect(&:date).include(day)
    content = '<ol>'
    @events.each do |event|
      content << "<li>#{event.title}</li>" if event.date == day
    end
    content << '</ol>'
    [content, {:class=>'event'}]
  end
end %>

Hopefully this has been helpful. If you find that you are stuck on something, feel free to shoot me a message. As always, feedback is always welcome. Enjoy!

Clone this wiki locally