From 4a4c99f7fac622f39799066482cf8a0e84c759b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20Mendon=C3=A7a=20Fran=C3=A7a?= Date: Tue, 30 Aug 2011 20:51:53 -0300 Subject: [PATCH] Add support for maxlenght to text area inputs. Closes #232 --- CHANGELOG.rdoc | 1 + .../config/initializers/simple_form.rb | 2 +- lib/simple_form.rb | 2 +- lib/simple_form/components.rb | 3 +- lib/simple_form/components/maxlength.rb | 32 +++++++++++++++++++ lib/simple_form/inputs/base.rb | 1 + lib/simple_form/inputs/mapping_input.rb | 4 +++ lib/simple_form/inputs/string_input.rb | 17 ++-------- test/inputs_test.rb | 17 ++++++++++ test/support/models.rb | 3 +- 10 files changed, 63 insertions(+), 19 deletions(-) create mode 100644 lib/simple_form/components/maxlength.rb diff --git a/CHANGELOG.rdoc b/CHANGELOG.rdoc index a26cd6fd..55d43d50 100644 --- a/CHANGELOG.rdoc +++ b/CHANGELOG.rdoc @@ -6,6 +6,7 @@ * Change form css class handling to only add the dom class when one is not given to the form call (by github.com/patrick99e99) * Support for required attributs when action validations are present (by github.com/csegura) * Don't generate `size` attribute for numeric input (by github.com/jasonmp85) + * Support for `maxlength` on text area inputs inferred from validation * bug fix * Fix bug when simple_fields_for is used with a hash like models and Rails 3.1 diff --git a/lib/generators/simple_form/templates/config/initializers/simple_form.rb b/lib/generators/simple_form/templates/config/initializers/simple_form.rb index 553961ba..bb43008d 100644 --- a/lib/generators/simple_form/templates/config/initializers/simple_form.rb +++ b/lib/generators/simple_form/templates/config/initializers/simple_form.rb @@ -2,7 +2,7 @@ SimpleForm.setup do |config| # Components used by the form builder to generate a complete input. You can remove # any of them, change the order, or even add your own components to the stack. - # config.components = [ :placeholder, :label_input, :hint, :error ] + # config.components = [ :placeholder, :maxlength, :label_input, :hint, :error ] # Default tag used on hints. # config.hint_tag = :span diff --git a/lib/simple_form.rb b/lib/simple_form.rb index be5fd28d..3b392907 100644 --- a/lib/simple_form.rb +++ b/lib/simple_form.rb @@ -45,7 +45,7 @@ module SimpleForm # Components used by the form builder. mattr_accessor :components - @@components = [ :placeholder, :label_input, :hint, :error ] + @@components = [ :placeholder, :maxlength, :label_input, :hint, :error ] # Series of attemps to detect a default label method for collection. mattr_accessor :collection_label_methods diff --git a/lib/simple_form/components.rb b/lib/simple_form/components.rb index a3511db7..c3e54d9e 100644 --- a/lib/simple_form/components.rb +++ b/lib/simple_form/components.rb @@ -6,5 +6,6 @@ module SimpleForm autoload :Labels, 'simple_form/components/labels' autoload :Placeholders, 'simple_form/components/placeholders' autoload :Wrapper, 'simple_form/components/wrapper' + autoload :Maxlength, 'simple_form/components/maxlength' end -end \ No newline at end of file +end diff --git a/lib/simple_form/components/maxlength.rb b/lib/simple_form/components/maxlength.rb new file mode 100644 index 00000000..cd1c021e --- /dev/null +++ b/lib/simple_form/components/maxlength.rb @@ -0,0 +1,32 @@ +module SimpleForm + module Components + module Maxlength + def maxlength + if has_maxlength? + input_html_options[:maxlength] ||= maximum_length_from_validation + input_html_options[:maxlength] ||= limit if limit && SimpleForm.html5 + end + nil + end + + def has_maxlength? + false + end + + def limit + column && column.limit + end + + def maximum_length_from_validation + return unless has_validators? + + length_validator = find_length_validator or return + length_validator.options[:maximum] + end + + def find_length_validator + attribute_validators.find { |v| ActiveModel::Validations::LengthValidator === v } + end + end + end +end diff --git a/lib/simple_form/inputs/base.rb b/lib/simple_form/inputs/base.rb index 9a3cbf0b..41e44da3 100644 --- a/lib/simple_form/inputs/base.rb +++ b/lib/simple_form/inputs/base.rb @@ -14,6 +14,7 @@ module SimpleForm include SimpleForm::Components::LabelInput include SimpleForm::Components::Placeholders include SimpleForm::Components::Wrapper + include SimpleForm::Components::Maxlength attr_reader :attribute_name, :column, :input_type, :reflection, :options, :input_html_options diff --git a/lib/simple_form/inputs/mapping_input.rb b/lib/simple_form/inputs/mapping_input.rb index 14a1faee..5070bc7a 100644 --- a/lib/simple_form/inputs/mapping_input.rb +++ b/lib/simple_form/inputs/mapping_input.rb @@ -13,6 +13,10 @@ module SimpleForm private + def has_maxlength? + text? + end + def has_placeholder? (text? || password?) && placeholder_present? end diff --git a/lib/simple_form/inputs/string_input.rb b/lib/simple_form/inputs/string_input.rb index d423db08..be29fa92 100644 --- a/lib/simple_form/inputs/string_input.rb +++ b/lib/simple_form/inputs/string_input.rb @@ -8,8 +8,6 @@ module SimpleForm def input input_html_options[:size] ||= [limit, SimpleForm.default_input_size].compact.min - input_html_options[:maxlength] ||= maximum_length_from_validation - input_html_options[:maxlength] ||= limit if limit && SimpleForm.html5 if password? || SimpleForm.html5 input_html_options[:type] ||= input_type unless string? end @@ -22,8 +20,8 @@ module SimpleForm protected - def limit - column && column.limit + def has_maxlength? + true end def has_placeholder? @@ -37,17 +35,6 @@ module SimpleForm def password? input_type == :password end - - def maximum_length_from_validation - return unless has_validators? - - length_validator = find_length_validator or return - length_validator.options[:maximum] - end - - def find_length_validator - attribute_validators.find { |v| ActiveModel::Validations::LengthValidator === v } - end end end end diff --git a/test/inputs_test.rb b/test/inputs_test.rb index bc3d5cfe..2cd001e5 100644 --- a/test/inputs_test.rb +++ b/test/inputs_test.rb @@ -398,6 +398,23 @@ class InputTest < ActionView::TestCase assert_select 'textarea.text[placeholder=Put in some text]' end + test 'input should get maxlength from column definition for text attributes' do + with_input_for @user, :description, :text + assert_select 'textarea.text[maxlength=200]' + end + + test 'input should infer maxlength column definition from validation when present for text attributes' do + with_input_for @validating_user, :description, :text + assert_select 'textarea.text[maxlength=50]' + end + + test 'when not using HTML5, does not show maxlength attribute for text attributes' do + swap SimpleForm, :html5 => false do + with_input_for @user, :description, :text + assert_no_select 'textarea.text[maxlength]' + end + end + test 'input should generate a file field' do with_input_for @user, :name, :file assert_select 'input#user_name[type=file]' diff --git a/test/support/models.rb b/test/support/models.rb index a38d21b9..06d7489e 100644 --- a/test/support/models.rb +++ b/test/support/models.rb @@ -67,7 +67,7 @@ class User def column_for_attribute(attribute) column_type, limit = case attribute.to_sym when :name, :status, :password then [:string, 100] - when :description then :text + when :description then [:text, 200] when :age then :integer when :credit_limit then [:decimal, 15] when :active then :boolean @@ -144,6 +144,7 @@ class ValidatingUser < User :less_than_or_equal_to => :max_attempts, :only_integer => true validates_length_of :name, :maximum => 25 + validates_length_of :description, :maximum => 50 def min_amount 10