informant 0.7.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.document +5 -0
- data/.gitignore +5 -0
- data/CHANGELOG.rdoc +7 -0
- data/LICENSE +20 -0
- data/README.rdoc +146 -0
- data/Rakefile +58 -0
- data/VERSION +1 -0
- data/informant.gemspec +54 -0
- data/lib/informant.rb +390 -0
- data/test/informant_test.rb +11 -0
- data/test/test_helper.rb +8 -0
- metadata +76 -0
data/.document
ADDED
data/CHANGELOG.rdoc
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2009 Alex Reisner
|
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.rdoc
ADDED
@@ -0,0 +1,146 @@
|
|
1
|
+
= Informant
|
2
|
+
|
3
|
+
Informant is a full-featured form builder for Ruby on Rails which promotes a simple syntax that keeps your views clean. Everything about a field (label, description, error display, etc) is encapsulated in a single method call. Examples and general information are below; please read the {API documentation}[http://rdoc.info/projects/alexreisner/informant] for more complete/detailed information.
|
4
|
+
|
5
|
+
|
6
|
+
== 1. Install
|
7
|
+
|
8
|
+
Install either as a plugin:
|
9
|
+
|
10
|
+
script/plugin install git://github.com/alexreisner/informant.git
|
11
|
+
|
12
|
+
or as a gem:
|
13
|
+
|
14
|
+
# add to config/environment.rb:
|
15
|
+
config.gem "informant", :source => "http://gemcutter.org/"
|
16
|
+
|
17
|
+
# at command prompt:
|
18
|
+
sudo rake gems:install
|
19
|
+
|
20
|
+
|
21
|
+
== 2. Configure
|
22
|
+
|
23
|
+
If you like you can set one of the Informant builders to be your application-wide default by adding something like this to your ApplicationHelper:
|
24
|
+
|
25
|
+
ActionView::Base.default_form_builder = Informant::Standard
|
26
|
+
|
27
|
+
However, this is not necessary. You can use choose your builder on a form-by-form basis with the <tt>:builder</tt> option to <tt>form_for</tt>. The available builders are:
|
28
|
+
|
29
|
+
Informant::Standard
|
30
|
+
Informant::Table
|
31
|
+
Informant::Simple
|
32
|
+
|
33
|
+
|
34
|
+
== 3. Use
|
35
|
+
|
36
|
+
As an example, this view code:
|
37
|
+
|
38
|
+
<% form_for @car, :builder => Informant::Standard do |f| %>
|
39
|
+
<% f.field_set "Details" do %>
|
40
|
+
|
41
|
+
<%= f.text_field :name,
|
42
|
+
:required => true,
|
43
|
+
:description => "Something Italian, please." %>
|
44
|
+
|
45
|
+
<%= f.select :manufacturer,
|
46
|
+
%w[Ascari Ferrari Lamborghini Pagani] %>
|
47
|
+
|
48
|
+
<%= f.integer_select :wheels,
|
49
|
+
:label => "Number of wheels",
|
50
|
+
:first => 2, :last => 4 %>
|
51
|
+
|
52
|
+
<%= f.text_area :description %>
|
53
|
+
|
54
|
+
<%= f.submit %>
|
55
|
+
|
56
|
+
<% end %>
|
57
|
+
<% end %>
|
58
|
+
|
59
|
+
renders HTML like this (assuming the <tt>@car</tt> is a new record):
|
60
|
+
|
61
|
+
<form action="/cars" class="new_car" id="new_car" method="post">
|
62
|
+
|
63
|
+
<!-- Rails' form authenticity token -->
|
64
|
+
<div style="margin: 0pt; padding: 0pt;">
|
65
|
+
<input name="authenticity_token" value="..." type="hidden" />
|
66
|
+
</div>
|
67
|
+
|
68
|
+
<fieldset>
|
69
|
+
<legend>Details</legend>
|
70
|
+
|
71
|
+
<div id="car_name_field" class="field">
|
72
|
+
<label for="car_name">Name <span class="required">*</span></label><br />
|
73
|
+
<input id="car_name" name="car[name]" size="30" value="" type="text" />
|
74
|
+
<p class="field_description">Something Italian, please.</p>
|
75
|
+
</div>
|
76
|
+
|
77
|
+
<div id="car_manufacturer_field" class="field">
|
78
|
+
<label for="car_manufacturer">Manufacturer</label><br />
|
79
|
+
<select id="car_manufacturer" name="car[manufacturer]">
|
80
|
+
<option value="Ascari">Ascari</option>
|
81
|
+
<option value="Ferrari">Ferrari</option>
|
82
|
+
<option value="Lamborghini">Lamborghini</option>
|
83
|
+
<option value="Pagani">Pagani</option>
|
84
|
+
</select>
|
85
|
+
</div>
|
86
|
+
|
87
|
+
<div id="car_wheels_field" class="field">
|
88
|
+
<label for="car_wheels">Number of wheels</label><br />
|
89
|
+
<select id="car_wheels" name="car[wheels]">
|
90
|
+
<option value="2">2</option>
|
91
|
+
<option value="3">3</option>
|
92
|
+
<option value="4">4</option>
|
93
|
+
</select>
|
94
|
+
</div>
|
95
|
+
|
96
|
+
<div id="car_description_field" class="field">
|
97
|
+
<label for="car_description">Description</label><br />
|
98
|
+
<textarea id="car_description" name="car[description]" cols="40" rows="20"></textarea>
|
99
|
+
</div>
|
100
|
+
|
101
|
+
<div class="button">
|
102
|
+
<input class="submit" id="car_submit" name="commit" value="Create" type="submit" />
|
103
|
+
</div>
|
104
|
+
|
105
|
+
</fieldset>
|
106
|
+
</form>
|
107
|
+
|
108
|
+
|
109
|
+
Note that the field label is inferred from the name if left blank, and the submit button (unless specified) says "Create" if the record is new, "Update" otherwise. There are other field options too. For a complete list please generate the API docs (<tt>cd vendor/plugins/informant; rake rdoc</tt>) or read them {online}[http://rdoc.info/projects/alexreisner/informant].
|
110
|
+
|
111
|
+
|
112
|
+
== Available Field Types
|
113
|
+
|
114
|
+
Currently the following field methods are available:
|
115
|
+
|
116
|
+
* standard types
|
117
|
+
* text_field
|
118
|
+
* text_area
|
119
|
+
* check_box
|
120
|
+
* password_field
|
121
|
+
* file_field
|
122
|
+
* radio_button
|
123
|
+
* hidden_field
|
124
|
+
* select
|
125
|
+
* time_zone_select
|
126
|
+
* date_select
|
127
|
+
* extended types
|
128
|
+
* integer_select
|
129
|
+
* year_select
|
130
|
+
* multipart_date_select
|
131
|
+
* habtm_check_boxes
|
132
|
+
* radio_buttons (note: plural)
|
133
|
+
|
134
|
+
Please see the inline documentation for arguments to each method.
|
135
|
+
|
136
|
+
|
137
|
+
== To-Do List
|
138
|
+
|
139
|
+
* hierarchical AJAX select fields
|
140
|
+
* add documentation for all field types
|
141
|
+
* tests
|
142
|
+
* custom options don't appear in HTML tags
|
143
|
+
* custom options work
|
144
|
+
|
145
|
+
|
146
|
+
Copyright (c) 2009 Alex Reisner, released under the MIT license
|
data/Rakefile
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'jeweler'
|
6
|
+
Jeweler::Tasks.new do |gem|
|
7
|
+
gem.name = "informant"
|
8
|
+
gem.summary = %Q{A full-featured form builder for Rails.}
|
9
|
+
gem.description = %Q{Informant is a full-featured form builder for Ruby on Rails which promotes a simple syntax that keeps your views clean. Everything about a field (label, description, error display, etc) is encapsulated in a single method call.}
|
10
|
+
gem.email = "alex@alexreisner.com"
|
11
|
+
gem.homepage = "http://github.com/alexreisner/informant"
|
12
|
+
gem.authors = ["Alex Reisner"]
|
13
|
+
gem.add_development_dependency "thoughtbot-shoulda"
|
14
|
+
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
15
|
+
end
|
16
|
+
Jeweler::GemcutterTasks.new
|
17
|
+
rescue LoadError
|
18
|
+
puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
|
19
|
+
end
|
20
|
+
|
21
|
+
require 'rake/testtask'
|
22
|
+
Rake::TestTask.new(:test) do |test|
|
23
|
+
test.libs << 'lib' << 'test'
|
24
|
+
test.pattern = 'test/**/*_test.rb'
|
25
|
+
test.verbose = true
|
26
|
+
end
|
27
|
+
|
28
|
+
begin
|
29
|
+
require 'rcov/rcovtask'
|
30
|
+
Rcov::RcovTask.new do |test|
|
31
|
+
test.libs << 'test'
|
32
|
+
test.pattern = 'test/**/*_test.rb'
|
33
|
+
test.verbose = true
|
34
|
+
end
|
35
|
+
rescue LoadError
|
36
|
+
task :rcov do
|
37
|
+
abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
task :test => :check_dependencies
|
42
|
+
|
43
|
+
task :default => :test
|
44
|
+
|
45
|
+
require 'rake/rdoctask'
|
46
|
+
Rake::RDocTask.new do |rdoc|
|
47
|
+
if File.exist?('VERSION')
|
48
|
+
version = File.read('VERSION')
|
49
|
+
else
|
50
|
+
version = ""
|
51
|
+
end
|
52
|
+
|
53
|
+
rdoc.rdoc_dir = 'rdoc'
|
54
|
+
rdoc.title = "Informant #{version}"
|
55
|
+
rdoc.rdoc_files.include('README*')
|
56
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
57
|
+
end
|
58
|
+
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.7.0
|
data/informant.gemspec
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE
|
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{informant}
|
8
|
+
s.version = "0.7.0"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["Alex Reisner"]
|
12
|
+
s.date = %q{2009-10-08}
|
13
|
+
s.description = %q{Informant is a full-featured form builder for Ruby on Rails which promotes a simple syntax that keeps your views clean. Everything about a field (label, description, error display, etc) is encapsulated in a single method call.}
|
14
|
+
s.email = %q{alex@alexreisner.com}
|
15
|
+
s.extra_rdoc_files = [
|
16
|
+
"LICENSE",
|
17
|
+
"README.rdoc"
|
18
|
+
]
|
19
|
+
s.files = [
|
20
|
+
".document",
|
21
|
+
".gitignore",
|
22
|
+
"CHANGELOG.rdoc",
|
23
|
+
"LICENSE",
|
24
|
+
"README.rdoc",
|
25
|
+
"Rakefile",
|
26
|
+
"VERSION",
|
27
|
+
"informant.gemspec",
|
28
|
+
"lib/informant.rb",
|
29
|
+
"test/informant_test.rb",
|
30
|
+
"test/test_helper.rb"
|
31
|
+
]
|
32
|
+
s.homepage = %q{http://github.com/alexreisner/informant}
|
33
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
34
|
+
s.require_paths = ["lib"]
|
35
|
+
s.rubygems_version = %q{1.3.5}
|
36
|
+
s.summary = %q{A full-featured form builder for Rails.}
|
37
|
+
s.test_files = [
|
38
|
+
"test/test_helper.rb",
|
39
|
+
"test/informant_test.rb"
|
40
|
+
]
|
41
|
+
|
42
|
+
if s.respond_to? :specification_version then
|
43
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
44
|
+
s.specification_version = 3
|
45
|
+
|
46
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
47
|
+
s.add_development_dependency(%q<thoughtbot-shoulda>, [">= 0"])
|
48
|
+
else
|
49
|
+
s.add_dependency(%q<thoughtbot-shoulda>, [">= 0"])
|
50
|
+
end
|
51
|
+
else
|
52
|
+
s.add_dependency(%q<thoughtbot-shoulda>, [">= 0"])
|
53
|
+
end
|
54
|
+
end
|
data/lib/informant.rb
ADDED
@@ -0,0 +1,390 @@
|
|
1
|
+
##
|
2
|
+
# The goal of Informant is to simplify your form code by encapsulating all
|
3
|
+
# aspects of a field (label, description, etc) in a single method call. What
|
4
|
+
# used to be written as:
|
5
|
+
#
|
6
|
+
# <div class="field">
|
7
|
+
# <%= f.label :name %><br />
|
8
|
+
# <%= f.text_field :name %><br />
|
9
|
+
# <p>Please use proper capitalization.</p>
|
10
|
+
# </div>
|
11
|
+
#
|
12
|
+
# can be written like this with Informant:
|
13
|
+
#
|
14
|
+
# <%= f.text_field :name, :description => "Please use proper capitalization." %>
|
15
|
+
#
|
16
|
+
# The label is inferred from the field name or can be specified explicitly.
|
17
|
+
# The complete list of options:
|
18
|
+
#
|
19
|
+
# * <tt>:label</tt> - add a <label> tag for the field
|
20
|
+
# * <tt>:colon</tt> - if true, includes a colon at the end of the label
|
21
|
+
# * <tt>:description</tt> - explanatory text displayed underneath the field
|
22
|
+
# * <tt>:required</tt> - adds an asterisk if true
|
23
|
+
# * <tt>:decoration</tt> - arbitrary string which is appended to the field (often used for AJAX "spinner")
|
24
|
+
#
|
25
|
+
# Informant contains several form builders, each with the same syntax but
|
26
|
+
# different display:
|
27
|
+
#
|
28
|
+
# * <tt>Informant::Standard</tt> - displays fields in a <div>
|
29
|
+
# * <tt>Informant::Table</tt> - displays fields in table rows
|
30
|
+
# * <tt>Informant::Simple</tt> - adds no containers at all
|
31
|
+
#
|
32
|
+
# Please see the per-method documentation for details. It's also easy to
|
33
|
+
# customize the display of any of the included builders. Just create a
|
34
|
+
# subclass and override the +default_field_template+ and
|
35
|
+
# +check_box_field_template+ methods.
|
36
|
+
#
|
37
|
+
module Informant
|
38
|
+
|
39
|
+
##
|
40
|
+
# Displays fields in a <div>, label on one line, field below it.
|
41
|
+
#
|
42
|
+
class Standard < ActionView::Helpers::FormBuilder
|
43
|
+
|
44
|
+
# Declare some options as custom (don't pass to built-in form helpers).
|
45
|
+
@@custom_field_options = [:label, :required, :description, :decoration]
|
46
|
+
@@custom_label_options = [:required, :colon, :label_for]
|
47
|
+
|
48
|
+
@@custom_options = @@custom_field_options + @@custom_label_options
|
49
|
+
|
50
|
+
# Run already-defined helpers through our "shell".
|
51
|
+
helpers = field_helpers +
|
52
|
+
%w(select time_zone_select date_select) -
|
53
|
+
%w(hidden_field fields_for label)
|
54
|
+
helpers.each do |h|
|
55
|
+
define_method h do |field, *args|
|
56
|
+
options = args.detect { |a| a.is_a?(Hash) } || {}
|
57
|
+
case h
|
58
|
+
when 'check_box':
|
59
|
+
template = "check_box_field"
|
60
|
+
options[:colon] = false
|
61
|
+
when 'radio_button':
|
62
|
+
template = "radio_button_choice"
|
63
|
+
options[:colon] = false
|
64
|
+
else
|
65
|
+
template = "default_field"
|
66
|
+
end
|
67
|
+
build_shell(field, options, template) { super }
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
##
|
72
|
+
# Render a set of radio buttons. Takes a method name, an array of
|
73
|
+
# choices (just like a +select+ field), and an Informant options hash.
|
74
|
+
#
|
75
|
+
def radio_buttons(method, choices, options = {})
|
76
|
+
choices.map!{ |i| i.is_a?(Array) ? i : [i] }
|
77
|
+
build_shell(method, options, "radio_buttons_field") do
|
78
|
+
choices.map{ |c| radio_button method, c[1], :label => c[0],
|
79
|
+
:label_for => [object_name, method, c[1].to_s.downcase].join('_') }
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
##
|
84
|
+
# Render a set of check boxes for selecting HABTM-associated objects.
|
85
|
+
# Takes a method name (eg, category_ids), an array of
|
86
|
+
# choices (just like a +select+ field), and an Informant options hash.
|
87
|
+
# In the default template the check boxes are enclosed in a <div> with
|
88
|
+
# CSS class <tt>habtm_check_boxes</tt> which can be styled thusly to
|
89
|
+
# achieve a scrolling list:
|
90
|
+
#
|
91
|
+
# .habtm_check_boxes {
|
92
|
+
# overflow: auto;
|
93
|
+
# height: 150px;
|
94
|
+
# }
|
95
|
+
#
|
96
|
+
# A hidden field is included which eliminates the need to handle the
|
97
|
+
# no-boxes-checked case in the controller, for example:
|
98
|
+
#
|
99
|
+
# <input type="hidden" name="article[categories][]" value="" />
|
100
|
+
#
|
101
|
+
# This ensures that un-checking all boxes will work as expected.
|
102
|
+
# Unfortunately the check_box template is not applied to each check box
|
103
|
+
# (because the standard method of querying the @object for the field's
|
104
|
+
# value does not work--ie, there is no "categories[]" method).
|
105
|
+
#
|
106
|
+
def habtm_check_boxes(method, choices, options = {})
|
107
|
+
choices.map!{ |i| i.is_a?(Array) ? i : [i] }
|
108
|
+
base_id = "#{object_name}_#{method}"
|
109
|
+
base_name = "#{object_name}[#{method}]"
|
110
|
+
|
111
|
+
@template.hidden_field_tag(
|
112
|
+
"#{base_name}[]", "", :id => "#{base_id}_empty") +
|
113
|
+
build_shell(method, options, "habtm_check_boxes_field") do
|
114
|
+
choices.map do |c|
|
115
|
+
field_id = "#{base_id}_#{c[1].to_s.downcase}"
|
116
|
+
"<div class=\"field\">" + @template.check_box_tag(
|
117
|
+
"#{base_name}[]", "1",
|
118
|
+
@object.send(method).include?(c[1]),
|
119
|
+
:id => field_id
|
120
|
+
) + @template.label_tag(field_id, c[0]) + "</div>\n"
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
##
|
126
|
+
# Standard Rails date selector.
|
127
|
+
#
|
128
|
+
def date_select(method, options = {})
|
129
|
+
options[:include_blank] ||= false
|
130
|
+
options[:start_year] ||= 1801
|
131
|
+
options[:end_year] ||= Time.now.year
|
132
|
+
options[:label_for] = "#{object_name}_#{method}_1i"
|
133
|
+
build_shell(method, options) { super }
|
134
|
+
end
|
135
|
+
|
136
|
+
##
|
137
|
+
# This differs from the Rails-default date_select in that it
|
138
|
+
# submits three distinct fields for storage in three separate attributes.
|
139
|
+
# This allows for partial dates (eg, "1984" or "October 1984").
|
140
|
+
# See {FlexDate}[http://github.com/alexreisner/flex_date] for
|
141
|
+
# storing and manipulating partial dates.
|
142
|
+
#
|
143
|
+
def multipart_date_select(method, options = {})
|
144
|
+
options[:include_blank] ||= false
|
145
|
+
options[:start_year] ||= 1801
|
146
|
+
options[:end_year] ||= Time.now.year
|
147
|
+
options[:prefix] = object_name # for date helpers
|
148
|
+
options[:label_for] = "#{object_name}_#{method}_y"
|
149
|
+
build_shell(method, options) do
|
150
|
+
[['y', 'year'], ['m', 'month'], ['d', 'day']].map{ |p|
|
151
|
+
i,j = p
|
152
|
+
value = @object.send(method.to_s + '_' + i)
|
153
|
+
options[:field_name] = method.to_s + '_' + i
|
154
|
+
eval("@template.select_#{j}(#{value.inspect}, options)")
|
155
|
+
}.join(' ')
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
##
|
160
|
+
# Year select field. Takes options <tt>:start_year</tt> and
|
161
|
+
# <tt>:end_year</tt>, and <tt>:step</tt>.
|
162
|
+
#
|
163
|
+
def year_select(method, options = {})
|
164
|
+
options[:first] = options[:start_year] || 1801
|
165
|
+
options[:last] = options[:end_year] || Date.today.year
|
166
|
+
integer_select(method, options)
|
167
|
+
end
|
168
|
+
|
169
|
+
##
|
170
|
+
# Integer select field.
|
171
|
+
# Takes options <tt>:first</tt>, <tt>:last</tt>, and <tt>:step</tt>.
|
172
|
+
#
|
173
|
+
def integer_select(method, options = {})
|
174
|
+
options[:step] ||= 1
|
175
|
+
choices = []; i = 0
|
176
|
+
(options[:first]..options[:last]).each do |n|
|
177
|
+
choices << n if i % options[:step] == 0
|
178
|
+
i += 1
|
179
|
+
end
|
180
|
+
select method, choices, options
|
181
|
+
end
|
182
|
+
|
183
|
+
##
|
184
|
+
# Submit button with smart default text (if +value+ is nil uses "Create"
|
185
|
+
# for new record or "Update" for old record).
|
186
|
+
#
|
187
|
+
def submit(value = nil, options = {})
|
188
|
+
value = (@object.new_record?? "Create" : "Update") if value.nil?
|
189
|
+
build_shell(value, options, 'submit_button') { super }
|
190
|
+
end
|
191
|
+
|
192
|
+
##
|
193
|
+
# Render a field label.
|
194
|
+
#
|
195
|
+
def label(method, text = nil, options = {})
|
196
|
+
colon = false if options[:colon].nil?
|
197
|
+
options[:for] = options[:label_for]
|
198
|
+
required = options[:required]
|
199
|
+
|
200
|
+
# remove special options
|
201
|
+
options.delete :colon
|
202
|
+
options.delete :label_for
|
203
|
+
options.delete :required
|
204
|
+
|
205
|
+
text = text.blank?? method.to_s.humanize : text.to_s
|
206
|
+
text += ':' if colon
|
207
|
+
text += ' <span class="required">*</span>' if required
|
208
|
+
super
|
209
|
+
end
|
210
|
+
|
211
|
+
##
|
212
|
+
# Render a field set (HTML <fieldset>). Takes the legend (optional), an
|
213
|
+
# options hash, and a block in which fields are rendered.
|
214
|
+
#
|
215
|
+
def field_set(legend = nil, options = nil, &block)
|
216
|
+
content = @template.capture(&block)
|
217
|
+
@template.concat(@template.tag(:fieldset, options, true))
|
218
|
+
@template.concat(@template.content_tag(:legend, legend)) unless legend.blank?
|
219
|
+
@template.concat(content)
|
220
|
+
@template.concat("</fieldset>")
|
221
|
+
end
|
222
|
+
|
223
|
+
|
224
|
+
private # ---------------------------------------------------------------
|
225
|
+
|
226
|
+
##
|
227
|
+
# Insert a field into its HTML "shell".
|
228
|
+
#
|
229
|
+
def build_shell(method, options, template = 'default_field') #:nodoc:
|
230
|
+
|
231
|
+
# Build new options hash for custom label options.
|
232
|
+
label_options = options.reject{ |i,j| !@@custom_label_options.include? i }
|
233
|
+
|
234
|
+
# Build new options hash for custom field options.
|
235
|
+
field_options = options.reject{ |i,j| !@@custom_field_options.include? i }
|
236
|
+
|
237
|
+
# Remove custom options from options hash so things like
|
238
|
+
# <tt>include_blank</tt> aren't added as HTML attributes.
|
239
|
+
options.reject!{ |i,j| @@custom_options.include? i }
|
240
|
+
|
241
|
+
locals = {
|
242
|
+
:element => yield,
|
243
|
+
:label => label(method, field_options[:label], label_options),
|
244
|
+
:description => field_options[:description],
|
245
|
+
:error => error_message_on(method, options),
|
246
|
+
:div_id => "#{@object_name}_#{method}_field",
|
247
|
+
:required => field_options[:required],
|
248
|
+
:decoration => field_options[:decoration] || nil
|
249
|
+
}
|
250
|
+
send "#{template}_template", locals
|
251
|
+
end
|
252
|
+
|
253
|
+
##
|
254
|
+
# Render default field template.
|
255
|
+
#
|
256
|
+
def default_field_template(l = {})
|
257
|
+
<<-END
|
258
|
+
<div id="#{l[:div_id]}" class="field">
|
259
|
+
#{l[:label]}<br />
|
260
|
+
#{l[:element]}#{l[:decoration]}
|
261
|
+
#{"<p class=\"field_description\">#{l[:description]}</p>" unless l[:description].blank?}
|
262
|
+
</div>
|
263
|
+
END
|
264
|
+
end
|
265
|
+
|
266
|
+
##
|
267
|
+
# Render check box field template.
|
268
|
+
#
|
269
|
+
def check_box_field_template(l = {})
|
270
|
+
<<-END
|
271
|
+
<div id="#{l[:div_id]}" class="field">
|
272
|
+
#{l[:element]} #{l[:label]} #{l[:decoration]}<br />
|
273
|
+
#{"<p class=\"field_description\">#{l[:description]}</p>" unless l[:description].blank?}
|
274
|
+
</div>
|
275
|
+
END
|
276
|
+
end
|
277
|
+
|
278
|
+
##
|
279
|
+
# Render single radio button. Note that this is the only field
|
280
|
+
# template without an enclosing <tt><div class="field"></tt> because it
|
281
|
+
# is intended for use only within the radio_buttons_template (plural).
|
282
|
+
#
|
283
|
+
def radio_button_choice_template(l = {})
|
284
|
+
<<-END
|
285
|
+
#{l[:element]} #{l[:label]}
|
286
|
+
END
|
287
|
+
end
|
288
|
+
|
289
|
+
##
|
290
|
+
# Render a group of radio buttons.
|
291
|
+
#
|
292
|
+
def radio_buttons_field_template(l = {})
|
293
|
+
default_field_template(l)
|
294
|
+
end
|
295
|
+
|
296
|
+
##
|
297
|
+
# Render a group of HABTM check boxes.
|
298
|
+
#
|
299
|
+
def habtm_check_boxes_field_template(l = {})
|
300
|
+
<<-END
|
301
|
+
<div id="#{l[:div_id]}" class="field">
|
302
|
+
#{l[:label]}<br />
|
303
|
+
<div class="habtm_check_boxes">#{l[:element]}</div>#{l[:decoration]}
|
304
|
+
#{"<p class=\"field_description\">#{l[:description]}</p>" unless l[:description].blank?}
|
305
|
+
</div>
|
306
|
+
END
|
307
|
+
end
|
308
|
+
|
309
|
+
##
|
310
|
+
# Render submit button template.
|
311
|
+
#
|
312
|
+
def submit_button_template(l = {})
|
313
|
+
<<-END
|
314
|
+
<div class="button">#{l[:element]}</div>
|
315
|
+
END
|
316
|
+
end
|
317
|
+
end
|
318
|
+
|
319
|
+
|
320
|
+
##
|
321
|
+
# Displays fields with no surrounding HTML containers.
|
322
|
+
#
|
323
|
+
class Simple < Standard
|
324
|
+
|
325
|
+
private # ---------------------------------------------------------------
|
326
|
+
|
327
|
+
##
|
328
|
+
# Render default field template.
|
329
|
+
#
|
330
|
+
def default_field_template(l = {})
|
331
|
+
"#{l[:element]}#{l[:decoration]}"
|
332
|
+
end
|
333
|
+
|
334
|
+
##
|
335
|
+
# Render check box field template.
|
336
|
+
#
|
337
|
+
def check_box_field_template(l = {})
|
338
|
+
"#{l[:element]} #{l[:label]} #{l[:decoration]}"
|
339
|
+
end
|
340
|
+
|
341
|
+
##
|
342
|
+
# Render submit button template.
|
343
|
+
#
|
344
|
+
def submit_button_template(l = {})
|
345
|
+
l[:element]
|
346
|
+
end
|
347
|
+
end
|
348
|
+
|
349
|
+
|
350
|
+
##
|
351
|
+
# Displays fields in table rows: label in first column, field (with
|
352
|
+
# description and decoration) in second.
|
353
|
+
#
|
354
|
+
class Table < Standard
|
355
|
+
|
356
|
+
private # ---------------------------------------------------------------
|
357
|
+
|
358
|
+
##
|
359
|
+
# Render default field template.
|
360
|
+
#
|
361
|
+
def default_field_template(l = {})
|
362
|
+
<<-END
|
363
|
+
<tr id="#{l[:div_id]}" class="field">
|
364
|
+
<td>#{l[:label]}</td>
|
365
|
+
<td>#{l[:element]}#{l[:decoration]}
|
366
|
+
#{"<p class=\"field_description\">#{l[:description]}</p>" unless l[:description].blank?}</td>
|
367
|
+
</tr>
|
368
|
+
END
|
369
|
+
end
|
370
|
+
|
371
|
+
##
|
372
|
+
# Render check box field template.
|
373
|
+
#
|
374
|
+
def check_box_field_template(l = {})
|
375
|
+
default_field_template(l)
|
376
|
+
end
|
377
|
+
|
378
|
+
##
|
379
|
+
# Render submit button template.
|
380
|
+
#
|
381
|
+
def submit_button_template(l = {})
|
382
|
+
<<-END
|
383
|
+
<tr id="#{l[:div_id]}" class="field">
|
384
|
+
<td></td>
|
385
|
+
<td class="button">#{l[:element]}</td>
|
386
|
+
</tr>
|
387
|
+
END
|
388
|
+
end
|
389
|
+
end
|
390
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class InformantTest < ActionView::TestCase
|
4
|
+
|
5
|
+
test "text field" do
|
6
|
+
# object_name, object, self, options, block
|
7
|
+
p = lambda{ |b| b.text_field(:color) }
|
8
|
+
b = Informant::Standard.new(:car, Object.new, @controller, {}, p)
|
9
|
+
assert_equal "", b
|
10
|
+
end
|
11
|
+
end
|
data/test/test_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,76 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: informant
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.7.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Alex Reisner
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-10-08 00:00:00 -04:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: thoughtbot-shoulda
|
17
|
+
type: :development
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: "0"
|
24
|
+
version:
|
25
|
+
description: Informant is a full-featured form builder for Ruby on Rails which promotes a simple syntax that keeps your views clean. Everything about a field (label, description, error display, etc) is encapsulated in a single method call.
|
26
|
+
email: alex@alexreisner.com
|
27
|
+
executables: []
|
28
|
+
|
29
|
+
extensions: []
|
30
|
+
|
31
|
+
extra_rdoc_files:
|
32
|
+
- LICENSE
|
33
|
+
- README.rdoc
|
34
|
+
files:
|
35
|
+
- .document
|
36
|
+
- .gitignore
|
37
|
+
- CHANGELOG.rdoc
|
38
|
+
- LICENSE
|
39
|
+
- README.rdoc
|
40
|
+
- Rakefile
|
41
|
+
- VERSION
|
42
|
+
- informant.gemspec
|
43
|
+
- lib/informant.rb
|
44
|
+
- test/informant_test.rb
|
45
|
+
- test/test_helper.rb
|
46
|
+
has_rdoc: true
|
47
|
+
homepage: http://github.com/alexreisner/informant
|
48
|
+
licenses: []
|
49
|
+
|
50
|
+
post_install_message:
|
51
|
+
rdoc_options:
|
52
|
+
- --charset=UTF-8
|
53
|
+
require_paths:
|
54
|
+
- lib
|
55
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
56
|
+
requirements:
|
57
|
+
- - ">="
|
58
|
+
- !ruby/object:Gem::Version
|
59
|
+
version: "0"
|
60
|
+
version:
|
61
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
62
|
+
requirements:
|
63
|
+
- - ">="
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
version: "0"
|
66
|
+
version:
|
67
|
+
requirements: []
|
68
|
+
|
69
|
+
rubyforge_project:
|
70
|
+
rubygems_version: 1.3.5
|
71
|
+
signing_key:
|
72
|
+
specification_version: 3
|
73
|
+
summary: A full-featured form builder for Rails.
|
74
|
+
test_files:
|
75
|
+
- test/test_helper.rb
|
76
|
+
- test/informant_test.rb
|