Skip to content

Instantly share code, notes, and snippets.

@aganov
Created October 4, 2011 13:48
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save aganov/1261688 to your computer and use it in GitHub Desktop.
Save aganov/1261688 to your computer and use it in GitHub Desktop.
Formtastic jQuery UI date and time picker input
# http://jqueryui.com/demos/datepicker/
# http://fgelinas.com/code/timepicker/
class DatetimeUiInput
include Formtastic::Inputs::Base
DATE_FORMAT = "%Y-%m-%d"
TIME_FORMAT = "%H:%M"
def to_html
input_wrapping do
fragments_wrapping do
hidden_fragments <<
fragments_label <<
template.content_tag(:ol,
fragments.map do |fragment|
fragment_wrapping do
fragment_label_html(fragment) <<
fragment_input_html(fragment)
end
end.join.html_safe, # TODO is this safe?
{ :class => 'fragments-group' } # TODO refactor to fragments_group_wrapping
)
end
end
end
def fragments
[:date, :time]
end
def fragment_wrapping(&block)
template.content_tag(:li, template.capture(&block), fragment_wrapping_html_options)
end
def fragment_wrapping_html_options
{ :class => 'fragment' }
end
def fragment_label(fragment)
labels_from_options = options[:labels] || {}
if labels_from_options.key?(fragment)
labels_from_options[fragment]
else
::I18n.t(fragment.to_s, :default => fragment.to_s.humanize, :scope => [:datetime, :prompts])
end
end
def fragment_id(fragment)
"#{input_html_options[:id]}_#{position(fragment)}s"
end
def fragment_name(fragment)
"#{method}(#{position(fragment)}s)"
end
def fragment_label_html(fragment)
text = fragment_label(fragment)
text.blank? ? "".html_safe : template.content_tag(:label, text, :for => fragment_id(fragment))
end
def value(fragment)
object.send(method).strftime(class_eval("#{fragment.to_s.upcase}_FORMAT"))
end
def fragment_input_html(fragment)
opts = input_html_options.merge(:id => fragment_id(fragment), :value => value(fragment), :class => "#{fragment}picker", :readonly => "readonly")
template.send(:text_field, object_name, fragment_name(fragment), opts)
end
def positions
{ :date => 1, :time => 2 }
end
def position(fragment)
positions[fragment]
end
def i18n_date_fragments
order = ::I18n.t(:order, :scope => [:date])
order = nil unless order.is_a?(Array)
order
end
def fragments_wrapping(&block)
template.content_tag(:fieldset,
template.capture(&block).html_safe,
fragments_wrapping_html_options
)
end
def fragments_wrapping_html_options
{ :class => "fragments" }
end
def fragments_label
if render_label?
template.content_tag(:legend,
builder.label(method, label_text, :for => "#{input_html_options[:id]}_1s"),
:class => "label"
)
else
"".html_safe
end
end
def fragments_inner_wrapping(&block)
template.content_tag(:ol,
template.capture(&block)
)
end
def hidden_fragments
"".html_safe
end
end
@stereoscott
Copy link

@aganov thanks for this! It's working great. @budu I'm still trying to figure out how to use strong_paramaters with this... I'm getting an ActiveRecord::MultiparameterAssignmentErrors exception when I try to post the form. Will post back when I figure it out.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment