storefront 0.2.1 → 0.2.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (73) hide show
  1. data/Rakefile +2 -2
  2. data/lib/storefront.rb +21 -3
  3. data/lib/storefront/configuration.rb +154 -0
  4. data/lib/storefront/dashboard.rb +8 -7
  5. data/lib/storefront/form.rb +70 -53
  6. data/lib/storefront/form/base.rb +50 -0
  7. data/lib/storefront/form/builder.rb +124 -0
  8. data/lib/storefront/form/errors.rb +20 -46
  9. data/lib/storefront/form/field.rb +102 -0
  10. data/lib/storefront/form/fieldset.rb +44 -0
  11. data/lib/storefront/form/hint.rb +34 -0
  12. data/lib/storefront/form/input.rb +191 -0
  13. data/lib/storefront/form/inputs/checkbox.rb +12 -0
  14. data/lib/storefront/form/inputs/date.rb +16 -0
  15. data/lib/storefront/form/inputs/file.rb +12 -0
  16. data/lib/storefront/form/inputs/hidden.rb +11 -0
  17. data/lib/storefront/form/inputs/radio.rb +11 -0
  18. data/lib/storefront/form/inputs/range.rb +15 -0
  19. data/lib/storefront/form/inputs/select.rb +68 -0
  20. data/lib/storefront/form/inputs/string.rb +89 -0
  21. data/lib/storefront/form/inputs/submit.rb +24 -0
  22. data/lib/storefront/form/inputs/textarea.rb +19 -0
  23. data/lib/storefront/form/inputs/value.rb +16 -0
  24. data/lib/storefront/form/label.rb +35 -0
  25. data/lib/storefront/helpers/attribute_helper.rb +29 -8
  26. data/lib/storefront/helpers/body_helper.rb +1 -1
  27. data/lib/storefront/helpers/cache_helper.rb +2 -2
  28. data/lib/storefront/helpers/component_helper.rb +34 -19
  29. data/lib/storefront/helpers/dashboard_helper.rb +9 -17
  30. data/lib/storefront/helpers/definition_list_helper.rb +82 -14
  31. data/lib/storefront/helpers/form_helper.rb +7 -2
  32. data/lib/storefront/helpers/head_helper.rb +2 -2
  33. data/lib/storefront/helpers/image_helper.rb +1 -25
  34. data/lib/storefront/helpers/list_helper.rb +120 -32
  35. data/lib/storefront/helpers/locale_helper.rb +98 -28
  36. data/lib/storefront/helpers/page_helper.rb +78 -60
  37. data/lib/storefront/helpers/request_helper.rb +3 -0
  38. data/lib/storefront/helpers/table_helper.rb +1 -1
  39. data/lib/storefront/helpers/template_helper.rb +11 -0
  40. data/lib/storefront/helpers/time_helper.rb +2 -2
  41. data/lib/storefront/helpers/widget_helper.rb +153 -2
  42. data/lib/storefront/model_helper.rb +17 -0
  43. data/lib/storefront/proxies/attribute_proxy.rb +150 -0
  44. data/lib/storefront/proxies/model_proxy.rb +249 -0
  45. data/lib/storefront/railtie.rb +4 -2
  46. data/lib/storefront/table.rb +7 -0
  47. data/test/form_helper_test.rb +1 -1
  48. metadata +25 -27
  49. data/init.rb +0 -1
  50. data/lib/storefront/form/elements.rb +0 -101
  51. data/lib/storefront/form/fields.rb +0 -420
  52. data/lib/storefront/form/hints.rb +0 -18
  53. data/lib/storefront/form/inputs.rb +0 -258
  54. data/lib/storefront/form/labels.rb +0 -81
  55. data/lib/storefront/form/model.rb +0 -84
  56. data/lib/storefront/microdata/address.rb +0 -7
  57. data/lib/storefront/microdata/event.rb +0 -13
  58. data/lib/storefront/microdata/geo.rb +0 -7
  59. data/lib/storefront/microdata/organization.rb +0 -7
  60. data/lib/storefront/microdata/person.rb +0 -7
  61. data/lib/storefront/microformat/event.rb +0 -7
  62. data/lib/storefront/microformat/person.rb +0 -7
  63. data/lib/storefront/models/container.rb +0 -0
  64. data/lib/storefront/models/element.rb +0 -15
  65. data/lib/storefront/models/form.rb +0 -0
  66. data/lib/storefront/models/form_element.rb +0 -0
  67. data/lib/storefront/models/link.rb +0 -0
  68. data/lib/storefront/models/list.rb +0 -0
  69. data/lib/storefront/models/list_element.rb +0 -0
  70. data/lib/storefront/models/table.rb +0 -0
  71. data/lib/storefront/models/term.rb +0 -0
  72. data/lib/storefront/models/term_list.rb +0 -0
  73. data/lib/storefront/models/validation.rb +0 -0
@@ -0,0 +1,124 @@
1
+ module Storefront
2
+ class Form
3
+ class Builder < Storefront::Form::Base
4
+ delegate :object, :parent, :to => :model
5
+
6
+ def fieldset(*args, &block)
7
+ options = default_options!(args.extract_options!)
8
+ options[:label] ||= args.shift
9
+
10
+ Storefront::Form::Fieldset.new(options).render(&block)
11
+ end
12
+
13
+ def fields(*args, &block)
14
+ options = args.extract_options!
15
+ options[:as] = :fields
16
+ options[:label] ||= false
17
+ attr_name = args.shift || attribute.name
18
+ template.capture_haml do
19
+ result = field attr_name, options do |_field|
20
+ template.haml_concat fieldset(&block).gsub(/\n$/, "")
21
+ end
22
+ template.haml_concat result.gsub(/\n$/, "")
23
+ end
24
+ end
25
+
26
+ def fields_for(*args, &block)
27
+ options = args.extract_options!
28
+ attribute = args.shift
29
+ macro = model.macro_for(attribute)
30
+ attr_name = nil
31
+
32
+ if options[:as] == :object
33
+ attr_name = attribute.to_s
34
+ else
35
+ attr_name = config.rename_nested_attributes ? "#{attribute}_attributes" : attribute.to_s
36
+ end
37
+
38
+ # do something here for counts
39
+ sub_parent = model.object
40
+ sub_object = args.shift
41
+
42
+ index = options.delete(:index)
43
+
44
+ unless index.present? && index.is_a?(::String)
45
+ if sub_object.blank? && index.present?
46
+ sub_object = sub_parent.send(attribute)[index]
47
+ elsif index.blank? && sub_object.present? && macro == :has_many
48
+ index = sub_parent.send(attribute).index(sub_object)
49
+ end
50
+ end
51
+
52
+ sub_object ||= model.default(attribute) || model.to_s.camelize.constantize.new
53
+ keys = [model.keys, attr_name]
54
+
55
+ model = Storefront::ModelProxy.new(
56
+ :object => sub_object,
57
+ :parent => sub_parent,
58
+ :keys => keys
59
+ )
60
+
61
+ options.merge!(
62
+ :template => template,
63
+ :model => model,
64
+ :parent_index => index,
65
+ :access_keys => access_keys,
66
+ :tabindex => tabindex
67
+ )
68
+ Storefront::Form::Builder.new(options).render(&block)
69
+ end
70
+
71
+ def field(*args, &block)
72
+ options = args.extract_options!
73
+ attribute_name = args.shift || attribute.name
74
+ attribute = Storefront::AttributeProxy.new(
75
+ :name => attribute_name,
76
+ :model => @model,
77
+ :required => options[:required] == true,
78
+ :disabled => options[:disabled] == true,
79
+ :top_level => options[:attribute] == false
80
+ )
81
+
82
+ options.reverse_merge!(
83
+ :template => template,
84
+ :model => model,
85
+ :attribute => attribute,
86
+ :parent_index => parent_index,
87
+ :index => index,
88
+ :field_html => options[:field_html] || {},
89
+ :input_html => options[:input_html] || {},
90
+ :label_html => options[:label_html] || {},
91
+ :error_html => options[:error_html] || {},
92
+ :hint_html => options[:hint_html] || {}
93
+ )
94
+
95
+ Storefront::Form::Field.new(options).render(&block)
96
+ end
97
+
98
+ def button(*args, &block)
99
+ options = args.extract_options!
100
+ options.reverse_merge!(:as => :submit)
101
+ options[:value] = args.shift || "Submit"
102
+ field(options[:value], options, &block)
103
+ end
104
+
105
+ def submit(*args, &block)
106
+ template.capture_haml do
107
+ result = fieldset :class => config.submit_fieldset_class do |fields|
108
+ template.haml_concat fields.button(*args).gsub(/\n$/, "")
109
+ yield(fields) if block_given?
110
+ end
111
+ template.haml_concat result.gsub(/\n$/, "")
112
+ end
113
+ end
114
+
115
+ def partial(path, options = {})
116
+ @template.render :partial => path, :locals => options.merge(:fields => self)
117
+ end
118
+
119
+ def render(&block)
120
+ yield(self)
121
+ end
122
+ end
123
+ end
124
+ end
@@ -1,57 +1,31 @@
1
1
  module Storefront
2
2
  class Form
3
- module Errors
4
- def errors_for(key, options = {})
5
- value = options[:error_attributes].delete(:value)
3
+ class Errors < Storefront::Form::Base
4
+ def initialize(options = {})
5
+ super
6
+
7
+ attributes.merge!(options[:error_html]) if options[:error_html]
8
+ attributes.delete :error_html
9
+ attributes.delete :error
10
+ # error
11
+ merge_class! @attributes, config.error_class
12
+ # aria-invalid = true|grammar|spelling
13
+ # aria-hidden
14
+ attributes[:id] ||= attribute.to_id(:type => :error, :index => index, :parent_index => parent_index) if config.id_enabled_on.include?("error")
15
+ @value = model.errors_for(attribute.name)
16
+ end
17
+
18
+ def render(&block)
6
19
  template.capture_haml do
7
20
  if value.present?
8
- template.haml_tag :output, options[:error_attributes] do
9
- template.haml_concat value.html_safe
21
+ template.haml_tag config.error_tag, attributes do
22
+ template.haml_concat value.join("\n").html_safe.gsub(/\n$/)
10
23
  end
11
- else
12
- template.haml_tag :output, options[:error_attributes]
13
- end
14
- end
15
- end
16
-
17
- def errors_on?(attribute, options = {})
18
-
19
- end
20
-
21
- def required?(attribute)
22
- attribute_sym = attribute.to_s.sub(/_id$/, '').to_sym
23
-
24
- if @object && @object.class.respond_to?(:reflect_on_validations_for)
25
- @object.class.reflect_on_validations_for(attribute_sym).any? do |validation|
26
- (validation.macro == :validates_presence_of || validation.macro == :validates_inclusion_of) &&
27
- validation.name == attribute_sym &&
28
- (validation.options.present? ? options_require_validation?(validation.options) : true)
29
- end
30
- else
31
- if @object && @object.class.respond_to?(:validators_on)
32
- !@object.class.validators_on(attribute_sym).find{|validator| (validator.kind == :presence || validator.kind == :inclusion) && (validator.options.present? ? options_require_validation?(validator.options) : true)}.nil?
33
- else
34
- true
24
+ elsif config.always_include_error_tag
25
+ template.haml_tag config.error_tag, attributes
35
26
  end
36
27
  end
37
28
  end
38
-
39
- def options_require_validation?(options) #nodoc
40
- allow_blank = options[:allow_blank]
41
- return !allow_blank unless allow_blank.nil?
42
- if_condition = !options[:if].nil?
43
- condition = if_condition ? options[:if] : options[:unless]
44
-
45
- condition = if condition.respond_to?(:call)
46
- condition.call(@object)
47
- elsif condition.is_a?(::Symbol) && @object.respond_to?(condition)
48
- @object.send(condition)
49
- else
50
- condition
51
- end
52
-
53
- if_condition ? !!condition : !condition
54
- end
55
29
  end
56
30
  end
57
31
  end
@@ -0,0 +1,102 @@
1
+ module Storefront
2
+ class Form
3
+ # input :name, :as => :string, :class => "string something", :label_method => x, :value_method => y
4
+ # disabled, readonly, accesskey, tabindex
5
+ # button, checkbox, color, date, datetime, datetime-local, email, file, hidden, image, month, number, password, radio, range , reset, search, submit, tel, text, time, url, week
6
+ # input :phone, :mask => /\d\d\d-\d\d\d-\d\d\d\d/, :hint => "Enter your phone number", :tip => "This is so we can call you."
7
+ class Field < Storefront::Form::Builder
8
+ def initialize(options = {})
9
+ super
10
+
11
+ # input type
12
+ options[:as] ||= attribute.input_type(options)
13
+ @input_type = options[:as]
14
+ @inputs = []
15
+
16
+ # class
17
+
18
+ classes = [config.field_class, input_type]
19
+
20
+ unless [:submit, :fieldset].include?(input_type)
21
+ classes += [
22
+ attribute.required? ? config.required_class : config.optional_class,
23
+ attribute.errors? ? config.error_class : config.valid_class,
24
+ ]
25
+ if attribute.validations.present?
26
+ classes << config.validate_class
27
+ end
28
+ end
29
+
30
+ merge_class! attributes, *classes.compact.uniq.map(&:to_s)
31
+
32
+ # id
33
+ if attributes[:id].blank? && config.id_enabled_on.include?("field")
34
+ attributes[:id] = attribute.to_id(:type => :field, :index => index, :parent_index => parent_index)
35
+ end
36
+
37
+ unless [:hidden, :submit].include?(input_type)
38
+ # errors
39
+ @errors = Storefront::Form::Errors.new(options.slice(:error_html, :error, :model, :index, :parent_index, :attribute, :template))
40
+
41
+ # label
42
+ @label = Storefront::Form::Label.new(options.slice(:label_html, :label, :model, :index, :parent_index, :attribute, :template))
43
+
44
+ # hint
45
+ @hints = Storefront::Form::Hint.new(options.slice(:hint_html, :hint, :model, :index, :parent_index, :attribute, :template))
46
+ end
47
+
48
+ unless input_type == :fieldset
49
+ # inputs
50
+ @input_attributes = default_options!.merge(attributes.except(:id, :class, :field_html, :attributes, :error_html, :label_html, :hint_html))
51
+ end
52
+
53
+ merge_class! options[:field_html], attributes[:class]
54
+
55
+ @attributes = options[:field_html].merge(:id => attributes[:id])
56
+ end
57
+
58
+ def input(*args)
59
+ #@tabindex = @tabindex + 1
60
+ options = args.extract_options!
61
+ key = args.shift || attribute.name
62
+ @inputs << input_for(input_type, key, options)
63
+ end
64
+
65
+ def render(&block)
66
+ template.capture_haml do
67
+ template.haml_tag :li, attributes do
68
+ input(attribute.name) unless block_given?
69
+ elements = extract_elements!(attributes)
70
+
71
+ result = elements.map do |element|
72
+ Array(send(element)).map(&:render)
73
+ end
74
+ template.haml_concat result.flatten.join.gsub(/\n$/, "") if result.present?
75
+
76
+ yield(self) if block_given? # template.capture_haml(self, &block)
77
+ end
78
+ end
79
+ end
80
+
81
+ protected
82
+ attr_reader :errors, :labels, :inputs, :hints, :label, :input_type
83
+
84
+ def input_for(key, attribute, options = {})
85
+ Storefront::Form::Input.find(key.to_sym).new(@input_attributes.merge(options))
86
+ end
87
+
88
+ def extract_elements!(options = {})
89
+ elements = []
90
+ if [:hidden, :submit].include?(input_type)
91
+ elements << :inputs
92
+ else
93
+ if @label.present? && @label.value?
94
+ elements << :label
95
+ end
96
+ elements = elements.concat [:inputs, :hints, :errors]
97
+ end
98
+ elements
99
+ end
100
+ end
101
+ end
102
+ end
@@ -0,0 +1,44 @@
1
+ module Storefront
2
+ class Form
3
+ class Fieldset < Storefront::Form::Base
4
+ attr_reader :builder
5
+
6
+ def initialize(options = {})
7
+ super
8
+
9
+ @label = localize(:titles, options[:label], nil, (attributes[:locale_options] || {}).merge(:allow_blank => true)) if options[:label].present?
10
+
11
+ merge_class! attributes, *[
12
+ config.fieldset_class
13
+ ]
14
+
15
+ attributes[:id] ||= label.underscore.strip.gsub(/[_\s]+/, config.separator) if label.present?
16
+ attributes.delete(:index)
17
+ attributes.delete(:parent_index)
18
+ attributes.delete(:label)
19
+
20
+ @builder = Storefront::Form::Builder.new(
21
+ :template => template,
22
+ :model => model,
23
+ :attribute => attribute,
24
+ :index => index,
25
+ :parent_index => parent_index
26
+ )
27
+ end
28
+
29
+ # form.inputs :basic_info, :locale_options => {:count => 1, :past => true}
30
+ def render(&block)
31
+ template.capture_haml do
32
+ template.haml_tag :fieldset, attributes do
33
+ template.haml_tag :legend, :class => config.legend_class do
34
+ template.haml_tag :span, label
35
+ end if label.present?
36
+ template.haml_tag config.field_list_tag, :class => config.list_class do
37
+ builder.render(&block)
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,34 @@
1
+ module Storefront
2
+ class Form
3
+ class Hint < Storefront::Form::Base
4
+ def initialize(options = {})
5
+ super
6
+
7
+ attributes.merge!(options[:hint_html]) if options[:hint_html]
8
+ attributes.delete :hint_html
9
+ attributes.delete :hint
10
+
11
+ unless options[:hint] == false
12
+ merge_class! attributes, config.hint_class
13
+ attributes[:id] ||= attribute.to_id(:type => :hint, :index => index, :parent_index => parent_index) if config.id_enabled_on.include?("hint")
14
+ if config.include_aria && config.hint_is_popup
15
+ attributes[:role] ||= :tooltip
16
+ end
17
+ @value = localize(:hints, attribute.name, options[:hint].is_a?(::String) ? options[:hint] : nil, :allow_blank => true)
18
+ end
19
+ end
20
+
21
+ def render(&block)
22
+ template.capture_haml do
23
+ if value.present?
24
+ template.haml_tag config.hint_tag, attributes do
25
+ template.haml_concat value.html_safe.gsub(/\n$/, "")
26
+ end
27
+ elsif config.always_include_hint_tag
28
+ template.haml_tag config.hint_tag, attributes
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,191 @@
1
+ module Storefront
2
+ class Form
3
+ class Input < Storefront::Form::Base
4
+ class << self
5
+ attr_accessor :resolves
6
+
7
+ def resolves(*input_types)
8
+ @resolves ||= []
9
+ @resolves = @resolves.concat(input_types.flatten.compact).uniq
10
+ end
11
+
12
+ def resolves?(name)
13
+ @resolves ||= []
14
+ @resolves.include?(name)
15
+ end
16
+
17
+ def registry
18
+ @registry ||= Dir[::File.join(::File.dirname(__FILE__), "inputs", "*")].map do |path|
19
+ next unless ::File.extname(path) == ".rb"
20
+ "Storefront::Form::#{::File.basename(path, ::File.extname(path)).camelize}".constantize
21
+ end.compact
22
+ end
23
+
24
+ def find(name)
25
+ registry.detect do |input_class|
26
+ input_class.resolves?(name)
27
+ end
28
+ end
29
+ end
30
+
31
+ def initialize(options = {})
32
+ super
33
+
34
+ # input type
35
+ options[:as] ||= attribute.input_type(options)
36
+ @input_type = options[:as]
37
+ @include_blank = options[:include_blank] != false
38
+ @value = options[:value]
39
+ @dynamic = options[:dynamic] == true
40
+
41
+ classes = [input_type, self.class.name.split("::").last.underscore, attribute.name.to_s.underscore.strip.gsub(/[_\s]+/, config.separator)]
42
+
43
+ if options[:input_html].present?
44
+ classes << options[:input_html].delete(:class)
45
+ end
46
+
47
+ unless [:submit].include?(input_type)
48
+ classes += [
49
+ attribute.required? ? config.required_class : config.optional_class,
50
+ attribute.errors? ? config.error_class : config.valid_class,
51
+ "input"
52
+ ]
53
+
54
+ if attribute.validations.present?
55
+ classes << config.validate_class
56
+ end
57
+ end
58
+
59
+ # class
60
+ merge_class! attributes, *classes.compact.uniq.map(&:to_s)
61
+
62
+ # id
63
+ attributes[:id] ||= attribute.to_id(:index => index, :parent_index => parent_index)
64
+
65
+ # validations
66
+ attributes.merge!(attribute.validations) if config.inline_validations && attribute.validations.present?
67
+ attributes[:placeholder] = options[:placeholder] if options[:placeholder].present?
68
+
69
+ # name
70
+ attributes[:name] ||= attribute.to_param(:index => index, :parent_index => parent_index)
71
+
72
+ # value
73
+ attributes[:value] ||= attribute.value(options[:value])
74
+
75
+ # attributes[:tabindex] = @tabindex
76
+ attributes[:maxlength] = options[:max] if options[:max].present?
77
+
78
+ # expressions
79
+ pattern = options[:match]
80
+ pattern = pattern.source if pattern.is_a?(::Regexp)
81
+ attributes[:"data-match"] = pattern if pattern.present?
82
+ attributes[:"aria-required"] = attribute.required.to_s if attribute.required?
83
+
84
+ # access key
85
+ access_key = attributes[:accesskey] || attribute.access_key
86
+ attributes[:accesskey] = access_key
87
+
88
+ attributes.merge!(options[:input_html]) if options[:input_html]
89
+
90
+ attributes.delete :include_blank
91
+ attributes.delete :input_html
92
+ attributes.delete :include_template
93
+ attributes.delete :as
94
+ attributes.delete :dynamic
95
+ attributes.delete :max
96
+ attributes.delete :min
97
+ attributes.delete :parent_index
98
+
99
+ attributes[:required] = "true" if attributes.delete(:required) == true
100
+ attributes[:disabled] = "true" if attributes.delete(:disabled) == true
101
+ attributes[:autofocus] = "true" if attributes.delete(:autofocus) == true
102
+ attributes[:"data-dynamic"] = "true" if @dynamic
103
+
104
+ attributes[:title] ||= attributes[:placeholder] if attributes[:placeholder].present?
105
+
106
+ autocomplete = attributes.delete(:autocomplete)
107
+ if autocomplete && config.include_aria
108
+ attributes[:"aria-autocomplete"] = case autocomplete
109
+ when :inline, :list, :both
110
+ autocomplete.to_s
111
+ else
112
+ "both"
113
+ end
114
+ end
115
+ end
116
+
117
+ def render(&block)
118
+ send(:"#{@input_type}_input")
119
+ end
120
+
121
+ protected
122
+ attr_reader :include_blank
123
+
124
+ def simple_input(type, options = {}, &block)
125
+ template.capture_haml do
126
+ template.haml_tag :input, extract_attributes!(type, options), &block
127
+ if @dynamic
128
+ template.haml_tag :ul, :class => "buttons" do
129
+ template.haml_tag :li do
130
+ template.haml_tag :a, config.add_label, :class => :add, :role => :button, :type => :button, :href => "#"
131
+ end
132
+ template.haml_tag :li do
133
+ template.haml_tag :a, config.remove_label, :class => :remove, :role => :button, :type => :button, :href => "#"
134
+ end
135
+ end
136
+ end
137
+ end
138
+ end
139
+
140
+ def rich_input(type, options = {}, &block)
141
+ template.capture_haml do
142
+ result = template.rich_button :inner_html => extract_attributes!(type, options), :as => :input
143
+ template.haml_concat result.gsub(/\n$/, "") if result
144
+ end
145
+ end
146
+
147
+ def extract_attributes!(type, options = {})
148
+ if [:numeric, :string, :password, :text, :phone, :url, :email].include?(type)
149
+ attributes = model.default_string_options(attribute.name, type).merge(self.attributes)
150
+ else
151
+ attributes = self.attributes
152
+ end
153
+
154
+ merge_class! attributes, options.delete(:class)
155
+
156
+ attributes[:type] = input_type_for(type)
157
+
158
+ attributes.merge(options)
159
+ end
160
+
161
+ def base_input(tag, *args, &block)
162
+ options = args.extract_options!
163
+ attributes = self.attributes
164
+ text = args.shift
165
+
166
+ template.capture_haml do
167
+ if block_given?
168
+ template.haml_tag tag, attributes, &block
169
+ else
170
+ if text.present?
171
+ template.haml_tag tag, text, attributes
172
+ else
173
+ template.haml_tag tag, attributes
174
+ end
175
+ end
176
+ end
177
+ end
178
+
179
+ def input_type_for(type)
180
+ case type
181
+ when :password, :text, :url, :email, :file, :textarea, :search, :submit, :radio, :checkbox
182
+ type
183
+ when :phone, :tel
184
+ :tel
185
+ else
186
+ :string
187
+ end
188
+ end
189
+ end
190
+ end
191
+ end