diff --git a/actionview/CHANGELOG.md b/actionview/CHANGELOG.md index 2c1ca12043..26170dfa77 100644 --- a/actionview/CHANGELOG.md +++ b/actionview/CHANGELOG.md @@ -1,3 +1,21 @@ +* Add `year_format` option to date_select tag. This option makes it possible to customize year + names. Lambda should be passed to use this option. + + Example: + + date_select('user_birthday', '', start_year: 1998, end_year: 2000, year_format: ->year { "Heisei #{year - 1988}" }) + + The HTML produced: + + + /* The rest is omitted */ + + *Koki Ryu* + * Fix JavaScript views rendering does not work with Firefox when using Content Security Policy. diff --git a/actionview/lib/action_view/helpers/date_helper.rb b/actionview/lib/action_view/helpers/date_helper.rb index 620e1e9f21..1622b9f680 100644 --- a/actionview/lib/action_view/helpers/date_helper.rb +++ b/actionview/lib/action_view/helpers/date_helper.rb @@ -850,7 +850,7 @@ module ActionView raise ArgumentError, "There are too many years options to be built. Are you sure you haven't mistyped something? You can provide the :max_years_allowed parameter." end - build_options_and_select(:year, val, options) + build_select(:year, build_year_options(val, options)) end end @@ -933,6 +933,21 @@ module ActionView end end + # Looks up year names by number. + # + # year_name(1998) # => 1998 + # + # If the :year_format option is passed: + # + # year_name(1998) # => "Heisei 10" + def year_name(number) + if year_format_lambda = @options[:year_format] + year_format_lambda.call(number) + else + number + end + end + def date_order @date_order ||= @options[:order] || translated_date_order end @@ -995,6 +1010,34 @@ module ActionView (select_options.join("\n") + "\n").html_safe end + # Build select option HTML for year. + # If year_format option is not passed + # build_year_options(1998, start: 1998, end: 2000) + # => " + # + # " + # + # If year_format option is passed + # build_year_options(1998, start: 1998, end: 2000, year_format: ->year { "Heisei #{ year - 1988 }" }) + # => " + # + # " + def build_year_options(selected, options = {}) + start = options.delete(:start) + stop = options.delete(:end) + step = options.delete(:step) + + select_options = [] + start.step(stop, step) do |value| + tag_options = { value: value } + tag_options[:selected] = "selected" if selected == value + text = year_name(value) + select_options << content_tag("option".freeze, text, tag_options) + end + + (select_options.join("\n") + "\n").html_safe + end + # Builds select tag from date type and HTML select options. # build_select(:month, "...") # => "\n).dup + expected << %(\n\n\n) + expected << "\n" + + assert_dom_equal expected, select_year(nil, start_year: 2003, end_year: 2005, year_format: year_format_lambda) + end + def test_select_hour expected = %(