問題 原本 simple_form 的 datetime <%= f.input :date_at, label: "日期" %>
會自動幫您把一個 datetime 欄位在前端 view 的部分分拆為 5 個 select,且 name 和 id 都用特殊的慣例處理過
<div class="form-group datetime optional date_at">
<label class="datetime optional control-label" for="model_date_at_1i">日期</label>
<select id="model_date_at_1i" name="model[date_at(1i)]" class="datetime optional form-control">
<option value="2010">2010</option>
...
<option value="2015" selected="selected">2015</option>
<option value="2016">2016</option>
...
</select>
<select id="model_date_at_2i" name="model[date_at(2i)]" class="datetime optional form-control">
<option value="1">January</option>
<option value="2">February</option>
<option value="3" selected="selected">March</option>
<option value="4">April</option>
<option value="5">May</option>
...
</select>
<select id="model_date_at_3i" name="model[date_at(3i)]" class="datetime optional form-control">
<option value="1">1</option>
<option value="2">2</option>
...
</select>
—
<select id="model_date_at_4i" name="model[date_at(4i)]" class="datetime optional form-control">
<option value="00">00</option>
<option value="01">01</option>
...
</select>
:
<select id="model_date_at_5i" name="model[date_at(5i)]" class="datetime optional form-control">
<option value="00">00</option>
<option value="01">01</option>
<option value="02">02</option>
<option value="03">03</option>
...
</select>
</div>
需求為想要客製 DateTimeInput 從本來的
.form-group
label
select
select
select
select
select
換成
.form-group
label
.row
.col-md-2
select
.col-md-2
select
.col-md-2
select
.col-md-2
select
.col-md-2
select
透過自訂 Input 的方式,但問題是不明白 Rails 預設的 @builder.date_select
是怎麼將單一個 datetime column 在前端拆成 5 個 select 然後 save 的時候又會合併成一個 datetime 的 value
# 自訂 DateTimeInput
class CustomDatetimeInput < SimpleForm::Inputs::Base
def input
template.content_tag(:div, class: 'row') do
template.concat year
template.concat month
template.concat day
template.concat hour
template.concat minute
end
end
def year
template.content_tag(:div, class: 'col-md-2') do
template.concat @builder.date_select(attribute_name, { discard_day: true, discard_month: true}, class: "form-control")
template.concat "<span>年</span>".html_safe
end
end
def month
template.content_tag(:div, class: 'col-md-2') do
template.concat @builder.select(attribute_name, (1..12).to_a, {}, { class: "datetime optional form-control" })
template.concat "<span>月</span>".html_safe
end
end
def day
template.content_tag(:div, class: 'col-md-2') do
template.concat @builder.select(attribute_name, (1..31).to_a, {}, { class: "datetime optional form-control" })
template.concat "<span>日</span>".html_safe
end
end
def hour
template.content_tag(:div, class: 'col-md-2') do
template.concat @builder.select(attribute_name, (0..23).to_a.map!{ |n| n.to_s.rjust(2, '0') }, {}, { class: "datetime optional form-control" })
template.concat "<span>時</span>".html_safe
end
end
def minute
template.content_tag(:div, class: 'col-md-2') do
template.concat @builder.select(attribute_name, (0..59).to_a.map!{ |n| n.to_s.rjust(2, '0') }, {}, { class: "datetime optional form-control" })
template.concat "<span>分</span>".html_safe
end
end
protected
def get_attr_name
position = case input_type
when :date, :datetime
date_order = input_options[:order] || I18n.t('date.order')
date_order.first.to_sym
else
:hour
end
position = ActionView::Helpers::DateTimeSelector::POSITION[position]
"#{attribute_name}_#{position}i".to_sym
end
end
另外一個髒髒的解法發現 day 會相依 month
class CustomDatetimeInput < SimpleForm::Inputs::Base
def input
template.content_tag(:div, class: 'row') do
template.concat year
template.concat month
template.concat day
template.concat hour
template.concat minute
end
end
def year
template.content_tag(:div, class: 'col-md-2') do
template.concat @builder.date_select(attribute_name, { discard_month: true, discard_day: true }, class: "form-control")
template.concat "<span>年</span>".html_safe
end
end
def month
template.content_tag(:div, class: 'col-md-2') do
template.concat @builder.date_select(attribute_name, { discard_year: true, discard_day: true }, class: "form-control")
template.concat "<span>月</span>".html_safe
end
end
def day
template.content_tag(:div, class: 'col-md-2') do
template.concat @builder.date_select(attribute_name, { discard_year: true, discard_month: false, discard_day: false }, class: "form-control")
template.concat "<span>日</span>".html_safe
end
end
def hour
template.content_tag(:div, class: 'col-md-2') do
template.concat @builder.time_select(attribute_name, { discard_minute: true }, class: "form-control")
template.concat "<span>時</span>".html_safe
end
end
def minute
template.content_tag(:div, class: 'col-md-2') do
template.concat @builder.time_select(attribute_name, { discard_hour: true }, class: "form-control")
template.concat "<span>分</span>".html_safe
end
end
end
相關參考文章 API1 API2 API3 API4 API5 API6 stackoverflow-1 google-group-ask API
https://github.com/zpaulovics/datetimepicker-rails