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, "...")
# => "