Make min_max also a component.

This commit is contained in:
José Valim 2011-12-04 16:31:13 +01:00
parent d3ddd2a601
commit f883b20b94
6 changed files with 65 additions and 54 deletions

View File

@ -10,14 +10,16 @@ SimpleForm.setup do |config|
b.use :html5
## Extensions
# Calculate maxlength from validations for string inputs
b.use :maxlength
# Automatically use translation to retrieve a placeholder
# Calculates maxlength from length validations automatically for string inputs
# b.use :maxlength
# Calculates pattern from format validations automatically for string inputs
# b.use :pattern
# Calculates min and max from length validations automatically for numeric inputs
# b.use :min_max
# Calculates placeholders automatically from I18n
b.use :placeholder
# Add the HTML5 required attribute to the input
# Calculates required from presence validations automatically
b.use :required
# Add a pattern from format validations for string inputs
b.use :pattern
## Inputs
b.use :label_input

View File

@ -144,6 +144,7 @@ module SimpleForm
wrappers :class => :input, :error_class => :field_with_errors do |b|
b.use :html5
b.use :min_max
b.use :maxlength
b.use :placeholder
b.use :required

View File

@ -11,6 +11,7 @@ module SimpleForm
autoload :HTML5, 'simple_form/components/html5'
autoload :LabelInput, 'simple_form/components/label_input'
autoload :Labels, 'simple_form/components/labels'
autoload :MinMax, 'simple_form/components/min_max'
autoload :Maxlength, 'simple_form/components/maxlength'
autoload :Pattern, 'simple_form/components/pattern'
autoload :Placeholders, 'simple_form/components/placeholders'

View File

@ -0,0 +1,51 @@
module SimpleForm
module Components
module MinMax
def min_max
return unless has_validators?
if numeric_validator = find_numericality_validator
validator_options = numeric_validator.options
input_html_options[:min] ||= minimum_value(validator_options)
input_html_options[:max] ||= maximum_value(validator_options)
end
end
private
def integer?
input_type == :integer
end
def minimum_value(validator_options)
if integer? && validator_options.key?(:greater_than)
evaluate_validator_option(validator_options[:greater_than]) + 1
else
evaluate_validator_option(validator_options[:greater_than_or_equal_to])
end
end
def maximum_value(validator_options)
if integer? && validator_options.key?(:less_than)
evaluate_validator_option(validator_options[:less_than]) - 1
else
evaluate_validator_option(validator_options[:less_than_or_equal_to])
end
end
def find_numericality_validator
find_validator(ActiveModel::Validations::NumericalityValidator)
end
def evaluate_validator_option(option)
if option.is_a?(Numeric)
option
elsif option.is_a?(Symbol)
object.send(option)
elsif option.respond_to?(:call)
option.call(object)
end
end
end
end
end

View File

@ -13,6 +13,7 @@ module SimpleForm
include SimpleForm::Components::Hints
include SimpleForm::Components::HTML5
include SimpleForm::Components::LabelInput
include SimpleForm::Components::MinMax
include SimpleForm::Components::Maxlength
include SimpleForm::Components::Pattern
include SimpleForm::Components::Placeholders
@ -44,7 +45,7 @@ module SimpleForm
enable :hint
# Usually disabled, needs to be enabled explicitly passing true as option.
disable :maxlength, :placeholder, :pattern
disable :maxlength, :placeholder, :pattern, :min_max
def initialize(builder, attribute_name, column, input_type, options = {})
super
@ -54,7 +55,7 @@ module SimpleForm
@column = column
@input_type = input_type
@reflection = options.delete(:reflection)
@options = self.class.default_options.merge(options)
@options = options.reverse_merge!(self.class.default_options)
@required = calculate_required
# Notice that html_options_for receives a reference to input_html_classes.

View File

@ -1,7 +1,7 @@
module SimpleForm
module Inputs
class NumericInput < Base
enable :placeholder
enable :placeholder, :min_max
def input
add_size!
@ -9,7 +9,6 @@ module SimpleForm
if html5?
input_html_options[:type] ||= "number"
input_html_options[:step] ||= integer? ? 1 : "any"
infer_attributes_from_validations!
end
@builder.text_field(attribute_name, input_html_options)
end
@ -20,50 +19,6 @@ module SimpleForm
def add_size!
input_html_options[:size] ||= nil
end
def infer_attributes_from_validations!
return unless has_validators?
if numeric_validator = find_numericality_validator
validator_options = numeric_validator.options
input_html_options[:min] ||= minimum_value(validator_options)
input_html_options[:max] ||= maximum_value(validator_options)
end
end
def integer?
input_type == :integer
end
def minimum_value(validator_options)
if integer? && validator_options.key?(:greater_than)
evaluate_validator_option(validator_options[:greater_than]) + 1
else
evaluate_validator_option(validator_options[:greater_than_or_equal_to])
end
end
def maximum_value(validator_options)
if integer? && validator_options.key?(:less_than)
evaluate_validator_option(validator_options[:less_than]) - 1
else
evaluate_validator_option(validator_options[:less_than_or_equal_to])
end
end
def find_numericality_validator
find_validator(ActiveModel::Validations::NumericalityValidator)
end
def evaluate_validator_option(option)
if option.is_a?(Numeric)
option
elsif option.is_a?(Symbol)
object.send(option)
elsif option.respond_to?(:call)
option.call(object)
end
end
end
end
end