Permalink
Browse files

Create more components. Make explicit the difference between helpers …

…and components. Add default options to wrappers.
  • Loading branch information...
1 parent 10f2e67 commit 94dab68cd7e8aba35971f71a6b0ab3f542b9c5f2 @josevalim josevalim committed Dec 4, 2011
View
@@ -149,7 +149,6 @@ def self.build(options={})
end
wrappers :class => :input, :error_class => :field_with_errors do |b|
- b.use :disabled
b.use :maxlength
b.use :placeholder
b.use :required
@@ -1,6 +1,11 @@
module SimpleForm
+ # Components are a special type of helpers that can work on their own.
+ # For example, by using a component, it will automatically change the
+ # output under given circunstences without user input. For example,
+ # the disabled helper always need a :disabled => true option given
+ # to the input in order to be enabled. On the other hand, things like
+ # hint can generate output automatically by doing I18n lookups.
module Components
- autoload :Disabled, 'simple_form/components/disabled'
autoload :Errors, 'simple_form/components/errors'
autoload :Hints, 'simple_form/components/hints'
autoload :LabelInput, 'simple_form/components/label_input'
@@ -9,8 +9,12 @@ def maxlength
private
def maximum_length_from_validation
- if has_validators? && (length_validator = find_length_validator)
- length_validator.options[:maximum]
+ if options[:maxlength] == true
+ if has_validators? && (length_validator = find_length_validator)
+ length_validator.options[:maximum]
+ end
+ else
+ options[:maxlength]
end
end
@@ -9,8 +9,12 @@ def pattern
private
def pattern_source
- if has_validators? && (pattern_validator = find_pattern_validator)
- pattern_validator.options[:with].source
+ if options[:pattern] == true
+ if has_validators? && (pattern_validator = find_pattern_validator)
+ pattern_validator.options[:with].source
+ end
+ else
+ options[:pattern]
end
end
@@ -2,18 +2,16 @@ module SimpleForm
module Components
module Placeholders
def placeholder
- input_html_options[:placeholder] ||= placeholder_text if has_placeholder?
+ input_html_options[:placeholder] ||= placeholder_text
nil
end
- def has_placeholder?
- placeholder_text.present?
- end
-
- private
-
def placeholder_text
- @placeholder_text ||= options[:placeholder] || translate(:placeholders)
+ if options[:placeholder] == true
+ translate(:placeholders).presence
+ else
+ options[:placeholder]
+ end
end
end
end
@@ -1,7 +1,12 @@
module SimpleForm
+ # Helpers are made of several helpers that cannot be turned on automatically.
+ # For instance, disabled cannot be turned on automatically, it requires the
+ # user to explicitly pass the option :disabled => true so it may work.
module Helpers
+ autoload :Autofocus, 'simple_form/helpers/autofocus'
+ autoload :Disabled, 'simple_form/helpers/disabled'
+ autoload :Readonly, 'simple_form/helpers/readonly'
autoload :Required, 'simple_form/helpers/required'
autoload :Validators, 'simple_form/helpers/validators'
- autoload :Readonly, 'simple_form/helpers/readonly'
end
end
@@ -0,0 +1,10 @@
+module SimpleForm
+ module Helpers
+ module Autofocus
+ private
+ def has_autofocus?
+ options[:autofocus] == true
+ end
+ end
+ end
+end
@@ -0,0 +1,13 @@
+module SimpleForm
+ module Helpers
+ module Disabled
+ def has_disabled?
+ options[:disabled] == true
+ end
+
+ def disabled_class
+ "disabled" if has_disabled?
+ end
+ end
+ end
+end
@@ -3,11 +3,12 @@ module Inputs
class Base
extend I18nCache
+ include SimpleForm::Helpers::Autofocus
+ include SimpleForm::Helpers::Disabled
include SimpleForm::Helpers::Readonly
include SimpleForm::Helpers::Required
include SimpleForm::Helpers::Validators
- include SimpleForm::Components::Disabled
include SimpleForm::Components::Errors
include SimpleForm::Components::Hints
include SimpleForm::Components::LabelInput
@@ -25,17 +26,20 @@ class Base
self.default_options = {}
def self.enable(*keys)
- options = self.default_options.dup
- keys.each { |key| options.delete(key) }
- self.default_options = options
+ self.ability(keys, true)
end
def self.disable(*keys)
+ self.ability(keys, false)
+ end
+
+ def self.ability(keys, value)
options = self.default_options.dup
- keys.each { |key| options[key] = false }
+ keys.each { |key| options[key] = value }
self.default_options = options
end
+ # Usually disabled, needs to be enabled explicitly passing true as option.
disable :maxlength, :placeholder, :pattern
def initialize(builder, attribute_name, column, input_type, options = {})
@@ -50,9 +54,10 @@ def initialize(builder, attribute_name, column, input_type, options = {})
# Notice that html_options_for receives a reference to input_html_classes.
# This means that classes added dynamically to input_html_classes will
# still propagate to input_html_options.
- @input_html_classes = [input_type, required_class, readonly_class].compact
+ @input_html_classes = [input_type, required_class, readonly_class, disabled_class].compact
@input_html_options = html_options_for(:input, input_html_classes).tap do |o|
o[:readonly] = true if has_readonly?
+ o[:disabled] = true if has_disabled?
o[:autofocus] = true if has_autofocus?
end
end
@@ -65,10 +70,6 @@ def input_options
options
end
- def has_autofocus?
- options[:autofocus]
- end
-
private
def add_size!
@@ -1,8 +1,8 @@
module SimpleForm
module Wrappers
- autoload :Builder, 'simple_form/wrappers/builder'
- autoload :Many, 'simple_form/wrappers/many'
- autoload :Root, 'simple_form/wrappers/root'
- autoload :Single, 'simple_form/wrappers/single'
+ autoload :Builder, 'simple_form/wrappers/builder'
+ autoload :Many, 'simple_form/wrappers/many'
+ autoload :Root, 'simple_form/wrappers/root'
+ autoload :Single, 'simple_form/wrappers/single'
end
end
@@ -25,6 +25,16 @@ module Wrappers
# end
# end
#
+ # The builder also accepts default options at the root level. This is usually
+ # used if you want a component to be disabled by default:
+ #
+ # config.wrappers :hint => false do |b|
+ # b.use :hint
+ # b.use :label_input
+ # end
+ #
+ # In the example above, hint defaults to false, which means it won't automatically
+ # do the lookup anymore. It will only be triggered when :hint is explicitly set.
class Builder
def initialize
@components = []
@@ -3,8 +3,16 @@ module Wrappers
# `Root` is the root wrapper for all components. It is special cased to
# always have a namespace and to add special html classes.
class Root < Many
+ attr_reader :options
+
def initialize(*args)
super(:wrapper, *args)
+ @options = @defaults.except(:tag, :class, :error_class)
+ end
+
+ def render(input)
+ input.options.reverse_merge!(@options)
+ super
end
# Provide a fallback if name cannot be found.
@@ -62,11 +62,18 @@ class StringInputTest < ActionView::TestCase
assert_select 'input[type=password].password[placeholder=Password Confirmation]#user_password'
end
- test 'input should infer pattern from attributes when pattern is true' do
+ test 'input should infer pattern from attributes' do
with_input_for @other_validating_user, :country, :string
assert_select 'input[pattern="\w+"]'
end
+ test 'input should infer pattern from attributes when pattern is true when default is false' do
+ swap_wrapper do
+ with_input_for @other_validating_user, :country, :string
+ assert_select 'input[pattern="\w+"]'
+ end
+ end
+
test 'input should use given pattern from attributes' do
with_input_for @other_validating_user, :country, :string, :input_html => { :pattern => "\\d+" }
assert_select 'input[pattern="\d+"]'
@@ -34,7 +34,8 @@ def swap_wrapper(name=:default, wrapper=self.custom_wrapper)
end
def custom_wrapper
- SimpleForm.build :tag => :section, :class => "custom_wrapper" do |b|
+ SimpleForm.build :tag => :section, :class => "custom_wrapper", :pattern => false do |b|
+ b.use :pattern
b.use :another, :class => "another_wrapper" do |ba|
ba.use :label
ba.use :input

0 comments on commit 94dab68

Please sign in to comment.