These helper methods are intended to make the use of the DHTML/JavaScript calendar from http://www.dynarch.com/projects/calendar/ as easy as possible.
Lest I forget it. The calendar has a bug that keeps it currently from working correctly in “flat” (in-page) mode. Please have a look at this patch
—MichaelSchuerig
—
S2: Tested with Internet Explorer 7 Beta 2 and Firefox
—
Michael, could you preface each block of code with a suggestion of which file in our project it is intended to be merged with?
—Tried to do this- SteveJernigan
I would also appreciate some more pre-explanation. such as what this module can do exactly. does it allow me to color certain dates? does it allow me to easily set onclick event on dates. I want to allow the user to browse through my apps via the application.
—Thinking of trying- Somekool
—
If you want to load the helper functions as an ActionView Helper plugin, replace
module CalendarHelper with module ActionView::Helpers::CalendarHelper and add the line ActionView::Base.send(:include, ActionView::Helpers::CalendarHelper) at the end of the code. Now put the code into the the file vendor/plugins/calendar_helper/lib/calendar_helper.rb and put an init.rb file into vendors/plugins/calendar_helper. This file should have the following content:require 'calendar_helper'
—
# The Calendar Helper methods create HTML code for different variants of the # Dynarch DHTML/JavaScript Calendar. # # Author: Michael Schuerig, <a href="mailto:michael@schuerig.de">michael@schuerig.de</a>, 2005 # Free for all uses. No warranty or anything. Comments welcome. # # Version 0.02: # Always set calendar_options's ifFormat value to '%Y/%m/%d %H:%M:%S' # so that the calendar recieves the object's time of day. Previously, # the '%c' formating used to set the initial date would be parsed by # the JavaScript calendar correctly to find the date, but it would not # pick up the time of day. # # Version 0.01: # Original version by Michael Schuerig. # # # # == Prerequisites # # Get the latest version of the calendar package from # <a href="http://www.dynarch.com/projects/calendar/">http://www.dynarch.com/projects/calendar/</a> # # == Installation # # You need to install at least these files from the jscalendar distribution # in the +public+ directory of your project # # public/ # images/ # calendar.gif [copied from img.gif] # javascripts/ # calendar.js # calendar-setup.js # calendar-en.js # stylesheets/ # calendar-system.css # # Then, in the head section of your page templates, possibly in a layout, # include the necessary files like this: # # <%= stylesheet_link_tag 'calendar-system.css' %> # <%= javascript_include_tag 'calendar', 'calendar-en', 'calendar-setup' %> # # == Common Options # # The +html_options+ argument is passed through mostly verbatim to the # +text_field+, +hidden_field+, and +image_tag+ helpers. # The +title+ attributes are handled specially, +field_title+ and # +button_title+ appear only on the respective elements as +title+. # # The +calendar_options+ argument accepts all the options of the # JavaScript +Calendar.setup+ method defined in +calendar-setup.js+. # The ifFormat option for +Calendar.setup+ is set up with a default # value that sets the calendar's date and time to the object's value, # so only set it if you need to send less specific times to the # calendar, such as not setting the number of seconds. # # module CalendarHelper # Returns HTML code for a calendar that pops up when the calendar image is # clicked. # # _Example:_ # # <%= popup_calendar 'person', 'birthday', # { :class => 'date', # :field_title => 'Birthday', # :button_image => 'calendar.gif', # :button_title => 'Show calendar' }, # { :firstDay => 1, # :range => [1920, 1990], # :step => 1, # :showOthers => true, # :cache => true } # %> # def popup_calendar(object, method, html_options = {}, calendar_options = {}) _calendar(object, method, false, true, html_options, calendar_options) end # Returns HTML code for a flat calendar. # # _Example:_ # # <%= calendar 'person', 'birthday', # { :class => 'date' }, # { :firstDay => 1, # :range => [1920, 1990], # :step => 1, # :showOthers => true } # %> # def calendar(object, method, html_options = {}, calendar_options = {}) _calendar(object, method, false, false, html_options, calendar_options) end # Returns HTML code for a date field and calendar that pops up when the # calendar image is clicked. # # _Example:_ # # <%= calendar_field 'person', 'birthday', # { :class => 'date', # :field_title => 'Birthday', # :button_title => 'Show calendar' }, # { :firstDay => 1, # :range => [1920, 1990], # :step => 1, # :showOthers => true, # :cache => true } # %> # def calendar_field(object, method, html_options = {}, calendar_options = {}) _calendar(object, method, true, true, html_options, calendar_options) end private def _calendar(object, method, show_field = true, popup = true, html_options = {}, calendar_options = {}) button_image = html_options[:button_image] || 'calendar' date = value(object, method) input_field_id = "#{object}_#{method}" calendar_id = "#{object}_#{method}_calendar" add_defaults(calendar_options, :ifFormat => '%Y/%m/%d %H:%M:%S') field_options = html_options.dup add_defaults(field_options, :value => date && date.strftime(calendar_options[:ifFormat]), :size => 12 ) rename_option(field_options, :field_title, :title) remove_option(field_options, :button_title) if show_field field = text_field(object, method, field_options) else field = hidden_field(object, method, field_options) end if popup button_options = html_options.dup add_mandatories(button_options, :id => calendar_id) rename_option(button_options, :button_title, :title) remove_option(button_options, :field_title) calendar = image_tag(button_image, button_options) else calendar = "<div id=\"#{calendar_id}\" class=\"#{html_options[:class]}\"></div>" end calendar_setup = calendar_options.dup add_mandatories(calendar_setup, :inputField => input_field_id, (popup ? :button : :flat) => calendar_id ) <<END #{field} #{calendar} <script type="text/javascript"> Calendar.setup({ #{format_js_hash(calendar_setup)} }) </script> END end def value(object_name, method_name) if object = self.instance_variable_get("@#{object_name}") object.send(method_name) else nil end end def add_mandatories(options, mandatories) options.merge!(mandatories) end def add_defaults(options, defaults) options.merge!(defaults) { |key, old_val, new_val| old_val } end def remove_option(options, key) options.delete(key) end def rename_option(options, old_key, new_key) if options.has_key?(old_key) options[new_key] = options.delete(old_key) end options end def format_js_hash(options) options.collect { |key,value| key.to_s + ':' + value.inspect }.join(',') end end
There’s still a problem that ActiveRecord doesn’t understand dates in their locale-dependend string form. So we need to make it know about dates.
require 'active_record' require 'date' module BoilerPlate # :nodoc: module Model # :nodoc: # I18n support for ActiveRecord. # Currently, all that it does is define a class variable # # ActiveRecord::Base.date_format # # and redefines +write_attribute+ to convert string values to dates # according to this format. module I18n def self.included(base) base.class_eval do unless method_defined?(:write_attribute_with_date_cast) alias_method :write_attribute_without_date_cast, :write_attribute def write_attribute_with_date_cast(attr, value) if column_for_attribute(attr).type == :date value = cast_to_date(value) end write_attribute_without_date_cast(attr, value) end alias_method :write_attribute, :write_attribute_with_date_cast cattr_accessor :date_format ActiveRecord::Base.date_format = '%Y-%m-%d' end end end protected def cast_to_date(value) case value when String Date.strptime(value, ActiveRecord::Base.date_format) rescue nil ### FIXME rescue better when Date, Time value else raise ArgumentError, "Argument for cast_to_date must be a String, Date, or Time; was: #{value.inspect}" end end end end end
{SRJ- I had to add an extra condition to check for nil to avoid failures on optional dates where I wasn’t using the calendar. ‘when nil return 0’}
require 'calendar_helper'
ActiveRecord::Base.class_eval do include BoilerPlate::Model::I18n end
class ApplicationController < ActionController::Base prepend_before_filter :localize def localize # determine locale and set other relevant stuff ActiveRecord::Base.date_format = date_format end end
—
Using this method results in the following error:undefined local variable or method `date_format' for #<HomeController:0x26e89fc>Is the value on the RHS of the assignment in localize above supposed to be a string literal? If not, where is the date_format variable declared and initialized? I’m sure I’m just a rails newbie who doesn’t understand how somethings are fitting together, but perhaps someone can clarify the instructions on this page?
I get the same error, replaced with a string literal, ”%Y-%m-%d” and now it runs. However, that isn’t the format of the returned date.
—
Q: Is there a place where we can download it, or do we have to copy & paste?
A1: :http://wiki.rubyonrails.org/rails/pages/DynamicCalendarHelper
calendar_helper is similar but unrelated project that creates an in-line calendar and installs as a nice plugin. It doesn’t do the DHTML form widget thing though, which is probably what this page and hence your question is trying to be about.