Skip to content

Instantly share code, notes, and snippets.

@znz
Last active May 31, 2018 13:44
Show Gist options
  • Save znz/4950096 to your computer and use it in GitHub Desktop.
Save znz/4950096 to your computer and use it in GitHub Desktop.
DateTimeSelector の選択肢のテキストの生成部分をもっと汎用的にしてほしい
# -*- coding: utf-8 -*-
# config/initializers/date_time_selector.rb
# based on actionpack-3.2.11/lib/action_view/helpers/date_helper.rb
require "action_view/helpers/date_helper"
class ActionView::Helpers::DateTimeSelector
undef select_day
def select_day
if @options[:use_hidden] || @options[:discard_day]
build_hidden(:day, day || 1)
else
build_options_and_select(:day, day, :start => 1, :end => 31, :leading_zeros => false, :use_two_digit_numbers => @options[:use_two_digit_numbers], :text_translator => @options[:day_text_translator])
end
end
undef select_year
def select_year
if !@datetime || @datetime == 0
val = '1'
middle_year = Date.today.year
else
val = middle_year = year
end
if @options[:use_hidden] || @options[:discard_year]
build_hidden(:year, val)
else
options = {}
options[:start] = @options[:start_year] || middle_year - 5
options[:end] = @options[:end_year] || middle_year + 5
options[:step] = options[:start] < options[:end] ? 1 : -1
options[:leading_zeros] = false
options[:max_years_allowed] = @options[:max_years_allowed] || 1000
options[:text_translator] = @options[:year_text_translator]
if (options[:end] - options[:start]).abs > options[:max_years_allowed]
raise ArgumentError, "There're 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)
end
end
undef build_options
def build_options(selected, options = {})
start = options.delete(:start) || 0
stop = options.delete(:end) || 59
step = options.delete(:step) || 1
options.reverse_merge!({:leading_zeros => true, :ampm => false, :use_two_digit_numbers => false})
leading_zeros = options.delete(:leading_zeros)
select_options = []
start.step(stop, step) do |i|
value = leading_zeros ? sprintf("%02d", i) : i
tag_options = { :value => value }
tag_options[:selected] = "selected" if selected == i
text = options[:use_two_digit_numbers] ? sprintf("%02d", i) : value
text = options[:ampm] ? AMPM_TRANSLATION[i] : text
text = options[:text_translator] ? options[:text_translator].call(text) : text
select_options << content_tag(:option, text, tag_options)
end
(select_options.join("\n") + "\n").html_safe
end
end
# example usage
# in helper
def year_text_translator(year)
case year
when 1868..1911
str = "明治#{year-1867}年"
when 1912
str = "明治#{year-1867}年/大正元年"
when 1912..1925
str = "大正#{year-1911}年"
when 1926
str = "大正#{year-1911}年/昭和元年"
when 1926..1988
str = "昭和#{year-1925}年"
when 1989
str = "昭和#{year-1925}年/平成元年"
else
str = "平成#{year-1988}年"
end
str = "#{year}年 (#{str})"
end
# and in view (example with simple_form)
# <%= f.input :birthday, start_year: 1900, end_year: Date.today.year, year_text_translator: lambda { |year| year_text_translator(year) }, day_text_translator: lambda { |day| "#{day}日" }, include_blank: true %>

元々のユーザーからの要望

  1. DateTimeSelector で月だけ n月 になっていて 年 や 日 がついていないのが変。
  2. 年には和暦も入れてほしい。

要望1 に関連する問題点

  • date で month_names (abbr_month_names) だけ翻訳対象になっていて、しかも月ごとにわかれているのは日本語からみるとおかしい。
  • 日本語としてはたとえば year_names: %{count}年, month_names: %{count}月, mday_names: %{count}日 のように年月日すべてが翻訳対象になってほしいし、月は個別に翻訳できる必要はない。

要望2 に関連する問題点

  • 和暦は年の範囲の計算が必要で、単純な翻訳では置換できない。
  • 現状でも月の翻訳や :ampm オプションなどが特別扱いが多い。

提案したい内容

  • 年月日時分をすべて汎用的な仕組みにする。
  • 互換性のため、月の翻訳や ampm 対応などをデフォルトにする。
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment