diff options
author | Rafael Mendonça França <rafaelmfranca@gmail.com> | 2012-01-16 17:19:07 -0300 |
---|---|---|
committer | Rafael Mendonça França <rafaelmfranca@gmail.com> | 2012-01-17 00:05:28 -0300 |
commit | e749fb5826d9f119847d2e1d5ec2aff30b00632e (patch) | |
tree | 4940ae00e86704044b6fcdb2d17031d69428c071 /actionpack/lib | |
parent | 21afd9b96d70d1e2b1cffdfb60f7ec64ab240472 (diff) | |
download | rails-e749fb5826d9f119847d2e1d5ec2aff30b00632e.tar.gz rails-e749fb5826d9f119847d2e1d5ec2aff30b00632e.tar.bz2 rails-e749fb5826d9f119847d2e1d5ec2aff30b00632e.zip |
Extract LabelTag
Diffstat (limited to 'actionpack/lib')
-rw-r--r-- | actionpack/lib/action_view/helpers/form_helper.rb | 56 | ||||
-rw-r--r-- | actionpack/lib/action_view/helpers/tags.rb | 7 | ||||
-rw-r--r-- | actionpack/lib/action_view/helpers/tags/label_tag.rb | 147 |
3 files changed, 156 insertions, 54 deletions
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 <a href="/terms">Terms</a>.'.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 |