sinatra-formhelpers 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.document +5 -0
- data/LICENSE +21 -0
- data/README.md +91 -0
- data/Rakefile +62 -0
- data/VERSION +1 -0
- data/lib/sinatra/form_helpers.rb +217 -0
- data/sinatra-formhelpers.gemspec +47 -0
- data/spec/form_helpers_spec.rb +295 -0
- data/spec/spec_helper.rb +55 -0
- metadata +73 -0
data/.document
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
sinatra-formhelpers - Suite of form helpers for sinatra
|
2
|
+
Copyright 2009 Tom Wilson
|
3
|
+
|
4
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
5
|
+
a copy of this software and associated documentation files (the
|
6
|
+
"Software"), to deal in the Software without restriction, including
|
7
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
8
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
9
|
+
permit persons to whom the Software is furnished to do so, subject to
|
10
|
+
the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be
|
13
|
+
included in all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
16
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
17
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
18
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
19
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
20
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
21
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,91 @@
|
|
1
|
+
Sinatra::FormHelpers - Lightweight form helpers for Sinatra
|
2
|
+
===========================================================
|
3
|
+
|
4
|
+
This plugin adds lightweight (3-5 lines each) form helpers to Sinatra that aid with
|
5
|
+
common form and HTML tags.
|
6
|
+
|
7
|
+
link "google", "http://www.google.com" # <a href="http://www.google.com">google</a>
|
8
|
+
label :person, :first_name # <label for="person_first_name">First Name</label>
|
9
|
+
input :person, :first_name # <input name="person[first_name]" id="person_first_name" type="text" />
|
10
|
+
|
11
|
+
There are also helpers for: form, textarea, submit, image, radio, checkbox, and select
|
12
|
+
|
13
|
+
Why Bother?
|
14
|
+
-----------
|
15
|
+
After all, you can just write Haml or write your own helpers or hand-code raw HTML or whatever. Well, here's some considerations:
|
16
|
+
|
17
|
+
1. Helpers maintain correct state across form submissions (eg, on errors, form stays filled in)
|
18
|
+
2. Generate automatic labels, valid CSS ID's, and <code>nested[names]</code> to make ORMs happy
|
19
|
+
3. No Rails ultra-magic(tm) here. Just fast, simple code.
|
20
|
+
|
21
|
+
Usage
|
22
|
+
-----
|
23
|
+
With Bundler/Isolate:
|
24
|
+
|
25
|
+
gem 'sinatra-formhelpers', '~>0.6.0'
|
26
|
+
|
27
|
+
Then, include it in a Sinatra application:
|
28
|
+
|
29
|
+
require 'sinatra/form_helpers'
|
30
|
+
|
31
|
+
If you're subclassing <code>Sinatra::Base</code>, you also need to call <code>helpers</code> manually:
|
32
|
+
|
33
|
+
class MyApp < Sinatra::Base
|
34
|
+
helpers Sinatra::FormHelpers
|
35
|
+
# ...
|
36
|
+
end
|
37
|
+
|
38
|
+
Views
|
39
|
+
-----
|
40
|
+
In your views, use these helpers to dynamically create form HTML elements. Here's an example in ERB:
|
41
|
+
|
42
|
+
<p>
|
43
|
+
Fill out the below form to sign up.
|
44
|
+
For more information, visit our <%= link 'FAQ', '/faq' %>
|
45
|
+
</p>
|
46
|
+
|
47
|
+
<%= form('/users', :post) %>
|
48
|
+
|
49
|
+
<%= input(:user, :first_name) %>
|
50
|
+
<%= input(:user, :last_name) %>
|
51
|
+
|
52
|
+
<%= input(:user, :email, :size => 40) %>
|
53
|
+
|
54
|
+
<%= password(:user, :password) %>
|
55
|
+
<%= password(:user, :confirm_password) %>
|
56
|
+
|
57
|
+
<%= radio(:user, :gender, ['M', 'F']) %>
|
58
|
+
|
59
|
+
<%= submit %>
|
60
|
+
|
61
|
+
Unlike the super-magic Rails <code>form\_for</code> method, the <code>form()</code> helper just takes a URL and method. (Note that <code>form()</code> will accept <code>:create</code>, <code>:update</code>, and <code>:delete</code> and include the special <code>\_method</code> hidden param for you.)
|
62
|
+
|
63
|
+
To reduce repetition, use <code>fieldset()</code> to prefix fields with a namespace:
|
64
|
+
|
65
|
+
<%= form('/users', :create) %>
|
66
|
+
|
67
|
+
<% fieldset(:user) do |f| %>
|
68
|
+
<%= f.input(:first_name) %>
|
69
|
+
<%= f.input(:last_name) %>
|
70
|
+
|
71
|
+
<%= f.input(:email, :size => 40) %>
|
72
|
+
|
73
|
+
<%= f.password(:password) %>
|
74
|
+
<%= f.password(:confirm_password) %>
|
75
|
+
|
76
|
+
<%= f.radio(:gender, ['M', 'F']) %>
|
77
|
+
<% end %>
|
78
|
+
|
79
|
+
<%= submit 'Create account' %>
|
80
|
+
<%= submit 'Cancel', :onclick => 'window.location=http://mydomain.com;return false' %>
|
81
|
+
|
82
|
+
This will create fields named <code>user[first\_name]</code>, <code>user[last\_name]<code>, and so forth.
|
83
|
+
|
84
|
+
Known Bugs
|
85
|
+
----------
|
86
|
+
* Currently <code>fieldset</code> does not return a <fieldset> tag properly (working on it)
|
87
|
+
|
88
|
+
|
89
|
+
Author
|
90
|
+
------
|
91
|
+
Copyright (c) 2011 [Nate Wiger](http://nateware.com). Based on initial efforts (c) 2009 twilson63.
|
data/Rakefile
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
require 'rake/clean'
|
2
|
+
require 'rake/testtask'
|
3
|
+
require 'fileutils'
|
4
|
+
|
5
|
+
require 'rubygems'
|
6
|
+
require 'rake'
|
7
|
+
|
8
|
+
begin
|
9
|
+
require 'jeweler'
|
10
|
+
Jeweler::Tasks.new do |gem|
|
11
|
+
gem.name = "sinatra-formhelpers"
|
12
|
+
gem.summary = %Q{Form helpers for Sinatra}
|
13
|
+
gem.description = %Q{Simple, lightweight form helpers for Sinatra. Based on initial efforts by twilson63.}
|
14
|
+
gem.email = "nate@wiger.org"
|
15
|
+
gem.homepage = "http://github.com/nateware/sinatra-formhelpers"
|
16
|
+
gem.authors = ["Nate Wiger"]
|
17
|
+
gem.add_development_dependency "bacon", ">= 0"
|
18
|
+
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
19
|
+
end
|
20
|
+
Jeweler::RubygemsDotOrgTasks.new
|
21
|
+
|
22
|
+
rescue LoadError
|
23
|
+
puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
|
24
|
+
end
|
25
|
+
|
26
|
+
|
27
|
+
# SPECS ===============================================================
|
28
|
+
|
29
|
+
task :test => :spec
|
30
|
+
desc "run all the specs"
|
31
|
+
task :spec do
|
32
|
+
sh "bacon spec/*_spec.rb"
|
33
|
+
end
|
34
|
+
|
35
|
+
begin
|
36
|
+
require 'rcov/rcovtask'
|
37
|
+
Rcov::RcovTask.new do |test|
|
38
|
+
test.libs << 'spec'
|
39
|
+
test.pattern = 'spec/**/*_spec.rb'
|
40
|
+
test.verbose = true
|
41
|
+
end
|
42
|
+
rescue LoadError
|
43
|
+
task :rcov do
|
44
|
+
abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
|
49
|
+
task :default => :test
|
50
|
+
|
51
|
+
require 'rake/rdoctask'
|
52
|
+
Rake::RDocTask.new do |rdoc|
|
53
|
+
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
54
|
+
|
55
|
+
rdoc.rdoc_dir = 'rdoc'
|
56
|
+
rdoc.title = "Sinatra::FormHelpers #{version}"
|
57
|
+
rdoc.rdoc_files.include('README*')
|
58
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
59
|
+
end
|
60
|
+
|
61
|
+
|
62
|
+
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.4.0
|
@@ -0,0 +1,217 @@
|
|
1
|
+
module Sinatra
|
2
|
+
module FormHelpers
|
3
|
+
# FormHelpers are a suite of helper methods
|
4
|
+
# built to make building forms in Sinatra
|
5
|
+
# a breeze.
|
6
|
+
#
|
7
|
+
# link "jackhq", "http://www.jackhq.com"
|
8
|
+
#
|
9
|
+
# label :person, :first_name
|
10
|
+
# input :person, :first_name
|
11
|
+
# textarea :person, :notes
|
12
|
+
#
|
13
|
+
# etc.
|
14
|
+
def form(action, method=:get, options={}, &block)
|
15
|
+
method_input = ''
|
16
|
+
if method.is_a? Symbol
|
17
|
+
case method.to_s.downcase
|
18
|
+
when 'delete', 'update'
|
19
|
+
method_input = %Q(<input type="hidden" name="_method" value="#{method}" />)
|
20
|
+
method = :post
|
21
|
+
when 'create'
|
22
|
+
method = :post
|
23
|
+
end
|
24
|
+
end
|
25
|
+
action = "/#{action}" if action.is_a? Symbol
|
26
|
+
|
27
|
+
out = tag(:form, nil, {:action => action, :method => method.to_s.upcase}.merge(options)) + method_input
|
28
|
+
out << fieldset(action, &block) + '</form>' if block_given?
|
29
|
+
out
|
30
|
+
end
|
31
|
+
|
32
|
+
def fieldset(obj, legend=nil, &block)
|
33
|
+
raise ArgumentError, "Missing block to fieldset()" unless block_given?
|
34
|
+
out = yield Fieldset.new(self, obj)
|
35
|
+
'<fieldset>' + (legend.nil? ? '' : "<legend>#{fast_escape_html(legend)}</legend>") + out + '</fieldset>'
|
36
|
+
end
|
37
|
+
|
38
|
+
# Link to a URL
|
39
|
+
def link(content, href=content, options={})
|
40
|
+
tag :a, content, options.merge(:href => href)
|
41
|
+
end
|
42
|
+
|
43
|
+
# Link to an image
|
44
|
+
def image(src, options={})
|
45
|
+
single_tag :img, options.merge(:src => src)
|
46
|
+
end
|
47
|
+
|
48
|
+
# Form field label
|
49
|
+
def label(obj, field, display = "", options={})
|
50
|
+
tag :label, (display.nil? || display == '') ? titleize(field.to_s) : display, options.merge(:for => "#{obj}_#{field}")
|
51
|
+
end
|
52
|
+
|
53
|
+
# Form text input. Specify the value as :value => 'foo'
|
54
|
+
def input(obj, field=nil, options={})
|
55
|
+
value = param_or_default(obj, field, options[:value])
|
56
|
+
single_tag :input, options.merge(
|
57
|
+
:type => "text", :id => css_id(obj, field),
|
58
|
+
:name => field.nil? ? obj : "#{obj}[#{field}]",
|
59
|
+
:value => value
|
60
|
+
)
|
61
|
+
end
|
62
|
+
|
63
|
+
# Form password input. Specify the value as :value => 'foo'
|
64
|
+
def password(obj, field=nil, options={})
|
65
|
+
value = param_or_default(obj, field, options[:value])
|
66
|
+
single_tag :input, options.merge(
|
67
|
+
:type => "password", :id => css_id(obj, field),
|
68
|
+
:name => field.nil? ? obj : "#{obj}[#{field}]",
|
69
|
+
:value => value
|
70
|
+
)
|
71
|
+
end
|
72
|
+
|
73
|
+
# Form textarea box.
|
74
|
+
def textarea(obj, field=nil, content='', options={})
|
75
|
+
content = param_or_default(obj, field, content)
|
76
|
+
tag :textarea, content, options.merge(
|
77
|
+
:id => css_id(obj, field),
|
78
|
+
:name => field.nil? ? obj : "#{obj}[#{field}]"
|
79
|
+
)
|
80
|
+
end
|
81
|
+
|
82
|
+
# Form submit tag.
|
83
|
+
def submit(value='Submit', options={})
|
84
|
+
single_tag :input, {:name => "submit", :type => "submit",
|
85
|
+
:value => value, :id => css_id('button', value)}.merge(options)
|
86
|
+
end
|
87
|
+
|
88
|
+
# Form reset tag. Does anyone use these anymore?
|
89
|
+
def reset(value='Reset', options={})
|
90
|
+
single_tag :input, {:name => "reset", :type => "reset",
|
91
|
+
:value => value, :id => css_id('button', value)}.merge(options)
|
92
|
+
end
|
93
|
+
|
94
|
+
# General purpose button, usually these need JavaScript hooks.
|
95
|
+
def button(value, options={})
|
96
|
+
single_tag :input, {:name => "button", :type => "button",
|
97
|
+
:value => value, :id => css_id('button', value)}.merge(options)
|
98
|
+
end
|
99
|
+
|
100
|
+
# Form checkbox. Specify an array of values to get a checkbox group.
|
101
|
+
def checkbox(obj, field, values, options={})
|
102
|
+
join = options.delete(:join) || ' '
|
103
|
+
labs = options.delete(:label)
|
104
|
+
vals = param_or_default(obj, field, [])
|
105
|
+
ary = values.is_a?(Array) && values.length > 1 ? '[]' : ''
|
106
|
+
Array(values).collect do |val|
|
107
|
+
id, text = id_and_text_from_value(val)
|
108
|
+
single_tag(:input, options.merge(:type => "checkbox", :id => css_id(obj, field, id),
|
109
|
+
:name => "#{obj}[#{field}]#{ary}", :value => id,
|
110
|
+
:checked => vals.include?(val) ? 'checked' : nil)) +
|
111
|
+
(labs.nil? || labs == true ? label(obj, "#{field}_#{id.to_s.downcase}", text) : '')
|
112
|
+
end.join(join)
|
113
|
+
end
|
114
|
+
|
115
|
+
# Form radio input. Specify an array of values to get a radio group.
|
116
|
+
def radio(obj, field, values, options={})
|
117
|
+
#content = @params[obj] && @params[obj][field.to_s] == value ? "true" : ""
|
118
|
+
# , :checked => content
|
119
|
+
join = options.delete(:join) || ' '
|
120
|
+
labs = options.delete(:label)
|
121
|
+
vals = param_or_default(obj, field, [])
|
122
|
+
Array(values).collect do |val|
|
123
|
+
id, text = id_and_text_from_value(val)
|
124
|
+
single_tag(:input, options.merge(:type => "radio", :id => css_id(obj, field, id),
|
125
|
+
:name => "#{obj}[#{field}]", :value => id,
|
126
|
+
:checked => vals.include?(val) ? 'checked' : nil)) +
|
127
|
+
(labs.nil? || labs == true ? label(obj, "#{field}_#{id.to_s.downcase}", text) : '')
|
128
|
+
end.join(join)
|
129
|
+
end
|
130
|
+
|
131
|
+
# Form select dropdown. Currently only single-select (not multi-select) is supported.
|
132
|
+
def select(obj, field, values, options={})
|
133
|
+
content = ""
|
134
|
+
Array(values).each do |val|
|
135
|
+
id, text = id_and_text_from_value(val)
|
136
|
+
if val.is_a? Array
|
137
|
+
content << tag(:option, text, :value => id)
|
138
|
+
else
|
139
|
+
content << tag(:option, text, :value => id)
|
140
|
+
end
|
141
|
+
end
|
142
|
+
tag :select, content, options.merge(:id => css_id(obj, field), :name => "#{obj}[#{field}]")
|
143
|
+
end
|
144
|
+
|
145
|
+
# Form hidden input. Specify value as :value => 'foo'
|
146
|
+
def hidden(obj, field="", options={})
|
147
|
+
content = param_or_default(obj, field, options[:value])
|
148
|
+
single_tag :input, options.merge(:type => "hidden", :id => css_id(obj, field), :name => "#{obj}[#{field}]")
|
149
|
+
end
|
150
|
+
|
151
|
+
# Standard open and close tags
|
152
|
+
# EX : tag :h1, "shizam", :title => "shizam"
|
153
|
+
# => <h1 title="shizam">shizam</h1>
|
154
|
+
def tag(name, content, options={})
|
155
|
+
"<#{name.to_s}" +
|
156
|
+
(options.length > 0 ? " #{hash_to_html_attrs(options)}" : '') +
|
157
|
+
(content.nil? ? '>' : ">#{content}</#{name}>")
|
158
|
+
end
|
159
|
+
|
160
|
+
# Standard single closing tags
|
161
|
+
# single_tag :img, :src => "images/google.jpg"
|
162
|
+
# => <img src="images/google.jpg" />
|
163
|
+
def single_tag(name, options={})
|
164
|
+
"<#{name.to_s} #{hash_to_html_attrs(options)} />"
|
165
|
+
end
|
166
|
+
|
167
|
+
def fast_escape_html(text)
|
168
|
+
text.to_s.gsub(/\&/,'&').gsub(/\"/,'"').gsub(/>/,'>').gsub(/</,'<')
|
169
|
+
end
|
170
|
+
|
171
|
+
def titleize(text)
|
172
|
+
text.to_s.gsub(/_+/, ' ').gsub(/\b('?[a-z])/) { $1.capitalize }
|
173
|
+
end
|
174
|
+
|
175
|
+
def param_or_default(obj, field, default)
|
176
|
+
if field
|
177
|
+
params[obj] ? params[obj][field.to_s] || default : default
|
178
|
+
else
|
179
|
+
params[obj] || default
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
def hash_to_html_attrs(options={})
|
184
|
+
html_attrs = ""
|
185
|
+
options.keys.sort.each do |key|
|
186
|
+
next if options[key].nil? # do not include empty attributes
|
187
|
+
html_attrs << %Q(#{key}="#{fast_escape_html(options[key])}" )
|
188
|
+
end
|
189
|
+
html_attrs.chop
|
190
|
+
end
|
191
|
+
|
192
|
+
def id_and_text_from_value(val)
|
193
|
+
if val.is_a? Array
|
194
|
+
[val.first, val.last]
|
195
|
+
else
|
196
|
+
[val, val]
|
197
|
+
end
|
198
|
+
end
|
199
|
+
|
200
|
+
def css_id(*things)
|
201
|
+
things.compact.map{|t| t.to_s}.join('_').downcase.gsub(/\W/,'_')
|
202
|
+
end
|
203
|
+
|
204
|
+
class Fieldset
|
205
|
+
def initialize(parent, name)
|
206
|
+
@parent = parent
|
207
|
+
@name = name.to_s.gsub(/\W+/,'')
|
208
|
+
end
|
209
|
+
|
210
|
+
def method_missing(meth, *args)
|
211
|
+
@parent.send(meth, @name, *args)
|
212
|
+
end
|
213
|
+
end
|
214
|
+
end
|
215
|
+
|
216
|
+
helpers FormHelpers
|
217
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = %q{sinatra-formhelpers}
|
8
|
+
s.version = "0.4.0"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = [%q{Nate Wiger}]
|
12
|
+
s.date = %q{2011-08-26}
|
13
|
+
s.description = %q{Simple, lightweight form helpers for Sinatra. Based on initial efforts by twilson63.}
|
14
|
+
s.email = %q{nate@wiger.org}
|
15
|
+
s.extra_rdoc_files = [
|
16
|
+
"LICENSE",
|
17
|
+
"README.md"
|
18
|
+
]
|
19
|
+
s.files = [
|
20
|
+
".document",
|
21
|
+
"LICENSE",
|
22
|
+
"README.md",
|
23
|
+
"Rakefile",
|
24
|
+
"VERSION",
|
25
|
+
"lib/sinatra/form_helpers.rb",
|
26
|
+
"sinatra-formhelpers.gemspec",
|
27
|
+
"spec/form_helpers_spec.rb",
|
28
|
+
"spec/spec_helper.rb"
|
29
|
+
]
|
30
|
+
s.homepage = %q{http://github.com/nateware/sinatra-formhelpers}
|
31
|
+
s.require_paths = [%q{lib}]
|
32
|
+
s.rubygems_version = %q{1.8.6}
|
33
|
+
s.summary = %q{Form helpers for Sinatra}
|
34
|
+
|
35
|
+
if s.respond_to? :specification_version then
|
36
|
+
s.specification_version = 3
|
37
|
+
|
38
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
39
|
+
s.add_development_dependency(%q<bacon>, [">= 0"])
|
40
|
+
else
|
41
|
+
s.add_dependency(%q<bacon>, [">= 0"])
|
42
|
+
end
|
43
|
+
else
|
44
|
+
s.add_dependency(%q<bacon>, [">= 0"])
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
@@ -0,0 +1,295 @@
|
|
1
|
+
require File.expand_path 'spec_helper', File.dirname(__FILE__)
|
2
|
+
|
3
|
+
# class Application < Sinatra::Base
|
4
|
+
# register Sinatra::FormHelpers
|
5
|
+
#
|
6
|
+
# set :raise_errors, false
|
7
|
+
# set :show_exceptions, false
|
8
|
+
#
|
9
|
+
# get '/link' do
|
10
|
+
#
|
11
|
+
# end
|
12
|
+
# end
|
13
|
+
#
|
14
|
+
# class Bacon::Context
|
15
|
+
# include Rack::Test::Methods
|
16
|
+
# def app
|
17
|
+
# Application # our application
|
18
|
+
# end
|
19
|
+
# end
|
20
|
+
|
21
|
+
describe "Sinatra::FormHelpers methods" do
|
22
|
+
it "renders an anchor tag" do
|
23
|
+
fh.form(:person, :create).should == '<form action="/person" method="POST">'
|
24
|
+
end
|
25
|
+
it 'renders a form tag' do
|
26
|
+
fh.form(:person, :update, :action => "/people/14").should ==
|
27
|
+
'<form action="/people/14" method="POST"><input type="hidden" name="_method" value="update" />'
|
28
|
+
end
|
29
|
+
it 'renders a form tag (2)' do
|
30
|
+
fh.form("/people/7", :delete).should ==
|
31
|
+
'<form action="/people/7" method="POST"><input type="hidden" name="_method" value="delete" />'
|
32
|
+
end
|
33
|
+
it 'renders a form tag (3)' do
|
34
|
+
fh.form("/people", :create).should ==
|
35
|
+
'<form action="/people" method="POST">'
|
36
|
+
end
|
37
|
+
it 'renders a nested form tag' do
|
38
|
+
fh.form(:person, :create) do |f|
|
39
|
+
# f.input(:first_name)
|
40
|
+
f.input(:last_name)
|
41
|
+
end.should == '<form action="/person" method="POST"><fieldset>' +
|
42
|
+
# '<input id="person_first_name" name="person[first_name]" type="text" />' +
|
43
|
+
'<input id="person_last_name" name="person[last_name]" type="text" />' +
|
44
|
+
'</fieldset></form>'
|
45
|
+
end
|
46
|
+
it 'nests form elements arbitrarily' do
|
47
|
+
fh.fieldset(:person) do |n|
|
48
|
+
# n.radio(:partners, 1..6)
|
49
|
+
n.textarea(:comments, "yo yo yo!")
|
50
|
+
end.should == '<fieldset>' +
|
51
|
+
# '<input id="person_partners_1" name="person[partners]" type="radio" value="1" /> ' +
|
52
|
+
# '<input id="person_partners_2" name="person[partners]" type="radio" value="2" /> ' +
|
53
|
+
# '<input id="person_partners_3" name="person[partners]" type="radio" value="3" /> ' +
|
54
|
+
# '<input id="person_partners_4" name="person[partners]" type="radio" value="4" /> ' +
|
55
|
+
# '<input id="person_partners_5" name="person[partners]" type="radio" value="5" /> ' +
|
56
|
+
# '<input id="person_partners_6" name="person[partners]" type="radio" value="6" />' +
|
57
|
+
'<textarea id="person_comments" name="person[comments]">yo yo yo!</textarea></fieldset>'
|
58
|
+
end
|
59
|
+
it 'renders a link tag' do
|
60
|
+
fh.link('http://google.com').should == '<a href="http://google.com">http://google.com</a>'
|
61
|
+
end
|
62
|
+
it 'renders a form label tag' do
|
63
|
+
fh.label(:person, :first_name).should == '<label for="person_first_name">First Name</label>'
|
64
|
+
end
|
65
|
+
it 'renders a form checkbox tag' do
|
66
|
+
fh.checkbox(:person, :gender, %w[M F], :join => '<br />').should ==
|
67
|
+
'<input id="person_gender_m" name="person[gender][]" type="checkbox" value="M" /><label for="person_gender_m">M</label><br />' +
|
68
|
+
'<input id="person_gender_f" name="person[gender][]" type="checkbox" value="F" /><label for="person_gender_f">F</label>'
|
69
|
+
end
|
70
|
+
it 'renders a minimal text tag' do
|
71
|
+
fh.input(:q).should == %q(<input id="q" name="q" type="text" />)
|
72
|
+
end
|
73
|
+
it 'renders a minimal textarea tag' do
|
74
|
+
fh.textarea(:r).should == %q(<textarea id="r" name="r"></textarea>)
|
75
|
+
end
|
76
|
+
it 'renders a submit tag' do
|
77
|
+
fh.submit.should == %q(<input id="button_submit" name="submit" type="submit" value="Submit" />)
|
78
|
+
fh.submit("Send!").should == %q(<input id="button_send_" name="submit" type="submit" value="Send!" />)
|
79
|
+
end
|
80
|
+
it 'renders a reset tag' do
|
81
|
+
fh.reset.should == %q(<input id="button_reset" name="reset" type="reset" value="Reset" />)
|
82
|
+
fh.reset("Blark").should == %q(<input id="button_blark" name="reset" type="reset" value="Blark" />)
|
83
|
+
end
|
84
|
+
it 'supports multiple values for checkboxes' do
|
85
|
+
fh.params = {:user => {'devices' => ['iPhone', 'iPad'] }}
|
86
|
+
fh.checkbox(:user, :devices, ['iPhone', 'iPad', 'iPod', 'iPoop']).should ==
|
87
|
+
"<input checked=\"checked\" id=\"user_devices_iphone\" name=\"user[devices][]\" type=\"checkbox\" value=\"iPhone\" /><label for=\"user_devices_iphone\">iPhone</label> <input checked=\"checked\" id=\"user_devices_ipad\" name=\"user[devices][]\" type=\"checkbox\" value=\"iPad\" /><label for=\"user_devices_ipad\">iPad</label> <input id=\"user_devices_ipod\" name=\"user[devices][]\" type=\"checkbox\" value=\"iPod\" /><label for=\"user_devices_ipod\">iPod</label> <input id=\"user_devices_ipoop\" name=\"user[devices][]\" type=\"checkbox\" value=\"iPoop\" /><label for=\"user_devices_ipoop\">iPoop</label>"
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
describe "Sinatra::FormHelpers in app" do
|
92
|
+
it 'renders an anchor tag' do
|
93
|
+
app.get '/link' do
|
94
|
+
erb "<%= link 'google', 'http://www.google.com', :title => 'Google' %>"
|
95
|
+
end
|
96
|
+
|
97
|
+
get '/link'
|
98
|
+
last_response.body.should == %q(<a href="http://www.google.com" title="Google">google</a>)
|
99
|
+
end
|
100
|
+
|
101
|
+
it 'renders a label tag' do
|
102
|
+
app.get '/label' do
|
103
|
+
erb "<%= label :person, :first_name %>"
|
104
|
+
end
|
105
|
+
|
106
|
+
get '/label'
|
107
|
+
last_response.body.should == %q(<label for="person_first_name">First Name</label>)
|
108
|
+
end
|
109
|
+
|
110
|
+
it 'renders a label tag with display input' do
|
111
|
+
app.get '/hello' do
|
112
|
+
erb "<%= label :person, :first_name, 'Hello World'%>"
|
113
|
+
end
|
114
|
+
|
115
|
+
get '/hello'
|
116
|
+
last_response.body.should == %q(<label for="person_first_name">Hello World</label>)
|
117
|
+
end
|
118
|
+
|
119
|
+
it 'renders an input tag type text without @params' do
|
120
|
+
app.get '/text' do
|
121
|
+
erb "<%= input :person, :first_name %>"
|
122
|
+
end
|
123
|
+
|
124
|
+
get '/text'
|
125
|
+
last_response.body.should =~ /name="person\[first_name\]"/
|
126
|
+
last_response.body.should == %q(<input id="person_first_name" name="person[first_name]" type="text" />)
|
127
|
+
end
|
128
|
+
|
129
|
+
it 'renders an input tag type text with single arg' do
|
130
|
+
app.get '/q' do
|
131
|
+
erb "<%= input :q %>"
|
132
|
+
end
|
133
|
+
|
134
|
+
get '/q'
|
135
|
+
last_response.body.should == %q(<input id="q" name="q" type="text" />)
|
136
|
+
end
|
137
|
+
|
138
|
+
it 'renders an input tag type text with @params' do
|
139
|
+
app.get '/tom' do
|
140
|
+
@params = { :person => {"first_name" => "Tom"}}
|
141
|
+
erb "<%= input :person, :first_name %>"
|
142
|
+
end
|
143
|
+
|
144
|
+
get '/tom'
|
145
|
+
last_response.body.should == %q(<input id="person_first_name" name="person[first_name]" type="text" value="Tom" />)
|
146
|
+
end
|
147
|
+
|
148
|
+
it 'renders an textarea tag type text without @params' do
|
149
|
+
app.get '/notes' do
|
150
|
+
erb "<%= textarea :person, :notes %>"
|
151
|
+
end
|
152
|
+
|
153
|
+
get '/notes?person[notes]=Yeppers'
|
154
|
+
last_response.body.should == %q(<textarea id="person_notes" name="person[notes]">Yeppers</textarea>)
|
155
|
+
end
|
156
|
+
|
157
|
+
it 'renders a textarea tag with @params' do
|
158
|
+
app.get '/notes2' do
|
159
|
+
@params = { :person => {"notes" => "This is a note"}}
|
160
|
+
erb "<%= textarea :person, :notes %>"
|
161
|
+
end
|
162
|
+
|
163
|
+
get '/notes2'
|
164
|
+
last_response.body.should == %q(<textarea id="person_notes" name="person[notes]">This is a note</textarea>)
|
165
|
+
end
|
166
|
+
|
167
|
+
it 'renders a textarea tag with @params' do
|
168
|
+
app.get '/img' do
|
169
|
+
erb "<%= image '/images/hello.png', :alt => 'Lolcatz' %>"
|
170
|
+
end
|
171
|
+
|
172
|
+
get '/img'
|
173
|
+
last_response.body.should == '<img alt="Lolcatz" src="/images/hello.png" />'
|
174
|
+
end
|
175
|
+
|
176
|
+
it 'renders an input tag with a submit type' do
|
177
|
+
app.get '/sub' do
|
178
|
+
erb "<%= submit 'Create' %>"
|
179
|
+
end
|
180
|
+
|
181
|
+
get '/sub'
|
182
|
+
last_response.body.should == '<input id="button_create" name="submit" type="submit" value="Create" />'
|
183
|
+
end
|
184
|
+
|
185
|
+
it 'renders an input tag with a submit type with zero args' do
|
186
|
+
app.get '/create' do
|
187
|
+
erb "<%= submit %>"
|
188
|
+
end
|
189
|
+
|
190
|
+
get '/create'
|
191
|
+
last_response.body.should == '<input id="button_submit" name="submit" type="submit" value="Submit" />'
|
192
|
+
end
|
193
|
+
|
194
|
+
it 'renders an input tag with a checkbox type' do
|
195
|
+
app.get '/check' do
|
196
|
+
erb "<%= checkbox :person, :active, 'Yes' %>"
|
197
|
+
end
|
198
|
+
|
199
|
+
get '/check'
|
200
|
+
last_response.body.should ==
|
201
|
+
'<input id="person_active_yes" name="person[active]" type="checkbox" value="Yes" /><label for="person_active_yes">Yes</label>'
|
202
|
+
end
|
203
|
+
|
204
|
+
it 'renders an input tag with a multiple checkbox type' do
|
205
|
+
app.get '/check2' do
|
206
|
+
erb "<%= checkbox :person, :eyes, [1,2,3] %>"
|
207
|
+
end
|
208
|
+
|
209
|
+
get '/check2'
|
210
|
+
last_response.body.should ==
|
211
|
+
'<input id="person_eyes_1" name="person[eyes][]" type="checkbox" value="1" /><label for="person_eyes_1">1</label> ' +
|
212
|
+
'<input id="person_eyes_2" name="person[eyes][]" type="checkbox" value="2" /><label for="person_eyes_2">2</label> ' +
|
213
|
+
'<input id="person_eyes_3" name="person[eyes][]" type="checkbox" value="3" /><label for="person_eyes_3">3</label>'
|
214
|
+
end
|
215
|
+
|
216
|
+
it 'renders an input tag with a radio type' do
|
217
|
+
app.get '/radio' do
|
218
|
+
erb "<%= radio :person, :gender, [['M','Male'],['F','Female'],'Other'] %>"
|
219
|
+
end
|
220
|
+
|
221
|
+
get '/radio'
|
222
|
+
last_response.body.should ==
|
223
|
+
"<input id=\"person_gender_m\" name=\"person[gender]\" type=\"radio\" value=\"M\" /><label for=\"person_gender_m\">Male</label> " +
|
224
|
+
"<input id=\"person_gender_f\" name=\"person[gender]\" type=\"radio\" value=\"F\" /><label for=\"person_gender_f\">Female</label> " +
|
225
|
+
"<input id=\"person_gender_other\" name=\"person[gender]\" type=\"radio\" value=\"Other\" /><label for=\"person_gender_other\">Other</label>"
|
226
|
+
end
|
227
|
+
|
228
|
+
it 'renders a select tag' do
|
229
|
+
app.get '/select' do
|
230
|
+
erb "<%= select :person, :relationship, ['Friend','CoWorker','Lead'] %>"
|
231
|
+
end
|
232
|
+
|
233
|
+
get '/select'
|
234
|
+
last_response.body.should == '<select id="person_relationship" name="person[relationship]">' +
|
235
|
+
'<option value="Friend">Friend</option><option value="CoWorker">CoWorker</option>' +
|
236
|
+
'<option value="Lead">Lead</option></select>'
|
237
|
+
end
|
238
|
+
|
239
|
+
it 'renders a hidden tag with value' do
|
240
|
+
app.get '/hidden' do
|
241
|
+
erb '<%= hidden :person, :id, :value => 1 %>'
|
242
|
+
end
|
243
|
+
|
244
|
+
get '/hidden'
|
245
|
+
last_response.body.should == '<input id="person_id" name="person[id]" type="hidden" value="1" />'
|
246
|
+
end
|
247
|
+
|
248
|
+
it 'renders a form tag' do
|
249
|
+
app.get '/form' do
|
250
|
+
erb "<%= form :person, :create %>"
|
251
|
+
end
|
252
|
+
|
253
|
+
get '/form'
|
254
|
+
last_response.body.should == %q(<form action="/person" method="POST">)
|
255
|
+
end
|
256
|
+
|
257
|
+
# it 'renders a form_for style tag' do
|
258
|
+
# app.get '/form_for' do
|
259
|
+
# erb <<-EndTemplate
|
260
|
+
# <% form(:person, :create) do |f| %>
|
261
|
+
# <%= f.input(:login) %>
|
262
|
+
# <%= f.password(:password) %>
|
263
|
+
# <%= submit %>
|
264
|
+
# <% end %>
|
265
|
+
# EndTemplate
|
266
|
+
# end
|
267
|
+
#
|
268
|
+
# get '/form_for'
|
269
|
+
# last_response.body.should == %q(<form action="/person" method="POST">)
|
270
|
+
# end
|
271
|
+
|
272
|
+
it 'renders a fieldset group' do
|
273
|
+
app.get '/fieldset' do
|
274
|
+
erb <<-EndTemplate
|
275
|
+
<% fieldset(:user) do |f| %>
|
276
|
+
<%= f.input(:first_name) %>
|
277
|
+
<%= f.input(:last_name) %>
|
278
|
+
|
279
|
+
<%= f.input(:email, :size => 40) %>
|
280
|
+
|
281
|
+
<%= f.password(:password) %>
|
282
|
+
<%= f.password(:confirm_password) %>
|
283
|
+
|
284
|
+
<%= f.radio(:gender, ['M', 'F']) %>
|
285
|
+
<% end %>
|
286
|
+
<%= submit %>
|
287
|
+
EndTemplate
|
288
|
+
end
|
289
|
+
|
290
|
+
get '/fieldset'
|
291
|
+
last_response.body.should ==
|
292
|
+
" <input id=\"user_first_name\" name=\"user[first_name]\" type=\"text\" />\n <input id=\"user_last_name\" name=\"user[last_name]\" type=\"text\" />\n\n <input id=\"user_email\" name=\"user[email]\" size=\"40\" type=\"text\" />\n\n <input id=\"user_password\" name=\"user[password]\" type=\"password\" />\n <input id=\"user_confirm_password\" name=\"user[confirm_password]\" type=\"password\" />\n\n <input id=\"user_gender_m\" name=\"user[gender]\" type=\"radio\" value=\"M\" /><label for=\"user_gender_m\">M</label> <input id=\"user_gender_f\" name=\"user[gender]\" type=\"radio\" value=\"F\" /><label for=\"user_gender_f\">F</label>\n<input id=\"button_submit\" name=\"submit\" type=\"submit\" value=\"Submit\" />"
|
293
|
+
end
|
294
|
+
end
|
295
|
+
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,55 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'bacon'
|
3
|
+
require 'rack/test'
|
4
|
+
|
5
|
+
$LOAD_PATH.unshift(File.expand_path File.dirname(__FILE__))
|
6
|
+
$LOAD_PATH.unshift(File.expand_path File.join(File.dirname(__FILE__), '..', 'lib'))
|
7
|
+
require 'sinatra/base'
|
8
|
+
require 'sinatra/form_helpers'
|
9
|
+
|
10
|
+
class TestFormHelpers
|
11
|
+
include Sinatra::FormHelpers
|
12
|
+
attr_accessor :params
|
13
|
+
def initialize
|
14
|
+
@params = {}
|
15
|
+
end
|
16
|
+
end
|
17
|
+
def fh
|
18
|
+
@fh ||= TestFormHelpers.new
|
19
|
+
end
|
20
|
+
|
21
|
+
class Application < Sinatra::Base
|
22
|
+
helpers Sinatra::FormHelpers
|
23
|
+
set :raise_errors, false
|
24
|
+
set :show_exceptions, false
|
25
|
+
end
|
26
|
+
|
27
|
+
Bacon.summary_on_exit
|
28
|
+
class Bacon::Context
|
29
|
+
include Rack::Test::Methods
|
30
|
+
def app
|
31
|
+
Application
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
# Lifted from sinatra/test_helpers (sinatra-contrib)
|
36
|
+
# def app
|
37
|
+
# @app ||= Class.new Sinatra::Base
|
38
|
+
# Rack::Lint.new @app
|
39
|
+
# end
|
40
|
+
#
|
41
|
+
# def app=(base)
|
42
|
+
# @app = base
|
43
|
+
# end
|
44
|
+
#
|
45
|
+
# def mock_app(base = Sinatra::Base, &block)
|
46
|
+
# inner = nil
|
47
|
+
# @app = Sinatra.new(base) do
|
48
|
+
# inner = self
|
49
|
+
# set :raise_errors, false
|
50
|
+
# set :show_exceptions, false
|
51
|
+
# class_eval(&block)
|
52
|
+
# end
|
53
|
+
# @settings = inner
|
54
|
+
# app
|
55
|
+
# end
|
metadata
ADDED
@@ -0,0 +1,73 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: sinatra-formhelpers
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease:
|
5
|
+
version: 0.4.0
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Nate Wiger
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
|
13
|
+
date: 2011-08-26 00:00:00 Z
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: bacon
|
17
|
+
prerelease: false
|
18
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
19
|
+
none: false
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: "0"
|
24
|
+
type: :development
|
25
|
+
version_requirements: *id001
|
26
|
+
description: Simple, lightweight form helpers for Sinatra. Based on initial efforts by twilson63.
|
27
|
+
email: nate@wiger.org
|
28
|
+
executables: []
|
29
|
+
|
30
|
+
extensions: []
|
31
|
+
|
32
|
+
extra_rdoc_files:
|
33
|
+
- LICENSE
|
34
|
+
- README.md
|
35
|
+
files:
|
36
|
+
- .document
|
37
|
+
- LICENSE
|
38
|
+
- README.md
|
39
|
+
- Rakefile
|
40
|
+
- VERSION
|
41
|
+
- lib/sinatra/form_helpers.rb
|
42
|
+
- sinatra-formhelpers.gemspec
|
43
|
+
- spec/form_helpers_spec.rb
|
44
|
+
- spec/spec_helper.rb
|
45
|
+
homepage: http://github.com/nateware/sinatra-formhelpers
|
46
|
+
licenses: []
|
47
|
+
|
48
|
+
post_install_message:
|
49
|
+
rdoc_options: []
|
50
|
+
|
51
|
+
require_paths:
|
52
|
+
- lib
|
53
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
54
|
+
none: false
|
55
|
+
requirements:
|
56
|
+
- - ">="
|
57
|
+
- !ruby/object:Gem::Version
|
58
|
+
version: "0"
|
59
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
60
|
+
none: false
|
61
|
+
requirements:
|
62
|
+
- - ">="
|
63
|
+
- !ruby/object:Gem::Version
|
64
|
+
version: "0"
|
65
|
+
requirements: []
|
66
|
+
|
67
|
+
rubyforge_project:
|
68
|
+
rubygems_version: 1.8.6
|
69
|
+
signing_key:
|
70
|
+
specification_version: 3
|
71
|
+
summary: Form helpers for Sinatra
|
72
|
+
test_files: []
|
73
|
+
|