Add configuration option to explicitly turn off HTML5 extensions.

This includes the new field types such as email, number, search, url,
tel, and the new attributes such as required, autofocus, maxlength, min, max, step.
None of these are technically allowed in the HTML4 or XHTML1.0 doc types.
Test coverage and updated README.

Update config file generator with new HTML5 option.
This commit is contained in:
Wolfram Arnold 2011-04-01 16:31:48 -07:00 committed by Rafael Mendonça França
parent aa3055ee0b
commit 25803824eb
9 changed files with 121 additions and 13 deletions

View File

@ -364,6 +364,22 @@ It's also possible to translate buttons, using Rails' built-in I18n support:
There are other options that can be configured through I18n API, such as required text and boolean. Be sure to check our locale file or the one copied to your application after you run "rails generate simple_form:install".
== HTML 5 Notice
By default, simple_form will generate input field types and attributes that are supported in HTML5, but are considered
invalid HTML for older document types HTML4 or XHTML1.0. The HTML5 extensions include the new field types such as email, number, search, url,
tel, and the new attributes such as required, autofocus, maxlength, min, max, step.
Most browsers will not care, but some of the newer ones, in particular Chrome 10, uses the required
attribute to force an input into a field and will prevent form submission without it. Depending on the design of
the site this may or may not be desired. In many cases it can break existing UI's.
The following configuration option permits disabling all HTML5 extensions:
SimpleForm.use_html5 = false # default is true
You can do this in the configuration block, generated in the following section.
== Configuration
SimpleForm has several configuration values. You can read and change them in the initializer created by SimpleForm, so if you haven't executed the command below yet, please do:

View File

@ -83,4 +83,9 @@ SimpleForm.setup do |config|
# When false, do not use translations for labels, hints or placeholders.
# config.translate = true
# Determines whether HTML5 types (:email, :url, :search, :tel) and attributes (e.g. required) are used
# or not. True by default.
# Having this on in non-HTML5 compliant sites can cause odd behavior in HTML5-aware browsers such as Chrome.
# config.use_html5 = true
end

View File

@ -122,6 +122,12 @@ module SimpleForm
mattr_accessor :translate
@@translate = true
# Determines whether HTML5 types (:email, :url, :search, :tel) and attributes (e.g. required) are used
# or not. True by default.
# Having this on in non-HTML5 compliant sites can cause odd behavior in HTML5-aware browsers such as Chrome.
mattr_accessor :use_html5
@@use_html5 = true
# Default way to setup SimpleForm. Run rails generate simple_form:install
# to create a fresh initializer with all configuration values.
def self.setup

View File

@ -28,9 +28,9 @@ module SimpleForm
@reflection = options.delete(:reflection)
@options = options
@input_html_options = html_options_for(:input, input_html_classes).tap do |o|
o[:required] = true if has_required?
o[:required] = true if has_required? # Don't make this conditional on HTML5 here, because we want the CSS class to be set
o[:disabled] = true if disabled?
o[:autofocus] = true if has_autofocus?
o[:autofocus] = true if has_autofocus? && SimpleForm.use_html5
end
end
@ -74,7 +74,7 @@ module SimpleForm
# Whether this input is valid for HTML 5 required attribute.
def has_required?
attribute_required?
attribute_required? && SimpleForm.use_html5
end
def has_autofocus?

View File

@ -32,7 +32,7 @@ module SimpleForm
# Select components does not allow the required html tag.
def has_required?
super && input_type != :select
super && input_type != :select && SimpleForm.use_html5
end
# Check if :include_blank must be included by default.

View File

@ -14,7 +14,7 @@ module SimpleForm
private
def has_placeholder?
(text? || password?) && placeholder_present?
(text? || password?) && placeholder_present? && SimpleForm.use_html5
end
def password?

View File

@ -2,10 +2,10 @@ module SimpleForm
module Inputs
class NumericInput < Base
def input
input_html_options[:type] ||= "number"
input_html_options[:type] ||= "number" if SimpleForm.use_html5
input_html_options[:size] ||= SimpleForm.default_input_size
input_html_options[:step] ||= integer? ? 1 : "any"
infer_attributes_from_validations!
input_html_options[:step] ||= integer? ? 1 : "any" if SimpleForm.use_html5
infer_attributes_from_validations! if SimpleForm.use_html5
@builder.text_field(attribute_name, input_html_options)
end
@ -16,7 +16,7 @@ module SimpleForm
protected
def has_placeholder?
placeholder_present?
SimpleForm.use_html5 && placeholder_present?
end
def infer_attributes_from_validations!

View File

@ -8,8 +8,10 @@ module SimpleForm
def input
input_html_options[:size] ||= [limit, SimpleForm.default_input_size].compact.min
input_html_options[:maxlength] ||= limit if limit
input_html_options[:type] ||= input_type unless string?
input_html_options[:maxlength] ||= limit if limit && SimpleForm.use_html5
if password? || SimpleForm.use_html5
input_html_options[:type] ||= input_type unless string?
end
@builder.send(input_method, attribute_name, input_html_options)
end
@ -25,12 +27,16 @@ module SimpleForm
end
def has_placeholder?
placeholder_present?
placeholder_present? && SimpleForm.use_html5
end
def string?
input_type == :string
end
def password?
input_type == :password
end
end
end
end

View File

@ -97,6 +97,13 @@ class InputTest < ActionView::TestCase
assert_select 'select.datetime:not([autofocus])'
end
test "when not using HTML5, it does not generate autofocus attribute" do
SimpleForm.use_html5 = false
with_input_for @user, :name, :string, :autofocus => true
assert_no_select 'input.string[autofocus]'
SimpleForm.use_html5 = true
end
test 'input should render components according to an optional :components option' do
with_input_for @user, :name, :string, :components => [:input, :label]
assert_select 'input + label'
@ -159,6 +166,13 @@ class InputTest < ActionView::TestCase
assert_select 'input.password[type=password][maxlength=100]'
end
test 'when not using HTML5, does not show maxlength attribute' do
SimpleForm.use_html5 = false
with_input_for @user, :password, :password
assert_no_select 'input[type=password][maxlength]'
SimpleForm.use_html5 = true
end
test 'input should not generate placeholder by default' do
with_input_for @user, :name, :string
assert_no_select 'input[placeholder]'
@ -183,10 +197,31 @@ class InputTest < ActionView::TestCase
end
end
test 'when not using HTML5, input should not show placeholder attribute' do
SimpleForm.use_html5 = false
store_translations(:en, :simple_form => { :placeholders => { :user => {
:name => 'Name goes here'
} } }) do
with_input_for @user, :name, :string
assert_no_select 'input.string[placeholder]'
end
SimpleForm.use_html5 = true
end
[:email, :url, :search, :tel].each do |type|
test "input should allow type #{type}" do
with_input_for @user, :name, type
assert_select "input.string.#{type}"
assert_select "input[type=#{type}]"
end
test "input should not allow type #{type} if HTML5 compatibility is disabled" do
SimpleForm.use_html5 = false
with_input_for @user, :name, type
assert_no_select "input[type=#{type}]"
SimpleForm.use_html5 = true
end
end
@ -323,6 +358,31 @@ class InputTest < ActionView::TestCase
end
end
# Numeric input but HTML5 disabled
test ' when not using HTML5 input should not generate field with type number and use text instead' do
SimpleForm.use_html5 = false
with_input_for @user, :age, :integer
assert_no_select "input[type=number]"
assert_no_select "input#user_age[text]"
SimpleForm.use_html5 = true
end
test 'when not using HTML5 input should not use min or max or step attributes' do
SimpleForm.use_html5 = false
with_input_for @validating_user, :age, :integer
assert_no_select "input[min]"
assert_no_select "input[max]"
assert_no_select "input[step]"
SimpleForm.use_html5 = true
end
test 'when not using HTML5 input should not use placeholder attribute' do
SimpleForm.use_html5 = false
with_input_for @user, :age, :integer, :placeholder => "Please enter"
assert_no_select "input[placeholder]"
SimpleForm.use_html5 = true
end
[:integer, :float, :decimal].each do |type|
test "#{type} input should infer min value from attributes with greater than or equal validation" do
with_input_for @validating_user, :age, type
@ -353,12 +413,19 @@ class InputTest < ActionView::TestCase
assert_select 'textarea.text[placeholder=Put in some text]'
end
test 'when not using HTML5 input should not generate placeholder attribute for text area' do
SimpleForm.use_html5 = false
with_input_for @user, :description, :text, :placeholder => 'Put in some text'
assert_no_select 'textarea.text[placeholder]'
SimpleForm.use_html5 = true
end
test 'input should generate a file field' do
with_input_for @user, :name, :file
assert_select 'input#user_name[type=file]'
end
test "input should generate a file field that don't accept placeholder" do
test "input should generate a file field that doesn't accept placeholder" do
with_input_for @user, :name, :file, :placeholder => 'Put in some text'
assert_no_select 'input[placeholder]'
end
@ -732,6 +799,14 @@ class InputTest < ActionView::TestCase
assert_select 'input[type=radio][required]'
end
test 'when not using HTML5, collection input with radio type should not generate required html attribute' do
SimpleForm.use_html5 = false
with_input_for @user, :name, :radio, :collection => ['Jose' , 'Carlos']
assert_select 'input[type=radio].required'
assert_no_select 'input[type=radio][required]'
SimpleForm.use_html5 = true
end
test 'collection input with select type should not generate invalid required html attribute' do
with_input_for @user, :name, :select, :collection => ['Jose' , 'Carlos']
assert_select 'select.required'