storefront 0.5.1 → 0.5.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Rakefile +1 -1
- data/lib/storefront.rb +1 -0
- data/lib/storefront/components/form.rb +2 -4
- data/lib/storefront/components/form/base.rb +40 -38
- data/lib/storefront/components/form/builder.rb +98 -96
- data/lib/storefront/components/form/errors.rb +22 -20
- data/lib/storefront/components/form/field.rb +75 -73
- data/lib/storefront/components/form/fieldset.rb +32 -30
- data/lib/storefront/components/form/hint.rb +23 -21
- data/lib/storefront/components/form/input.rb +143 -141
- data/lib/storefront/components/form/inputs.rb +4 -2
- data/lib/storefront/components/form/inputs/checkbox.rb +8 -6
- data/lib/storefront/components/form/inputs/date.rb +9 -7
- data/lib/storefront/components/form/inputs/file.rb +8 -6
- data/lib/storefront/components/form/inputs/hidden.rb +7 -5
- data/lib/storefront/components/form/inputs/radio.rb +6 -4
- data/lib/storefront/components/form/inputs/range.rb +8 -6
- data/lib/storefront/components/form/inputs/select.rb +52 -50
- data/lib/storefront/components/form/inputs/string.rb +64 -62
- data/lib/storefront/components/form/inputs/submit.rb +17 -15
- data/lib/storefront/components/form/inputs/textarea.rb +13 -11
- data/lib/storefront/components/form/inputs/value.rb +11 -9
- data/lib/storefront/components/form/label.rb +24 -22
- metadata +1 -1
data/Rakefile
CHANGED
@@ -5,7 +5,7 @@ require 'rake/gempackagetask'
|
|
5
5
|
spec = Gem::Specification.new do |s|
|
6
6
|
s.name = "storefront"
|
7
7
|
s.authors = ["Lance Pollard"]
|
8
|
-
s.version = "0.5.
|
8
|
+
s.version = "0.5.2"
|
9
9
|
s.description = "Opinionated Forms, Tables, and Widgets for Rails and Sinatra"
|
10
10
|
s.summary = "A simple and semantic FormBuilder, TableBuilder, Locale Interpolator, and Widget API for Rails 3 and Sinatra"
|
11
11
|
s.homepage = "http://github.com/viatropos/storefront"
|
data/lib/storefront.rb
CHANGED
@@ -22,5 +22,6 @@ require "storefront/configuration"
|
|
22
22
|
|
23
23
|
Dir["#{this}/storefront/helpers/**/*"].each { |path| require path unless ::File.directory?(path) }
|
24
24
|
require "storefront/components/base"
|
25
|
+
require "storefront/components/form"
|
25
26
|
Dir["#{this}/storefront/components/**/*"].each { |path| require path unless ::File.directory?(path) }
|
26
27
|
Dir["#{this}/storefront/models/**/*"].each { |path| require path unless ::File.directory?(path) }
|
@@ -1,8 +1,6 @@
|
|
1
|
-
require 'storefront/components/form/base'
|
2
|
-
|
3
1
|
module Storefront
|
4
2
|
module Components
|
5
|
-
class Form < Base
|
3
|
+
class Form < ::Storefront::Components::Base
|
6
4
|
attr_reader :model, :template, :tabindex, :access_keys, :attributes
|
7
5
|
delegate :object, :parent, :to => :model
|
8
6
|
|
@@ -11,7 +9,7 @@ module Storefront
|
|
11
9
|
@template = template
|
12
10
|
@model = Storefront::Model.new(:object => extract_object!(args.shift))
|
13
11
|
@attributes = extract_attributes!(options)
|
14
|
-
@builder = Storefront::Form::Builder.new(
|
12
|
+
@builder = Storefront::Components::Form::Builder.new(
|
15
13
|
:template => template,
|
16
14
|
:tabindex => 1,
|
17
15
|
:access_keys => {},
|
@@ -1,49 +1,51 @@
|
|
1
1
|
module Storefront
|
2
|
-
|
3
|
-
class
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
protected
|
2
|
+
module Components
|
3
|
+
class Form
|
4
|
+
class Base < Storefront::Components::Base
|
5
|
+
include Storefront::Helpers::ContentHelper
|
6
|
+
include Storefront::Helpers::DomHelper
|
7
|
+
|
8
|
+
def initialize(options = {})
|
9
|
+
@template = options[:template]
|
10
|
+
@model = options[:model]
|
11
|
+
@attribute = options[:attribute]
|
12
|
+
@parent_index = options[:parent_index]
|
13
|
+
@index = options[:index]
|
14
|
+
@tabindex = options[:tabindex]
|
15
|
+
@access_keys = options[:access_keys]
|
16
|
+
@attributes = clone_attributes(options.except(:template, :model, :attribute, :access_keys, :index, :tabindex))
|
17
|
+
end
|
19
18
|
|
20
|
-
|
21
|
-
attr_accessor :attributes, :value, :label, :access_keys, :tabindex, :input_type
|
19
|
+
protected
|
22
20
|
|
23
|
-
|
24
|
-
|
25
|
-
options[:index] ||= index
|
26
|
-
options[:attribute] ||= attribute
|
27
|
-
options[:template] ||= template
|
28
|
-
options
|
29
|
-
end
|
21
|
+
attr_accessor :template, :model, :attribute, :index, :parent_index
|
22
|
+
attr_accessor :attributes, :value, :label, :access_keys, :tabindex, :input_type
|
30
23
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
24
|
+
def default_options!(options = {})
|
25
|
+
options[:model] ||= model
|
26
|
+
options[:index] ||= index
|
27
|
+
options[:attribute] ||= attribute
|
28
|
+
options[:template] ||= template
|
29
|
+
options
|
30
|
+
end
|
35
31
|
|
36
|
-
|
37
|
-
|
38
|
-
|
32
|
+
def config
|
33
|
+
Storefront.configuration
|
34
|
+
end
|
35
|
+
alias_method :storefront_config, :config
|
39
36
|
|
40
|
-
|
41
|
-
|
42
|
-
return default.to_s unless default.is_a?(::Symbol)
|
43
|
-
attribute = default
|
37
|
+
def value?
|
38
|
+
@value.present?
|
44
39
|
end
|
40
|
+
|
41
|
+
def localize(key, attribute, default, options = {})
|
42
|
+
if default.present?
|
43
|
+
return default.to_s unless default.is_a?(::Symbol)
|
44
|
+
attribute = default
|
45
|
+
end
|
45
46
|
|
46
|
-
|
47
|
+
t?(attribute, options.reverse_merge(:scope => :"forms.#{key}", :model => model.object))
|
48
|
+
end
|
47
49
|
end
|
48
50
|
end
|
49
51
|
end
|
@@ -1,123 +1,125 @@
|
|
1
1
|
module Storefront
|
2
|
-
|
3
|
-
class
|
4
|
-
|
2
|
+
module Components
|
3
|
+
class Form
|
4
|
+
class Builder < Storefront::Components::Form::Base
|
5
|
+
delegate :object, :parent, :to => :model
|
5
6
|
|
6
|
-
|
7
|
-
|
8
|
-
|
7
|
+
def fieldset(*args, &block)
|
8
|
+
options = default_options!(args.extract_options!)
|
9
|
+
options[:label] ||= args.shift
|
9
10
|
|
10
|
-
|
11
|
-
|
11
|
+
Storefront::Components::Form::Fieldset.new(options).render(&block)
|
12
|
+
end
|
12
13
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
14
|
+
def fields(*args, &block)
|
15
|
+
options = args.extract_options!
|
16
|
+
options[:as] = :fields
|
17
|
+
options[:label] ||= false
|
18
|
+
attr_name = args.shift || attribute.name
|
19
|
+
template.capture_haml do
|
20
|
+
result = field attr_name, options do |_field|
|
21
|
+
template.haml_concat fieldset(&block).gsub(/\n$/, "")
|
22
|
+
end
|
23
|
+
template.haml_concat result.gsub(/\n$/, "")
|
21
24
|
end
|
22
|
-
template.haml_concat result.gsub(/\n$/, "")
|
23
25
|
end
|
24
|
-
end
|
25
26
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
27
|
+
def fields_for(*args, &block)
|
28
|
+
options = args.extract_options!
|
29
|
+
attribute = args.shift
|
30
|
+
macro = model.macro_for(attribute)
|
31
|
+
attr_name = nil
|
31
32
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
33
|
+
if options[:as] == :object
|
34
|
+
attr_name = attribute.to_s
|
35
|
+
else
|
36
|
+
attr_name = config.rename_nested_attributes ? "#{attribute}_attributes" : attribute.to_s
|
37
|
+
end
|
37
38
|
|
38
|
-
|
39
|
-
|
40
|
-
|
39
|
+
# do something here for counts
|
40
|
+
sub_parent = model.object
|
41
|
+
sub_object = args.shift
|
41
42
|
|
42
|
-
|
43
|
+
index = options.delete(:index)
|
43
44
|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
45
|
+
unless index.present? && index.is_a?(::String)
|
46
|
+
if sub_object.blank? && index.present?
|
47
|
+
sub_object = sub_parent.send(attribute)[index]
|
48
|
+
elsif index.blank? && sub_object.present? && macro == :has_many
|
49
|
+
index = sub_parent.send(attribute).index(sub_object)
|
50
|
+
end
|
49
51
|
end
|
50
|
-
end
|
51
52
|
|
52
|
-
|
53
|
-
|
53
|
+
sub_object ||= model.default(attribute) || model.to_s.camelize.constantize.new
|
54
|
+
keys = [model.keys, attr_name]
|
54
55
|
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
56
|
+
model = Storefront::ModelProxy.new(
|
57
|
+
:object => sub_object,
|
58
|
+
:parent => sub_parent,
|
59
|
+
:keys => keys
|
60
|
+
)
|
60
61
|
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
62
|
+
options.merge!(
|
63
|
+
:template => template,
|
64
|
+
:model => model,
|
65
|
+
:parent_index => index,
|
66
|
+
:access_keys => access_keys,
|
67
|
+
:tabindex => tabindex
|
68
|
+
)
|
69
|
+
Storefront::Components::Form::Builder.new(options).render(&block)
|
70
|
+
end
|
70
71
|
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
72
|
+
def field(*args, &block)
|
73
|
+
options = args.extract_options!
|
74
|
+
attribute_name = args.shift || attribute.name
|
75
|
+
attribute = Storefront::Attribute.new(
|
76
|
+
:name => attribute_name,
|
77
|
+
:model => @model,
|
78
|
+
:required => options[:required] == true,
|
79
|
+
:disabled => options[:disabled] == true,
|
80
|
+
:top_level => options[:attribute] == false
|
81
|
+
)
|
81
82
|
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
83
|
+
options.reverse_merge!(
|
84
|
+
:template => template,
|
85
|
+
:model => model,
|
86
|
+
:attribute => attribute,
|
87
|
+
:parent_index => parent_index,
|
88
|
+
:index => index,
|
89
|
+
:field_html => options[:field_html] || {},
|
90
|
+
:input_html => options[:input_html] || {},
|
91
|
+
:label_html => options[:label_html] || {},
|
92
|
+
:error_html => options[:error_html] || {},
|
93
|
+
:hint_html => options[:hint_html] || {}
|
94
|
+
)
|
94
95
|
|
95
|
-
|
96
|
-
|
96
|
+
Storefront::Components::Form::Field.new(options).render(&block)
|
97
|
+
end
|
97
98
|
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
99
|
+
def button(*args, &block)
|
100
|
+
options = args.extract_options!
|
101
|
+
options.reverse_merge!(:as => :submit)
|
102
|
+
options[:value] = args.shift || "Submit"
|
103
|
+
field(options[:value], options, &block)
|
104
|
+
end
|
104
105
|
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
106
|
+
def submit(*args, &block)
|
107
|
+
template.capture_haml do
|
108
|
+
result = fieldset :class => config.submit_fieldset_class do |fields|
|
109
|
+
template.haml_concat fields.button(*args).gsub(/\n$/, "")
|
110
|
+
yield(fields) if block_given?
|
111
|
+
end
|
112
|
+
template.haml_concat result.gsub(/\n$/, "")
|
110
113
|
end
|
111
|
-
template.haml_concat result.gsub(/\n$/, "")
|
112
114
|
end
|
113
|
-
end
|
114
115
|
|
115
|
-
|
116
|
-
|
117
|
-
|
116
|
+
def partial(path, options = {})
|
117
|
+
@template.render :partial => path, :locals => options.merge(:fields => self)
|
118
|
+
end
|
118
119
|
|
119
|
-
|
120
|
-
|
120
|
+
def render(&block)
|
121
|
+
yield(self)
|
122
|
+
end
|
121
123
|
end
|
122
124
|
end
|
123
125
|
end
|
@@ -1,26 +1,28 @@
|
|
1
1
|
module Storefront
|
2
|
-
|
3
|
-
class
|
4
|
-
|
5
|
-
|
2
|
+
module Components
|
3
|
+
class Form
|
4
|
+
class Errors < Storefront::Components::Form::Base
|
5
|
+
def initialize(options = {})
|
6
|
+
super
|
6
7
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
8
|
+
attributes.merge!(options[:error_html]) if options[:error_html]
|
9
|
+
attributes.delete :error_html
|
10
|
+
attributes.delete :error
|
11
|
+
# error
|
12
|
+
merge_class! @attributes, config.error_class
|
13
|
+
# aria-invalid = true|grammar|spelling
|
14
|
+
# aria-hidden
|
15
|
+
attributes[:id] ||= attribute.to_id(:type => :error, :index => index, :parent_index => parent_index) if config.id_enabled_on.include?("error")
|
16
|
+
@value = model.errors_for(attribute.name)
|
17
|
+
end
|
17
18
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
19
|
+
def render(&block)
|
20
|
+
template.capture_haml do
|
21
|
+
if value.present?
|
22
|
+
template.haml_tag config.error_tag, value.join("\n").html_safe.gsub(/\n$/, ""), attributes
|
23
|
+
elsif config.always_include_error_tag
|
24
|
+
template.haml_tag config.error_tag, attributes
|
25
|
+
end
|
24
26
|
end
|
25
27
|
end
|
26
28
|
end
|
@@ -1,101 +1,103 @@
|
|
1
1
|
module Storefront
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
2
|
+
module Components
|
3
|
+
class Form
|
4
|
+
# input :name, :as => :string, :class => "string something", :label_method => x, :value_method => y
|
5
|
+
# disabled, readonly, accesskey, tabindex
|
6
|
+
# button, checkbox, color, date, datetime, datetime-local, email, file, hidden, image, month, number, password, radio, range , reset, search, submit, tel, text, time, url, week
|
7
|
+
# 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."
|
8
|
+
class Field < Storefront::Components::Form::Builder
|
9
|
+
def initialize(options = {})
|
10
|
+
super
|
10
11
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
12
|
+
# input type
|
13
|
+
options[:as] ||= attribute.input_type(options)
|
14
|
+
@input_type = options[:as]
|
15
|
+
@inputs = []
|
15
16
|
|
16
|
-
|
17
|
+
# class
|
17
18
|
|
18
|
-
|
19
|
+
classes = [config.field_class, input_type]
|
19
20
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
21
|
+
unless [:submit, :fieldset].include?(input_type)
|
22
|
+
classes += [
|
23
|
+
attribute.required? ? config.required_class : config.optional_class,
|
24
|
+
attribute.errors? ? config.error_class : config.valid_class,
|
25
|
+
]
|
26
|
+
if options[:validate] != false && attribute.validations.present?
|
27
|
+
classes << config.validate_class
|
28
|
+
end
|
27
29
|
end
|
28
|
-
end
|
29
30
|
|
30
|
-
|
31
|
+
merge_class! attributes, *classes.compact.uniq.map(&:to_s)
|
31
32
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
33
|
+
# id
|
34
|
+
if attributes[:id].blank? && config.id_enabled_on.include?("field")
|
35
|
+
attributes[:id] = attribute.to_id(:type => :field, :index => index, :parent_index => parent_index)
|
36
|
+
end
|
36
37
|
|
37
|
-
|
38
|
-
|
39
|
-
|
38
|
+
unless [:hidden, :submit].include?(input_type)
|
39
|
+
# errors
|
40
|
+
@errors = Storefront::Components::Form::Errors.new(options.slice(:rich_input, :error_html, :error, :model, :index, :parent_index, :attribute, :template))
|
40
41
|
|
41
|
-
|
42
|
-
|
42
|
+
# label
|
43
|
+
@label = Storefront::Components::Form::Label.new(options.slice(:rich_input, :label_html, :label, :model, :index, :parent_index, :attribute, :template))
|
43
44
|
|
44
|
-
|
45
|
-
|
46
|
-
|
45
|
+
# hint
|
46
|
+
@hints = Storefront::Components::Form::Hint.new(options.slice(:rich_input, :hint_html, :hint, :model, :index, :parent_index, :attribute, :template))
|
47
|
+
end
|
47
48
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
49
|
+
unless input_type == :fieldset
|
50
|
+
# inputs
|
51
|
+
@input_attributes = default_options!.merge(attributes.except(:id, :class, :field_html, :attributes, :error_html, :label_html, :hint_html))
|
52
|
+
end
|
52
53
|
|
53
|
-
|
54
|
+
merge_class! options[:field_html], attributes[:class]
|
54
55
|
|
55
|
-
|
56
|
-
|
56
|
+
@attributes = options[:field_html].merge(:id => attributes[:id])
|
57
|
+
end
|
57
58
|
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
59
|
+
def input(*args)
|
60
|
+
#@tabindex = @tabindex + 1
|
61
|
+
options = args.extract_options!
|
62
|
+
key = args.shift || attribute.name
|
63
|
+
@inputs << input_for(input_type, key, options)
|
64
|
+
end
|
64
65
|
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
66
|
+
def render(&block)
|
67
|
+
template.capture_haml do
|
68
|
+
template.haml_tag :li, attributes do
|
69
|
+
input(attribute.name) unless block_given?
|
70
|
+
elements = extract_elements!(attributes)
|
70
71
|
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
72
|
+
result = elements.map do |element|
|
73
|
+
Array(send(element)).map(&:render)
|
74
|
+
end
|
75
|
+
template.haml_concat result.flatten.join.gsub(/\n$/, "") if result.present?
|
75
76
|
|
76
|
-
|
77
|
+
yield(self) if block_given? # template.capture_haml(self, &block)
|
78
|
+
end
|
77
79
|
end
|
78
80
|
end
|
79
|
-
end
|
80
81
|
|
81
|
-
|
82
|
-
|
82
|
+
protected
|
83
|
+
attr_reader :errors, :labels, :inputs, :hints, :label, :input_type
|
83
84
|
|
84
|
-
|
85
|
-
|
86
|
-
|
85
|
+
def input_for(key, attribute, options = {})
|
86
|
+
Storefront::Components::Form::Input.find(key.to_sym).new(@input_attributes.merge(options))
|
87
|
+
end
|
87
88
|
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
89
|
+
def extract_elements!(options = {})
|
90
|
+
elements = []
|
91
|
+
if [:hidden, :submit].include?(input_type)
|
92
|
+
elements << :inputs
|
93
|
+
else
|
94
|
+
if @label.present? && @label.value?
|
95
|
+
elements << :label
|
96
|
+
end
|
97
|
+
elements = elements.concat [:inputs, :hints, :errors]
|
95
98
|
end
|
96
|
-
elements
|
99
|
+
elements
|
97
100
|
end
|
98
|
-
elements
|
99
101
|
end
|
100
102
|
end
|
101
103
|
end
|