Merge pull request #935 from plataformatec/vs-html5-datetime-inputs

Support to date, datetime and time inputs.
This commit is contained in:
Rafael Mendonça França 2013-12-05 12:46:43 -08:00
commit 1071d8f714
4 changed files with 119 additions and 42 deletions

View File

@ -5,6 +5,8 @@
* Add wrapper mapping per form basis [@rcillo](https://github.com/rcillo) and [@bernardoamc](https://github.com/bernardoamc) * Add wrapper mapping per form basis [@rcillo](https://github.com/rcillo) and [@bernardoamc](https://github.com/bernardoamc)
* Add `for` attribute to `label` when collections are rendered as radio or checkbox [@erichkist](https://github.com/erichkist), [@ulissesalmeida](https://github.com/ulissesalmeida) and [@fabioyamate](https://github.com/fabioyamate) * Add `for` attribute to `label` when collections are rendered as radio or checkbox [@erichkist](https://github.com/erichkist), [@ulissesalmeida](https://github.com/ulissesalmeida) and [@fabioyamate](https://github.com/fabioyamate)
* Add `include_default_input_wrapper_class` config [@luizcosta](https://github.com/luizcosta) * Add `include_default_input_wrapper_class` config [@luizcosta](https://github.com/luizcosta)
* Map `datetime`, `date` and `time` input types to their respective HTML5 input tags
when the `:html5` is set to `true` [@volmer](https://github.com/volmer)
### bug fix ### bug fix
* Collection input generates `required` attribute if it has `prompt` option. [@nashby](https://github.com/nashby) * Collection input generates `required` attribute if it has `prompt` option. [@nashby](https://github.com/nashby)

View File

@ -500,9 +500,9 @@ specifying the helper method in the column `Mapping` as the `as:` option.
`float` | `input[type=number]` | `float` `float` | `input[type=number]` | `float`
`decimal` | `input[type=number]` | `decimal` `decimal` | `input[type=number]` | `decimal`
`range` | `input[type=range]` | - `range` | `input[type=range]` | -
`datetime` | `input[type=datetime]` | `datetime/timestamp` `datetime` | `datetime select` | `datetime/timestamp`
`date` | `input[type=date]` | `date` `date` | `date select` | `date`
`time` | `input[type=time]` | `time` `time` | `time select` | `time`
`select` | `select` | `belongs_to`/`has_many`/`has_and_belongs_to_many` associations `select` | `select` | `belongs_to`/`has_many`/`has_and_belongs_to_many` associations
`radio_buttons` | collection of `input[type=radio]` | `belongs_to` associations `radio_buttons` | collection of `input[type=radio]` | `belongs_to` associations
`check_boxes` | collection of `input[type=checkbox]` | `has_many`/`has_and_belongs_to_many` associations `check_boxes` | collection of `input[type=checkbox]` | `has_many`/`has_and_belongs_to_many` associations

View File

@ -2,7 +2,11 @@ module SimpleForm
module Inputs module Inputs
class DateTimeInput < Base class DateTimeInput < Base
def input def input
@builder.send(:"#{input_type}_select", attribute_name, input_options, input_html_options) if use_html5_inputs?
@builder.send(:"#{input_type}_field", attribute_name, input_html_options)
else
@builder.send(:"#{input_type}_select", attribute_name, input_options, input_html_options)
end
end end
private private
@ -19,6 +23,10 @@ module SimpleForm
position = ActionView::Helpers::DateTimeSelector::POSITION[position] position = ActionView::Helpers::DateTimeSelector::POSITION[position]
"#{attribute_name}_#{position}i" "#{attribute_name}_#{position}i"
end end
def use_html5_inputs?
input_options[:html5]
end
end end
end end
end end

View File

@ -1,18 +1,69 @@
# encoding: UTF-8 # encoding: UTF-8
require 'test_helper' require 'test_helper'
# Tests for all different kinds of inputs. # Tests for datetime, date and time inputs when HTML5 compatibility is enabled in the wrapper.
class DateTimeInputTest < ActionView::TestCase class DateTimeInputWithHtml5Test < ActionView::TestCase
# DateTime input test 'input should generate a datetime input for datetime attributes if HTML5 compatibility is explicitly enbled' do
test 'input should generate a datetime select by default for datetime attributes' do with_input_for @user, :created_at, :datetime, html5: true
assert_select 'input[type="datetime"]'
end
test 'input should generate a datetime select for datetime attributes' do
with_input_for @user, :created_at, :datetime with_input_for @user, :created_at, :datetime
1.upto(5) do |i|
assert_select "form select.datetime#user_created_at_#{i}i" assert_select 'select.datetime'
end
test 'input should generate a date input for date attributes if HTML5 compatibility is explicitly enbled' do
with_input_for @user, :born_at, :date, html5: true
assert_select 'input[type="date"]'
end
test 'input should generate a date select for date attributes' do
with_input_for @user, :born_at, :date
assert_select 'select.date'
end
test 'input should generate a time input for time attributes if HTML5 compatibility is explicitly enbled' do
with_input_for @user, :delivery_time, :time, html5: true
assert_select 'input[type="time"]'
end
test 'input should generate a time select for time attributes' do
with_input_for @user, :delivery_time, :time
assert_select 'select.time'
end
test 'input should generate required html attribute' do
with_input_for @user, :delivery_time, :time, required: true, html5: true
assert_select 'input.required'
assert_select 'input[required]'
end
test 'input should have an aria-required html attribute' do
with_input_for @user, :delivery_time, :time, required: true, html5: true
assert_select 'input[aria-required=true]'
end
end
# Tests for datetime, date and time inputs when HTML5 compatibility is enabled in the wrapper.
class DateTimeInputWithoutHtml5Test < ActionView::TestCase
test 'input should generate a datetime select by default for datetime attributes' do
swap_wrapper do
with_input_for @user, :created_at, :datetime
1.upto(5) do |i|
assert_select "form select.datetime#user_created_at_#{i}i"
end
end end
end end
test 'input should be able to pass options to datetime select' do test 'input should be able to pass options to datetime select' do
with_input_for @user, :created_at, :datetime, with_input_for @user, :created_at, :datetime, html5: false,
disabled: true, prompt: { year: 'ano', month: 'mês', day: 'dia' } disabled: true, prompt: { year: 'ano', month: 'mês', day: 'dia' }
assert_select 'select.datetime[disabled=disabled]' assert_select 'select.datetime[disabled=disabled]'
@ -21,16 +72,26 @@ class DateTimeInputTest < ActionView::TestCase
assert_select 'select.datetime option', 'dia' assert_select 'select.datetime option', 'dia'
end end
test 'input should generate a datetime input for datetime attributes if HTML5 compatibility is explicitly enabled' do
swap_wrapper do
with_input_for @user, :created_at, :datetime, html5: true
assert_select 'input[type="datetime"]'
end
end
test 'input should generate a date select for date attributes' do test 'input should generate a date select for date attributes' do
with_input_for @user, :born_at, :date swap_wrapper do
assert_select 'select.date#user_born_at_1i' with_input_for @user, :born_at, :date
assert_select 'select.date#user_born_at_2i' assert_select 'select.date#user_born_at_1i'
assert_select 'select.date#user_born_at_3i' assert_select 'select.date#user_born_at_2i'
assert_no_select 'select.date#user_born_at_4i' assert_select 'select.date#user_born_at_3i'
assert_no_select 'select.date#user_born_at_4i'
end
end end
test 'input should be able to pass options to date select' do test 'input should be able to pass options to date select' do
with_input_for @user, :born_at, :date, as: :date, with_input_for @user, :born_at, :date, as: :date, html5: false,
disabled: true, prompt: { year: 'ano', month: 'mês', day: 'dia' } disabled: true, prompt: { year: 'ano', month: 'mês', day: 'dia' }
assert_select 'select.date[disabled=disabled]' assert_select 'select.date[disabled=disabled]'
@ -40,21 +101,31 @@ class DateTimeInputTest < ActionView::TestCase
end end
test 'input should be able to pass :default to date select' do test 'input should be able to pass :default to date select' do
with_input_for @user, :born_at, :date, default: Date.today with_input_for @user, :born_at, :date, default: Date.today, html5: false
assert_select "select.date option[value=#{Date.today.year}][selected=selected]" assert_select "select.date option[value=#{Date.today.year}][selected=selected]"
end end
test 'input should generate a date input for date attributes if HTML5 compatibility is explicitly enabled' do
swap_wrapper do
with_input_for @user, :born_at, :date, html5: true
assert_select 'input[type="date"]'
end
end
test 'input should generate a time select for time attributes' do test 'input should generate a time select for time attributes' do
with_input_for @user, :delivery_time, :time swap_wrapper do
assert_select 'input[type=hidden]#user_delivery_time_1i' with_input_for @user, :delivery_time, :time
assert_select 'input[type=hidden]#user_delivery_time_2i' assert_select 'input[type=hidden]#user_delivery_time_1i'
assert_select 'input[type=hidden]#user_delivery_time_3i' assert_select 'input[type=hidden]#user_delivery_time_2i'
assert_select 'select.time#user_delivery_time_4i' assert_select 'input[type=hidden]#user_delivery_time_3i'
assert_select 'select.time#user_delivery_time_5i' assert_select 'select.time#user_delivery_time_4i'
assert_select 'select.time#user_delivery_time_5i'
end
end end
test 'input should be able to pass options to time select' do test 'input should be able to pass options to time select' do
with_input_for @user, :delivery_time, :time, required: true, with_input_for @user, :delivery_time, :time, required: true, html5: false,
disabled: true, prompt: { hour: 'hora', minute: 'minuto' } disabled: true, prompt: { hour: 'hora', minute: 'minuto' }
assert_select 'select.time[disabled=disabled]' assert_select 'select.time[disabled=disabled]'
@ -62,44 +133,40 @@ class DateTimeInputTest < ActionView::TestCase
assert_select 'select.time option', 'minuto' assert_select 'select.time option', 'minuto'
end end
test 'input should generate a time input for time attributes if HTML5 compatibility is explicitly enabled' do
swap_wrapper do
with_input_for @user, :delivery_time, :time, html5: true
assert_select 'input[type="time"]'
end
end
test 'label should use i18n to get target for date input type' do test 'label should use i18n to get target for date input type' do
store_translations(:en, date: { order: ['month', 'day', 'year'] }) do store_translations(:en, date: { order: ['month', 'day', 'year'] }) do
with_input_for :project, :created_at, :date with_input_for :project, :created_at, :date, html5: false
assert_select 'label[for=project_created_at_2i]' assert_select 'label[for=project_created_at_2i]'
end end
end end
test 'label should use i18n to get target for datetime input type' do test 'label should use i18n to get target for datetime input type' do
store_translations(:en, date: { order: ['month', 'day', 'year'] }) do store_translations(:en, date: { order: ['month', 'day', 'year'] }) do
with_input_for :project, :created_at, :datetime with_input_for :project, :created_at, :datetime, html5: false
assert_select 'label[for=project_created_at_2i]' assert_select 'label[for=project_created_at_2i]'
end end
end end
test 'label should use order to get target when date input type' do test 'label should use order to get target when date input type' do
with_input_for :project, :created_at, :date, order: ['month', 'year', 'day'] with_input_for :project, :created_at, :date, order: ['month', 'year', 'day'], html5: false
assert_select 'label[for=project_created_at_2i]' assert_select 'label[for=project_created_at_2i]'
end end
test 'label should use order to get target when datetime input type' do test 'label should use order to get target when datetime input type' do
with_input_for :project, :created_at, :datetime, order: ['month', 'year', 'day'] with_input_for :project, :created_at, :datetime, order: ['month', 'year', 'day'], html5: false
assert_select 'label[for=project_created_at_2i]' assert_select 'label[for=project_created_at_2i]'
end end
test 'label should point to first option when time input type' do test 'label should point to first option when time input type' do
with_input_for :project, :created_at, :time with_input_for :project, :created_at, :time, html5: false
assert_select 'label[for=project_created_at_4i]' assert_select 'label[for=project_created_at_4i]'
end end
test 'date time input should generate required html attribute' do
with_input_for @user, :delivery_time, :time, required: true
assert_select 'select.required'
assert_select 'select[required]'
end
test 'date time input has an aria-required html attribute' do
with_input_for @user, :delivery_time, :time, required: true
assert_select 'select.required'
assert_select 'select[aria-required=true]'
end
end end