2010-09-09 29 views
41

Tôi có mô hình ActiveRecord Event với cột ngày giờ starts_at. Tôi muốn trình bày biểu mẫu, trong đó ngày và giờ cho starts_at được chọn riêng biệt (ví dụ: "23-10-2010" cho ngày và "18:00" cho thời gian). Các trường này phải được hỗ trợ bởi cột đơn starts_at và xác thực tốt nhất nên chống lại starts_at.Các trường biểu mẫu ngày và giờ riêng biệt trong Rails

Tôi có thể tất nhiên muck xung quanh với các thuộc tính ảo và móc, nhưng tôi muốn một giải pháp thanh lịch hơn. Tôi đã thử nghiệm với cả hai composed_of (rdoc) và thuộc tính trang trí (lighthouse discussion, github) mà không thành công.

Dưới đây là một phác thảo sơ bộ những gì tôi muốn ..

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 

Bất kỳ trợ giúp đánh giá cao.

+0

Tôi đã thực hiện điều này một vài lần nhưng vẫn chưa tìm được giải pháp tốt. Lý do cho việc chia nhỏ nó là vì vậy tôi có thể sử dụng một datepicker và time_select một cách riêng biệt. – benvds

Trả lời

9

Đã nhìn vào ngày hôm nay cho một dự án Rails, và đi qua đá quý này:

https://github.com/shekibobo/time_splitter

DateTimes Thiết có thể là một điều khó khăn hoặc xấu xí, đặc biệt là thông qua một mẫu web. Việc tìm kiếm một DatePicker hoặc TimePicker tốt thật dễ dàng, nhưng việc làm cho chúng hoạt động trên cả hai có thể khó khăn. TimeSplitter tự động tạo ra các accessors cho ngày, giờ, giờ và min trên các thuộc tính datetime hoặc time của bạn, làm cho nó tầm thường để sử dụng các đầu vào biểu mẫu khác nhau để thiết lập các phần khác nhau của một trường datetime.

Hình như nó sẽ làm công việc cho bạn

+0

Có cách nào để đặt múi giờ cho đá quý này không? Nó luôn luôn tiết kiệm trong UTC. –

+0

Trong thử nghiệm của tôi, nó đang sử dụng múi giờ được cấu hình. Bạn có chắc là bạn đã cài đặt đúng không? – asgeo1

+0

Tôi đã thử sử dụng đá quý này và gặp sự cố ngay lập tức http://stackoverflow.com/questions/29858627/time-splitter-gem-getting-uninitialized-constant-sheettimesplitter –

0

Đây có phải là do sự cố thiết kế không? Nó thực sự dễ dàng hơn nhiều nếu bạn chỉ cần lưu starts_at như một kiểu dữ liệu datetime và sử dụng cái gì đó như:

http://puna.net.nz/timepicker.htm#

Nó chỉ đơn giản chạy trên đầu trang của bất cứ trường ngày bạn có cho mô hình của bạn.

+1

Không có vấn đề gì về thiết kế. Dữ liệu phải là một cột trong khi trình tạo biểu mẫu phải xử lý 2 thuộc tính khác nhau cho cùng một cột đó. – benvds

38

Bạn có phải xem text_field trong chế độ xem không?

Theo như tôi có thể biết, bạn có thể có trường date_time và sau đó chỉ cần sử dụng hai trường nhập khác nhau để đặt các phần khác nhau của trường.

form_for @event do |f| 
    f.date_select :starts_at 
    f.time_select :starts_at, :ignore_date => true 
    f.submit 
end 

Kể từ ngày ray và thời gian chọn những người giúp đỡ thiết lập năm thông số khác nhau (starts_at(1i) cho phần năm, 2i cho phần tháng, và vân vân), có nghĩa rằng date_select chỉ đặt chúng cho phần ngày, trong khi bạn vượt qua đến time_select, nó sẽ chỉ đặt phần giờ và phút.

Nếu bạn phải có text_field Tôi không chắc chắn cách thực hiện, nhưng có thể sử dụng một số phép thuật jQuery trước khi đặt thông số datetime trước khi gửi biểu mẫu.

+1

Tốt, có vẻ như hoạt động tốt và đủ giải pháp. Nhưng những gì tôi thực sự muốn thấy là một cách để phân chia và tái tạo lại các thuộc tính xung quanh trình trợ giúp biểu mẫu. Ví dụ. before_form_build & before_form_validation. – benvds

+0

Sau đó, tôi nghĩ bạn cần phải thực hiện một số hacking thủ công trên băm params. – Frost

2

giải pháp Elegant có thể cung cấp date_time_attribute gem:

class MyModel < ActiveRecord::Base 
    include DateTimeAttribute 

    date_time_attribute :starts_at 
end 

Nó sẽ cho phép bạn thiết lập starts_at_datestarts_at_time riêng:

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 

Nó cũng sẽ cho phép bạn chơi với các múi giờ, sử dụng Chronic ...

+0

Bạn có chắc chắn rằng bạn có thể trộn 'date_select' và 'text_field'? Tôi không thể sử dụng 'text_field' và' time_select' và không có tài liệu nào cho thấy bạn có thể. –

+0

Bạn không cần phải bao gồm mô-đun DateTimeAttribute, như đã nói trong README của kho lưu trữ của đá quý: https://github.com/einzige/date_time_attribute#rails-users –

3

Sử dụng date_selecttime_select là một cách hay để thực hiện.

Tuy nhiên, tôi muốn có text_field cho ngày đó (vì vậy tôi có thể sử dụng bộ chọn ngày JavaScript).

Sử dụng strong_parameters hoặc Rails 4+:

mô hình/event.rb

# Add a virtual attribute 
attr_accessor :start_at_date 

views/sự kiện/_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 

controllers/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 
    ... 
+0

Tại sao bạn sử dụng '!!' trong *** nếu *** so sánh? Điều đó có nghĩa là gì? –

+0

Chuyển đổi giá trị thành boolean (http://stackoverflow.com/questions/524658/what-does-mean-in-ruby), có thể không bắt buộc. –

+0

Yeah thats những gì tôi mặc dù nhưng dù sao cảm ơn bạn đã phản ứng. :) –

Các vấn đề liên quan