在Rails中单独的date和时间表单字段
我有一个ActiveRecord模型Event
与date时间列starts_at
。 我想提出一个表格,其中starts_at
date和时间是分开select的(例如, "23-10-2010"
为date, "18:00"
为时间)。 这些字段应该由单列starts_at
,并且validation也应该优先针对starts_at
。
我当然可以使用虚拟属性和钩子,但我想要一个更优雅的解决scheme。 我已经尝试了compos_of ( rdoc )和attribute-decorator( 灯塔讨论 , github )都没有成功。
下面是我想要的粗略轮廓。
class Event < ActiveRecord::Base validates_presence_of :start_date end # View # On submission this should set start_date. form_for @event do |f| f.text_field :starts_at_date # date-part of start_date f.text_field :starts_at_time_of_day # time-of-day-part of start_date f.submit end
任何帮助赞赏。
今天看着这个Rails项目,碰到了这个gem:
https://github.com/shekibobo/time_splitter
设置date时间可能是一个困难或丑陋的事情,尤其是通过networkingforms。 find一个好的DatePicker或TimePicker很容易,但让他们在这两个工作都很困难。 TimeSplitter自动生成datetime,time和time属性的date,时间,小时和分钟访问器,使得使用不同的表单input来设置date时间字段的不同部分变得微不足道。
看起来它会为你做的工作
你必须在视图中有一个text_field
?
据我所知,你可以有一个date_time
字段,然后只使用两个不同的input字段来设置字段的不同部分。
form_for @event do |f| f.date_select :starts_at f.time_select :starts_at, :ignore_date => true f.submit end
由于导轨date和时间select助手设置了五个不同的参数(年份部分的starts_at(1i)
,月份部分的2i
等等),这意味着date_select
只设置date部分,而如果您通过:ignore_date => true
time_select
,它只会设置小时和分钟部分。
如果你必须有一个text_field
我不知道该怎么做,但在发送表单之前设置datetime参数之前,可能会使用一些jQuery魔术。
使用date_select
和time_select
是一个好方法。
不过,我想要一个text_field
的date(所以我可以使用JavaScriptdateselect器)。
使用strong_parameters或Rails 4+:
车型/ event.rb
# Add a virtual attribute attr_accessor :start_at_date
观点/事件/ _form.html.haml
- # A text field for the date, and time_select for time = f.label :start_at = f.text_field :start_at_date, value: (f.object.start_at.present? ? f.object.start_at.to_date : nil) = f.time_select :start_at, :ignore_date => true
控制器/ events_controller.rb
# If using a date_select, time_select, datetime_select # Rails expects multiparameter attributes # Convert the date to the muiltiparameter parts def event_params if !!params[:event] && (params[:event]["start_at(4i)"].present? || params[:event]["start_at(5i)"].present?) if params[:event][:start_at_date].present? start_at_date = params[:event][:start_at_date] else start_at_date = Date.today end year = start_at_date.match(/^(\d{4})[\-\/]/)[1] month = start_at_date.match(/[\-\/](\d{2})[\-\/]/)[1] day = start_at_date.match(/[\-\/](\d{2})$/)[1] params[:event]["start_at(1i)"] = year params[:event]["start_at(2i)"] = month params[:event]["start_at(3i)"] = day end ...
优雅的解决scheme可能会提供date_time_attribute gem :
class MyModel < ActiveRecord::Base include DateTimeAttribute date_time_attribute :starts_at end
它将允许您分别设置starts_at_date
和starts_at_time
:
form_for @event do |f| f.text_field :starts_at_date f.text_field :starts_at_time f.submit end # this will work too: form_for @event do |f| f.date_select :starts_at_date f.time_select :starts_at_time, :ignore_date => true f.text_field :starts_at_time_zone f.submit end # or form_for @event do |f| f.date_select :starts_at_date f.text_field :starts_at_time f.submit end
它也可以让你玩时区,使用慢性等。
这是因为devise问题吗? 如果您只是将starts_at另存为date时间数据types并使用如下所示,
http://puna.net.nz/timepicker.htm#
它只是运行在你的模型的任何date字段之上。