visionmedia-dm-forms 0.0.2 → 0.0.3
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/History.rdoc +4 -0
- data/Manifest +19 -16
- data/README.rdoc +4 -33
- data/Rakefile +6 -4
- data/Todo.rdoc +13 -15
- data/dm-forms.gemspec +7 -4
- data/examples/benchmarks.rb +26 -110
- data/examples/login.rb +20 -0
- data/lib/dm-forms.rb +5 -6
- data/lib/dm-forms/base.rb +115 -0
- data/lib/dm-forms/core_ext.rb +27 -22
- data/lib/dm-forms/helpers.rb +83 -0
- data/lib/dm-forms/mixins.rb +8 -0
- data/lib/dm-forms/mixins/descriptions.rb +18 -0
- data/lib/dm-forms/mixins/errors.rb +0 -0
- data/lib/dm-forms/mixins/labels.rb +16 -0
- data/lib/dm-forms/mixins/wrappers.rb +26 -0
- data/lib/dm-forms/tag.rb +67 -134
- data/lib/dm-forms/version.rb +1 -4
- data/spec/functional/helpers_spec.rb +186 -0
- data/spec/functional/mixins/descriptions_spec.rb +19 -0
- data/spec/functional/mixins/labels_spec.rb +19 -0
- data/spec/functional/mixins/wrappers_spec.rb +21 -0
- data/spec/functional/tag_spec.rb +33 -41
- data/spec/integration/datamapper_spec.rb +73 -45
- data/spec/spec_helper.rb +5 -7
- data/tasks/spec.rake +5 -0
- metadata +42 -22
- data/examples/datamapper.rb +0 -37
- data/examples/elements.rb +0 -31
- data/examples/haml.rb +0 -21
- data/examples/login.haml +0 -4
- data/lib/dm-forms/elements.rb +0 -210
- data/lib/dm-forms/model_elements.rb +0 -33
- data/spec/functional/core_ext_spec.rb +0 -56
- data/spec/functional/elements_spec.rb +0 -209
- data/spec/integration/haml_spec.rb +0 -29
data/lib/dm-forms/core_ext.rb
CHANGED
@@ -1,39 +1,44 @@
|
|
1
1
|
|
2
|
-
class
|
3
|
-
|
4
|
-
|
2
|
+
class String
|
3
|
+
|
4
|
+
##
|
5
|
+
# String to bool.
|
6
|
+
|
7
|
+
def to_bool
|
8
|
+
!empty? and self != '0' and self != 'false' and self != 'nil'
|
5
9
|
end
|
6
|
-
|
10
|
+
|
7
11
|
end
|
8
12
|
|
9
|
-
class
|
10
|
-
|
13
|
+
class TrueClass
|
14
|
+
|
11
15
|
##
|
12
|
-
#
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
# 'im_a_simple.String'.humanize # => 'im a simple String'
|
17
|
-
#
|
18
|
-
|
19
|
-
def humanize
|
20
|
-
gsub(/[^a-zA-Z\d]/, ' ') || self
|
16
|
+
# True to bool.
|
17
|
+
|
18
|
+
def to_bool
|
19
|
+
self
|
21
20
|
end
|
22
21
|
|
22
|
+
end
|
23
|
+
|
24
|
+
class FalseClass
|
25
|
+
|
23
26
|
##
|
24
|
-
#
|
27
|
+
# False to bool.
|
25
28
|
|
26
|
-
def
|
27
|
-
|
29
|
+
def to_bool
|
30
|
+
self
|
28
31
|
end
|
32
|
+
|
29
33
|
end
|
30
34
|
|
31
|
-
class
|
35
|
+
class NilClass
|
32
36
|
|
33
37
|
##
|
34
|
-
#
|
38
|
+
# Nil to bool.
|
35
39
|
|
36
|
-
def
|
37
|
-
|
40
|
+
def to_bool
|
41
|
+
false
|
38
42
|
end
|
43
|
+
|
39
44
|
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
|
2
|
+
module DataMapper
|
3
|
+
module Form
|
4
|
+
module Helpers
|
5
|
+
|
6
|
+
def fields_for model, attrs = {}, &block
|
7
|
+
with_form_context model do
|
8
|
+
capture &block
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def submit value = nil, attrs = {}
|
13
|
+
attrs[:value] = value unless value.blank?
|
14
|
+
form_context(nil, self).unbound_submit attrs
|
15
|
+
end
|
16
|
+
|
17
|
+
%w( form fieldset ).each do |type|
|
18
|
+
class_eval <<-EOF
|
19
|
+
def #{type} *args, &block
|
20
|
+
form_context(nil, self).#{type} *args, &block
|
21
|
+
end
|
22
|
+
EOF
|
23
|
+
end
|
24
|
+
|
25
|
+
%w( form_for fieldset_for ).each do |type|
|
26
|
+
class_eval <<-EOF
|
27
|
+
def #{type} model, attrs = {}, &block
|
28
|
+
with_form_context model do
|
29
|
+
#{type.sub(/_for/, '')} attrs, &block
|
30
|
+
end
|
31
|
+
end
|
32
|
+
EOF
|
33
|
+
end
|
34
|
+
|
35
|
+
%w( checkbox button file textarea
|
36
|
+
hidden password radio select textfield ).each do |type|
|
37
|
+
define_method type do |*args|
|
38
|
+
method = bound?(*args) ? :"bound_#{type}" : :"unbound_#{type}"
|
39
|
+
form_context(nil, self).send method, *args
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
#:nodoc:
|
44
|
+
|
45
|
+
def new_form_context *args
|
46
|
+
Base.new *args
|
47
|
+
end
|
48
|
+
|
49
|
+
def form_context *args
|
50
|
+
@__form_context ||= new_form_context *args
|
51
|
+
end
|
52
|
+
|
53
|
+
def with_form_context model, attrs = {}, &block
|
54
|
+
last_context, @__form_context = form_context, new_form_context(model, self)
|
55
|
+
captured = instance_eval &block
|
56
|
+
@__form_context = last_context
|
57
|
+
captured
|
58
|
+
end
|
59
|
+
|
60
|
+
def bound? *args
|
61
|
+
args.first.is_a? Symbol
|
62
|
+
end
|
63
|
+
|
64
|
+
def clear_buffer
|
65
|
+
@buffer = ''
|
66
|
+
end
|
67
|
+
|
68
|
+
def buffer string = nil
|
69
|
+
@buffer ||= ''
|
70
|
+
end
|
71
|
+
|
72
|
+
def capture &block
|
73
|
+
if block.arity > 0
|
74
|
+
yield self
|
75
|
+
else
|
76
|
+
instance_eval &block
|
77
|
+
end
|
78
|
+
buffer
|
79
|
+
end
|
80
|
+
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
|
2
|
+
module DataMapper::Form::Descriptions
|
3
|
+
|
4
|
+
def tag name, contents = nil, attrs = {}, &block
|
5
|
+
description = description_tag attrs
|
6
|
+
super + description
|
7
|
+
end
|
8
|
+
|
9
|
+
def self_closing_tag name, attrs = {}
|
10
|
+
description = description_tag attrs
|
11
|
+
super + description
|
12
|
+
end
|
13
|
+
|
14
|
+
def description_tag attrs = {}
|
15
|
+
(description = attrs.delete(:description)) ? tag(:span, description, :class => 'description') : ''
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
File without changes
|
@@ -0,0 +1,16 @@
|
|
1
|
+
|
2
|
+
module DataMapper::Form::Labels
|
3
|
+
|
4
|
+
def tag name, contents = nil, attrs = {}, &block
|
5
|
+
label_tag(attrs) + super
|
6
|
+
end
|
7
|
+
|
8
|
+
def self_closing_tag name, attrs = {}
|
9
|
+
label_tag(attrs) + super
|
10
|
+
end
|
11
|
+
|
12
|
+
def label_tag attrs = {}
|
13
|
+
(label = attrs.delete(:label)) ? tag(:label, label, :for => attrs[:name]) : ''
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
|
2
|
+
module DataMapper::Form::Wrappers
|
3
|
+
|
4
|
+
def tag name, contents = nil, attrs = {}, &block
|
5
|
+
attrs, contents = contents, nil if contents.is_a? Hash
|
6
|
+
unless name.in? :form, :fieldset, :legend, :span, :div, :option, :optgroup
|
7
|
+
tag(:div, super, :class => wrapper_classes(name, attrs))
|
8
|
+
else
|
9
|
+
super
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def self_closing_tag name, attrs = {}
|
14
|
+
tag :div, super, :class => wrapper_classes(name, attrs)
|
15
|
+
end
|
16
|
+
|
17
|
+
def wrapper_classes name, attrs = {}
|
18
|
+
classes = attrs.include?(:type) ? "form-#{attrs[:type]}" : "form-#{name}"
|
19
|
+
classes.add_class "form-#{classify_name(attrs[:name])}"
|
20
|
+
end
|
21
|
+
|
22
|
+
def classify_name name
|
23
|
+
name.to_s.gsub('[', '-').gsub(']', '')
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
data/lib/dm-forms/tag.rb
CHANGED
@@ -1,156 +1,89 @@
|
|
1
1
|
|
2
2
|
module DataMapper
|
3
3
|
module Form
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
#
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
#
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
#
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
#
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
#
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
# Tag's description.
|
43
|
-
|
44
|
-
attr_accessor :description
|
45
|
-
|
46
|
-
def initialize name, options = {}, &block
|
47
|
-
@name, @options, @attributes = name, options, (options[:attributes] ||= {})
|
48
|
-
@before, @after = attribute(:before, ''), attribute(:after, '')
|
49
|
-
@description = Elements.desc(attribute(:description)) || ''
|
50
|
-
@model = attribute :model
|
51
|
-
(@attributes[:value] ||= '') << Elements.capture_elements(@model, &block) if block_given?
|
4
|
+
module Tag
|
5
|
+
|
6
|
+
#--
|
7
|
+
# Borrowed / adapted from Merb
|
8
|
+
#++
|
9
|
+
|
10
|
+
BOOL_ATTRIBUTES = :selected, :checked, :multiple
|
11
|
+
|
12
|
+
##
|
13
|
+
# Creates a generic tag. You can invoke it a variety of ways.
|
14
|
+
#
|
15
|
+
# tag :div
|
16
|
+
# # <div></div>
|
17
|
+
#
|
18
|
+
# tag :div, 'content'
|
19
|
+
# # <div>content</div>
|
20
|
+
#
|
21
|
+
# tag :div, :class => 'class'
|
22
|
+
# # <div class="class"></div>
|
23
|
+
#
|
24
|
+
# tag :div, 'content', :class => 'class'
|
25
|
+
# # <div class="class">content</div>
|
26
|
+
#
|
27
|
+
# tag :div do
|
28
|
+
# 'content'
|
29
|
+
# end
|
30
|
+
# # <div>content</div>
|
31
|
+
#
|
32
|
+
# tag :div, :class => 'class' do
|
33
|
+
# 'content'
|
34
|
+
# end
|
35
|
+
# # <div class="class">content</div>
|
36
|
+
#
|
37
|
+
|
38
|
+
def tag name, contents = nil, attrs = {}, &block
|
39
|
+
attrs, contents = contents, nil if contents.is_a? Hash
|
40
|
+
contents = yield if block_given?
|
41
|
+
open_tag(name, attrs) + contents.to_s + close_tag(name)
|
52
42
|
end
|
53
43
|
|
54
44
|
##
|
55
|
-
#
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
prepare_boolean_attributes
|
60
|
-
before << label
|
61
|
-
close = self_closing? ? " />" : ">#{inner_html}</#{@name}>"
|
62
|
-
open = "<#{@name} #{@attributes.to_html_attributes}"
|
63
|
-
tag = before << open << close << description << after << "\n"
|
64
|
-
end
|
65
|
-
alias :to_s :render
|
45
|
+
# Creates the opening tag with attributes for the provided +name+
|
46
|
+
# attrs is a hash where all members will be mapped to key="value"
|
47
|
+
#
|
48
|
+
# Note: This tag will need to be closed
|
66
49
|
|
67
|
-
|
68
|
-
|
69
|
-
# utilize :multiple => true, instead of :multiple => :multiple.
|
70
|
-
|
71
|
-
def prepare_boolean_attributes
|
72
|
-
@attributes.each_pair do |key, value|
|
73
|
-
if BOOLEAN_ATTRIBUTES.include? key
|
74
|
-
if value
|
75
|
-
@attributes[key] = key
|
76
|
-
else
|
77
|
-
@attributes.delete key
|
78
|
-
end
|
79
|
-
end
|
80
|
-
end
|
50
|
+
def open_tag name, attrs = {}
|
51
|
+
"<#{name}#{optional_attrs(attrs)}>"
|
81
52
|
end
|
82
53
|
|
83
54
|
##
|
84
|
-
#
|
85
|
-
|
86
|
-
def
|
87
|
-
|
88
|
-
end
|
89
|
-
|
90
|
-
##
|
91
|
-
# The inner HTML of this tag, only available for
|
92
|
-
# elements which are not self-closing.
|
93
|
-
|
94
|
-
def inner_html
|
95
|
-
attribute :value, '' unless self_closing?
|
55
|
+
# Creates a closing tag
|
56
|
+
|
57
|
+
def close_tag name
|
58
|
+
"</#{name}>\n"
|
96
59
|
end
|
97
|
-
|
98
|
-
##
|
99
|
-
# Is the element required.
|
100
60
|
|
101
|
-
def required?
|
102
|
-
attribute :required, false
|
103
|
-
end
|
104
|
-
|
105
61
|
##
|
106
|
-
#
|
62
|
+
# Creates a self closing tag. Like <br/> or <img src="..."/>
|
63
|
+
#
|
64
|
+
# +name+ : the name of the tag to create
|
65
|
+
# +attrs+ : a hash where all members will be mapped to key="value"
|
107
66
|
|
108
|
-
def
|
109
|
-
|
67
|
+
def self_closing_tag name, attrs = {}
|
68
|
+
"<#{name}#{optional_attrs(attrs)}/>\n"
|
110
69
|
end
|
111
70
|
|
112
|
-
##
|
113
|
-
# Wither or not this tag has a label.
|
114
|
-
|
115
|
-
def has_label?
|
116
|
-
!@attributes[:label].blank?
|
117
|
-
end
|
118
|
-
|
119
|
-
##
|
120
|
-
# Returns user generated classes as well as those generated by
|
121
|
-
# dm-forms for styling consistancy.
|
122
|
-
|
123
|
-
def classes
|
124
|
-
@classes ||= [@attributes[:class], generate_classes].join(' ').strip if should_add_classes?
|
125
|
-
end
|
126
|
-
|
127
71
|
private
|
128
72
|
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
classes = "form-#{@name == :input ? @attributes[:type] : @name}"
|
134
|
-
classes << " form-#{@attributes[:name]}" unless @attributes[:name].blank?
|
135
|
-
classes
|
136
|
-
end
|
137
|
-
|
138
|
-
##
|
139
|
-
# Wither or not classes should be added to this element.
|
140
|
-
|
141
|
-
def should_add_classes?
|
142
|
-
!(IGNORE_CLASSES_ON_ELEMENTS.include? @name or IGNORE_CLASSES_ON_ELEMENTS.include? @attributes[:type])
|
73
|
+
#:stopdoc:
|
74
|
+
|
75
|
+
def optional_attrs attrs = {}
|
76
|
+
' ' + boolean_attrs(attrs).to_html_attributes unless attrs.blank?
|
143
77
|
end
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
@attributes.delete(attribute) || default
|
78
|
+
|
79
|
+
def boolean_attrs attrs = {}
|
80
|
+
attrs.each do |key, value|
|
81
|
+
if key.in? BOOL_ATTRIBUTES
|
82
|
+
value.to_bool ? attrs[key] = key : attrs.delete(key)
|
83
|
+
end
|
84
|
+
end
|
152
85
|
end
|
153
|
-
|
86
|
+
|
154
87
|
end
|
155
88
|
end
|
156
|
-
end
|
89
|
+
end
|