Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

* Ensure time format is used for datetime pickers. #44

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 18 additions & 11 deletions lib/app/helpers/form_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@ module FormHelper

# Mehtod that generates datepicker input field inside a form
def datepicker(object_name, method, options = {}, timepicker = false)
input_tag = JqueryDatepicker::InstanceTag.new(object_name, method, self, options.delete(:object))
dp_options, tf_options = input_tag.split_options(options)
tf_options[:value] = input_tag.format_date(tf_options[:value], String.new(dp_options[:dateFormat])) if tf_options[:value] && !tf_options[:value].empty? && dp_options.has_key?(:dateFormat)
input_tag = JqueryDatepicker::InstanceTag.new(object_name, method, self, options.delete(:object))
dp_options, tf_options = input_tag.split_options(options)
if dp_options.has_key?(:dateFormat)
tf_options[:value] = input_tag.format_date(tf_options[:value], dp_options[:dateFormat], dp_options[:timeFormat] || (timepicker && 'HH:mm'))
end
html = input_tag.to_input_field_tag("text", tf_options)
method = timepicker ? "datetimepicker" : "datepicker"
html += javascript_tag("jQuery(document).ready(function(){jQuery('##{input_tag.get_name_and_id(tf_options.stringify_keys)["id"]}').#{method}(#{dp_options.to_json})});")
Expand All @@ -30,7 +32,8 @@ def datetime_picker(method, options = {})

class JqueryDatepicker::InstanceTag < ActionView::Helpers::InstanceTag

FORMAT_REPLACEMENTES = { "yy" => "%Y", "mm" => "%m", "dd" => "%d", "d" => "%-d", "m" => "%-m", "y" => "%y", "M" => "%b"}
FORMAT_REPLACEMENTES = {"yy" => "%Y", "mm" => "%m", "dd" => "%d", "d" => "%-d", "m" => "%-m", "y" => "%y", "M" => "%b"}
TIME_FORMAT_REPLACEMENTS = {'HH' => '%H', "mm" => "%M", "ss" => "%s"}

# Extending ActionView::Helpers::InstanceTag module to make Rails build the name and id
# Just returns the options before generate the HTML in order to use the same id and name (see to_input_field_tag mehtod)
Expand All @@ -41,25 +44,29 @@ def get_name_and_id(options = {})
end

def available_datepicker_options
[:disabled, :altField, :altFormat, :appendText, :autoSize, :buttonImage, :buttonImageOnly, :buttonText, :calculateWeek, :changeMonth, :changeYear, :closeText, :constrainInput, :currentText, :dateFormat, :dayNames, :dayNamesMin, :dayNamesShort, :defaultDate, :duration, :firstDay, :gotoCurrent, :hideIfNoPrevNext, :isRTL, :maxDate, :minDate, :monthNames, :monthNamesShort, :navigationAsDateFormat, :nextText, :numberOfMonths, :prevText, :selectOtherMonths, :shortYearCutoff, :showAnim, :showButtonPanel, :showCurrentAtPos, :showMonthAfterYear, :showOn, :showOptions, :showOtherMonths, :showWeek, :stepMonths, :weekHeader, :yearRange, :yearSuffix]
[:disabled, :altField, :altFormat, :appendText, :autoSize, :buttonImage, :buttonImageOnly, :buttonText, :calculateWeek, :changeMonth, :changeYear, :closeText, :constrainInput, :currentText, :dateFormat, :dayNames, :dayNamesMin, :dayNamesShort, :defaultDate, :duration, :firstDay, :gotoCurrent, :hideIfNoPrevNext, :isRTL, :maxDate, :minDate, :monthNames, :monthNamesShort, :navigationAsDateFormat, :nextText, :numberOfMonths, :prevText, :selectOtherMonths, :shortYearCutoff, :showAnim, :showButtonPanel, :showCurrentAtPos, :showMonthAfterYear, :showOn, :showOptions, :showOtherMonths, :showWeek, :stepMonths, :timeFormat, :weekHeader, :yearRange, :yearSuffix]
end

def split_options(options)
tf_options = options.slice!(*available_datepicker_options)
return options, tf_options
end

def format_date(tb_formatted, format)
new_format = translate_format(format)
Date.parse(tb_formatted).strftime(new_format)
def format_date(tb_formatted, format, time_format)
tb_formatted ||= retrieve_object(@object).try(:send, @method_name)
return tb_formatted if tb_formatted.blank?
new_format = translate_format(format, time_format)
(tb_formatted.respond_to?(:strftime) ? tb_formatted : Time.parse(tb_formatted)).strftime(new_format)
end

# Method that translates the datepicker date formats, defined in (http://docs.jquery.com/UI/Datepicker/formatDate)
# to the ruby standard format (http://www.ruby-doc.org/core-1.9.3/Time.html#method-i-strftime).
# This gem is not going to support all the options, just the most used.

def translate_format(format)
format.gsub!(/#{FORMAT_REPLACEMENTES.keys.join("|")}/) { |match| FORMAT_REPLACEMENTES[match] }
def translate_format(format, time_format = nil)
f = format.gsub(/#{FORMAT_REPLACEMENTES.keys.join("|")}/) { |match| FORMAT_REPLACEMENTES[match] }
f += ' ' + time_format.gsub(/#{TIME_FORMAT_REPLACEMENTS.keys.join("|")}/) { |match| TIME_FORMAT_REPLACEMENTS[match] } if time_format
f
end

end
end
37 changes: 36 additions & 1 deletion spec/jquery_datepicker_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,18 @@
EOTEMPLATE
end

let :datetimepicker_input_dateFormat_Ymd_template_datetime do
<<-EOTEMPLATE
<%= datetime_picker_input(:foo, :att1, :dateFormat => "yy-mm-dd") %>
EOTEMPLATE
end

let :datetimepicker_input_dateFormat_Ymd_HM_template_datetime do
<<-EOTEMPLATE
<%= datetime_picker_input(:foo, :att1, :dateFormat => "yy-mm-dd", :timeFormat => "HH:mm", :value => "#{current_value.to_s}") %>
EOTEMPLATE
end

let :datepicker_input_with_value_template do
<<-EOTEMPLATE
<%= datepicker_input(:foo, :att1, :value => "#{current_value.to_s}") %>
Expand Down Expand Up @@ -126,6 +138,14 @@
"<script type=\"text/javascript\">\n//<![CDATA[\njQuery(document).ready(function(){jQuery('#foo_att1').datepicker({\"dateFormat\":\"m/d/y\",\"maxDate\":\"+1M +10D\",\"minDate\":-20})});\n//]]>\n</script>"
end

let :valid_response_javascript_with_options_Ymd do
"<script type=\"text/javascript\">\n//<![CDATA[\njQuery(document).ready(function(){jQuery('#foo_att1').datetimepicker({\"dateFormat\":\"yy-mm-dd\"})});\n//]]>\n</script>"
end

let :valid_response_javascript_with_options_Ymd_HM do
"<script type=\"text/javascript\">\n//<![CDATA[\njQuery(document).ready(function(){jQuery('#foo_att1').datetimepicker({\"dateFormat\":\"yy-mm-dd\",\"timeFormat\":\"HH:mm\"})});\n//]]>\n</script>"
end

let :valid_response_input_with_options do
"<input id=\"foo_att1\" name=\"foo[att1]\" size=\"30\" tabindex=\"70\" type=\"text\" />"
end
Expand Down Expand Up @@ -154,6 +174,10 @@
"<input id=\"foo_att1\" name=\"foo[att1]\" size=\"30\" type=\"text\" value=\"#{current_value.strftime('%-m/%-d/%y')}\" />"
end

let :valid_response_input_with_value_formatted_Ymd_HHmm do
"<input id=\"foo_att1\" name=\"foo[att1]\" size=\"30\" type=\"text\" value=\"#{current_value.strftime('%Y-%m-%d %H:%M')}\" />"
end

it "should return a valid code when calling from the helper" do
render :inline => datepicker_input_template
rendered.strip.should == valid_response_input+valid_response_javascript
Expand Down Expand Up @@ -204,6 +228,17 @@
rendered.strip.should == valid_response_input_with_value_formatted_dmY+valid_response_javascript_with_options_dmY
end

it "should format the date if dateFormat is set Y-m-d" do
@foo = Foo.new(current_value)
render :inline => datetimepicker_input_dateFormat_Ymd_template_datetime
rendered.strip.should == valid_response_input_with_value_formatted_Ymd_HHmm+valid_response_javascript_with_options_Ymd
end

it "should format the date if dateFormat, timeFormat, and value params are set Y-m-d HH:mm" do
render :inline => datetimepicker_input_dateFormat_Ymd_HM_template_datetime
rendered.strip.should == valid_response_input_with_value_formatted_Ymd_HHmm+valid_response_javascript_with_options_Ymd_HM
end

it "should render empty default value, but format the date if format options are sent but value is nil" do
render :inline => datepicker_input_with_options_with_empty_value_template
rendered.strip.should == valid_response_input_with_options_empty+valid_response_javascript_with_options
Expand Down Expand Up @@ -286,4 +321,4 @@
input_tag.translate_format("yy/m-dd").should eq("%Y/%-m-%d")
end
end
end
end
8 changes: 6 additions & 2 deletions spec/spec_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,16 @@ class Foo
extend ActiveModel::Naming
include ActiveModel::Conversion

def initialize(value = nil)
@att1 = value
end

def persisted?
false
end

# Mocking an attribute
def att1

@att1
end
end
end