From e749fb5826d9f119847d2e1d5ec2aff30b00632e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20Mendon=C3=A7a=20Fran=C3=A7a?= Date: Mon, 16 Jan 2012 17:19:07 -0300 Subject: [PATCH 01/31] Extract LabelTag --- .../lib/action_view/helpers/form_helper.rb | 56 +------ actionpack/lib/action_view/helpers/tags.rb | 7 + .../lib/action_view/helpers/tags/label_tag.rb | 147 ++++++++++++++++++ 3 files changed, 156 insertions(+), 54 deletions(-) create mode 100644 actionpack/lib/action_view/helpers/tags.rb create mode 100644 actionpack/lib/action_view/helpers/tags/label_tag.rb diff --git a/actionpack/lib/action_view/helpers/form_helper.rb b/actionpack/lib/action_view/helpers/form_helper.rb index ca2eb1ac10..b312d72b99 100644 --- a/actionpack/lib/action_view/helpers/form_helper.rb +++ b/actionpack/lib/action_view/helpers/form_helper.rb @@ -3,6 +3,7 @@ require 'action_view/helpers/date_helper' require 'action_view/helpers/tag_helper' require 'action_view/helpers/form_tag_helper' require 'action_view/helpers/active_model_helper' +require 'action_view/helpers/tags' require 'active_support/core_ext/class/attribute' require 'active_support/core_ext/hash/slice' require 'active_support/core_ext/object/blank' @@ -654,16 +655,7 @@ module ActionView # 'Accept Terms.'.html_safe # end def label(object_name, method, content_or_options = nil, options = nil, &block) - content_is_options = content_or_options.is_a?(Hash) - if content_is_options || block_given? - options = content_or_options if content_is_options - text = nil - else - text = content_or_options - end - - options ||= {} - InstanceTag.new(object_name, method, self, options.delete(:object)).to_label_tag(text, options, &block) + ActionView::Helpers::Tags::LabelTag.new(object_name, method, self, content_or_options, options).render(&block) end # Returns an input tag of the "text" type tailored for accessing a specified attribute (identified by +method+) on an object @@ -979,50 +971,6 @@ module ActionView @auto_index = retrieve_autoindex(Regexp.last_match.pre_match) if Regexp.last_match end - def to_label_tag(text = nil, options = {}, &block) - options = options.stringify_keys - tag_value = options.delete("value") - name_and_id = options.dup - - if name_and_id["for"] - name_and_id["id"] = name_and_id["for"] - else - name_and_id.delete("id") - end - - add_default_name_and_id_for_value(tag_value, name_and_id) - options.delete("index") - options.delete("namespace") - options["for"] ||= name_and_id["id"] - - if block_given? - @template_object.label_tag(name_and_id["id"], options, &block) - else - content = if text.blank? - object_name.gsub!(/\[(.*)_attributes\]\[\d\]/, '.\1') - method_and_value = tag_value.present? ? "#{method_name}.#{tag_value}" : method_name - - if object.respond_to?(:to_model) - key = object.class.model_name.i18n_key - i18n_default = ["#{key}.#{method_and_value}".to_sym, ""] - end - - i18n_default ||= "" - I18n.t("#{object_name}.#{method_and_value}", :default => i18n_default, :scope => "helpers.label").presence - else - text.to_s - end - - content ||= if object && object.class.respond_to?(:human_attribute_name) - object.class.human_attribute_name(method_name) - end - - content ||= method_name.humanize - - label_tag(name_and_id["id"], content, options) - end - end - def to_input_field_tag(field_type, options = {}) options = options.stringify_keys options["size"] = options["maxlength"] || DEFAULT_FIELD_OPTIONS["size"] unless options.key?("size") diff --git a/actionpack/lib/action_view/helpers/tags.rb b/actionpack/lib/action_view/helpers/tags.rb new file mode 100644 index 0000000000..a5eef5a34a --- /dev/null +++ b/actionpack/lib/action_view/helpers/tags.rb @@ -0,0 +1,7 @@ +module ActionView + module Helpers + module Tags + autoload :LabelTag, 'action_view/helpers/tags/label_tag' + end + end +end diff --git a/actionpack/lib/action_view/helpers/tags/label_tag.rb b/actionpack/lib/action_view/helpers/tags/label_tag.rb new file mode 100644 index 0000000000..0141f0ab10 --- /dev/null +++ b/actionpack/lib/action_view/helpers/tags/label_tag.rb @@ -0,0 +1,147 @@ +module ActionView + module Helpers + module Tags + class LabelTag + include Helpers::TagHelper, Helpers::FormTagHelper + + attr_reader :object + + def initialize(object_name, method_name, template_object, content, options) + content_is_options = content.is_a?(Hash) + if content_is_options + options = content + @content = nil + else + @content = content + end + + options ||= {} + + @object_name, @method_name = object_name.to_s.dup, method_name.to_s.dup + @template_object = template_object + + @object_name.sub!(/\[\]$/,"") || @object_name.sub!(/\[\]\]$/,"]") + @object = retrieve_object(options.delete(:object)) + @options = options + @auto_index = retrieve_autoindex(Regexp.last_match.pre_match) if Regexp.last_match + end + + def render(&block) + options = @options.stringify_keys + tag_value = options.delete("value") + name_and_id = options.dup + + if name_and_id["for"] + name_and_id["id"] = name_and_id["for"] + else + name_and_id.delete("id") + end + + add_default_name_and_id_for_value(tag_value, name_and_id) + options.delete("index") + options.delete("namespace") + options["for"] ||= name_and_id["id"] + + if block_given? + @template_object.label_tag(name_and_id["id"], options, &block) + else + content = if @content.blank? + @object_name.gsub!(/\[(.*)_attributes\]\[\d\]/, '.\1') + method_and_value = tag_value.present? ? "#{@method_name}.#{tag_value}" : @method_name + + if object.respond_to?(:to_model) + key = object.class.model_name.i18n_key + i18n_default = ["#{key}.#{method_and_value}".to_sym, ""] + end + + i18n_default ||= "" + I18n.t("#{@object_name}.#{method_and_value}", :default => i18n_default, :scope => "helpers.label").presence + else + @content.to_s + end + + content ||= if object && object.class.respond_to?(:human_attribute_name) + object.class.human_attribute_name(@method_name) + end + + content ||= @method_name.humanize + + label_tag(name_and_id["id"], content, options) + end + end + + private + + def retrieve_object(object) + if object + object + elsif @template_object.instance_variable_defined?("@#{@object_name}") + @template_object.instance_variable_get("@#{@object_name}") + end + rescue NameError + # As @object_name may contain the nested syntax (item[subobject]) we need to fallback to nil. + nil + end + + def retrieve_autoindex(pre_match) + object = self.object || @template_object.instance_variable_get("@#{pre_match}") + if object && object.respond_to?(:to_param) + object.to_param + else + raise ArgumentError, "object[] naming but object param and @object var don't exist or don't respond to to_param: #{object.inspect}" + end + end + + def add_default_name_and_id_for_value(tag_value, options) + unless tag_value.nil? + pretty_tag_value = tag_value.to_s.gsub(/\s/, "_").gsub(/[^-\w]/, "").downcase + specified_id = options["id"] + add_default_name_and_id(options) + options["id"] += "_#{pretty_tag_value}" if specified_id.blank? && options["id"].present? + else + add_default_name_and_id(options) + end + end + + def add_default_name_and_id(options) + if options.has_key?("index") + options["name"] ||= tag_name_with_index(options["index"]) + options["id"] = options.fetch("id"){ tag_id_with_index(options["index"]) } + options.delete("index") + elsif defined?(@auto_index) + options["name"] ||= tag_name_with_index(@auto_index) + options["id"] = options.fetch("id"){ tag_id_with_index(@auto_index) } + else + options["name"] ||= tag_name + (options['multiple'] ? '[]' : '') + options["id"] = options.fetch("id"){ tag_id } + end + options["id"] = [options.delete('namespace'), options["id"]].compact.join("_").presence + end + + def tag_name + "#{@object_name}[#{sanitized_method_name}]" + end + + def tag_name_with_index(index) + "#{@object_name}[#{index}][#{sanitized_method_name}]" + end + + def tag_id + "#{sanitized_object_name}_#{sanitized_method_name}" + end + + def tag_id_with_index(index) + "#{sanitized_object_name}_#{index}_#{sanitized_method_name}" + end + + def sanitized_object_name + @sanitized_object_name ||= @object_name.gsub(/\]\[|[^-a-zA-Z0-9:.]/, "_").sub(/_$/, "") + end + + def sanitized_method_name + @sanitized_method_name ||= @method_name.sub(/\?$/,"") + end + end + end + end +end From 520fe7defea2271cc540e8190a7b9d83d8dfb8d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20Mendon=C3=A7a=20Fran=C3=A7a?= Date: Mon, 16 Jan 2012 17:41:24 -0300 Subject: [PATCH 02/31] Extract TextFieldTag --- .../lib/action_view/helpers/form_helper.rb | 2 +- actionpack/lib/action_view/helpers/tags.rb | 3 +- .../helpers/tags/text_field_tag.rb | 114 ++++++++++++++++++ 3 files changed, 117 insertions(+), 2 deletions(-) create mode 100644 actionpack/lib/action_view/helpers/tags/text_field_tag.rb diff --git a/actionpack/lib/action_view/helpers/form_helper.rb b/actionpack/lib/action_view/helpers/form_helper.rb index b312d72b99..e1244346d4 100644 --- a/actionpack/lib/action_view/helpers/form_helper.rb +++ b/actionpack/lib/action_view/helpers/form_helper.rb @@ -677,7 +677,7 @@ module ActionView # # => # def text_field(object_name, method, options = {}) - InstanceTag.new(object_name, method, self, options.delete(:object)).to_input_field_tag("text", options) + ActionView::Helpers::Tags::TextFieldTag.new(object_name, method, self, options).render end # Returns an input tag of the "password" type tailored for accessing a specified attribute (identified by +method+) on an object diff --git a/actionpack/lib/action_view/helpers/tags.rb b/actionpack/lib/action_view/helpers/tags.rb index a5eef5a34a..f84b5486ae 100644 --- a/actionpack/lib/action_view/helpers/tags.rb +++ b/actionpack/lib/action_view/helpers/tags.rb @@ -1,7 +1,8 @@ module ActionView module Helpers module Tags - autoload :LabelTag, 'action_view/helpers/tags/label_tag' + autoload :LabelTag, 'action_view/helpers/tags/label_tag' + autoload :TextFieldTag, 'action_view/helpers/tags/text_field_tag' end end end diff --git a/actionpack/lib/action_view/helpers/tags/text_field_tag.rb b/actionpack/lib/action_view/helpers/tags/text_field_tag.rb new file mode 100644 index 0000000000..996a153cf8 --- /dev/null +++ b/actionpack/lib/action_view/helpers/tags/text_field_tag.rb @@ -0,0 +1,114 @@ +module ActionView + module Helpers + module Tags + class TextFieldTag + include Helpers::ActiveModelInstanceTag, Helpers::TagHelper, Helpers::FormTagHelper + + DEFAULT_FIELD_OPTIONS = { "size" => 30 } + + attr_reader :object + + def initialize(object_name, method_name, template_object, options = {}) + @object_name, @method_name = object_name.to_s.dup, method_name.to_s.dup + @template_object = template_object + + @object_name.sub!(/\[\]$/,"") || @object_name.sub!(/\[\]\]$/,"]") + @object = retrieve_object(options.delete(:object)) + @options = options + @auto_index = retrieve_autoindex(Regexp.last_match.pre_match) if Regexp.last_match + end + + def render(&block) + options = @options.stringify_keys + options["size"] = options["maxlength"] || DEFAULT_FIELD_OPTIONS["size"] unless options.key?("size") + options = DEFAULT_FIELD_OPTIONS.merge(options) + options["type"] ||= "text" + options["value"] = options.fetch("value"){ value_before_type_cast(object) } + options["value"] &&= ERB::Util.html_escape(options["value"]) + add_default_name_and_id(options) + tag("input", options) + end + + private + + def value_before_type_cast(object) + unless object.nil? + object.respond_to?(@method_name + "_before_type_cast") ? + object.send(@method_name + "_before_type_cast") : + object.send(@method_name) + end + end + + def retrieve_object(object) + if object + object + elsif @template_object.instance_variable_defined?("@#{@object_name}") + @template_object.instance_variable_get("@#{@object_name}") + end + rescue NameError + # As @object_name may contain the nested syntax (item[subobject]) we need to fallback to nil. + nil + end + + def retrieve_autoindex(pre_match) + object = self.object || @template_object.instance_variable_get("@#{pre_match}") + if object && object.respond_to?(:to_param) + object.to_param + else + raise ArgumentError, "object[] naming but object param and @object var don't exist or don't respond to to_param: #{object.inspect}" + end + end + + def add_default_name_and_id_for_value(tag_value, options) + unless tag_value.nil? + pretty_tag_value = tag_value.to_s.gsub(/\s/, "_").gsub(/[^-\w]/, "").downcase + specified_id = options["id"] + add_default_name_and_id(options) + options["id"] += "_#{pretty_tag_value}" if specified_id.blank? && options["id"].present? + else + add_default_name_and_id(options) + end + end + + def add_default_name_and_id(options) + if options.has_key?("index") + options["name"] ||= tag_name_with_index(options["index"]) + options["id"] = options.fetch("id"){ tag_id_with_index(options["index"]) } + options.delete("index") + elsif defined?(@auto_index) + options["name"] ||= tag_name_with_index(@auto_index) + options["id"] = options.fetch("id"){ tag_id_with_index(@auto_index) } + else + options["name"] ||= tag_name + (options['multiple'] ? '[]' : '') + options["id"] = options.fetch("id"){ tag_id } + end + options["id"] = [options.delete('namespace'), options["id"]].compact.join("_").presence + end + + def tag_name + "#{@object_name}[#{sanitized_method_name}]" + end + + def tag_name_with_index(index) + "#{@object_name}[#{index}][#{sanitized_method_name}]" + end + + def tag_id + "#{sanitized_object_name}_#{sanitized_method_name}" + end + + def tag_id_with_index(index) + "#{sanitized_object_name}_#{index}_#{sanitized_method_name}" + end + + def sanitized_object_name + @sanitized_object_name ||= @object_name.gsub(/\]\[|[^-a-zA-Z0-9:.]/, "_").sub(/_$/, "") + end + + def sanitized_method_name + @sanitized_method_name ||= @method_name.sub(/\?$/,"") + end + end + end + end +end From 801dcb0a391a2145a38a7eb8a3879f59a654a825 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20Mendon=C3=A7a=20Fran=C3=A7a?= Date: Mon, 16 Jan 2012 17:49:39 -0300 Subject: [PATCH 03/31] Extract duplicated code to a class --- actionpack/lib/action_view/helpers/tags.rb | 1 + .../lib/action_view/helpers/tags/base_tag.rb | 107 ++++++++++++++++++ .../lib/action_view/helpers/tags/label_tag.rb | 94 +-------------- .../helpers/tags/text_field_tag.rb | 100 +--------------- 4 files changed, 116 insertions(+), 186 deletions(-) create mode 100644 actionpack/lib/action_view/helpers/tags/base_tag.rb diff --git a/actionpack/lib/action_view/helpers/tags.rb b/actionpack/lib/action_view/helpers/tags.rb index f84b5486ae..cff5b0220c 100644 --- a/actionpack/lib/action_view/helpers/tags.rb +++ b/actionpack/lib/action_view/helpers/tags.rb @@ -1,6 +1,7 @@ module ActionView module Helpers module Tags + autoload :BaseTag, 'action_view/helpers/tags/base_tag' autoload :LabelTag, 'action_view/helpers/tags/label_tag' autoload :TextFieldTag, 'action_view/helpers/tags/text_field_tag' end diff --git a/actionpack/lib/action_view/helpers/tags/base_tag.rb b/actionpack/lib/action_view/helpers/tags/base_tag.rb new file mode 100644 index 0000000000..b9cb5f1a93 --- /dev/null +++ b/actionpack/lib/action_view/helpers/tags/base_tag.rb @@ -0,0 +1,107 @@ +module ActionView + module Helpers + module Tags + class BaseTag + include Helpers::ActiveModelInstanceTag, Helpers::TagHelper, Helpers::FormTagHelper + + DEFAULT_FIELD_OPTIONS = { "size" => 30 } + + attr_reader :object + + def initialize(object_name, method_name, template_object, options = {}) + @object_name, @method_name = object_name.to_s.dup, method_name.to_s.dup + @template_object = template_object + + @object_name.sub!(/\[\]$/,"") || @object_name.sub!(/\[\]\]$/,"]") + @object = retrieve_object(options.delete(:object)) + @options = options + @auto_index = retrieve_autoindex(Regexp.last_match.pre_match) if Regexp.last_match + end + + def render(&block) + raise "Abstract Method called" + end + + private + + def value_before_type_cast(object) + unless object.nil? + object.respond_to?(@method_name + "_before_type_cast") ? + object.send(@method_name + "_before_type_cast") : + object.send(@method_name) + end + end + + def retrieve_object(object) + if object + object + elsif @template_object.instance_variable_defined?("@#{@object_name}") + @template_object.instance_variable_get("@#{@object_name}") + end + rescue NameError + # As @object_name may contain the nested syntax (item[subobject]) we need to fallback to nil. + nil + end + + def retrieve_autoindex(pre_match) + object = self.object || @template_object.instance_variable_get("@#{pre_match}") + if object && object.respond_to?(:to_param) + object.to_param + else + raise ArgumentError, "object[] naming but object param and @object var don't exist or don't respond to to_param: #{object.inspect}" + end + end + + def add_default_name_and_id_for_value(tag_value, options) + unless tag_value.nil? + pretty_tag_value = tag_value.to_s.gsub(/\s/, "_").gsub(/[^-\w]/, "").downcase + specified_id = options["id"] + add_default_name_and_id(options) + options["id"] += "_#{pretty_tag_value}" if specified_id.blank? && options["id"].present? + else + add_default_name_and_id(options) + end + end + + def add_default_name_and_id(options) + if options.has_key?("index") + options["name"] ||= tag_name_with_index(options["index"]) + options["id"] = options.fetch("id"){ tag_id_with_index(options["index"]) } + options.delete("index") + elsif defined?(@auto_index) + options["name"] ||= tag_name_with_index(@auto_index) + options["id"] = options.fetch("id"){ tag_id_with_index(@auto_index) } + else + options["name"] ||= tag_name + (options['multiple'] ? '[]' : '') + options["id"] = options.fetch("id"){ tag_id } + end + options["id"] = [options.delete('namespace'), options["id"]].compact.join("_").presence + end + + def tag_name + "#{@object_name}[#{sanitized_method_name}]" + end + + def tag_name_with_index(index) + "#{@object_name}[#{index}][#{sanitized_method_name}]" + end + + def tag_id + "#{sanitized_object_name}_#{sanitized_method_name}" + end + + def tag_id_with_index(index) + "#{sanitized_object_name}_#{index}_#{sanitized_method_name}" + end + + def sanitized_object_name + @sanitized_object_name ||= @object_name.gsub(/\]\[|[^-a-zA-Z0-9:.]/, "_").sub(/_$/, "") + end + + def sanitized_method_name + @sanitized_method_name ||= @method_name.sub(/\?$/,"") + end + end + end + end +end diff --git a/actionpack/lib/action_view/helpers/tags/label_tag.rb b/actionpack/lib/action_view/helpers/tags/label_tag.rb index 0141f0ab10..8a7b15de59 100644 --- a/actionpack/lib/action_view/helpers/tags/label_tag.rb +++ b/actionpack/lib/action_view/helpers/tags/label_tag.rb @@ -1,29 +1,19 @@ module ActionView module Helpers module Tags - class LabelTag - include Helpers::TagHelper, Helpers::FormTagHelper - - attr_reader :object - - def initialize(object_name, method_name, template_object, content, options) - content_is_options = content.is_a?(Hash) + class LabelTag < BaseTag + def initialize(object_name, method_name, template_object, content_or_options = nil, options = nil) + content_is_options = content_or_options.is_a?(Hash) if content_is_options - options = content + options = content_or_options @content = nil else - @content = content + @content = content_or_options end options ||= {} - @object_name, @method_name = object_name.to_s.dup, method_name.to_s.dup - @template_object = template_object - - @object_name.sub!(/\[\]$/,"") || @object_name.sub!(/\[\]\]$/,"]") - @object = retrieve_object(options.delete(:object)) - @options = options - @auto_index = retrieve_autoindex(Regexp.last_match.pre_match) if Regexp.last_match + super(object_name, method_name, template_object, options) end def render(&block) @@ -69,78 +59,6 @@ module ActionView label_tag(name_and_id["id"], content, options) end end - - private - - def retrieve_object(object) - if object - object - elsif @template_object.instance_variable_defined?("@#{@object_name}") - @template_object.instance_variable_get("@#{@object_name}") - end - rescue NameError - # As @object_name may contain the nested syntax (item[subobject]) we need to fallback to nil. - nil - end - - def retrieve_autoindex(pre_match) - object = self.object || @template_object.instance_variable_get("@#{pre_match}") - if object && object.respond_to?(:to_param) - object.to_param - else - raise ArgumentError, "object[] naming but object param and @object var don't exist or don't respond to to_param: #{object.inspect}" - end - end - - def add_default_name_and_id_for_value(tag_value, options) - unless tag_value.nil? - pretty_tag_value = tag_value.to_s.gsub(/\s/, "_").gsub(/[^-\w]/, "").downcase - specified_id = options["id"] - add_default_name_and_id(options) - options["id"] += "_#{pretty_tag_value}" if specified_id.blank? && options["id"].present? - else - add_default_name_and_id(options) - end - end - - def add_default_name_and_id(options) - if options.has_key?("index") - options["name"] ||= tag_name_with_index(options["index"]) - options["id"] = options.fetch("id"){ tag_id_with_index(options["index"]) } - options.delete("index") - elsif defined?(@auto_index) - options["name"] ||= tag_name_with_index(@auto_index) - options["id"] = options.fetch("id"){ tag_id_with_index(@auto_index) } - else - options["name"] ||= tag_name + (options['multiple'] ? '[]' : '') - options["id"] = options.fetch("id"){ tag_id } - end - options["id"] = [options.delete('namespace'), options["id"]].compact.join("_").presence - end - - def tag_name - "#{@object_name}[#{sanitized_method_name}]" - end - - def tag_name_with_index(index) - "#{@object_name}[#{index}][#{sanitized_method_name}]" - end - - def tag_id - "#{sanitized_object_name}_#{sanitized_method_name}" - end - - def tag_id_with_index(index) - "#{sanitized_object_name}_#{index}_#{sanitized_method_name}" - end - - def sanitized_object_name - @sanitized_object_name ||= @object_name.gsub(/\]\[|[^-a-zA-Z0-9:.]/, "_").sub(/_$/, "") - end - - def sanitized_method_name - @sanitized_method_name ||= @method_name.sub(/\?$/,"") - end end end end diff --git a/actionpack/lib/action_view/helpers/tags/text_field_tag.rb b/actionpack/lib/action_view/helpers/tags/text_field_tag.rb index 996a153cf8..1dee28203f 100644 --- a/actionpack/lib/action_view/helpers/tags/text_field_tag.rb +++ b/actionpack/lib/action_view/helpers/tags/text_field_tag.rb @@ -1,24 +1,8 @@ module ActionView module Helpers module Tags - class TextFieldTag - include Helpers::ActiveModelInstanceTag, Helpers::TagHelper, Helpers::FormTagHelper - - DEFAULT_FIELD_OPTIONS = { "size" => 30 } - - attr_reader :object - - def initialize(object_name, method_name, template_object, options = {}) - @object_name, @method_name = object_name.to_s.dup, method_name.to_s.dup - @template_object = template_object - - @object_name.sub!(/\[\]$/,"") || @object_name.sub!(/\[\]\]$/,"]") - @object = retrieve_object(options.delete(:object)) - @options = options - @auto_index = retrieve_autoindex(Regexp.last_match.pre_match) if Regexp.last_match - end - - def render(&block) + class TextFieldTag < BaseTag + def render options = @options.stringify_keys options["size"] = options["maxlength"] || DEFAULT_FIELD_OPTIONS["size"] unless options.key?("size") options = DEFAULT_FIELD_OPTIONS.merge(options) @@ -28,86 +12,6 @@ module ActionView add_default_name_and_id(options) tag("input", options) end - - private - - def value_before_type_cast(object) - unless object.nil? - object.respond_to?(@method_name + "_before_type_cast") ? - object.send(@method_name + "_before_type_cast") : - object.send(@method_name) - end - end - - def retrieve_object(object) - if object - object - elsif @template_object.instance_variable_defined?("@#{@object_name}") - @template_object.instance_variable_get("@#{@object_name}") - end - rescue NameError - # As @object_name may contain the nested syntax (item[subobject]) we need to fallback to nil. - nil - end - - def retrieve_autoindex(pre_match) - object = self.object || @template_object.instance_variable_get("@#{pre_match}") - if object && object.respond_to?(:to_param) - object.to_param - else - raise ArgumentError, "object[] naming but object param and @object var don't exist or don't respond to to_param: #{object.inspect}" - end - end - - def add_default_name_and_id_for_value(tag_value, options) - unless tag_value.nil? - pretty_tag_value = tag_value.to_s.gsub(/\s/, "_").gsub(/[^-\w]/, "").downcase - specified_id = options["id"] - add_default_name_and_id(options) - options["id"] += "_#{pretty_tag_value}" if specified_id.blank? && options["id"].present? - else - add_default_name_and_id(options) - end - end - - def add_default_name_and_id(options) - if options.has_key?("index") - options["name"] ||= tag_name_with_index(options["index"]) - options["id"] = options.fetch("id"){ tag_id_with_index(options["index"]) } - options.delete("index") - elsif defined?(@auto_index) - options["name"] ||= tag_name_with_index(@auto_index) - options["id"] = options.fetch("id"){ tag_id_with_index(@auto_index) } - else - options["name"] ||= tag_name + (options['multiple'] ? '[]' : '') - options["id"] = options.fetch("id"){ tag_id } - end - options["id"] = [options.delete('namespace'), options["id"]].compact.join("_").presence - end - - def tag_name - "#{@object_name}[#{sanitized_method_name}]" - end - - def tag_name_with_index(index) - "#{@object_name}[#{index}][#{sanitized_method_name}]" - end - - def tag_id - "#{sanitized_object_name}_#{sanitized_method_name}" - end - - def tag_id_with_index(index) - "#{sanitized_object_name}_#{index}_#{sanitized_method_name}" - end - - def sanitized_object_name - @sanitized_object_name ||= @object_name.gsub(/\]\[|[^-a-zA-Z0-9:.]/, "_").sub(/_$/, "") - end - - def sanitized_method_name - @sanitized_method_name ||= @method_name.sub(/\?$/,"") - end end end end From 514308a49553e3a41c306d2df703ef7086ee054b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20Mendon=C3=A7a=20Fran=C3=A7a?= Date: Mon, 16 Jan 2012 18:38:13 -0300 Subject: [PATCH 04/31] Rename classes --- actionpack/lib/action_view/helpers/form_helper.rb | 4 ++-- actionpack/lib/action_view/helpers/tags.rb | 6 +++--- .../lib/action_view/helpers/tags/{base_tag.rb => base.rb} | 2 +- .../lib/action_view/helpers/tags/{label_tag.rb => label.rb} | 2 +- .../helpers/tags/{text_field_tag.rb => text_field.rb} | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) rename actionpack/lib/action_view/helpers/tags/{base_tag.rb => base.rb} (99%) rename actionpack/lib/action_view/helpers/tags/{label_tag.rb => label.rb} (98%) rename actionpack/lib/action_view/helpers/tags/{text_field_tag.rb => text_field.rb} (93%) diff --git a/actionpack/lib/action_view/helpers/form_helper.rb b/actionpack/lib/action_view/helpers/form_helper.rb index e1244346d4..d3d0e2e2f8 100644 --- a/actionpack/lib/action_view/helpers/form_helper.rb +++ b/actionpack/lib/action_view/helpers/form_helper.rb @@ -655,7 +655,7 @@ module ActionView # 'Accept Terms.'.html_safe # end def label(object_name, method, content_or_options = nil, options = nil, &block) - ActionView::Helpers::Tags::LabelTag.new(object_name, method, self, content_or_options, options).render(&block) + ActionView::Helpers::Tags::Label.new(object_name, method, self, content_or_options, options).render(&block) end # Returns an input tag of the "text" type tailored for accessing a specified attribute (identified by +method+) on an object @@ -677,7 +677,7 @@ module ActionView # # => # def text_field(object_name, method, options = {}) - ActionView::Helpers::Tags::TextFieldTag.new(object_name, method, self, options).render + ActionView::Helpers::Tags::TextField.new(object_name, method, self, options).render end # Returns an input tag of the "password" type tailored for accessing a specified attribute (identified by +method+) on an object diff --git a/actionpack/lib/action_view/helpers/tags.rb b/actionpack/lib/action_view/helpers/tags.rb index cff5b0220c..bc2fb34deb 100644 --- a/actionpack/lib/action_view/helpers/tags.rb +++ b/actionpack/lib/action_view/helpers/tags.rb @@ -1,9 +1,9 @@ module ActionView module Helpers module Tags - autoload :BaseTag, 'action_view/helpers/tags/base_tag' - autoload :LabelTag, 'action_view/helpers/tags/label_tag' - autoload :TextFieldTag, 'action_view/helpers/tags/text_field_tag' + autoload :Base, 'action_view/helpers/tags/base' + autoload :Label, 'action_view/helpers/tags/label' + autoload :TextField, 'action_view/helpers/tags/text_field' end end end diff --git a/actionpack/lib/action_view/helpers/tags/base_tag.rb b/actionpack/lib/action_view/helpers/tags/base.rb similarity index 99% rename from actionpack/lib/action_view/helpers/tags/base_tag.rb rename to actionpack/lib/action_view/helpers/tags/base.rb index b9cb5f1a93..24f66f764e 100644 --- a/actionpack/lib/action_view/helpers/tags/base_tag.rb +++ b/actionpack/lib/action_view/helpers/tags/base.rb @@ -1,7 +1,7 @@ module ActionView module Helpers module Tags - class BaseTag + class Base #:nodoc: include Helpers::ActiveModelInstanceTag, Helpers::TagHelper, Helpers::FormTagHelper DEFAULT_FIELD_OPTIONS = { "size" => 30 } diff --git a/actionpack/lib/action_view/helpers/tags/label_tag.rb b/actionpack/lib/action_view/helpers/tags/label.rb similarity index 98% rename from actionpack/lib/action_view/helpers/tags/label_tag.rb rename to actionpack/lib/action_view/helpers/tags/label.rb index 8a7b15de59..74ac92ee18 100644 --- a/actionpack/lib/action_view/helpers/tags/label_tag.rb +++ b/actionpack/lib/action_view/helpers/tags/label.rb @@ -1,7 +1,7 @@ module ActionView module Helpers module Tags - class LabelTag < BaseTag + class Label < Base #:nodoc: def initialize(object_name, method_name, template_object, content_or_options = nil, options = nil) content_is_options = content_or_options.is_a?(Hash) if content_is_options diff --git a/actionpack/lib/action_view/helpers/tags/text_field_tag.rb b/actionpack/lib/action_view/helpers/tags/text_field.rb similarity index 93% rename from actionpack/lib/action_view/helpers/tags/text_field_tag.rb rename to actionpack/lib/action_view/helpers/tags/text_field.rb index 1dee28203f..4e745061db 100644 --- a/actionpack/lib/action_view/helpers/tags/text_field_tag.rb +++ b/actionpack/lib/action_view/helpers/tags/text_field.rb @@ -1,7 +1,7 @@ module ActionView module Helpers module Tags - class TextFieldTag < BaseTag + class TextField < Base #:nodoc: def render options = @options.stringify_keys options["size"] = options["maxlength"] || DEFAULT_FIELD_OPTIONS["size"] unless options.key?("size") From 0ac47bd8192cb8b5b61b6a9ab2ce8b3b352870f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20Mendon=C3=A7a=20Fran=C3=A7a?= Date: Mon, 16 Jan 2012 19:07:52 -0300 Subject: [PATCH 05/31] Extract PasswordField --- actionpack/lib/action_view/helpers/form_helper.rb | 2 +- actionpack/lib/action_view/helpers/tags.rb | 7 ++++--- .../lib/action_view/helpers/tags/password_field.rb | 12 ++++++++++++ .../lib/action_view/helpers/tags/text_field.rb | 8 +++++++- 4 files changed, 24 insertions(+), 5 deletions(-) create mode 100644 actionpack/lib/action_view/helpers/tags/password_field.rb diff --git a/actionpack/lib/action_view/helpers/form_helper.rb b/actionpack/lib/action_view/helpers/form_helper.rb index d3d0e2e2f8..87674cc2d0 100644 --- a/actionpack/lib/action_view/helpers/form_helper.rb +++ b/actionpack/lib/action_view/helpers/form_helper.rb @@ -699,7 +699,7 @@ module ActionView # # => # def password_field(object_name, method, options = {}) - InstanceTag.new(object_name, method, self, options.delete(:object)).to_input_field_tag("password", { :value => nil }.merge!(options)) + ActionView::Helpers::Tags::PasswordField.new(object_name, method, self, options).render end # Returns a hidden input tag tailored for accessing a specified attribute (identified by +method+) on an object diff --git a/actionpack/lib/action_view/helpers/tags.rb b/actionpack/lib/action_view/helpers/tags.rb index bc2fb34deb..036fb1efd8 100644 --- a/actionpack/lib/action_view/helpers/tags.rb +++ b/actionpack/lib/action_view/helpers/tags.rb @@ -1,9 +1,10 @@ module ActionView module Helpers module Tags - autoload :Base, 'action_view/helpers/tags/base' - autoload :Label, 'action_view/helpers/tags/label' - autoload :TextField, 'action_view/helpers/tags/text_field' + autoload :Base, 'action_view/helpers/tags/base' + autoload :Label, 'action_view/helpers/tags/label' + autoload :TextField, 'action_view/helpers/tags/text_field' + autoload :PasswordField, 'action_view/helpers/tags/password_field' end end end diff --git a/actionpack/lib/action_view/helpers/tags/password_field.rb b/actionpack/lib/action_view/helpers/tags/password_field.rb new file mode 100644 index 0000000000..6e7a4d3c36 --- /dev/null +++ b/actionpack/lib/action_view/helpers/tags/password_field.rb @@ -0,0 +1,12 @@ +module ActionView + module Helpers + module Tags + class PasswordField < TextField #:nodoc: + def render + @options = {:value => nil}.merge!(@options) + super + end + end + end + end +end diff --git a/actionpack/lib/action_view/helpers/tags/text_field.rb b/actionpack/lib/action_view/helpers/tags/text_field.rb index 4e745061db..758fd636f2 100644 --- a/actionpack/lib/action_view/helpers/tags/text_field.rb +++ b/actionpack/lib/action_view/helpers/tags/text_field.rb @@ -6,12 +6,18 @@ module ActionView options = @options.stringify_keys options["size"] = options["maxlength"] || DEFAULT_FIELD_OPTIONS["size"] unless options.key?("size") options = DEFAULT_FIELD_OPTIONS.merge(options) - options["type"] ||= "text" + options["type"] ||= field_type options["value"] = options.fetch("value"){ value_before_type_cast(object) } options["value"] &&= ERB::Util.html_escape(options["value"]) add_default_name_and_id(options) tag("input", options) end + + private + + def field_type + self.class.name.split("::").last.sub("Field", "").downcase + end end end end From 7cc373e4a052b1e90a916f7cae930a3da6613625 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20Mendon=C3=A7a=20Fran=C3=A7a?= Date: Mon, 16 Jan 2012 19:22:31 -0300 Subject: [PATCH 06/31] Adding one test case for label with block --- actionpack/test/template/form_helper_test.rb | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/actionpack/test/template/form_helper_test.rb b/actionpack/test/template/form_helper_test.rb index 82e001732d..5be6a2e4e5 100644 --- a/actionpack/test/template/form_helper_test.rb +++ b/actionpack/test/template/form_helper_test.rb @@ -232,6 +232,10 @@ class FormHelperTest < ActionView::TestCase assert_dom_equal('', label(:post, :title) { "The title, please:" }) end + def test_label_with_block_and_options + assert_dom_equal('', label(:post, :title, "for" => "my_for") { "The title, please:" }) + end + def test_label_with_block_in_erb assert_equal "", view.render("test/label_with_block") end From 6aeb799866ae08a0e8944cc23a48f1616b60d560 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20Mendon=C3=A7a=20Fran=C3=A7a?= Date: Mon, 16 Jan 2012 20:02:39 -0300 Subject: [PATCH 07/31] Extract HiddenField --- actionpack/lib/action_view/helpers/form_helper.rb | 2 +- actionpack/lib/action_view/helpers/tags.rb | 1 + .../lib/action_view/helpers/tags/hidden_field.rb | 12 ++++++++++++ 3 files changed, 14 insertions(+), 1 deletion(-) create mode 100644 actionpack/lib/action_view/helpers/tags/hidden_field.rb diff --git a/actionpack/lib/action_view/helpers/form_helper.rb b/actionpack/lib/action_view/helpers/form_helper.rb index 87674cc2d0..1fbd3f80e6 100644 --- a/actionpack/lib/action_view/helpers/form_helper.rb +++ b/actionpack/lib/action_view/helpers/form_helper.rb @@ -717,7 +717,7 @@ module ActionView # hidden_field(:user, :token) # # => def hidden_field(object_name, method, options = {}) - InstanceTag.new(object_name, method, self, options.delete(:object)).to_input_field_tag("hidden", options) + ActionView::Helpers::Tags::HiddenField.new(object_name, method, self, options).render end # Returns a file upload input tag tailored for accessing a specified attribute (identified by +method+) on an object diff --git a/actionpack/lib/action_view/helpers/tags.rb b/actionpack/lib/action_view/helpers/tags.rb index 036fb1efd8..b663f8b68f 100644 --- a/actionpack/lib/action_view/helpers/tags.rb +++ b/actionpack/lib/action_view/helpers/tags.rb @@ -5,6 +5,7 @@ module ActionView autoload :Label, 'action_view/helpers/tags/label' autoload :TextField, 'action_view/helpers/tags/text_field' autoload :PasswordField, 'action_view/helpers/tags/password_field' + autoload :HiddenField, 'action_view/helpers/tags/hidden_field' end end end diff --git a/actionpack/lib/action_view/helpers/tags/hidden_field.rb b/actionpack/lib/action_view/helpers/tags/hidden_field.rb new file mode 100644 index 0000000000..ea86596e0b --- /dev/null +++ b/actionpack/lib/action_view/helpers/tags/hidden_field.rb @@ -0,0 +1,12 @@ +module ActionView + module Helpers + module Tags + class HiddenField < TextField #:nodoc: + def render + @options.update(:size => nil) + super + end + end + end + end +end From 68b870f6be0eff3de6b3dfb6ba64b253419260ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20Mendon=C3=A7a=20Fran=C3=A7a?= Date: Mon, 16 Jan 2012 20:14:56 -0300 Subject: [PATCH 08/31] Extract FileField --- actionpack/lib/action_view/helpers/form_helper.rb | 2 +- actionpack/lib/action_view/helpers/tags.rb | 1 + .../lib/action_view/helpers/tags/file_field.rb | 12 ++++++++++++ .../lib/action_view/helpers/tags/text_field.rb | 4 ++-- 4 files changed, 16 insertions(+), 3 deletions(-) create mode 100644 actionpack/lib/action_view/helpers/tags/file_field.rb diff --git a/actionpack/lib/action_view/helpers/form_helper.rb b/actionpack/lib/action_view/helpers/form_helper.rb index 1fbd3f80e6..9c8966e528 100644 --- a/actionpack/lib/action_view/helpers/form_helper.rb +++ b/actionpack/lib/action_view/helpers/form_helper.rb @@ -738,7 +738,7 @@ module ActionView # # => # def file_field(object_name, method, options = {}) - InstanceTag.new(object_name, method, self, options.delete(:object)).to_input_field_tag("file", options.update({:size => nil})) + ActionView::Helpers::Tags::FileField.new(object_name, method, self, options).render end # Returns a textarea opening and closing tag set tailored for accessing a specified attribute (identified by +method+) diff --git a/actionpack/lib/action_view/helpers/tags.rb b/actionpack/lib/action_view/helpers/tags.rb index b663f8b68f..5b43f43fea 100644 --- a/actionpack/lib/action_view/helpers/tags.rb +++ b/actionpack/lib/action_view/helpers/tags.rb @@ -6,6 +6,7 @@ module ActionView autoload :TextField, 'action_view/helpers/tags/text_field' autoload :PasswordField, 'action_view/helpers/tags/password_field' autoload :HiddenField, 'action_view/helpers/tags/hidden_field' + autoload :FileField, 'action_view/helpers/tags/file_field' end end end diff --git a/actionpack/lib/action_view/helpers/tags/file_field.rb b/actionpack/lib/action_view/helpers/tags/file_field.rb new file mode 100644 index 0000000000..56442e1c14 --- /dev/null +++ b/actionpack/lib/action_view/helpers/tags/file_field.rb @@ -0,0 +1,12 @@ +module ActionView + module Helpers + module Tags + class FileField < TextField #:nodoc: + def render + @options.update(:size => nil) + super + end + end + end + end +end diff --git a/actionpack/lib/action_view/helpers/tags/text_field.rb b/actionpack/lib/action_view/helpers/tags/text_field.rb index 758fd636f2..0f81726eb4 100644 --- a/actionpack/lib/action_view/helpers/tags/text_field.rb +++ b/actionpack/lib/action_view/helpers/tags/text_field.rb @@ -7,7 +7,7 @@ module ActionView options["size"] = options["maxlength"] || DEFAULT_FIELD_OPTIONS["size"] unless options.key?("size") options = DEFAULT_FIELD_OPTIONS.merge(options) options["type"] ||= field_type - options["value"] = options.fetch("value"){ value_before_type_cast(object) } + options["value"] = options.fetch("value"){ value_before_type_cast(object) } unless field_type == "file" options["value"] &&= ERB::Util.html_escape(options["value"]) add_default_name_and_id(options) tag("input", options) @@ -16,7 +16,7 @@ module ActionView private def field_type - self.class.name.split("::").last.sub("Field", "").downcase + @field_type ||= self.class.name.split("::").last.sub("Field", "").downcase end end end From 8e8c6c35832e6a9d9ee09b645e9f34b3594128c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20Mendon=C3=A7a=20Fran=C3=A7a?= Date: Mon, 16 Jan 2012 20:29:01 -0300 Subject: [PATCH 09/31] Extract TextArea --- .../lib/action_view/helpers/form_helper.rb | 14 +------------ actionpack/lib/action_view/helpers/tags.rb | 1 + .../lib/action_view/helpers/tags/text_area.rb | 20 +++++++++++++++++++ 3 files changed, 22 insertions(+), 13 deletions(-) create mode 100644 actionpack/lib/action_view/helpers/tags/text_area.rb diff --git a/actionpack/lib/action_view/helpers/form_helper.rb b/actionpack/lib/action_view/helpers/form_helper.rb index 9c8966e528..837b1a8d9a 100644 --- a/actionpack/lib/action_view/helpers/form_helper.rb +++ b/actionpack/lib/action_view/helpers/form_helper.rb @@ -766,7 +766,7 @@ module ActionView # # #{@entry.body} # # def text_area(object_name, method, options = {}) - InstanceTag.new(object_name, method, self, options.delete(:object)).to_text_area_tag(options) + ActionView::Helpers::Tags::TextArea.new(object_name, method, self, options).render end # Returns a checkbox tag tailored for accessing a specified attribute (identified by +method+) on an object @@ -960,7 +960,6 @@ module ActionView DEFAULT_FIELD_OPTIONS = { "size" => 30 } DEFAULT_RADIO_OPTIONS = { } - DEFAULT_TEXT_AREA_OPTIONS = { "cols" => 40, "rows" => 20 } def initialize(object_name, method_name, template_object, object = nil) @object_name, @method_name = object_name.to_s.dup, method_name.to_s.dup @@ -1010,17 +1009,6 @@ module ActionView tag("input", options) end - def to_text_area_tag(options = {}) - options = DEFAULT_TEXT_AREA_OPTIONS.merge(options.stringify_keys) - add_default_name_and_id(options) - - if size = options.delete("size") - options["cols"], options["rows"] = size.split("x") if size.respond_to?(:split) - end - - content_tag("textarea", ERB::Util.html_escape(options.delete('value') || value_before_type_cast(object)), options) - end - def to_check_box_tag(options = {}, checked_value = "1", unchecked_value = "0") options = options.stringify_keys options["type"] = "checkbox" diff --git a/actionpack/lib/action_view/helpers/tags.rb b/actionpack/lib/action_view/helpers/tags.rb index 5b43f43fea..76e1927b80 100644 --- a/actionpack/lib/action_view/helpers/tags.rb +++ b/actionpack/lib/action_view/helpers/tags.rb @@ -7,6 +7,7 @@ module ActionView autoload :PasswordField, 'action_view/helpers/tags/password_field' autoload :HiddenField, 'action_view/helpers/tags/hidden_field' autoload :FileField, 'action_view/helpers/tags/file_field' + autoload :TextArea, 'action_view/helpers/tags/text_area' end end end diff --git a/actionpack/lib/action_view/helpers/tags/text_area.rb b/actionpack/lib/action_view/helpers/tags/text_area.rb new file mode 100644 index 0000000000..a7db8eb437 --- /dev/null +++ b/actionpack/lib/action_view/helpers/tags/text_area.rb @@ -0,0 +1,20 @@ +module ActionView + module Helpers + module Tags + class TextArea < Base #:nodoc: + DEFAULT_TEXT_AREA_OPTIONS = { "cols" => 40, "rows" => 20 } + + def render + options = DEFAULT_TEXT_AREA_OPTIONS.merge(@options.stringify_keys) + add_default_name_and_id(options) + + if size = options.delete("size") + options["cols"], options["rows"] = size.split("x") if size.respond_to?(:split) + end + + content_tag("textarea", ERB::Util.html_escape(options.delete('value') || value_before_type_cast(object)), options) + end + end + end + end +end From f42e1db35ab3a0300b8e02ac55e0ae82873b5986 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20Mendon=C3=A7a=20Fran=C3=A7a?= Date: Mon, 16 Jan 2012 20:48:32 -0300 Subject: [PATCH 10/31] Extract CheckBox --- .../lib/action_view/helpers/form_helper.rb | 41 +------------ actionpack/lib/action_view/helpers/tags.rb | 1 + .../lib/action_view/helpers/tags/check_box.rb | 60 +++++++++++++++++++ 3 files changed, 62 insertions(+), 40 deletions(-) create mode 100644 actionpack/lib/action_view/helpers/tags/check_box.rb diff --git a/actionpack/lib/action_view/helpers/form_helper.rb b/actionpack/lib/action_view/helpers/form_helper.rb index 837b1a8d9a..c804c2646c 100644 --- a/actionpack/lib/action_view/helpers/form_helper.rb +++ b/actionpack/lib/action_view/helpers/form_helper.rb @@ -828,7 +828,7 @@ module ActionView # # # def check_box(object_name, method, options = {}, checked_value = "1", unchecked_value = "0") - InstanceTag.new(object_name, method, self, options.delete(:object)).to_check_box_tag(options, checked_value, unchecked_value) + ActionView::Helpers::Tags::CheckBox.new(object_name, method, self, checked_value, unchecked_value, options).render end # Returns a radio button tag for accessing a specified attribute (identified by +method+) on an object @@ -1009,28 +1009,6 @@ module ActionView tag("input", options) end - def to_check_box_tag(options = {}, checked_value = "1", unchecked_value = "0") - options = options.stringify_keys - options["type"] = "checkbox" - options["value"] = checked_value - if options.has_key?("checked") - cv = options.delete "checked" - checked = cv == true || cv == "checked" - else - checked = self.class.check_box_checked?(value(object), checked_value) - end - options["checked"] = "checked" if checked - if options["multiple"] - add_default_name_and_id_for_value(checked_value, options) - options.delete("multiple") - else - add_default_name_and_id(options) - end - hidden = unchecked_value ? tag("input", "name" => options["name"], "type" => "hidden", "value" => unchecked_value, "disabled" => options["disabled"]) : "" - checkbox = tag("input", options) - hidden + checkbox - end - def to_boolean_select_tag(options = {}) options = options.stringify_keys add_default_name_and_id(options) @@ -1089,23 +1067,6 @@ module ActionView end end - def check_box_checked?(value, checked_value) - case value - when TrueClass, FalseClass - value - when NilClass - false - when Integer - value != 0 - when String - value == checked_value - when Array - value.include?(checked_value) - else - value.to_i != 0 - end - end - def radio_button_checked?(value, checked_value) value.to_s == checked_value.to_s end diff --git a/actionpack/lib/action_view/helpers/tags.rb b/actionpack/lib/action_view/helpers/tags.rb index 76e1927b80..175bc5eb64 100644 --- a/actionpack/lib/action_view/helpers/tags.rb +++ b/actionpack/lib/action_view/helpers/tags.rb @@ -8,6 +8,7 @@ module ActionView autoload :HiddenField, 'action_view/helpers/tags/hidden_field' autoload :FileField, 'action_view/helpers/tags/file_field' autoload :TextArea, 'action_view/helpers/tags/text_area' + autoload :CheckBox, 'action_view/helpers/tags/check_box' end end end diff --git a/actionpack/lib/action_view/helpers/tags/check_box.rb b/actionpack/lib/action_view/helpers/tags/check_box.rb new file mode 100644 index 0000000000..89aaad632c --- /dev/null +++ b/actionpack/lib/action_view/helpers/tags/check_box.rb @@ -0,0 +1,60 @@ +module ActionView + module Helpers + module Tags + class CheckBox < Base #:nodoc: + def initialize(object_name, method_name, template_object, checked_value, unchecked_value, options) + @checked_value = checked_value + @unchecked_value = unchecked_value + super(object_name, method_name, template_object, options) + end + + def render + options = @options.stringify_keys + options["type"] = "checkbox" + options["value"] = @checked_value + + if options.has_key?("checked") + cv = options.delete "checked" + checked = cv == true || cv == "checked" + else + checked = check_box_checked?(value(object)) + end + + options["checked"] = "checked" if checked + if options["multiple"] + add_default_name_and_id_for_value(@checked_value, options) + options.delete("multiple") + else + add_default_name_and_id(options) + end + hidden = @unchecked_value ? tag("input", "name" => options["name"], "type" => "hidden", "value" => @unchecked_value, "disabled" => options["disabled"]) : "" + checkbox = tag("input", options) + hidden + checkbox + end + + private + + def value(object) + object.send @method_name if object + end + + def check_box_checked?(value) + case value + when TrueClass, FalseClass + value + when NilClass + false + when Integer + value != 0 + when String + value == @checked_value + when Array + value.include?(@checked_value) + else + value.to_i != 0 + end + end + end + end + end +end From d6b9eb9b4417f1f8705284e520b796466a690ed6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20Mendon=C3=A7a=20Fran=C3=A7a?= Date: Mon, 16 Jan 2012 21:06:13 -0300 Subject: [PATCH 11/31] Extract RadioButton --- .../lib/action_view/helpers/form_helper.rb | 22 +----------- actionpack/lib/action_view/helpers/tags.rb | 1 + .../lib/action_view/helpers/tags/base.rb | 4 +++ .../lib/action_view/helpers/tags/check_box.rb | 4 --- .../action_view/helpers/tags/radio_button.rb | 35 +++++++++++++++++++ 5 files changed, 41 insertions(+), 25 deletions(-) create mode 100644 actionpack/lib/action_view/helpers/tags/radio_button.rb diff --git a/actionpack/lib/action_view/helpers/form_helper.rb b/actionpack/lib/action_view/helpers/form_helper.rb index c804c2646c..3b15e7097a 100644 --- a/actionpack/lib/action_view/helpers/form_helper.rb +++ b/actionpack/lib/action_view/helpers/form_helper.rb @@ -850,7 +850,7 @@ module ActionView # # => # # def radio_button(object_name, method, tag_value, options = {}) - InstanceTag.new(object_name, method, self, options.delete(:object)).to_radio_button_tag(tag_value, options) + ActionView::Helpers::Tags::RadioButton.new(object_name, method, self, tag_value, options).render end # Returns an input of type "search" for accessing a specified attribute (identified by +method+) on an object @@ -959,7 +959,6 @@ module ActionView attr_reader :object, :method_name, :object_name DEFAULT_FIELD_OPTIONS = { "size" => 30 } - DEFAULT_RADIO_OPTIONS = { } def initialize(object_name, method_name, template_object, object = nil) @object_name, @method_name = object_name.to_s.dup, method_name.to_s.dup @@ -994,21 +993,6 @@ module ActionView to_input_field_tag(field_type, options) end - def to_radio_button_tag(tag_value, options = {}) - options = DEFAULT_RADIO_OPTIONS.merge(options.stringify_keys) - options["type"] = "radio" - options["value"] = tag_value - if options.has_key?("checked") - cv = options.delete "checked" - checked = cv == true || cv == "checked" - else - checked = self.class.radio_button_checked?(value(object), tag_value) - end - options["checked"] = "checked" if checked - add_default_name_and_id_for_value(tag_value, options) - tag("input", options) - end - def to_boolean_select_tag(options = {}) options = options.stringify_keys add_default_name_and_id(options) @@ -1066,10 +1050,6 @@ module ActionView object.send(method_name) end end - - def radio_button_checked?(value, checked_value) - value.to_s == checked_value.to_s - end end private diff --git a/actionpack/lib/action_view/helpers/tags.rb b/actionpack/lib/action_view/helpers/tags.rb index 175bc5eb64..0ae7baffc6 100644 --- a/actionpack/lib/action_view/helpers/tags.rb +++ b/actionpack/lib/action_view/helpers/tags.rb @@ -9,6 +9,7 @@ module ActionView autoload :FileField, 'action_view/helpers/tags/file_field' autoload :TextArea, 'action_view/helpers/tags/text_area' autoload :CheckBox, 'action_view/helpers/tags/check_box' + autoload :RadioButton, 'action_view/helpers/tags/radio_button' end end end diff --git a/actionpack/lib/action_view/helpers/tags/base.rb b/actionpack/lib/action_view/helpers/tags/base.rb index 24f66f764e..c50c7716d4 100644 --- a/actionpack/lib/action_view/helpers/tags/base.rb +++ b/actionpack/lib/action_view/helpers/tags/base.rb @@ -24,6 +24,10 @@ module ActionView private + def value(object) + object.send @method_name if object + end + def value_before_type_cast(object) unless object.nil? object.respond_to?(@method_name + "_before_type_cast") ? diff --git a/actionpack/lib/action_view/helpers/tags/check_box.rb b/actionpack/lib/action_view/helpers/tags/check_box.rb index 89aaad632c..55574e6f06 100644 --- a/actionpack/lib/action_view/helpers/tags/check_box.rb +++ b/actionpack/lib/action_view/helpers/tags/check_box.rb @@ -34,10 +34,6 @@ module ActionView private - def value(object) - object.send @method_name if object - end - def check_box_checked?(value) case value when TrueClass, FalseClass diff --git a/actionpack/lib/action_view/helpers/tags/radio_button.rb b/actionpack/lib/action_view/helpers/tags/radio_button.rb new file mode 100644 index 0000000000..3f6a360928 --- /dev/null +++ b/actionpack/lib/action_view/helpers/tags/radio_button.rb @@ -0,0 +1,35 @@ +module ActionView + module Helpers + module Tags + class RadioButton < Base #:nodoc: + def initialize(object_name, method_name, template_object, tag_value, options) + @tag_value = tag_value + super(object_name, method_name, template_object, options) + end + + def render + options = @options.stringify_keys + options["type"] = "radio" + options["value"] = @tag_value + + if options.has_key?("checked") + cv = options.delete "checked" + checked = cv == true || cv == "checked" + else + checked = radio_button_checked?(value(object)) + end + + options["checked"] = "checked" if checked + add_default_name_and_id_for_value(@tag_value, options) + tag("input", options) + end + + private + + def radio_button_checked?(value) + value.to_s == @tag_value.to_s + end + end + end + end +end From 675fb8defdbfdabdd57298b760e701b0b5c74e48 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20Mendon=C3=A7a=20Fran=C3=A7a?= Date: Mon, 16 Jan 2012 21:17:33 -0300 Subject: [PATCH 12/31] Remove code duplication between CheckBox ans RadioButton --- actionpack/lib/action_view/helpers/tags/base.rb | 9 +++++++++ actionpack/lib/action_view/helpers/tags/check_box.rb | 12 +++--------- .../lib/action_view/helpers/tags/radio_button.rb | 12 ++---------- 3 files changed, 14 insertions(+), 19 deletions(-) diff --git a/actionpack/lib/action_view/helpers/tags/base.rb b/actionpack/lib/action_view/helpers/tags/base.rb index c50c7716d4..9f026f69b1 100644 --- a/actionpack/lib/action_view/helpers/tags/base.rb +++ b/actionpack/lib/action_view/helpers/tags/base.rb @@ -47,6 +47,15 @@ module ActionView nil end + def input_checked?(object, options) + if options.has_key?("checked") + checked = options.delete "checked" + checked == true || checked == "checked" + else + checked?(value(object)) + end + end + def retrieve_autoindex(pre_match) object = self.object || @template_object.instance_variable_get("@#{pre_match}") if object && object.respond_to?(:to_param) diff --git a/actionpack/lib/action_view/helpers/tags/check_box.rb b/actionpack/lib/action_view/helpers/tags/check_box.rb index 55574e6f06..2cdc13524b 100644 --- a/actionpack/lib/action_view/helpers/tags/check_box.rb +++ b/actionpack/lib/action_view/helpers/tags/check_box.rb @@ -12,21 +12,15 @@ module ActionView options = @options.stringify_keys options["type"] = "checkbox" options["value"] = @checked_value + options["checked"] = "checked" if input_checked?(object, options) - if options.has_key?("checked") - cv = options.delete "checked" - checked = cv == true || cv == "checked" - else - checked = check_box_checked?(value(object)) - end - - options["checked"] = "checked" if checked if options["multiple"] add_default_name_and_id_for_value(@checked_value, options) options.delete("multiple") else add_default_name_and_id(options) end + hidden = @unchecked_value ? tag("input", "name" => options["name"], "type" => "hidden", "value" => @unchecked_value, "disabled" => options["disabled"]) : "" checkbox = tag("input", options) hidden + checkbox @@ -34,7 +28,7 @@ module ActionView private - def check_box_checked?(value) + def checked?(value) case value when TrueClass, FalseClass value diff --git a/actionpack/lib/action_view/helpers/tags/radio_button.rb b/actionpack/lib/action_view/helpers/tags/radio_button.rb index 3f6a360928..72edd21662 100644 --- a/actionpack/lib/action_view/helpers/tags/radio_button.rb +++ b/actionpack/lib/action_view/helpers/tags/radio_button.rb @@ -11,22 +11,14 @@ module ActionView options = @options.stringify_keys options["type"] = "radio" options["value"] = @tag_value - - if options.has_key?("checked") - cv = options.delete "checked" - checked = cv == true || cv == "checked" - else - checked = radio_button_checked?(value(object)) - end - - options["checked"] = "checked" if checked + options["checked"] = "checked" if input_checked?(object, options) add_default_name_and_id_for_value(@tag_value, options) tag("input", options) end private - def radio_button_checked?(value) + def checked?(value) value.to_s == @tag_value.to_s end end From 487471611b8eab1f1367fa2ef93aed77fb52dee4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20Mendon=C3=A7a=20Fran=C3=A7a?= Date: Mon, 16 Jan 2012 21:25:32 -0300 Subject: [PATCH 13/31] Extract SearchField --- .../lib/action_view/helpers/form_helper.rb | 15 +----------- actionpack/lib/action_view/helpers/tags.rb | 1 + .../action_view/helpers/tags/search_field.rb | 24 +++++++++++++++++++ 3 files changed, 26 insertions(+), 14 deletions(-) create mode 100644 actionpack/lib/action_view/helpers/tags/search_field.rb diff --git a/actionpack/lib/action_view/helpers/form_helper.rb b/actionpack/lib/action_view/helpers/form_helper.rb index 3b15e7097a..4348d36def 100644 --- a/actionpack/lib/action_view/helpers/form_helper.rb +++ b/actionpack/lib/action_view/helpers/form_helper.rb @@ -876,20 +876,7 @@ module ActionView # # => # def search_field(object_name, method, options = {}) - options = options.stringify_keys - - if options["autosave"] - if options["autosave"] == true - options["autosave"] = request.host.split(".").reverse.join(".") - end - options["results"] ||= 10 - end - - if options["onsearch"] - options["incremental"] = true unless options.has_key?("incremental") - end - - InstanceTag.new(object_name, method, self, options.delete("object")).to_input_field_tag("search", options) + ActionView::Helpers::Tags::SearchField.new(object_name, method, self, options).render end # Returns a text_field of type "tel". diff --git a/actionpack/lib/action_view/helpers/tags.rb b/actionpack/lib/action_view/helpers/tags.rb index 0ae7baffc6..a60d263cae 100644 --- a/actionpack/lib/action_view/helpers/tags.rb +++ b/actionpack/lib/action_view/helpers/tags.rb @@ -7,6 +7,7 @@ module ActionView autoload :PasswordField, 'action_view/helpers/tags/password_field' autoload :HiddenField, 'action_view/helpers/tags/hidden_field' autoload :FileField, 'action_view/helpers/tags/file_field' + autoload :SearchField, 'action_view/helpers/tags/search_field' autoload :TextArea, 'action_view/helpers/tags/text_area' autoload :CheckBox, 'action_view/helpers/tags/check_box' autoload :RadioButton, 'action_view/helpers/tags/radio_button' diff --git a/actionpack/lib/action_view/helpers/tags/search_field.rb b/actionpack/lib/action_view/helpers/tags/search_field.rb new file mode 100644 index 0000000000..818fd4b887 --- /dev/null +++ b/actionpack/lib/action_view/helpers/tags/search_field.rb @@ -0,0 +1,24 @@ +module ActionView + module Helpers + module Tags + class SearchField < TextField #:nodoc: + def render + options = @options.stringify_keys + + if options["autosave"] + if options["autosave"] == true + options["autosave"] = request.host.split(".").reverse.join(".") + end + options["results"] ||= 10 + end + + if options["onsearch"] + options["incremental"] = true unless options.has_key?("incremental") + end + + super + end + end + end + end +end From 4cfdd238ed3bc7d4f54faab923dbceeeb7a4bced Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20Mendon=C3=A7a=20Fran=C3=A7a?= Date: Mon, 16 Jan 2012 21:37:31 -0300 Subject: [PATCH 14/31] Extract TelField --- actionpack/lib/action_view/helpers/form_helper.rb | 2 +- actionpack/lib/action_view/helpers/tags.rb | 1 + actionpack/lib/action_view/helpers/tags/tel_field.rb | 8 ++++++++ 3 files changed, 10 insertions(+), 1 deletion(-) create mode 100644 actionpack/lib/action_view/helpers/tags/tel_field.rb diff --git a/actionpack/lib/action_view/helpers/form_helper.rb b/actionpack/lib/action_view/helpers/form_helper.rb index 4348d36def..0626ff4d85 100644 --- a/actionpack/lib/action_view/helpers/form_helper.rb +++ b/actionpack/lib/action_view/helpers/form_helper.rb @@ -885,7 +885,7 @@ module ActionView # # => # def telephone_field(object_name, method, options = {}) - InstanceTag.new(object_name, method, self, options.delete(:object)).to_input_field_tag("tel", options) + ActionView::Helpers::Tags::TelField.new(object_name, method, self, options).render end alias phone_field telephone_field diff --git a/actionpack/lib/action_view/helpers/tags.rb b/actionpack/lib/action_view/helpers/tags.rb index a60d263cae..fcd8f6ff36 100644 --- a/actionpack/lib/action_view/helpers/tags.rb +++ b/actionpack/lib/action_view/helpers/tags.rb @@ -8,6 +8,7 @@ module ActionView autoload :HiddenField, 'action_view/helpers/tags/hidden_field' autoload :FileField, 'action_view/helpers/tags/file_field' autoload :SearchField, 'action_view/helpers/tags/search_field' + autoload :TelField, 'action_view/helpers/tags/tel_field' autoload :TextArea, 'action_view/helpers/tags/text_area' autoload :CheckBox, 'action_view/helpers/tags/check_box' autoload :RadioButton, 'action_view/helpers/tags/radio_button' diff --git a/actionpack/lib/action_view/helpers/tags/tel_field.rb b/actionpack/lib/action_view/helpers/tags/tel_field.rb new file mode 100644 index 0000000000..87c1f6b6b6 --- /dev/null +++ b/actionpack/lib/action_view/helpers/tags/tel_field.rb @@ -0,0 +1,8 @@ +module ActionView + module Helpers + module Tags + class TelField < TextField #:nodoc: + end + end + end +end From 864d7575a3908f14ffc2830a6b2ea78a98756079 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20Mendon=C3=A7a=20Fran=C3=A7a?= Date: Mon, 16 Jan 2012 21:42:54 -0300 Subject: [PATCH 15/31] Extract UrlField --- actionpack/lib/action_view/helpers/form_helper.rb | 2 +- actionpack/lib/action_view/helpers/tags.rb | 1 + actionpack/lib/action_view/helpers/tags/url_field.rb | 8 ++++++++ 3 files changed, 10 insertions(+), 1 deletion(-) create mode 100644 actionpack/lib/action_view/helpers/tags/url_field.rb diff --git a/actionpack/lib/action_view/helpers/form_helper.rb b/actionpack/lib/action_view/helpers/form_helper.rb index 0626ff4d85..110b6b433b 100644 --- a/actionpack/lib/action_view/helpers/form_helper.rb +++ b/actionpack/lib/action_view/helpers/form_helper.rb @@ -895,7 +895,7 @@ module ActionView # # => # def url_field(object_name, method, options = {}) - InstanceTag.new(object_name, method, self, options.delete(:object)).to_input_field_tag("url", options) + ActionView::Helpers::Tags::UrlField.new(object_name, method, self, options).render end # Returns a text_field of type "email". diff --git a/actionpack/lib/action_view/helpers/tags.rb b/actionpack/lib/action_view/helpers/tags.rb index fcd8f6ff36..68bf8910c1 100644 --- a/actionpack/lib/action_view/helpers/tags.rb +++ b/actionpack/lib/action_view/helpers/tags.rb @@ -9,6 +9,7 @@ module ActionView autoload :FileField, 'action_view/helpers/tags/file_field' autoload :SearchField, 'action_view/helpers/tags/search_field' autoload :TelField, 'action_view/helpers/tags/tel_field' + autoload :UrlField, 'action_view/helpers/tags/url_field' autoload :TextArea, 'action_view/helpers/tags/text_area' autoload :CheckBox, 'action_view/helpers/tags/check_box' autoload :RadioButton, 'action_view/helpers/tags/radio_button' diff --git a/actionpack/lib/action_view/helpers/tags/url_field.rb b/actionpack/lib/action_view/helpers/tags/url_field.rb new file mode 100644 index 0000000000..1ffdfe0b3c --- /dev/null +++ b/actionpack/lib/action_view/helpers/tags/url_field.rb @@ -0,0 +1,8 @@ +module ActionView + module Helpers + module Tags + class UrlField < TextField #:nodoc: + end + end + end +end From 647aff9e51dca62ea793c68c5ff830c8b364aa50 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20Mendon=C3=A7a=20Fran=C3=A7a?= Date: Mon, 16 Jan 2012 21:43:06 -0300 Subject: [PATCH 16/31] Extract EmailField --- actionpack/lib/action_view/helpers/form_helper.rb | 2 +- actionpack/lib/action_view/helpers/tags.rb | 1 + actionpack/lib/action_view/helpers/tags/email_field.rb | 8 ++++++++ 3 files changed, 10 insertions(+), 1 deletion(-) create mode 100644 actionpack/lib/action_view/helpers/tags/email_field.rb diff --git a/actionpack/lib/action_view/helpers/form_helper.rb b/actionpack/lib/action_view/helpers/form_helper.rb index 110b6b433b..ab957597cd 100644 --- a/actionpack/lib/action_view/helpers/form_helper.rb +++ b/actionpack/lib/action_view/helpers/form_helper.rb @@ -904,7 +904,7 @@ module ActionView # # => # def email_field(object_name, method, options = {}) - InstanceTag.new(object_name, method, self, options.delete(:object)).to_input_field_tag("email", options) + ActionView::Helpers::Tags::EmailField.new(object_name, method, self, options).render end # Returns an input tag of type "number". diff --git a/actionpack/lib/action_view/helpers/tags.rb b/actionpack/lib/action_view/helpers/tags.rb index 68bf8910c1..eb48625f80 100644 --- a/actionpack/lib/action_view/helpers/tags.rb +++ b/actionpack/lib/action_view/helpers/tags.rb @@ -10,6 +10,7 @@ module ActionView autoload :SearchField, 'action_view/helpers/tags/search_field' autoload :TelField, 'action_view/helpers/tags/tel_field' autoload :UrlField, 'action_view/helpers/tags/url_field' + autoload :EmailField, 'action_view/helpers/tags/email_field' autoload :TextArea, 'action_view/helpers/tags/text_area' autoload :CheckBox, 'action_view/helpers/tags/check_box' autoload :RadioButton, 'action_view/helpers/tags/radio_button' diff --git a/actionpack/lib/action_view/helpers/tags/email_field.rb b/actionpack/lib/action_view/helpers/tags/email_field.rb new file mode 100644 index 0000000000..45cde507d7 --- /dev/null +++ b/actionpack/lib/action_view/helpers/tags/email_field.rb @@ -0,0 +1,8 @@ +module ActionView + module Helpers + module Tags + class EmailField < TextField #:nodoc: + end + end + end +end From 0f49caa6e0544521765fce2010337e3376e18c83 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20Mendon=C3=A7a=20Fran=C3=A7a?= Date: Mon, 16 Jan 2012 21:49:55 -0300 Subject: [PATCH 17/31] Extract NumberField --- .../lib/action_view/helpers/form_helper.rb | 2 +- actionpack/lib/action_view/helpers/tags.rb | 1 + .../action_view/helpers/tags/number_field.rb | 19 +++++++++++++++++++ 3 files changed, 21 insertions(+), 1 deletion(-) create mode 100644 actionpack/lib/action_view/helpers/tags/number_field.rb diff --git a/actionpack/lib/action_view/helpers/form_helper.rb b/actionpack/lib/action_view/helpers/form_helper.rb index ab957597cd..8d0375bf4f 100644 --- a/actionpack/lib/action_view/helpers/form_helper.rb +++ b/actionpack/lib/action_view/helpers/form_helper.rb @@ -912,7 +912,7 @@ module ActionView # ==== Options # * Accepts same options as number_field_tag def number_field(object_name, method, options = {}) - InstanceTag.new(object_name, method, self, options.delete(:object)).to_number_field_tag("number", options) + ActionView::Helpers::Tags::NumberField.new(object_name, method, self, options).render end # Returns an input tag of type "range". diff --git a/actionpack/lib/action_view/helpers/tags.rb b/actionpack/lib/action_view/helpers/tags.rb index eb48625f80..6071ce1913 100644 --- a/actionpack/lib/action_view/helpers/tags.rb +++ b/actionpack/lib/action_view/helpers/tags.rb @@ -11,6 +11,7 @@ module ActionView autoload :TelField, 'action_view/helpers/tags/tel_field' autoload :UrlField, 'action_view/helpers/tags/url_field' autoload :EmailField, 'action_view/helpers/tags/email_field' + autoload :NumberField, 'action_view/helpers/tags/number_field' autoload :TextArea, 'action_view/helpers/tags/text_area' autoload :CheckBox, 'action_view/helpers/tags/check_box' autoload :RadioButton, 'action_view/helpers/tags/radio_button' diff --git a/actionpack/lib/action_view/helpers/tags/number_field.rb b/actionpack/lib/action_view/helpers/tags/number_field.rb new file mode 100644 index 0000000000..e89fdbec46 --- /dev/null +++ b/actionpack/lib/action_view/helpers/tags/number_field.rb @@ -0,0 +1,19 @@ +module ActionView + module Helpers + module Tags + class NumberField < TextField #:nodoc: + def render + options = @options.stringify_keys + options['size'] ||= nil + + if range = options.delete("in") || options.delete("within") + options.update("min" => range.min, "max" => range.max) + end + + @options = options + super + end + end + end + end +end From f0041d4714f264bd72e9aaab055b03a7106c5990 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20Mendon=C3=A7a=20Fran=C3=A7a?= Date: Mon, 16 Jan 2012 21:54:44 -0300 Subject: [PATCH 18/31] Extract RangeField --- actionpack/lib/action_view/helpers/form_helper.rb | 12 +----------- actionpack/lib/action_view/helpers/tags.rb | 1 + .../lib/action_view/helpers/tags/range_field.rb | 8 ++++++++ 3 files changed, 10 insertions(+), 11 deletions(-) create mode 100644 actionpack/lib/action_view/helpers/tags/range_field.rb diff --git a/actionpack/lib/action_view/helpers/form_helper.rb b/actionpack/lib/action_view/helpers/form_helper.rb index 8d0375bf4f..4d45e9d65b 100644 --- a/actionpack/lib/action_view/helpers/form_helper.rb +++ b/actionpack/lib/action_view/helpers/form_helper.rb @@ -920,7 +920,7 @@ module ActionView # ==== Options # * Accepts same options as range_field_tag def range_field(object_name, method, options = {}) - InstanceTag.new(object_name, method, self, options.delete(:object)).to_number_field_tag("range", options) + ActionView::Helpers::Tags::RangeField.new(object_name, method, self, options).render end private @@ -970,16 +970,6 @@ module ActionView tag("input", options) end - def to_number_field_tag(field_type, options = {}) - options = options.stringify_keys - options['size'] ||= nil - - if range = options.delete("in") || options.delete("within") - options.update("min" => range.min, "max" => range.max) - end - to_input_field_tag(field_type, options) - end - def to_boolean_select_tag(options = {}) options = options.stringify_keys add_default_name_and_id(options) diff --git a/actionpack/lib/action_view/helpers/tags.rb b/actionpack/lib/action_view/helpers/tags.rb index 6071ce1913..4dfd81841e 100644 --- a/actionpack/lib/action_view/helpers/tags.rb +++ b/actionpack/lib/action_view/helpers/tags.rb @@ -12,6 +12,7 @@ module ActionView autoload :UrlField, 'action_view/helpers/tags/url_field' autoload :EmailField, 'action_view/helpers/tags/email_field' autoload :NumberField, 'action_view/helpers/tags/number_field' + autoload :RangeField, 'action_view/helpers/tags/range_field' autoload :TextArea, 'action_view/helpers/tags/text_area' autoload :CheckBox, 'action_view/helpers/tags/check_box' autoload :RadioButton, 'action_view/helpers/tags/radio_button' diff --git a/actionpack/lib/action_view/helpers/tags/range_field.rb b/actionpack/lib/action_view/helpers/tags/range_field.rb new file mode 100644 index 0000000000..47db4680e7 --- /dev/null +++ b/actionpack/lib/action_view/helpers/tags/range_field.rb @@ -0,0 +1,8 @@ +module ActionView + module Helpers + module Tags + class RangeField < NumberField #:nodoc: + end + end + end +end From 39dc7fc8aedf7b114064953c6ef166c648cd15a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20Mendon=C3=A7a=20Fran=C3=A7a?= Date: Mon, 16 Jan 2012 22:14:45 -0300 Subject: [PATCH 19/31] Remove unused code --- .../lib/action_view/helpers/form_helper.rb | 31 ------------------- 1 file changed, 31 deletions(-) diff --git a/actionpack/lib/action_view/helpers/form_helper.rb b/actionpack/lib/action_view/helpers/form_helper.rb index 4d45e9d65b..13a0240f33 100644 --- a/actionpack/lib/action_view/helpers/form_helper.rb +++ b/actionpack/lib/action_view/helpers/form_helper.rb @@ -956,37 +956,6 @@ module ActionView @auto_index = retrieve_autoindex(Regexp.last_match.pre_match) if Regexp.last_match end - def to_input_field_tag(field_type, options = {}) - options = options.stringify_keys - options["size"] = options["maxlength"] || DEFAULT_FIELD_OPTIONS["size"] unless options.key?("size") - options = DEFAULT_FIELD_OPTIONS.merge(options) - if field_type == "hidden" - options.delete("size") - end - options["type"] ||= field_type - options["value"] = options.fetch("value"){ value_before_type_cast(object) } unless field_type == "file" - options["value"] &&= ERB::Util.html_escape(options["value"]) - add_default_name_and_id(options) - tag("input", options) - end - - def to_boolean_select_tag(options = {}) - options = options.stringify_keys - add_default_name_and_id(options) - value = value(object) - tag_text = "" - end - - def to_content_tag(tag_name, options = {}) - content_tag(tag_name, value(object), options) - end - def retrieve_object(object) if object object From 18f181db479630679bcc414b8c290b40d8b26781 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20Mendon=C3=A7a=20Fran=C3=A7a?= Date: Mon, 16 Jan 2012 22:54:55 -0300 Subject: [PATCH 20/31] Extract Select --- .../helpers/form_options_helper.rb | 19 +------ actionpack/lib/action_view/helpers/tags.rb | 1 + .../lib/action_view/helpers/tags/select.rb | 57 +++++++++++++++++++ 3 files changed, 59 insertions(+), 18 deletions(-) create mode 100644 actionpack/lib/action_view/helpers/tags/select.rb diff --git a/actionpack/lib/action_view/helpers/form_options_helper.rb b/actionpack/lib/action_view/helpers/form_options_helper.rb index ba9ff1d5aa..8cce6d72cb 100644 --- a/actionpack/lib/action_view/helpers/form_options_helper.rb +++ b/actionpack/lib/action_view/helpers/form_options_helper.rb @@ -154,7 +154,7 @@ module ActionView # key in the query string, that works for ordinary forms. # def select(object, method, choices, options = {}, html_options = {}) - InstanceTag.new(object, method, self, options.delete(:object)).to_select_tag(choices, options, html_options) + ActionView::Helpers::Tags::Select.new(object, method, self, choices, options, html_options).render end # Returns def collection_select(object, method, collection, value_method, text_method, options = {}, html_options = {}) - InstanceTag.new(object, method, self, options.delete(:object)).to_collection_select_tag(collection, value_method, text_method, options, html_options) + ActionView::Helpers::Tags::CollectionSelect.new(object, method, self, collection, value_method, text_method, options, html_options).render end - # Returns # def grouped_collection_select(object, method, collection, group_method, group_label_method, option_key_method, option_value_method, options = {}, html_options = {}) - InstanceTag.new(object, method, self, options.delete(:object)).to_grouped_collection_select_tag(collection, group_method, group_label_method, option_key_method, option_value_method, options, html_options) + ActionView::Helpers::Tags::GroupedCollectionSelect.new(object, method, self, collection, group_method, group_label_method, option_key_method, option_value_method, options, html_options).render end # Return select and option tags for the given object and method, using @@ -575,12 +575,6 @@ module ActionView class InstanceTag #:nodoc: include FormOptionsHelper - def to_grouped_collection_select_tag(collection, group_method, group_label_method, option_key_method, option_value_method, options, html_options) - select_content_tag( - option_groups_from_collection_for_select(collection, group_method, group_label_method, option_key_method, option_value_method, value(object)), options, html_options - ) - end - def to_time_zone_select_tag(priority_zones, options, html_options) select_content_tag( time_zone_options_for_select(value(object) || options[:default], priority_zones, options[:model] || ActiveSupport::TimeZone), options, html_options diff --git a/actionpack/lib/action_view/helpers/tags.rb b/actionpack/lib/action_view/helpers/tags.rb index 9fe373f8c9..5f94a177fd 100644 --- a/actionpack/lib/action_view/helpers/tags.rb +++ b/actionpack/lib/action_view/helpers/tags.rb @@ -1,23 +1,24 @@ module ActionView module Helpers module Tags - autoload :Base, 'action_view/helpers/tags/base' - autoload :Label, 'action_view/helpers/tags/label' - autoload :TextField, 'action_view/helpers/tags/text_field' - autoload :PasswordField, 'action_view/helpers/tags/password_field' - autoload :HiddenField, 'action_view/helpers/tags/hidden_field' - autoload :FileField, 'action_view/helpers/tags/file_field' - autoload :SearchField, 'action_view/helpers/tags/search_field' - autoload :TelField, 'action_view/helpers/tags/tel_field' - autoload :UrlField, 'action_view/helpers/tags/url_field' - autoload :EmailField, 'action_view/helpers/tags/email_field' - autoload :NumberField, 'action_view/helpers/tags/number_field' - autoload :RangeField, 'action_view/helpers/tags/range_field' - autoload :TextArea, 'action_view/helpers/tags/text_area' - autoload :CheckBox, 'action_view/helpers/tags/check_box' - autoload :RadioButton, 'action_view/helpers/tags/radio_button' - autoload :Select, 'action_view/helpers/tags/select' - autoload :CollectionSelect, 'action_view/helpers/tags/collection_select' + autoload :Base, 'action_view/helpers/tags/base' + autoload :Label, 'action_view/helpers/tags/label' + autoload :TextField, 'action_view/helpers/tags/text_field' + autoload :PasswordField, 'action_view/helpers/tags/password_field' + autoload :HiddenField, 'action_view/helpers/tags/hidden_field' + autoload :FileField, 'action_view/helpers/tags/file_field' + autoload :SearchField, 'action_view/helpers/tags/search_field' + autoload :TelField, 'action_view/helpers/tags/tel_field' + autoload :UrlField, 'action_view/helpers/tags/url_field' + autoload :EmailField, 'action_view/helpers/tags/email_field' + autoload :NumberField, 'action_view/helpers/tags/number_field' + autoload :RangeField, 'action_view/helpers/tags/range_field' + autoload :TextArea, 'action_view/helpers/tags/text_area' + autoload :CheckBox, 'action_view/helpers/tags/check_box' + autoload :RadioButton, 'action_view/helpers/tags/radio_button' + autoload :Select, 'action_view/helpers/tags/select' + autoload :CollectionSelect, 'action_view/helpers/tags/collection_select' + autoload :GroupedCollectionSelect, 'action_view/helpers/tags/grouped_collection_select' end end end diff --git a/actionpack/lib/action_view/helpers/tags/grouped_collection_select.rb b/actionpack/lib/action_view/helpers/tags/grouped_collection_select.rb new file mode 100644 index 0000000000..507466a57a --- /dev/null +++ b/actionpack/lib/action_view/helpers/tags/grouped_collection_select.rb @@ -0,0 +1,24 @@ +module ActionView + module Helpers + module Tags + class GroupedCollectionSelect < Base #:nodoc: + def initialize(object_name, method_name, template_object, collection, group_method, group_label_method, option_key_method, option_value_method, options, html_options) + @collection = collection + @group_method = group_method + @group_label_method = group_label_method + @option_key_method = option_key_method + @option_value_method = option_value_method + @html_options = html_options + + super(object_name, method_name, template_object, options) + end + + def render + select_content_tag( + option_groups_from_collection_for_select(@collection, @group_method, @group_label_method, @option_key_method, @option_value_method, value(@object)), @options, @html_options + ) + end + end + end + end +end From 8461ad9744c3fea7db0c4c02af66afa30241ebb2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20Mendon=C3=A7a=20Fran=C3=A7a?= Date: Mon, 16 Jan 2012 23:20:27 -0300 Subject: [PATCH 23/31] Extract TimeZoneSelect --- .../helpers/form_options_helper.rb | 35 +------------------ actionpack/lib/action_view/helpers/tags.rb | 1 + .../helpers/tags/time_zone_select.rb | 20 +++++++++++ 3 files changed, 22 insertions(+), 34 deletions(-) create mode 100644 actionpack/lib/action_view/helpers/tags/time_zone_select.rb diff --git a/actionpack/lib/action_view/helpers/form_options_helper.rb b/actionpack/lib/action_view/helpers/form_options_helper.rb index 8cacbbd791..1252bbff51 100644 --- a/actionpack/lib/action_view/helpers/form_options_helper.rb +++ b/actionpack/lib/action_view/helpers/form_options_helper.rb @@ -273,7 +273,7 @@ module ActionView # # time_zone_select( "user", "time_zone", ActiveSupport::TimeZone.all.sort, :model => ActiveSupport::TimeZone) def time_zone_select(object, method, priority_zones = nil, options = {}, html_options = {}) - InstanceTag.new(object, method, self, options.delete(:object)).to_time_zone_select_tag(priority_zones, options, html_options) + ActionView::Helpers::Tags::TimeZoneSelect.new(object, method, self, priority_zones, options, html_options).render end # Accepts a container (hash, array, enumerable, your type) and returns a string of option tags. Given a container @@ -572,39 +572,6 @@ module ActionView end end - class InstanceTag #:nodoc: - include FormOptionsHelper - - def to_time_zone_select_tag(priority_zones, options, html_options) - select_content_tag( - time_zone_options_for_select(value(object) || options[:default], priority_zones, options[:model] || ActiveSupport::TimeZone), options, html_options - ) - end - - private - def add_options(option_tags, options, value = nil) - if options[:include_blank] - option_tags = "\n" + option_tags - end - if value.blank? && options[:prompt] - prompt = options[:prompt].kind_of?(String) ? options[:prompt] : I18n.translate('helpers.select.prompt', :default => 'Please select') - option_tags = "\n" + option_tags - end - option_tags.html_safe - end - - def select_content_tag(option_tags, options, html_options) - html_options = html_options.stringify_keys - add_default_name_and_id(html_options) - select = content_tag("select", add_options(option_tags, options, value(object)), html_options) - if html_options["multiple"] - tag("input", :disabled => html_options["disabled"], :name => html_options["name"], :type => "hidden", :value => "") + select - else - select - end - end - end - class FormBuilder def select(method, choices, options = {}, html_options = {}) @template.select(@object_name, method, choices, objectify_options(options), @default_options.merge(html_options)) diff --git a/actionpack/lib/action_view/helpers/tags.rb b/actionpack/lib/action_view/helpers/tags.rb index 5f94a177fd..4bcad6da8e 100644 --- a/actionpack/lib/action_view/helpers/tags.rb +++ b/actionpack/lib/action_view/helpers/tags.rb @@ -19,6 +19,7 @@ module ActionView autoload :Select, 'action_view/helpers/tags/select' autoload :CollectionSelect, 'action_view/helpers/tags/collection_select' autoload :GroupedCollectionSelect, 'action_view/helpers/tags/grouped_collection_select' + autoload :TimeZoneSelect, 'action_view/helpers/tags/time_zone_select' end end end diff --git a/actionpack/lib/action_view/helpers/tags/time_zone_select.rb b/actionpack/lib/action_view/helpers/tags/time_zone_select.rb new file mode 100644 index 0000000000..0a176157c3 --- /dev/null +++ b/actionpack/lib/action_view/helpers/tags/time_zone_select.rb @@ -0,0 +1,20 @@ +module ActionView + module Helpers + module Tags + class TimeZoneSelect < Base #:nodoc: + def initialize(object_name, method_name, template_object, priority_zones, options, html_options) + @priority_zones = priority_zones + @html_options = html_options + + super(object_name, method_name, template_object, options) + end + + def render + select_content_tag( + time_zone_options_for_select(value(@object) || @options[:default], @priority_zones, @options[:model] || ActiveSupport::TimeZone), @options, @html_options + ) + end + end + end + end +end From 2a86c14637302edba13f3a268a581c498ce5e079 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20Mendon=C3=A7a=20Fran=C3=A7a?= Date: Mon, 16 Jan 2012 23:31:37 -0300 Subject: [PATCH 24/31] Cleanup --- .../lib/action_view/helpers/form_helper.rb | 73 +------------------ 1 file changed, 1 insertion(+), 72 deletions(-) diff --git a/actionpack/lib/action_view/helpers/form_helper.rb b/actionpack/lib/action_view/helpers/form_helper.rb index 13a0240f33..a6ef05d2eb 100644 --- a/actionpack/lib/action_view/helpers/form_helper.rb +++ b/actionpack/lib/action_view/helpers/form_helper.rb @@ -945,8 +945,6 @@ module ActionView attr_reader :object, :method_name, :object_name - DEFAULT_FIELD_OPTIONS = { "size" => 30 } - def initialize(object_name, method_name, template_object, object = nil) @object_name, @method_name = object_name.to_s.dup, method_name.to_s.dup @template_object = template_object @@ -977,77 +975,8 @@ module ActionView end def value(object) - self.class.value(object, @method_name) + object.send @method_name if object end - - def value_before_type_cast(object) - self.class.value_before_type_cast(object, @method_name) - end - - class << self - def value(object, method_name) - object.send method_name if object - end - - def value_before_type_cast(object, method_name) - unless object.nil? - object.respond_to?(method_name + "_before_type_cast") ? - object.send(method_name + "_before_type_cast") : - object.send(method_name) - end - end - end - - private - def add_default_name_and_id_for_value(tag_value, options) - unless tag_value.nil? - pretty_tag_value = tag_value.to_s.gsub(/\s/, "_").gsub(/[^-\w]/, "").downcase - specified_id = options["id"] - add_default_name_and_id(options) - options["id"] += "_#{pretty_tag_value}" if specified_id.blank? && options["id"].present? - else - add_default_name_and_id(options) - end - end - - def add_default_name_and_id(options) - if options.has_key?("index") - options["name"] ||= tag_name_with_index(options["index"]) - options["id"] = options.fetch("id"){ tag_id_with_index(options["index"]) } - options.delete("index") - elsif defined?(@auto_index) - options["name"] ||= tag_name_with_index(@auto_index) - options["id"] = options.fetch("id"){ tag_id_with_index(@auto_index) } - else - options["name"] ||= tag_name + (options['multiple'] ? '[]' : '') - options["id"] = options.fetch("id"){ tag_id } - end - options["id"] = [options.delete('namespace'), options["id"]].compact.join("_").presence - end - - def tag_name - "#{@object_name}[#{sanitized_method_name}]" - end - - def tag_name_with_index(index) - "#{@object_name}[#{index}][#{sanitized_method_name}]" - end - - def tag_id - "#{sanitized_object_name}_#{sanitized_method_name}" - end - - def tag_id_with_index(index) - "#{sanitized_object_name}_#{index}_#{sanitized_method_name}" - end - - def sanitized_object_name - @sanitized_object_name ||= @object_name.gsub(/\]\[|[^-a-zA-Z0-9:.]/, "_").sub(/_$/, "") - end - - def sanitized_method_name - @sanitized_method_name ||= @method_name.sub(/\?$/,"") - end end class FormBuilder From e70f68fd1ebcb35a9f82b0b3c5a6ea14a4e253cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20Mendon=C3=A7a=20Fran=C3=A7a?= Date: Mon, 16 Jan 2012 23:47:49 -0300 Subject: [PATCH 25/31] Extract DateSelect --- .../helpers/active_model_helper.rb | 2 +- .../lib/action_view/helpers/date_helper.rb | 6 +- actionpack/lib/action_view/helpers/tags.rb | 1 + .../action_view/helpers/tags/date_select.rb | 60 +++++++++++++++++++ 4 files changed, 63 insertions(+), 6 deletions(-) create mode 100644 actionpack/lib/action_view/helpers/tags/date_select.rb diff --git a/actionpack/lib/action_view/helpers/active_model_helper.rb b/actionpack/lib/action_view/helpers/active_model_helper.rb index 56f15604a6..06137f6be6 100644 --- a/actionpack/lib/action_view/helpers/active_model_helper.rb +++ b/actionpack/lib/action_view/helpers/active_model_helper.rb @@ -16,7 +16,7 @@ module ActionView end end - %w(content_tag to_date_select_tag to_datetime_select_tag to_time_select_tag).each do |meth| + %w(content_tag to_datetime_select_tag to_time_select_tag).each do |meth| module_eval "def #{meth}(*) error_wrapping(super) end", __FILE__, __LINE__ end diff --git a/actionpack/lib/action_view/helpers/date_helper.rb b/actionpack/lib/action_view/helpers/date_helper.rb index 2806348337..d1d802de53 100644 --- a/actionpack/lib/action_view/helpers/date_helper.rb +++ b/actionpack/lib/action_view/helpers/date_helper.rb @@ -213,7 +213,7 @@ module ActionView # Note: If the day is not included as an option but the month is, the day will be set to the 1st to ensure that # all month choices are valid. def date_select(object_name, method, options = {}, html_options = {}) - InstanceTag.new(object_name, method, self, options.delete(:object)).to_date_select_tag(options, html_options) + ActionView::Helpers::Tags::DateSelect.new(object_name, method, self, options, html_options).render end # Returns a set of select tags (one for hour, minute and optionally second) pre-selected for accessing a @@ -975,10 +975,6 @@ module ActionView end module DateHelperInstanceTag - def to_date_select_tag(options = {}, html_options = {}) - datetime_selector(options, html_options).select_date.html_safe - end - def to_time_select_tag(options = {}, html_options = {}) datetime_selector(options, html_options).select_time.html_safe end diff --git a/actionpack/lib/action_view/helpers/tags.rb b/actionpack/lib/action_view/helpers/tags.rb index 4bcad6da8e..b81c515c49 100644 --- a/actionpack/lib/action_view/helpers/tags.rb +++ b/actionpack/lib/action_view/helpers/tags.rb @@ -20,6 +20,7 @@ module ActionView autoload :CollectionSelect, 'action_view/helpers/tags/collection_select' autoload :GroupedCollectionSelect, 'action_view/helpers/tags/grouped_collection_select' autoload :TimeZoneSelect, 'action_view/helpers/tags/time_zone_select' + autoload :DateSelect, 'action_view/helpers/tags/date_select' end end end diff --git a/actionpack/lib/action_view/helpers/tags/date_select.rb b/actionpack/lib/action_view/helpers/tags/date_select.rb new file mode 100644 index 0000000000..2f2681bf65 --- /dev/null +++ b/actionpack/lib/action_view/helpers/tags/date_select.rb @@ -0,0 +1,60 @@ +module ActionView + module Helpers + module Tags + class DateSelect < Base #:nodoc: + def initialize(object_name, method_name, template_object, options, html_options) + @html_options = html_options + + super(object_name, method_name, template_object, options) + end + + def render + error_wrapping(datetime_selector(@options, @html_options).select_date.html_safe) + end + + private + + def datetime_selector(options, html_options) + datetime = value(object) || default_datetime(options) + @auto_index ||= nil + + options = options.dup + options[:field_name] = @method_name + options[:include_position] = true + options[:prefix] ||= @object_name + options[:index] = @auto_index if @auto_index && !options.has_key?(:index) + + DateTimeSelector.new(datetime, options, html_options) + end + + def default_datetime(options) + return if options[:include_blank] || options[:prompt] + + case options[:default] + when nil + Time.current + when Date, Time + options[:default] + else + default = options[:default].dup + + # Rename :minute and :second to :min and :sec + default[:min] ||= default[:minute] + default[:sec] ||= default[:second] + + time = Time.current + + [:year, :month, :day, :hour, :min, :sec].each do |key| + default[key] ||= time.send(key) + end + + Time.utc_time( + default[:year], default[:month], default[:day], + default[:hour], default[:min], default[:sec] + ) + end + end + end + end + end +end From b69e449c512d68b54af3d15cdf2d92181c2817d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20Mendon=C3=A7a=20Fran=C3=A7a?= Date: Mon, 16 Jan 2012 23:55:48 -0300 Subject: [PATCH 26/31] Extract TimeSelect --- actionpack/lib/action_view/helpers/active_model_helper.rb | 2 +- actionpack/lib/action_view/helpers/date_helper.rb | 6 +----- actionpack/lib/action_view/helpers/tags.rb | 1 + actionpack/lib/action_view/helpers/tags/date_select.rb | 6 +++++- actionpack/lib/action_view/helpers/tags/time_select.rb | 8 ++++++++ 5 files changed, 16 insertions(+), 7 deletions(-) create mode 100644 actionpack/lib/action_view/helpers/tags/time_select.rb diff --git a/actionpack/lib/action_view/helpers/active_model_helper.rb b/actionpack/lib/action_view/helpers/active_model_helper.rb index 06137f6be6..cb801e50c4 100644 --- a/actionpack/lib/action_view/helpers/active_model_helper.rb +++ b/actionpack/lib/action_view/helpers/active_model_helper.rb @@ -16,7 +16,7 @@ module ActionView end end - %w(content_tag to_datetime_select_tag to_time_select_tag).each do |meth| + %w(content_tag to_datetime_select_tag).each do |meth| module_eval "def #{meth}(*) error_wrapping(super) end", __FILE__, __LINE__ end diff --git a/actionpack/lib/action_view/helpers/date_helper.rb b/actionpack/lib/action_view/helpers/date_helper.rb index d1d802de53..fb80996dfa 100644 --- a/actionpack/lib/action_view/helpers/date_helper.rb +++ b/actionpack/lib/action_view/helpers/date_helper.rb @@ -251,7 +251,7 @@ module ActionView # Note: If the day is not included as an option but the month is, the day will be set to the 1st to ensure that # all month choices are valid. def time_select(object_name, method, options = {}, html_options = {}) - InstanceTag.new(object_name, method, self, options.delete(:object)).to_time_select_tag(options, html_options) + ActionView::Helpers::Tags::TimeSelect.new(object_name, method, self, options, html_options).render end # Returns a set of select tags (one for year, month, day, hour, and minute) pre-selected for accessing a @@ -975,10 +975,6 @@ module ActionView end module DateHelperInstanceTag - def to_time_select_tag(options = {}, html_options = {}) - datetime_selector(options, html_options).select_time.html_safe - end - def to_datetime_select_tag(options = {}, html_options = {}) datetime_selector(options, html_options).select_datetime.html_safe end diff --git a/actionpack/lib/action_view/helpers/tags.rb b/actionpack/lib/action_view/helpers/tags.rb index b81c515c49..cc8af5f417 100644 --- a/actionpack/lib/action_view/helpers/tags.rb +++ b/actionpack/lib/action_view/helpers/tags.rb @@ -21,6 +21,7 @@ module ActionView autoload :GroupedCollectionSelect, 'action_view/helpers/tags/grouped_collection_select' autoload :TimeZoneSelect, 'action_view/helpers/tags/time_zone_select' autoload :DateSelect, 'action_view/helpers/tags/date_select' + autoload :TimeSelect, 'action_view/helpers/tags/time_select' end end end diff --git a/actionpack/lib/action_view/helpers/tags/date_select.rb b/actionpack/lib/action_view/helpers/tags/date_select.rb index 2f2681bf65..5912598ca1 100644 --- a/actionpack/lib/action_view/helpers/tags/date_select.rb +++ b/actionpack/lib/action_view/helpers/tags/date_select.rb @@ -9,11 +9,15 @@ module ActionView end def render - error_wrapping(datetime_selector(@options, @html_options).select_date.html_safe) + error_wrapping(datetime_selector(@options, @html_options).send("select_#{select_type}").html_safe) end private + def select_type + self.class.name.split("::").last.sub("Select", "").downcase + end + def datetime_selector(options, html_options) datetime = value(object) || default_datetime(options) @auto_index ||= nil diff --git a/actionpack/lib/action_view/helpers/tags/time_select.rb b/actionpack/lib/action_view/helpers/tags/time_select.rb new file mode 100644 index 0000000000..9e97deb706 --- /dev/null +++ b/actionpack/lib/action_view/helpers/tags/time_select.rb @@ -0,0 +1,8 @@ +module ActionView + module Helpers + module Tags + class TimeSelect < DateSelect #:nodoc: + end + end + end +end From f6fc352927ca1db03e4c0541a49845ac9e51573a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20Mendon=C3=A7a=20Fran=C3=A7a?= Date: Tue, 17 Jan 2012 00:00:42 -0300 Subject: [PATCH 27/31] Extract DatetimeSelect --- .../helpers/active_model_helper.rb | 2 +- .../lib/action_view/helpers/date_helper.rb | 54 +------------------ actionpack/lib/action_view/helpers/tags.rb | 1 + .../helpers/tags/datetime_select.rb | 8 +++ 4 files changed, 11 insertions(+), 54 deletions(-) create mode 100644 actionpack/lib/action_view/helpers/tags/datetime_select.rb diff --git a/actionpack/lib/action_view/helpers/active_model_helper.rb b/actionpack/lib/action_view/helpers/active_model_helper.rb index cb801e50c4..6a9fbcf0f2 100644 --- a/actionpack/lib/action_view/helpers/active_model_helper.rb +++ b/actionpack/lib/action_view/helpers/active_model_helper.rb @@ -16,7 +16,7 @@ module ActionView end end - %w(content_tag to_datetime_select_tag).each do |meth| + %w(content_tag).each do |meth| module_eval "def #{meth}(*) error_wrapping(super) end", __FILE__, __LINE__ end diff --git a/actionpack/lib/action_view/helpers/date_helper.rb b/actionpack/lib/action_view/helpers/date_helper.rb index fb80996dfa..1456f90520 100644 --- a/actionpack/lib/action_view/helpers/date_helper.rb +++ b/actionpack/lib/action_view/helpers/date_helper.rb @@ -287,7 +287,7 @@ module ActionView # # The selects are prepared for multi-parameter assignment to an Active Record object. def datetime_select(object_name, method, options = {}, html_options = {}) - InstanceTag.new(object_name, method, self, options.delete(:object)).to_datetime_select_tag(options, html_options) + ActionView::Helpers::Tags::DatetimeSelect.new(object_name, method, self, options, html_options).render end # Returns a set of html select-tags (one for year, month, day, hour, minute, and second) pre-selected with the @@ -974,58 +974,6 @@ module ActionView end end - module DateHelperInstanceTag - def to_datetime_select_tag(options = {}, html_options = {}) - datetime_selector(options, html_options).select_datetime.html_safe - end - - private - def datetime_selector(options, html_options) - datetime = value(object) || default_datetime(options) - @auto_index ||= nil - - options = options.dup - options[:field_name] = @method_name - options[:include_position] = true - options[:prefix] ||= @object_name - options[:index] = @auto_index if @auto_index && !options.has_key?(:index) - - DateTimeSelector.new(datetime, options, html_options) - end - - def default_datetime(options) - return if options[:include_blank] || options[:prompt] - - case options[:default] - when nil - Time.current - when Date, Time - options[:default] - else - default = options[:default].dup - - # Rename :minute and :second to :min and :sec - default[:min] ||= default[:minute] - default[:sec] ||= default[:second] - - time = Time.current - - [:year, :month, :day, :hour, :min, :sec].each do |key| - default[key] ||= time.send(key) - end - - Time.utc_time( - default[:year], default[:month], default[:day], - default[:hour], default[:min], default[:sec] - ) - end - end - end - - class InstanceTag #:nodoc: - include DateHelperInstanceTag - end - class FormBuilder def date_select(method, options = {}, html_options = {}) @template.date_select(@object_name, method, objectify_options(options), html_options) diff --git a/actionpack/lib/action_view/helpers/tags.rb b/actionpack/lib/action_view/helpers/tags.rb index cc8af5f417..89b3efda5f 100644 --- a/actionpack/lib/action_view/helpers/tags.rb +++ b/actionpack/lib/action_view/helpers/tags.rb @@ -22,6 +22,7 @@ module ActionView autoload :TimeZoneSelect, 'action_view/helpers/tags/time_zone_select' autoload :DateSelect, 'action_view/helpers/tags/date_select' autoload :TimeSelect, 'action_view/helpers/tags/time_select' + autoload :DatetimeSelect, 'action_view/helpers/tags/datetime_select' end end end diff --git a/actionpack/lib/action_view/helpers/tags/datetime_select.rb b/actionpack/lib/action_view/helpers/tags/datetime_select.rb new file mode 100644 index 0000000000..a32c840bce --- /dev/null +++ b/actionpack/lib/action_view/helpers/tags/datetime_select.rb @@ -0,0 +1,8 @@ +module ActionView + module Helpers + module Tags + class DatetimeSelect < DateSelect #:nodoc: + end + end + end +end From c048f0ba8361a80290c268a351543e00547950b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20Mendon=C3=A7a=20Fran=C3=A7a?= Date: Tue, 17 Jan 2012 00:01:25 -0300 Subject: [PATCH 28/31] Do not need each here anymore --- actionpack/lib/action_view/helpers/active_model_helper.rb | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/actionpack/lib/action_view/helpers/active_model_helper.rb b/actionpack/lib/action_view/helpers/active_model_helper.rb index 6a9fbcf0f2..973135e2ea 100644 --- a/actionpack/lib/action_view/helpers/active_model_helper.rb +++ b/actionpack/lib/action_view/helpers/active_model_helper.rb @@ -16,9 +16,7 @@ module ActionView end end - %w(content_tag).each do |meth| - module_eval "def #{meth}(*) error_wrapping(super) end", __FILE__, __LINE__ - end + module_eval "def content_tag(*) error_wrapping(super) end", __FILE__, __LINE__ def tag(type, options, *) tag_generate_errors?(options) ? error_wrapping(super) : super From ad44ece292d477e05321fff6037a4423c0e53c2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20Mendon=C3=A7a=20Fran=C3=A7a?= Date: Tue, 17 Jan 2012 00:02:08 -0300 Subject: [PATCH 29/31] Remove unused code --- .../lib/action_view/helpers/form_helper.rb | 39 ------------------- 1 file changed, 39 deletions(-) diff --git a/actionpack/lib/action_view/helpers/form_helper.rb b/actionpack/lib/action_view/helpers/form_helper.rb index a6ef05d2eb..0beb6625f7 100644 --- a/actionpack/lib/action_view/helpers/form_helper.rb +++ b/actionpack/lib/action_view/helpers/form_helper.rb @@ -940,45 +940,6 @@ module ActionView end end - class InstanceTag - include Helpers::ActiveModelInstanceTag, Helpers::TagHelper, Helpers::FormTagHelper - - attr_reader :object, :method_name, :object_name - - def initialize(object_name, method_name, template_object, object = nil) - @object_name, @method_name = object_name.to_s.dup, method_name.to_s.dup - @template_object = template_object - - @object_name.sub!(/\[\]$/,"") || @object_name.sub!(/\[\]\]$/,"]") - @object = retrieve_object(object) - @auto_index = retrieve_autoindex(Regexp.last_match.pre_match) if Regexp.last_match - end - - def retrieve_object(object) - if object - object - elsif @template_object.instance_variable_defined?("@#{@object_name}") - @template_object.instance_variable_get("@#{@object_name}") - end - rescue NameError - # As @object_name may contain the nested syntax (item[subobject]) we need to fallback to nil. - nil - end - - def retrieve_autoindex(pre_match) - object = self.object || @template_object.instance_variable_get("@#{pre_match}") - if object && object.respond_to?(:to_param) - object.to_param - else - raise ArgumentError, "object[] naming but object param and @object var don't exist or don't respond to to_param: #{object.inspect}" - end - end - - def value(object) - object.send @method_name if object - end - end - class FormBuilder # The methods which wrap a form helper call. class_attribute :field_helpers From 8b4c74f77cd7fe3f2264c18f4ddc7dd495493c4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20Mendon=C3=A7a=20Fran=C3=A7a?= Date: Tue, 17 Jan 2012 15:07:05 -0300 Subject: [PATCH 30/31] Do not need of ActionView::Helpers scope since we are inside ActionView::Helpers --- .../lib/action_view/helpers/date_helper.rb | 6 ++-- .../lib/action_view/helpers/form_helper.rb | 28 +++++++++---------- .../helpers/form_options_helper.rb | 8 +++--- 3 files changed, 21 insertions(+), 21 deletions(-) diff --git a/actionpack/lib/action_view/helpers/date_helper.rb b/actionpack/lib/action_view/helpers/date_helper.rb index 1456f90520..f5077b034a 100644 --- a/actionpack/lib/action_view/helpers/date_helper.rb +++ b/actionpack/lib/action_view/helpers/date_helper.rb @@ -213,7 +213,7 @@ module ActionView # Note: If the day is not included as an option but the month is, the day will be set to the 1st to ensure that # all month choices are valid. def date_select(object_name, method, options = {}, html_options = {}) - ActionView::Helpers::Tags::DateSelect.new(object_name, method, self, options, html_options).render + Tags::DateSelect.new(object_name, method, self, options, html_options).render end # Returns a set of select tags (one for hour, minute and optionally second) pre-selected for accessing a @@ -251,7 +251,7 @@ module ActionView # Note: If the day is not included as an option but the month is, the day will be set to the 1st to ensure that # all month choices are valid. def time_select(object_name, method, options = {}, html_options = {}) - ActionView::Helpers::Tags::TimeSelect.new(object_name, method, self, options, html_options).render + Tags::TimeSelect.new(object_name, method, self, options, html_options).render end # Returns a set of select tags (one for year, month, day, hour, and minute) pre-selected for accessing a @@ -287,7 +287,7 @@ module ActionView # # The selects are prepared for multi-parameter assignment to an Active Record object. def datetime_select(object_name, method, options = {}, html_options = {}) - ActionView::Helpers::Tags::DatetimeSelect.new(object_name, method, self, options, html_options).render + Tags::DatetimeSelect.new(object_name, method, self, options, html_options).render end # Returns a set of html select-tags (one for year, month, day, hour, minute, and second) pre-selected with the diff --git a/actionpack/lib/action_view/helpers/form_helper.rb b/actionpack/lib/action_view/helpers/form_helper.rb index 0beb6625f7..10277599a0 100644 --- a/actionpack/lib/action_view/helpers/form_helper.rb +++ b/actionpack/lib/action_view/helpers/form_helper.rb @@ -655,7 +655,7 @@ module ActionView # 'Accept Terms.'.html_safe # end def label(object_name, method, content_or_options = nil, options = nil, &block) - ActionView::Helpers::Tags::Label.new(object_name, method, self, content_or_options, options).render(&block) + Tags::Label.new(object_name, method, self, content_or_options, options).render(&block) end # Returns an input tag of the "text" type tailored for accessing a specified attribute (identified by +method+) on an object @@ -677,7 +677,7 @@ module ActionView # # => # def text_field(object_name, method, options = {}) - ActionView::Helpers::Tags::TextField.new(object_name, method, self, options).render + Tags::TextField.new(object_name, method, self, options).render end # Returns an input tag of the "password" type tailored for accessing a specified attribute (identified by +method+) on an object @@ -699,7 +699,7 @@ module ActionView # # => # def password_field(object_name, method, options = {}) - ActionView::Helpers::Tags::PasswordField.new(object_name, method, self, options).render + Tags::PasswordField.new(object_name, method, self, options).render end # Returns a hidden input tag tailored for accessing a specified attribute (identified by +method+) on an object @@ -717,7 +717,7 @@ module ActionView # hidden_field(:user, :token) # # => def hidden_field(object_name, method, options = {}) - ActionView::Helpers::Tags::HiddenField.new(object_name, method, self, options).render + Tags::HiddenField.new(object_name, method, self, options).render end # Returns a file upload input tag tailored for accessing a specified attribute (identified by +method+) on an object @@ -738,7 +738,7 @@ module ActionView # # => # def file_field(object_name, method, options = {}) - ActionView::Helpers::Tags::FileField.new(object_name, method, self, options).render + Tags::FileField.new(object_name, method, self, options).render end # Returns a textarea opening and closing tag set tailored for accessing a specified attribute (identified by +method+) @@ -766,7 +766,7 @@ module ActionView # # #{@entry.body} # # def text_area(object_name, method, options = {}) - ActionView::Helpers::Tags::TextArea.new(object_name, method, self, options).render + Tags::TextArea.new(object_name, method, self, options).render end # Returns a checkbox tag tailored for accessing a specified attribute (identified by +method+) on an object @@ -828,7 +828,7 @@ module ActionView # # # def check_box(object_name, method, options = {}, checked_value = "1", unchecked_value = "0") - ActionView::Helpers::Tags::CheckBox.new(object_name, method, self, checked_value, unchecked_value, options).render + Tags::CheckBox.new(object_name, method, self, checked_value, unchecked_value, options).render end # Returns a radio button tag for accessing a specified attribute (identified by +method+) on an object @@ -850,7 +850,7 @@ module ActionView # # => # # def radio_button(object_name, method, tag_value, options = {}) - ActionView::Helpers::Tags::RadioButton.new(object_name, method, self, tag_value, options).render + Tags::RadioButton.new(object_name, method, self, tag_value, options).render end # Returns an input of type "search" for accessing a specified attribute (identified by +method+) on an object @@ -876,7 +876,7 @@ module ActionView # # => # def search_field(object_name, method, options = {}) - ActionView::Helpers::Tags::SearchField.new(object_name, method, self, options).render + Tags::SearchField.new(object_name, method, self, options).render end # Returns a text_field of type "tel". @@ -885,7 +885,7 @@ module ActionView # # => # def telephone_field(object_name, method, options = {}) - ActionView::Helpers::Tags::TelField.new(object_name, method, self, options).render + Tags::TelField.new(object_name, method, self, options).render end alias phone_field telephone_field @@ -895,7 +895,7 @@ module ActionView # # => # def url_field(object_name, method, options = {}) - ActionView::Helpers::Tags::UrlField.new(object_name, method, self, options).render + Tags::UrlField.new(object_name, method, self, options).render end # Returns a text_field of type "email". @@ -904,7 +904,7 @@ module ActionView # # => # def email_field(object_name, method, options = {}) - ActionView::Helpers::Tags::EmailField.new(object_name, method, self, options).render + Tags::EmailField.new(object_name, method, self, options).render end # Returns an input tag of type "number". @@ -912,7 +912,7 @@ module ActionView # ==== Options # * Accepts same options as number_field_tag def number_field(object_name, method, options = {}) - ActionView::Helpers::Tags::NumberField.new(object_name, method, self, options).render + Tags::NumberField.new(object_name, method, self, options).render end # Returns an input tag of type "range". @@ -920,7 +920,7 @@ module ActionView # ==== Options # * Accepts same options as range_field_tag def range_field(object_name, method, options = {}) - ActionView::Helpers::Tags::RangeField.new(object_name, method, self, options).render + Tags::RangeField.new(object_name, method, self, options).render end private diff --git a/actionpack/lib/action_view/helpers/form_options_helper.rb b/actionpack/lib/action_view/helpers/form_options_helper.rb index 1252bbff51..e323350608 100644 --- a/actionpack/lib/action_view/helpers/form_options_helper.rb +++ b/actionpack/lib/action_view/helpers/form_options_helper.rb @@ -154,7 +154,7 @@ module ActionView # key in the query string, that works for ordinary forms. # def select(object, method, choices, options = {}, html_options = {}) - ActionView::Helpers::Tags::Select.new(object, method, self, choices, options, html_options).render + Tags::Select.new(object, method, self, choices, options, html_options).render end # Returns def collection_select(object, method, collection, value_method, text_method, options = {}, html_options = {}) - ActionView::Helpers::Tags::CollectionSelect.new(object, method, self, collection, value_method, text_method, options, html_options).render + Tags::CollectionSelect.new(object, method, self, collection, value_method, text_method, options, html_options).render end # Returns # def grouped_collection_select(object, method, collection, group_method, group_label_method, option_key_method, option_value_method, options = {}, html_options = {}) - ActionView::Helpers::Tags::GroupedCollectionSelect.new(object, method, self, collection, group_method, group_label_method, option_key_method, option_value_method, options, html_options).render + Tags::GroupedCollectionSelect.new(object, method, self, collection, group_method, group_label_method, option_key_method, option_value_method, options, html_options).render end # Return select and option tags for the given object and method, using @@ -273,7 +273,7 @@ module ActionView # # time_zone_select( "user", "time_zone", ActiveSupport::TimeZone.all.sort, :model => ActiveSupport::TimeZone) def time_zone_select(object, method, priority_zones = nil, options = {}, html_options = {}) - ActionView::Helpers::Tags::TimeZoneSelect.new(object, method, self, priority_zones, options, html_options).render + Tags::TimeZoneSelect.new(object, method, self, priority_zones, options, html_options).render end # Accepts a container (hash, array, enumerable, your type) and returns a string of option tags. Given a container From 6f1bf526d7f1869b47f6047c4285c673bb06d0ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20Mendon=C3=A7a=20Fran=C3=A7a?= Date: Tue, 17 Jan 2012 18:52:48 -0300 Subject: [PATCH 31/31] Extract input_checked? to a module --- actionpack/lib/action_view/helpers/tags/base.rb | 9 --------- .../lib/action_view/helpers/tags/check_box.rb | 4 ++++ .../lib/action_view/helpers/tags/checkable.rb | 16 ++++++++++++++++ .../lib/action_view/helpers/tags/radio_button.rb | 4 ++++ 4 files changed, 24 insertions(+), 9 deletions(-) create mode 100644 actionpack/lib/action_view/helpers/tags/checkable.rb diff --git a/actionpack/lib/action_view/helpers/tags/base.rb b/actionpack/lib/action_view/helpers/tags/base.rb index 7580cbe20d..24956beb9c 100644 --- a/actionpack/lib/action_view/helpers/tags/base.rb +++ b/actionpack/lib/action_view/helpers/tags/base.rb @@ -48,15 +48,6 @@ module ActionView nil end - def input_checked?(object, options) - if options.has_key?("checked") - checked = options.delete "checked" - checked == true || checked == "checked" - else - checked?(value(object)) - end - end - def retrieve_autoindex(pre_match) object = self.object || @template_object.instance_variable_get("@#{pre_match}") if object && object.respond_to?(:to_param) diff --git a/actionpack/lib/action_view/helpers/tags/check_box.rb b/actionpack/lib/action_view/helpers/tags/check_box.rb index 2cdc13524b..b3bd6eb2ad 100644 --- a/actionpack/lib/action_view/helpers/tags/check_box.rb +++ b/actionpack/lib/action_view/helpers/tags/check_box.rb @@ -1,7 +1,11 @@ +require 'action_view/helpers/tags/checkable' + module ActionView module Helpers module Tags class CheckBox < Base #:nodoc: + include Checkable + def initialize(object_name, method_name, template_object, checked_value, unchecked_value, options) @checked_value = checked_value @unchecked_value = unchecked_value diff --git a/actionpack/lib/action_view/helpers/tags/checkable.rb b/actionpack/lib/action_view/helpers/tags/checkable.rb new file mode 100644 index 0000000000..b97c0c68d7 --- /dev/null +++ b/actionpack/lib/action_view/helpers/tags/checkable.rb @@ -0,0 +1,16 @@ +module ActionView + module Helpers + module Tags + module Checkable + def input_checked?(object, options) + if options.has_key?("checked") + checked = options.delete "checked" + checked == true || checked == "checked" + else + checked?(value(object)) + end + end + end + end + end +end diff --git a/actionpack/lib/action_view/helpers/tags/radio_button.rb b/actionpack/lib/action_view/helpers/tags/radio_button.rb index 72edd21662..8a0421f061 100644 --- a/actionpack/lib/action_view/helpers/tags/radio_button.rb +++ b/actionpack/lib/action_view/helpers/tags/radio_button.rb @@ -1,7 +1,11 @@ +require 'action_view/helpers/tags/checkable' + module ActionView module Helpers module Tags class RadioButton < Base #:nodoc: + include Checkable + def initialize(object_name, method_name, template_object, tag_value, options) @tag_value = tag_value super(object_name, method_name, template_object, options)