merb_helpers 0.4.0
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/LICENSE +20 -0
- data/README +4 -0
- data/Rakefile +37 -0
- data/TODO +5 -0
- data/lib/form_helpers.rb +183 -0
- data/lib/form_model.rb +5 -0
- data/lib/merb_helpers.rb +12 -0
- data/lib/merb_helpers/merbtasks.rb +6 -0
- data/specs/merb_helpers_spec.rb +412 -0
- data/specs/spec_helper.rb +99 -0
- metadata +66 -0
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2007 YOUR NAME
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README
ADDED
data/Rakefile
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake/gempackagetask'
|
3
|
+
|
4
|
+
PLUGIN = "merb_helpers"
|
5
|
+
NAME = "merb_helpers"
|
6
|
+
VERSION = "0.4.0"
|
7
|
+
AUTHOR = "Yehuda Katz"
|
8
|
+
EMAIL = "wycats@gmail.com"
|
9
|
+
HOMEPAGE = "http://merb.rubyforge.org/"
|
10
|
+
SUMMARY = "Helper support for merb (similar to the Rails form helpers)"
|
11
|
+
|
12
|
+
spec = Gem::Specification.new do |s|
|
13
|
+
s.name = NAME
|
14
|
+
s.version = VERSION
|
15
|
+
s.platform = Gem::Platform::RUBY
|
16
|
+
s.has_rdoc = true
|
17
|
+
s.extra_rdoc_files = ["README", "LICENSE", 'TODO']
|
18
|
+
s.summary = SUMMARY
|
19
|
+
s.description = s.summary
|
20
|
+
s.author = AUTHOR
|
21
|
+
s.email = EMAIL
|
22
|
+
s.homepage = HOMEPAGE
|
23
|
+
s.requirements << 'merb'
|
24
|
+
s.require_path = 'lib'
|
25
|
+
s.autorequire = PLUGIN
|
26
|
+
s.files = %w(LICENSE README Rakefile TODO) + Dir.glob("{lib,specs}/**/*")
|
27
|
+
end
|
28
|
+
|
29
|
+
spec.add_dependency("merb", ">=0.4")
|
30
|
+
|
31
|
+
Rake::GemPackageTask.new(spec) do |pkg|
|
32
|
+
pkg.gem_spec = spec
|
33
|
+
end
|
34
|
+
|
35
|
+
task :install => [:package] do
|
36
|
+
sh %{sudo gem install pkg/#{NAME}-#{VERSION}}
|
37
|
+
end
|
data/TODO
ADDED
data/lib/form_helpers.rb
ADDED
@@ -0,0 +1,183 @@
|
|
1
|
+
module Merb
|
2
|
+
module Helpers
|
3
|
+
module Form
|
4
|
+
|
5
|
+
def error_messages_for(obj, error_li = nil, html_class='submittal_failed')
|
6
|
+
return "" unless obj.errors
|
7
|
+
header_message = block_given? ? yield(obj.errors) : "<h2>Form submittal failed because of #{obj.errors.size} problems</h2>"
|
8
|
+
ret = %Q{
|
9
|
+
<div class='#{html_class}'>
|
10
|
+
#{header_message}
|
11
|
+
<ul>
|
12
|
+
}
|
13
|
+
obj.errors.each {|err| ret << (error_li ? error_li.call(err) : "<li>#{err[0]} #{err[1]}</li>") }
|
14
|
+
ret << %Q{
|
15
|
+
</ul>
|
16
|
+
</div>
|
17
|
+
}
|
18
|
+
end
|
19
|
+
|
20
|
+
def obj_from_ivar_or_sym(obj)
|
21
|
+
obj.is_a?(Symbol) ? instance_variable_get("@#{obj}") : obj
|
22
|
+
end
|
23
|
+
|
24
|
+
def tag(tag_name, contents, attrs = {})
|
25
|
+
open_tag(tag_name, attrs) + contents + "</#{tag_name}>"
|
26
|
+
end
|
27
|
+
|
28
|
+
def form_tag(attrs = {}, &block)
|
29
|
+
attrs.merge!( :enctype => "multipart/form-data" ) if attrs.delete(:multipart)
|
30
|
+
fake_form_method = set_form_method(attrs)
|
31
|
+
concat(open_tag("form", attrs), block.binding)
|
32
|
+
concat(generate_fake_form_method(fake_form_method), block.binding) if fake_form_method
|
33
|
+
concat(capture(&block), block.binding)
|
34
|
+
concat("</form>", block.binding)
|
35
|
+
end
|
36
|
+
|
37
|
+
def form_for(obj, attrs={}, &block)
|
38
|
+
obj = obj_from_ivar_or_sym(obj)
|
39
|
+
fake_form_method = set_form_method(attrs, obj)
|
40
|
+
concat(open_tag("form", attrs), block.binding)
|
41
|
+
concat(generate_fake_form_method(fake_form_method), block.binding) if fake_form_method
|
42
|
+
fields_for(obj, attrs, &block)
|
43
|
+
concat("</form>", block.binding)
|
44
|
+
end
|
45
|
+
|
46
|
+
def fields_for(obj, attrs=nil, &block)
|
47
|
+
obj = obj_from_ivar_or_sym(obj)
|
48
|
+
old_obj, @_obj = @_obj, obj
|
49
|
+
@_object_name = "#{@_obj.class}".snake_case
|
50
|
+
old_block, @_block = @_block, block
|
51
|
+
|
52
|
+
concat(capture(&block), block.binding)
|
53
|
+
|
54
|
+
@_obj, @_block = old_obj, old_block
|
55
|
+
end
|
56
|
+
|
57
|
+
def control_name(col)
|
58
|
+
"#{@_object_name}[#{col}]"
|
59
|
+
end
|
60
|
+
|
61
|
+
def control_value(col)
|
62
|
+
@_obj.send(col)
|
63
|
+
end
|
64
|
+
|
65
|
+
def control_name_value(col, attrs)
|
66
|
+
{:name => control_name(col), :value => control_value(col)}.merge(attrs)
|
67
|
+
end
|
68
|
+
|
69
|
+
def text_control(col, attrs = {})
|
70
|
+
errorify_field(attrs, col)
|
71
|
+
text_field(control_name_value(col, attrs))
|
72
|
+
end
|
73
|
+
|
74
|
+
def text_field(attrs = {})
|
75
|
+
attrs.merge!(:type => "text")
|
76
|
+
optional_label(attrs) { self_closing_tag("input", attrs) }
|
77
|
+
end
|
78
|
+
|
79
|
+
def checkbox_control(col, attrs = {})
|
80
|
+
errorify_field(attrs, col)
|
81
|
+
val = @_obj.send(col)
|
82
|
+
attrs.merge!(:value => val ? "1" : "0")
|
83
|
+
attrs.merge!(:checked => "checked") if val
|
84
|
+
checkbox_field(control_name_value(col, attrs))
|
85
|
+
end
|
86
|
+
|
87
|
+
def checkbox_field(attrs = {})
|
88
|
+
attrs.merge!(:type => :checkbox)
|
89
|
+
attrs.add_html_class!("checkbox")
|
90
|
+
optional_label(attrs){self_closing_tag("input", attrs)}
|
91
|
+
end
|
92
|
+
|
93
|
+
def hidden_control(col, attrs = {})
|
94
|
+
attrs.delete(:label)
|
95
|
+
errorify_field(attrs, col)
|
96
|
+
hidden_field(control_name_value(col, attrs))
|
97
|
+
end
|
98
|
+
|
99
|
+
def hidden_field(attrs = {})
|
100
|
+
attrs.delete(:label)
|
101
|
+
attrs.merge!(:type => :hidden)
|
102
|
+
self_closing_tag("input", attrs)
|
103
|
+
end
|
104
|
+
|
105
|
+
def radio_group_control(col, options = {}, attrs = {})
|
106
|
+
errorify_field(attrs, col)
|
107
|
+
val = @_obj.send(col)
|
108
|
+
ret = ""
|
109
|
+
options.each do |opt|
|
110
|
+
hash = {:name => "#{@_object_name}[#{col}]", :value => opt, :label => opt}
|
111
|
+
hash.merge!(:selected => "selected") if val.to_s == opt.to_s
|
112
|
+
ret << radio_field(hash)
|
113
|
+
end
|
114
|
+
ret
|
115
|
+
end
|
116
|
+
|
117
|
+
def radio_field(attrs = {})
|
118
|
+
attrs.merge!(:type => "radio")
|
119
|
+
attrs.add_html_class!("radio")
|
120
|
+
optional_label(attrs){self_closing_tag("input", attrs)}
|
121
|
+
end
|
122
|
+
|
123
|
+
def text_area_control(col, attrs = {})
|
124
|
+
attrs ||= {}
|
125
|
+
errorify_field(attrs, col)
|
126
|
+
text_area_field(control_value(col), attrs.merge(:name => control_name(col)))
|
127
|
+
end
|
128
|
+
|
129
|
+
def text_area_field(val, attrs = {})
|
130
|
+
val ||=""
|
131
|
+
optional_label(attrs) do
|
132
|
+
open_tag("textarea", attrs) +
|
133
|
+
val +
|
134
|
+
"</textarea>"
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
def submit_button(contents, attrs = {})
|
139
|
+
attrs.merge!(:type => "submit")
|
140
|
+
tag("button", contents, attrs)
|
141
|
+
end
|
142
|
+
|
143
|
+
def label(name, contents = "", attrs = {})
|
144
|
+
tag("label", name.to_s + contents, attrs)
|
145
|
+
end
|
146
|
+
|
147
|
+
private
|
148
|
+
# Fake out the browser to send back the method for RESTful stuff.
|
149
|
+
# Fall silently back to post if a method is given that is not supported here
|
150
|
+
def set_form_method(options = {}, obj = nil)
|
151
|
+
options[:method] ||= (!obj || obj.new_record? ? :post : :put)
|
152
|
+
if ![:get,:post].include?(options[:method])
|
153
|
+
fake_form_method = options[:method] if [:put, :delete].include?(options[:method])
|
154
|
+
options[:method] = :post
|
155
|
+
end
|
156
|
+
fake_form_method
|
157
|
+
end
|
158
|
+
|
159
|
+
def generate_fake_form_method(fake_form_method)
|
160
|
+
fake_form_method ? hidden_field(:name => "_method", :value => "#{fake_form_method}") : ""
|
161
|
+
end
|
162
|
+
|
163
|
+
def optional_label(attrs = {})
|
164
|
+
label = attrs.delete(:label) if attrs
|
165
|
+
if label
|
166
|
+
title = label.is_a?(Hash) ? label.delete(:title) : label
|
167
|
+
label(title, yield, label.is_a?(Hash) ? label : {})
|
168
|
+
else
|
169
|
+
yield
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
def errorify_field(attrs, col)
|
174
|
+
attrs.add_html_class!("error") if !@_obj.valid? && @_obj.errors.on(col)
|
175
|
+
end
|
176
|
+
|
177
|
+
end
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
class Merb::ViewContext
|
182
|
+
include Merb::Helpers::Form
|
183
|
+
end
|
data/lib/form_model.rb
ADDED
data/lib/merb_helpers.rb
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
# make sure we're running inside Merb
|
2
|
+
if defined?(Merb::Plugins)
|
3
|
+
|
4
|
+
# Merb gives you a Merb::Plugins.config hash...feel free to put your stuff in your piece of it
|
5
|
+
Merb::Plugins.config[:merb_helpers] = {
|
6
|
+
:chickens => false
|
7
|
+
}
|
8
|
+
|
9
|
+
require 'form_model'
|
10
|
+
require 'form_helpers'
|
11
|
+
Merb::Plugins.add_rakefiles "merb_helpers/merbtasks"
|
12
|
+
end
|
@@ -0,0 +1,412 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper'
|
2
|
+
require 'merb_helpers'
|
3
|
+
|
4
|
+
include Merb::ViewContextMixin
|
5
|
+
include Merb::ErubisCaptureMixin
|
6
|
+
include Merb::Helpers::Form
|
7
|
+
|
8
|
+
describe "error_messages_for" do
|
9
|
+
before :each do
|
10
|
+
@obj = Object.new
|
11
|
+
def @obj.errors() [["foo", "bar"], ["baz", "bat"]] end
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should build default error messages" do
|
15
|
+
errs = error_messages_for(@obj)
|
16
|
+
errs.should include("<h2>Form submittal failed because of 2 problems</h2>")
|
17
|
+
errs.should include("<li>foo bar</li>")
|
18
|
+
errs.should include("<li>baz bat</li>")
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should accept a custom HTML class" do
|
22
|
+
errs = error_messages_for(@obj, nil, "foo")
|
23
|
+
errs.should include("<div class='foo'>")
|
24
|
+
end
|
25
|
+
|
26
|
+
it "should accept a custom header block" do
|
27
|
+
errs = error_messages_for(@obj) {|errs| "<h3>Failure: #{errs.size} issues</h3>"}
|
28
|
+
errs.should include("<h3>Failure: 2 issues</h3>")
|
29
|
+
end
|
30
|
+
|
31
|
+
it "should accept a custom error list item block" do
|
32
|
+
errs = error_messages_for(@obj, proc {|err| "<li>#{err[0]} column: #{err[1]}</li>"})
|
33
|
+
errs.should include("<li>foo column: bar</li>")
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
|
38
|
+
describe "form_tag" do
|
39
|
+
it_should_behave_like "FakeBufferConsumer"
|
40
|
+
|
41
|
+
it "should use the post method by default" do
|
42
|
+
form_tag do
|
43
|
+
_buffer << "CONTENT"
|
44
|
+
end
|
45
|
+
_buffer.should match_tag(:form, :method => "post")
|
46
|
+
_buffer.should include("CONTENT")
|
47
|
+
end
|
48
|
+
|
49
|
+
it "should use the get method if set" do
|
50
|
+
form_tag :method => :get do
|
51
|
+
_buffer << "CONTENT"
|
52
|
+
end
|
53
|
+
_buffer.should match_tag(:form, :method => "get")
|
54
|
+
_buffer.should include("CONTENT")
|
55
|
+
end
|
56
|
+
|
57
|
+
it "should fake out the put method if set" do
|
58
|
+
form_tag :method => :put do
|
59
|
+
_buffer << "CONTENT"
|
60
|
+
end
|
61
|
+
_buffer.should match_tag(:form, :method => "post")
|
62
|
+
_buffer.should match_tag(:input, :type => "hidden", :name => "_method", :value => "put")
|
63
|
+
end
|
64
|
+
|
65
|
+
it "should fake out the delete method if set" do
|
66
|
+
form_tag :method => :delete do
|
67
|
+
_buffer << "CONTENT"
|
68
|
+
end
|
69
|
+
_buffer.should match_tag(:form, :method => "post")
|
70
|
+
_buffer.should match_tag(:input, :type => "hidden", :name => "_method", :value => "delete")
|
71
|
+
end
|
72
|
+
|
73
|
+
it "should silently set method to post if an unsupported method is used" do
|
74
|
+
form_tag :method => :dodgy do
|
75
|
+
_buffer << "CONTENT"
|
76
|
+
end
|
77
|
+
_buffer.should match_tag(:form, :method => "post")
|
78
|
+
_buffer.should_not match_tag(:input, :type => "hidden", :name => "_method", :value => "dodgy")
|
79
|
+
end
|
80
|
+
|
81
|
+
it "should take create a form" do
|
82
|
+
form_tag(:action => "foo", :method => :post) do
|
83
|
+
_buffer << "Hello"
|
84
|
+
end
|
85
|
+
_buffer.should match_tag(:form, :action => "foo", :method => "post")
|
86
|
+
_buffer.should include("Hello")
|
87
|
+
end
|
88
|
+
|
89
|
+
it "should set a form to be mutlipart" do
|
90
|
+
form_tag( :action => "foo", :method => :post, :multipart => true ) do
|
91
|
+
_buffer << "CONTENT"
|
92
|
+
end
|
93
|
+
_buffer.should match_tag( :form, :action => "foo", :method => "post", :enctype => "multipart/form-data")
|
94
|
+
_buffer.should include("CONTENT")
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
describe "form_for" do
|
99
|
+
it_should_behave_like "FakeBufferConsumer"
|
100
|
+
|
101
|
+
it "should wrap the contents in a form tag" do
|
102
|
+
form_for(:obj) do
|
103
|
+
_buffer << "Hello"
|
104
|
+
end
|
105
|
+
_buffer.should match_tag(:form, :method => "post")
|
106
|
+
_buffer.should match_tag(:input, :type => "hidden", :value => "put", :name => "_method")
|
107
|
+
end
|
108
|
+
|
109
|
+
it "should set the method to post be default" do
|
110
|
+
@obj2 = FakeModel2.new
|
111
|
+
form_for(:obj2) do
|
112
|
+
end
|
113
|
+
_buffer.should match_tag(:form, :method => "post")
|
114
|
+
_buffer.should_not match_tag(:input, :type => "hidden", :name => "_method")
|
115
|
+
end
|
116
|
+
|
117
|
+
it "should support PUT if the object passed in is not a new_record? via a hidden field" do
|
118
|
+
form_for(:obj) do
|
119
|
+
end
|
120
|
+
_buffer.should match_tag(:form, :method => "post")
|
121
|
+
_buffer.should match_tag(:input, :type => "hidden", :value => "put", :name => "_method")
|
122
|
+
end
|
123
|
+
|
124
|
+
end
|
125
|
+
|
126
|
+
describe "fields_for" do
|
127
|
+
it_should_behave_like "FakeBufferConsumer"
|
128
|
+
|
129
|
+
it "should dump the contents in the context of the object" do
|
130
|
+
fields_for(:obj) do
|
131
|
+
text_control(:foo).should match_tag(:input, :type => "text", :value => "foowee")
|
132
|
+
_buffer << "Hello"
|
133
|
+
end
|
134
|
+
_buffer.should == "Hello"
|
135
|
+
end
|
136
|
+
|
137
|
+
it "should be able to modify the context midstream" do
|
138
|
+
@obj2 = FakeModel2.new
|
139
|
+
form_for(:obj) do
|
140
|
+
text_control(:foo).should match_tag(:input, :type => "text", :value => "foowee")
|
141
|
+
fields_for(:obj2) do
|
142
|
+
text_control(:foo).should match_tag(:input, :name => "fake_model2[foo]", :type => "text", :value => "foowee2")
|
143
|
+
end
|
144
|
+
text_control(:foo).should match_tag(:input, :type => "text", :value => "foowee")
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
it "should handle an explicit nil attribute" do
|
149
|
+
fields_for(:obj, nil) do
|
150
|
+
_buffer << text_control(:foo)
|
151
|
+
end
|
152
|
+
_buffer.should match_tag(:input, :name => "fake_model[foo]", :value => "foowee", :type => "text")
|
153
|
+
end
|
154
|
+
|
155
|
+
end
|
156
|
+
|
157
|
+
describe "text_field (basic)" do
|
158
|
+
it_should_behave_like "FakeBufferConsumer"
|
159
|
+
|
160
|
+
it "should return a basic text field based on the values passed in" do
|
161
|
+
text_field(:name => "foo", :value => "bar").should match_tag( :input, :type => "text", :name => "foo", :value => "bar")
|
162
|
+
end
|
163
|
+
|
164
|
+
it "should wrap the field in a label if the :label option is passed to the text_field" do
|
165
|
+
result = text_field(:label => "LABEL" )
|
166
|
+
result.should match(/<label>LABEL<input type="text"\s*\/><\/label>/)
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
describe "text_control (data bound)" do
|
171
|
+
it_should_behave_like "FakeBufferConsumer"
|
172
|
+
|
173
|
+
it "should take a string object and return a useful text control" do
|
174
|
+
f = form_for :obj do
|
175
|
+
text_control(:foo).should match_tag(:input, :type => "text", :name => "fake_model[foo]", :value => "foowee")
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
it "should take additional attributes and use them" do
|
180
|
+
form_for :obj do
|
181
|
+
text_control(:foo, :bar => "7").should match_tag(:input, :type => "text", :name => "fake_model[foo]", :value => "foowee", :bar => "7")
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
185
|
+
it "should wrap the text_control in a label if the :label option is passed in" do
|
186
|
+
form_for :obj do
|
187
|
+
_buffer << text_control(:foo, :label => "LABEL")
|
188
|
+
end
|
189
|
+
_buffer.should match(/<label>LABEL<input/)
|
190
|
+
res = _buffer.scan(/<[^>]*>/)
|
191
|
+
res[2].should_not match_tag(:input, :label => "LABEL")
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
describe "checkbox_field (basic)" do
|
196
|
+
it "should return a basic checkbox based on the values passed in" do
|
197
|
+
checkbox_field(:name => "foo", :checked => "checked").should match_tag(:input, :class => "checkbox", :name => "foo", :checked => "checked")
|
198
|
+
end
|
199
|
+
|
200
|
+
it "should wrap the checkbox_field in a label if the :label option is passed in" do
|
201
|
+
result = checkbox_field(:label => "LABEL" )
|
202
|
+
result.should match(/<label>LABEL<input/)
|
203
|
+
res = result.scan(/<[^>]*>/)
|
204
|
+
res[2].should_not match_tag(:input, :label => "LABEL")
|
205
|
+
end
|
206
|
+
end
|
207
|
+
|
208
|
+
describe "checkbox_control (data bound)" do
|
209
|
+
it_should_behave_like "FakeBufferConsumer"
|
210
|
+
|
211
|
+
it "should take a string and return a useful checkbox control" do
|
212
|
+
form_for :obj do
|
213
|
+
checkbox_control(:baz).should match_tag(:input, :type =>"checkbox", :name => "fake_model[baz]", :class => "checkbox", :value => "1", :checked => "checked")
|
214
|
+
checkbox_control(:bat).should match_tag(:input, :type =>"checkbox", :name => "fake_model[bat]", :class => "checkbox", :value => "0")
|
215
|
+
end
|
216
|
+
end
|
217
|
+
|
218
|
+
it "should render controls with errors if their attribute contains an error" do
|
219
|
+
form_for :obj do
|
220
|
+
checkbox_control(:bazbad).should match_tag(:input, :type =>"checkbox", :name => "fake_model[bazbad]",
|
221
|
+
:class => "error checkbox", :value => "1", :checked => "checked")
|
222
|
+
checkbox_control(:batbad).should match_tag(:input, :type =>"checkbox", :name => "fake_model[batbad]",
|
223
|
+
:class => "error checkbox", :value => "0")
|
224
|
+
end
|
225
|
+
end
|
226
|
+
|
227
|
+
it "should wrap the checkbox_control in a label if the label option is passed in" do
|
228
|
+
form_for :obj do
|
229
|
+
_buffer << checkbox_control(:foo, :label => "LABEL")
|
230
|
+
end
|
231
|
+
_buffer.should match( /<label>LABEL<input/ )
|
232
|
+
res = _buffer.scan(/<[^>]*>/)
|
233
|
+
res[2].should_not match_tag(:input, :label => "LABEL")
|
234
|
+
end
|
235
|
+
end
|
236
|
+
|
237
|
+
describe "hidden_field (basic)" do
|
238
|
+
|
239
|
+
it "should return a basic checkbox based on the values passed in" do
|
240
|
+
hidden_field(:name => "foo", :value => "bar").should match_tag(:input, :type => "hidden", :name => "foo", :value => "bar")
|
241
|
+
end
|
242
|
+
|
243
|
+
it "should not render a label if the :label option is passed in" do
|
244
|
+
res = hidden_field(:label => "LABEL")
|
245
|
+
res.should_not match(/<label>LABEL/)
|
246
|
+
res.should_not match_tag(:input, :label=> "LABEL")
|
247
|
+
end
|
248
|
+
end
|
249
|
+
|
250
|
+
describe "hidden_control (data bound)" do
|
251
|
+
it_should_behave_like "FakeBufferConsumer"
|
252
|
+
|
253
|
+
it "should take a string and return a useful checkbox control" do
|
254
|
+
form_for :obj do
|
255
|
+
hidden_control(:foo).should match_tag(:input, :type =>"hidden", :name => "fake_model[foo]", :value => "foowee")
|
256
|
+
end
|
257
|
+
end
|
258
|
+
|
259
|
+
it "should render controls with errors if their attribute contains an error" do
|
260
|
+
form_for :obj do
|
261
|
+
hidden_control(:foobad).should match_tag(:input, :type =>"hidden", :name => "fake_model[foobad]", :value => "foowee", :class => "error")
|
262
|
+
end
|
263
|
+
end
|
264
|
+
|
265
|
+
it "should not render a label if the :label option is passed in" do
|
266
|
+
form_for :obj do
|
267
|
+
res = hidden_control(:foo, :label => "LABEL")
|
268
|
+
res.should_not match(/<label>LABEL/)
|
269
|
+
res.should_not match_tag(:input, :label=> "LABEL")
|
270
|
+
end
|
271
|
+
end
|
272
|
+
|
273
|
+
end
|
274
|
+
|
275
|
+
describe "radio button (basic)" do
|
276
|
+
it "should should return a basic radio button based on the values passed in" do
|
277
|
+
radio_field(:name => "foo", :value => "bar").should match_tag(:input, :type => "radio", :name => "foo", :value => "bar")
|
278
|
+
end
|
279
|
+
|
280
|
+
it "should render a label when the label is passed in" do
|
281
|
+
result = radio_field(:name => "foo", :value => "bar", :label => "LABEL")
|
282
|
+
result.should match(/<label>LABEL<input/)
|
283
|
+
res = result.scan(/<[^>]*>/)
|
284
|
+
res[2].should_not match_tag(:input, :label => "LABEL")
|
285
|
+
end
|
286
|
+
|
287
|
+
end
|
288
|
+
|
289
|
+
describe "radio button groups (data bound)" do
|
290
|
+
it_should_behave_like "FakeBufferConsumer"
|
291
|
+
|
292
|
+
it "should return a group of radio buttons" do
|
293
|
+
form_for :obj do
|
294
|
+
radio = radio_group_control(:foo, [:foowee, :baree]).scan(/<[^>]*>/)
|
295
|
+
radio[1].should match_tag(:input, :type => "radio", :name => "fake_model[foo]", :value => "foowee", :selected => "selected")
|
296
|
+
radio[4].should match_tag(:input, :type => "radio", :name => "fake_model[foo]", :value => "baree")
|
297
|
+
radio[2].should not_match_tag(:selected => "selected")
|
298
|
+
end
|
299
|
+
end
|
300
|
+
|
301
|
+
it "should wrap the each radio button in the group in a label corresponding to the options" do
|
302
|
+
form_for :obj do
|
303
|
+
radio = radio_group_control(:foo, [:foowee, :baree])
|
304
|
+
radio.scan( /<label>(foowee|baree)<input/ ).size.should == 2
|
305
|
+
radio = radio.scan(/<[^>]*>/)
|
306
|
+
radio[1].should_not match_tag(:input, :label => "LABEL")
|
307
|
+
radio[4].should_not match_tag(:input, :label => "LABEL")
|
308
|
+
end
|
309
|
+
end
|
310
|
+
end
|
311
|
+
|
312
|
+
describe "text area (basic)" do
|
313
|
+
it "should should return a basic text area based on the values passed in" do
|
314
|
+
text_area_field("foo", :name => "foo").should match_tag(:textarea, :name => "foo")
|
315
|
+
end
|
316
|
+
|
317
|
+
it "should handle a nil content" do
|
318
|
+
text_area_field(nil, :name => "foo").should == "<textarea name=\"foo\"></textarea>"
|
319
|
+
end
|
320
|
+
|
321
|
+
it "should handle a nil attributes hash" do
|
322
|
+
text_area_field("CONTENT", nil).should == "<textarea>CONTENT</textarea>"
|
323
|
+
end
|
324
|
+
|
325
|
+
it "should render a label when the label is passed in" do
|
326
|
+
result = text_area_field( "CONTENT", :name => "foo", :value => "bar", :label => "LABEL")
|
327
|
+
result.should match(/<label>LABEL<textarea/)
|
328
|
+
res = result.scan(/<[^>]*>/)
|
329
|
+
res[1].should_not match_tag(:textarea, :label => "LABEL")
|
330
|
+
end
|
331
|
+
end
|
332
|
+
|
333
|
+
describe "text area (data bound)" do
|
334
|
+
it_should_behave_like "FakeBufferConsumer"
|
335
|
+
|
336
|
+
it "should return a bound text area" do
|
337
|
+
form_for :obj do
|
338
|
+
ta = text_area_control(:foo)
|
339
|
+
tab = text_area_control(:foobad)
|
340
|
+
ta.should match_tag(:textarea, :name => "fake_model[foo]")
|
341
|
+
tab.should match_tag(:textarea, :name => "fake_model[foobad]", :class => "error")
|
342
|
+
ta.should include("foowee")
|
343
|
+
end
|
344
|
+
end
|
345
|
+
|
346
|
+
it "should handle a nil content value" do
|
347
|
+
@obj.nothing.should be_nil
|
348
|
+
form_for :obj do
|
349
|
+
text_area_control(:nothing).should match_tag(:textarea, :name => "fake_model[nothing]")
|
350
|
+
end
|
351
|
+
end
|
352
|
+
|
353
|
+
it "should handle a nil attribute hash" do
|
354
|
+
form_for :obj do
|
355
|
+
text_area_control(:nothing, nil).should match_tag(:textarea, :name => "fake_model[nothing]")
|
356
|
+
end
|
357
|
+
end
|
358
|
+
|
359
|
+
it "should render a label when the label is passed in" do
|
360
|
+
form_for :obj do
|
361
|
+
result = text_area_control( :foo, :label => "LABEL")
|
362
|
+
result.should match(/<label>LABEL<textarea/)
|
363
|
+
res = result.scan(/<[^>]*>/)
|
364
|
+
res[1].should_not match_tag(:textarea, :label => "LABEL")
|
365
|
+
end
|
366
|
+
end
|
367
|
+
|
368
|
+
end
|
369
|
+
|
370
|
+
describe "form helper supporting methods for controls" do
|
371
|
+
it_should_behave_like "FakeBufferConsumer"
|
372
|
+
|
373
|
+
it "should give class_name[colname] for control_name" do
|
374
|
+
form_for :obj do
|
375
|
+
text_control( :foo ).should match_tag( :input, :type => "text", :name => "fake_model[foo]")
|
376
|
+
end
|
377
|
+
end
|
378
|
+
|
379
|
+
it "should provide value=method_value for the control_value method" do
|
380
|
+
form_for :obj do
|
381
|
+
text_control( :foo ).should match_tag( :input, :type => "text", :value => "foowee")
|
382
|
+
end
|
383
|
+
end
|
384
|
+
|
385
|
+
it "should give name and value for a call to control_name_value" do
|
386
|
+
form_for :obj do
|
387
|
+
control_name_value(:foo, :attribute => "ATTRIBUTE" ).should == { :name => "fake_model[foo]",
|
388
|
+
:value => "foowee",
|
389
|
+
:attribute => "ATTRIBUTE"}
|
390
|
+
end
|
391
|
+
end
|
392
|
+
end
|
393
|
+
|
394
|
+
describe "submit_button" do
|
395
|
+
it_should_behave_like "FakeBufferConsumer"
|
396
|
+
|
397
|
+
it "should produce a simple submit button" do
|
398
|
+
submit_button("Foo").should == "<button type=\"submit\">Foo</button>"
|
399
|
+
end
|
400
|
+
end
|
401
|
+
|
402
|
+
describe "label helpers" do
|
403
|
+
it_should_behave_like "FakeBufferConsumer"
|
404
|
+
|
405
|
+
it "should add a label to arbitrary markup in a template" do
|
406
|
+
result = label("Name:", text_field(:name => "name_value"))
|
407
|
+
result.should == "<label>Name:<input type=\"text\" name=\"name_value\"/></label>"
|
408
|
+
|
409
|
+
end
|
410
|
+
|
411
|
+
end
|
412
|
+
|
@@ -0,0 +1,99 @@
|
|
1
|
+
$TESTING=true
|
2
|
+
$:.push File.join(File.dirname(__FILE__), '..', 'lib')
|
3
|
+
require 'rubygems'
|
4
|
+
require 'merb'
|
5
|
+
# require 'merb/test/rspec'
|
6
|
+
|
7
|
+
class FakeModel
|
8
|
+
def self.columns
|
9
|
+
[FakeColumn.new(:foo, :string),
|
10
|
+
FakeColumn.new(:foobad, :string),
|
11
|
+
FakeColumn.new(:bar, :integer),
|
12
|
+
FakeColumn.new(:barbad, :integer),
|
13
|
+
FakeColumn.new(:baz, :boolean),
|
14
|
+
FakeColumn.new(:bazbad, :boolean),
|
15
|
+
FakeColumn.new(:bat, :boolean),
|
16
|
+
FakeColumn.new(:batbad, :boolean)
|
17
|
+
]
|
18
|
+
end
|
19
|
+
|
20
|
+
def valid?
|
21
|
+
false
|
22
|
+
end
|
23
|
+
|
24
|
+
def new_record?
|
25
|
+
false
|
26
|
+
end
|
27
|
+
|
28
|
+
def errors
|
29
|
+
FakeErrors.new(self)
|
30
|
+
end
|
31
|
+
|
32
|
+
def foo
|
33
|
+
"foowee"
|
34
|
+
end
|
35
|
+
|
36
|
+
alias_method :foobad, :foo
|
37
|
+
|
38
|
+
def bar
|
39
|
+
7
|
40
|
+
end
|
41
|
+
alias_method :barbad, :bar
|
42
|
+
|
43
|
+
def baz
|
44
|
+
true
|
45
|
+
end
|
46
|
+
alias_method :bazbad, :baz
|
47
|
+
|
48
|
+
def bat
|
49
|
+
false
|
50
|
+
end
|
51
|
+
alias_method :batbad, :bat
|
52
|
+
|
53
|
+
def nothing
|
54
|
+
nil
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
class FakeModel2 < FakeModel
|
59
|
+
|
60
|
+
def foo
|
61
|
+
"foowee2"
|
62
|
+
end
|
63
|
+
alias_method :foobad, :foo
|
64
|
+
|
65
|
+
def new_record?
|
66
|
+
true
|
67
|
+
end
|
68
|
+
|
69
|
+
end
|
70
|
+
|
71
|
+
class FakeErrors
|
72
|
+
|
73
|
+
def initialize(model)
|
74
|
+
@model = model
|
75
|
+
end
|
76
|
+
|
77
|
+
def on(name)
|
78
|
+
name.to_s.include?("bad")
|
79
|
+
end
|
80
|
+
|
81
|
+
end
|
82
|
+
|
83
|
+
class FakeColumn
|
84
|
+
attr_accessor :name, :type
|
85
|
+
def initialize(name, type)
|
86
|
+
@name, @type = name, type
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
|
91
|
+
|
92
|
+
|
93
|
+
describe "FakeBufferConsumer", :shared => true do
|
94
|
+
|
95
|
+
before :each do
|
96
|
+
@obj = FakeModel.new
|
97
|
+
def _buffer(buf = "") @buffer ||= "" end
|
98
|
+
end
|
99
|
+
end
|
metadata
ADDED
@@ -0,0 +1,66 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
rubygems_version: 0.9.4
|
3
|
+
specification_version: 1
|
4
|
+
name: merb_helpers
|
5
|
+
version: !ruby/object:Gem::Version
|
6
|
+
version: 0.4.0
|
7
|
+
date: 2007-11-05 00:00:00 -08:00
|
8
|
+
summary: Helper support for merb (similar to the Rails form helpers)
|
9
|
+
require_paths:
|
10
|
+
- lib
|
11
|
+
email: wycats@gmail.com
|
12
|
+
homepage: http://merb.rubyforge.org/
|
13
|
+
rubyforge_project:
|
14
|
+
description: Helper support for merb (similar to the Rails form helpers)
|
15
|
+
autorequire: merb_helpers
|
16
|
+
default_executable:
|
17
|
+
bindir: bin
|
18
|
+
has_rdoc: true
|
19
|
+
required_ruby_version: !ruby/object:Gem::Version::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">"
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 0.0.0
|
24
|
+
version:
|
25
|
+
platform: ruby
|
26
|
+
signing_key:
|
27
|
+
cert_chain:
|
28
|
+
post_install_message:
|
29
|
+
authors:
|
30
|
+
- Yehuda Katz
|
31
|
+
files:
|
32
|
+
- LICENSE
|
33
|
+
- README
|
34
|
+
- Rakefile
|
35
|
+
- TODO
|
36
|
+
- lib/form_helpers.rb
|
37
|
+
- lib/form_model.rb
|
38
|
+
- lib/merb_helpers
|
39
|
+
- lib/merb_helpers/merbtasks.rb
|
40
|
+
- lib/merb_helpers.rb
|
41
|
+
- specs/merb_helpers_spec.rb
|
42
|
+
- specs/spec_helper.rb
|
43
|
+
test_files: []
|
44
|
+
|
45
|
+
rdoc_options: []
|
46
|
+
|
47
|
+
extra_rdoc_files:
|
48
|
+
- README
|
49
|
+
- LICENSE
|
50
|
+
- TODO
|
51
|
+
executables: []
|
52
|
+
|
53
|
+
extensions: []
|
54
|
+
|
55
|
+
requirements:
|
56
|
+
- merb
|
57
|
+
dependencies:
|
58
|
+
- !ruby/object:Gem::Dependency
|
59
|
+
name: merb
|
60
|
+
version_requirement:
|
61
|
+
version_requirements: !ruby/object:Gem::Version::Requirement
|
62
|
+
requirements:
|
63
|
+
- - ">="
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
version: "0.4"
|
66
|
+
version:
|