better_form 0.7.0 → 0.8.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +101 -37
- data/lib/better_form/builder.rb +17 -51
- data/lib/better_form/version.rb +1 -1
- data/lib/generators/better_form/better_form_generator.rb +12 -0
- data/lib/generators/better_form/templates/better_form.rb +12 -0
- data/lib/generators/better_form/templates/field.html.erb +31 -0
- data/lib/generators/better_form/templates/inline_field.html.erb +11 -0
- metadata +7 -5
data/README.md
CHANGED
@@ -1,12 +1,19 @@
|
|
1
1
|
better_form Readme
|
2
2
|
==================
|
3
3
|
|
4
|
-
A Rails 3
|
4
|
+
A better Rails 3 FormBuilder.
|
5
5
|
|
6
|
-
|
7
|
-
|
8
|
-
*
|
9
|
-
*
|
6
|
+
Features:
|
7
|
+
|
8
|
+
* Uses partials to put you in control of templating your form fields
|
9
|
+
* Free Javascript validation using the same validations you specify in your models
|
10
|
+
* Out of the box support for common cases; fully customizeable if that's how you roll
|
11
|
+
|
12
|
+
Why should I use `better_form` over `formtastic` or `simple_form`?
|
13
|
+
|
14
|
+
* No DSL; just use the default Rails form helpers
|
15
|
+
* No fixed ideas about what options or output you want for your fields
|
16
|
+
* Less features, less code, less complexity; you get DRY fields with DRY validators and nothing more
|
10
17
|
|
11
18
|
Links
|
12
19
|
=====
|
@@ -18,44 +25,113 @@ Links
|
|
18
25
|
Installation and Usage
|
19
26
|
======================
|
20
27
|
|
21
|
-
Add `better_form` to your Gemfile
|
28
|
+
Add `better_form` to your Gemfile and run `bundle install`.
|
29
|
+
|
30
|
+
Generate the required initializer and boilerplate form field partial:
|
31
|
+
|
32
|
+
rails generate better_form
|
33
|
+
|
34
|
+
Use the `better_form_for` method to create a better form, and add fields using the default Rails form helpers.
|
35
|
+
|
36
|
+
Customizing your form fields
|
37
|
+
============================
|
38
|
+
|
39
|
+
Modify the generated form field partial in `app/views/better_form/_field.html.erb`. Or, create your own from scratch using whatever templating engine you prefer - it's just a regular partial.
|
40
|
+
|
41
|
+
A few ideas to get you in the mood:
|
42
|
+
|
43
|
+
# Epic error messages
|
44
|
+
<%= field[:field] %>
|
45
|
+
<%= error_messages.each do |message| %>
|
46
|
+
<h1 class="fail">OH NOES! <%= message %></h1>
|
47
|
+
<% end %>
|
48
|
+
|
49
|
+
# Floated field descriptions
|
50
|
+
<div class="form_field">
|
51
|
+
<%= field[:field] %>
|
52
|
+
<div class="description float-right"><%= field[:description] -%></div>
|
53
|
+
</div>
|
54
|
+
|
55
|
+
# All the bells and whistles
|
56
|
+
<div class="better_form_field <%= 'invalid' if error_messages %>">
|
57
|
+
<div class="field">
|
58
|
+
<% if field[:prefix] %>
|
59
|
+
<span class="field_prefix"><%= field[:prefix] %></span>
|
60
|
+
<% end %>
|
61
|
+
<%= field[:field] %>
|
62
|
+
<% if field[:suffix] %>
|
63
|
+
<span class="field_suffix"><%= field[:suffix] %></span>
|
64
|
+
<% end %>
|
65
|
+
<% if field[:description] %>
|
66
|
+
<br>
|
67
|
+
<span class="field_description"><%= field[:description] %></span>
|
68
|
+
<% end %>
|
69
|
+
</div>
|
70
|
+
<%= if error_messages %>
|
71
|
+
<span class="error_header">Oops!</span>
|
72
|
+
<div class="field_errors">
|
73
|
+
<%= error_messages.each do |message| %>
|
74
|
+
<p class="error_message">
|
75
|
+
<%= image_tag('warning_small') %>
|
76
|
+
<%= message %>
|
77
|
+
</p>
|
78
|
+
<% end %>
|
79
|
+
</div>
|
80
|
+
</div>
|
81
|
+
</div>
|
82
|
+
|
83
|
+
Have a look at `app/views/better_form/_field.html.erb` to get started.
|
84
|
+
|
85
|
+
Built-in options
|
86
|
+
================
|
22
87
|
|
23
|
-
|
88
|
+
Validations
|
89
|
+
-----------
|
24
90
|
|
25
|
-
|
91
|
+
Fields can automatically have validation data generated for them using the validations defined in your models:
|
92
|
+
|
93
|
+
class User < ActiveRecord::Base
|
94
|
+
validates :name, :presence => true
|
95
|
+
end
|
26
96
|
|
27
|
-
|
97
|
+
<%= f.text_field :name %>
|
28
98
|
|
29
|
-
=
|
99
|
+
<label for='user_name'>What shall we call you?</label>
|
100
|
+
<input type='text' id='user_name' name='user[name]' data-validates-presence="Name is required" />
|
101
|
+
|
102
|
+
Setting a custom error message will be reflected in the validation that is generated:
|
103
|
+
|
104
|
+
validates :name, :presence => { :message => 'Please enter your full name' }
|
105
|
+
|
106
|
+
<input type='text' id='user_name' name='user[name]' data-validates-presence="Please enter your full name" />
|
30
107
|
|
31
|
-
|
108
|
+
Validations are enabled by default. They can be enabled or disabled for a form, or for particular fields:
|
32
109
|
|
33
|
-
|
34
|
-
|
35
|
-
|
110
|
+
# Don't generate validations for this form, unless instructed to for specific fields
|
111
|
+
<%= better_form_for @user, :validate => false do |f| %>
|
112
|
+
<%= f.text_field :name %>
|
113
|
+
<%= f.text_field :password, :validate => true %>
|
36
114
|
|
37
115
|
Labels
|
38
116
|
------
|
39
117
|
|
40
|
-
Fields
|
118
|
+
Fields can automatically have label text generated for them, with the label text defaulting to the attribute that the field is for:
|
41
119
|
|
42
|
-
|
120
|
+
<%= f.text_field :name %>
|
43
121
|
|
44
122
|
<label for='user_name'>Name</label>
|
45
123
|
<input type='text' id='user_name' name='user[name]' />
|
46
124
|
|
47
125
|
To specify your own label text, pass a string as the `:label` option:
|
48
126
|
|
49
|
-
|
127
|
+
<%= f.text_field :name, :label => "What shall we call you?" %>
|
50
128
|
|
51
129
|
<label for='user_name'>What shall we call you?</label>
|
52
130
|
<input type='text' id='user_name' name='user[name]' />
|
53
131
|
|
54
132
|
To skip label generation for a specific field, pass `false` as the `:label` option:
|
55
133
|
|
56
|
-
|
57
|
-
|
58
|
-
<input type='text' id='user_name' name='user[name]' />
|
134
|
+
<%= f.text_field :name, :label => false %>
|
59
135
|
|
60
136
|
You can set the default for the entire form in the same way. Field-level `:label` options will override the default value. For example:
|
61
137
|
|
@@ -73,22 +149,10 @@ You can set the default for the entire form in the same way. Field-level `:label
|
|
73
149
|
<label for='user_password'>Pick a strong password</label>
|
74
150
|
<input type='password' id='user_password' name='user[password]' />
|
75
151
|
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
Fields will automatically have validation data generated for them using the validations defined in your models:
|
80
|
-
|
81
|
-
class User < ActiveRecord::Base
|
82
|
-
validates :name, :presence => true
|
83
|
-
end
|
152
|
+
Troubleshooting
|
153
|
+
===============
|
84
154
|
|
85
|
-
|
155
|
+
If you get a `BetterForm::InstallationError`, you need to run `rails generate better_form`. This installs an initializer that overrides a method
|
156
|
+
in `better_form` and lets you customize the handling of your field partial.
|
86
157
|
|
87
|
-
|
88
|
-
<input type='text' id='user_name' name='user[name]' data-validates-presence="Name is required" />
|
89
|
-
|
90
|
-
Setting a custom error message will be reflected in the validation that is generated:
|
91
|
-
|
92
|
-
validates :name, :presence => { :message => 'Please enter your full name' }
|
93
|
-
|
94
|
-
<input type='text' id='user_name' name='user[name]' data-validates-presence="Please enter your full name" />
|
158
|
+
You will need to restart WEBrick after running the generator so that the initializer is loaded.
|
data/lib/better_form/builder.rb
CHANGED
@@ -1,87 +1,53 @@
|
|
1
1
|
module BetterForm
|
2
|
-
|
3
|
-
|
2
|
+
# Raised when the better_form initializer has not been installed
|
3
|
+
class InstallationError < StandardError
|
4
|
+
end
|
4
5
|
|
6
|
+
class Builder < ActionView::Helpers::FormBuilder
|
5
7
|
helpers = field_helpers + %w(date_select datetime_select time_select collection_select select time_zone_select) - %w(label hidden_field fields_for)
|
6
8
|
helpers.each do |field_type|
|
7
9
|
define_method(field_type) do |field_name, *args|
|
8
10
|
options = args.extract_options!
|
9
11
|
|
10
|
-
|
11
|
-
prefix = (options.delete(:prefix) || '').html_safe
|
12
|
-
suffix = (options.delete(:suffix) || '').html_safe
|
13
|
-
description = (options.delete(:description) || '').html_safe
|
14
|
-
|
15
|
-
# Extract the label argument and validate argument
|
16
|
-
label = options.delete(:label)
|
17
|
-
validate = options.delete(:validate)
|
18
|
-
|
19
|
-
error_message = ''.html_safe
|
12
|
+
error_messages = @object.errors[field_name]
|
20
13
|
|
21
14
|
# If this field is explicitly validated, or this field and the whole form aren't explicitly *not* validated
|
15
|
+
validate = options.delete(:validate)
|
22
16
|
if validate or (validate != false and @template.validate_all? != false)
|
23
17
|
# Generate validations for the field
|
24
18
|
validations = generate_validations(@object, field_name)
|
25
19
|
options.merge!(validations)
|
26
|
-
|
27
|
-
# Add an 'invalid' class to it if it has errors
|
28
|
-
unless @object.errors[field_name].blank?
|
29
|
-
css_classes = options.delete(:class)
|
30
|
-
options.merge!({ :class => "#{css_classes} invalid" })
|
31
|
-
error_message = generate_error(field_name)
|
32
|
-
end
|
33
20
|
end
|
34
21
|
|
35
|
-
# Generate
|
22
|
+
# Generate label_text if necessary, or set it to nil if we're not labelling this field
|
23
|
+
label = options.delete(:label)
|
36
24
|
if (label == false) or (label == nil and @template.label_all? == false)
|
37
|
-
|
25
|
+
generated_label = nil
|
38
26
|
else
|
39
|
-
|
27
|
+
generated_label = generate_label(field_name, label)
|
40
28
|
end
|
41
29
|
|
42
30
|
# Generate the field itself
|
43
|
-
|
44
|
-
|
45
|
-
# Generate the field description
|
46
|
-
description = generate_description(description)
|
31
|
+
form_field = super(field_name, *(args << options))
|
47
32
|
|
48
33
|
# Join all the parts together to make a better form field!
|
49
|
-
better_form_field(
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
|
-
def submit(options = {})
|
54
|
-
value = options.delete(:value)
|
55
|
-
cancel_url = options.delete(:cancel)
|
56
|
-
if cancel_url
|
57
|
-
super(value, options) + "<span class='cancel'>or #{link_to('Cancel', cancel_url)}</span>".html_safe
|
58
|
-
else
|
59
|
-
super(value, options)
|
34
|
+
better_form_field(form_field, field_type, generated_label, error_messages, options)
|
60
35
|
end
|
61
36
|
end
|
62
37
|
|
63
|
-
def better_form_field(
|
64
|
-
|
38
|
+
def better_form_field(form_field, field_type, generated_label, error_messages, options)
|
39
|
+
raise BetterForm::InstallationError, "You need to run `rails generate better_form` and restart WEBrick before you can use better_form"
|
65
40
|
end
|
66
41
|
|
67
42
|
private
|
68
|
-
def generate_label(
|
43
|
+
def generate_label(field_name, label)
|
69
44
|
if label == true
|
70
|
-
label_text =
|
45
|
+
label_text = field_name.to_s.humanize
|
71
46
|
else
|
72
47
|
label_text = label.to_s
|
73
48
|
end
|
74
49
|
|
75
|
-
|
76
|
-
label(method, label_text, options ||= {})
|
77
|
-
end
|
78
|
-
|
79
|
-
def generate_description(description)
|
80
|
-
content_tag(:span, description, :class => 'field-desc') unless description.blank?
|
81
|
-
end
|
82
|
-
|
83
|
-
def generate_error(field_name)
|
84
|
-
content_tag(:span, @object.errors[field_name].join(tag(:br)).html_safe, :class => :error_message)
|
50
|
+
label(field_name, label_text)
|
85
51
|
end
|
86
52
|
|
87
53
|
def generate_validations(object, attribute)
|
data/lib/better_form/version.rb
CHANGED
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'rails/generators'
|
2
|
+
|
3
|
+
class BetterFormGenerator < Rails::Generators::Base
|
4
|
+
source_root File.join(File.dirname(__FILE__), "templates")
|
5
|
+
|
6
|
+
desc 'Install the default better_form initializer and partial'
|
7
|
+
def generate
|
8
|
+
copy_file "better_form.rb", "config/initializers/better_form.rb"
|
9
|
+
copy_file "field.html.erb", "app/views/better_form/_field.html.erb"
|
10
|
+
copy_file "inline_field.html.erb", "app/views/better_form/_inline_field.html.erb"
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
module BetterForm
|
2
|
+
class Builder
|
3
|
+
def better_form_field(form_field, field_type, generated_label, error_messages, options)
|
4
|
+
if [:radio_button, :check_box].include?(field_type.to_sym)
|
5
|
+
content = @template.render(:partial => 'better_form/inline_field', :locals => { :form_field => form_field, :field_type => field_type, :generated_label => generated_label, :error_messages => error_messages, :options => options })
|
6
|
+
else
|
7
|
+
content = @template.render(:partial => 'better_form/field', :locals => { :form_field => form_field, :field_type => field_type, :generated_label => generated_label, :error_messages => error_messages, :options => options })
|
8
|
+
end
|
9
|
+
content
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
<%#
|
2
|
+
This is the default partial created when you run `rails generate better_form`
|
3
|
+
Modify it as you see fit to support the functionality you need and generate
|
4
|
+
the markup you desire.
|
5
|
+
|
6
|
+
You can replace this partial entirely with your own HAML version.
|
7
|
+
|
8
|
+
Any options passed to the Rails form helper will be available in the
|
9
|
+
`options` local variable. For example, to set options[:prefix] and
|
10
|
+
options[:suffix]:
|
11
|
+
|
12
|
+
f.text_field :amount, :prefix => '$', :suffix => '/hour'
|
13
|
+
|
14
|
+
You can also edit the initializer in config/initializers/better_form.rb. You
|
15
|
+
might like to do this to render different partials based on the field type or
|
16
|
+
some other condition.
|
17
|
+
%>
|
18
|
+
|
19
|
+
<div class="form_field">
|
20
|
+
<%= generated_label %>
|
21
|
+
<span>
|
22
|
+
<span class="field_prefix"><%= options[:prefix] %></span>
|
23
|
+
<%= form_field %>
|
24
|
+
<span class="field_suffix"><%= options[:suffix] %></span>
|
25
|
+
<span class="field_description"><%= options[:description] %></span>
|
26
|
+
</span>
|
27
|
+
<% error_messages.each do |message| %>
|
28
|
+
<span class="error_message"><%= message %></span>
|
29
|
+
<br />
|
30
|
+
<% end %>
|
31
|
+
</div>
|
@@ -0,0 +1,11 @@
|
|
1
|
+
<div class="form_field">
|
2
|
+
<%= form_field %>
|
3
|
+
<span>
|
4
|
+
<%= generated_label %>
|
5
|
+
<span class="field_description"><%= options[:description] %></span>
|
6
|
+
</span>
|
7
|
+
<% error_messages.each do |message| %>
|
8
|
+
<span class="error_message"><%= message %></span>
|
9
|
+
<br />
|
10
|
+
<% end %>
|
11
|
+
</div>
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: better_form
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.8.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,8 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2011-
|
13
|
-
default_executable:
|
12
|
+
date: 2011-10-07 00:00:00.000000000 Z
|
14
13
|
dependencies: []
|
15
14
|
description:
|
16
15
|
email:
|
@@ -19,13 +18,16 @@ executables: []
|
|
19
18
|
extensions: []
|
20
19
|
extra_rdoc_files: []
|
21
20
|
files:
|
21
|
+
- lib/generators/better_form/better_form_generator.rb
|
22
|
+
- lib/generators/better_form/templates/inline_field.html.erb
|
23
|
+
- lib/generators/better_form/templates/field.html.erb
|
24
|
+
- lib/generators/better_form/templates/better_form.rb
|
22
25
|
- lib/better_form.rb
|
23
26
|
- lib/better_form/builder.rb
|
24
27
|
- lib/better_form/view_helper.rb
|
25
28
|
- lib/better_form/version.rb
|
26
29
|
- LICENSE
|
27
30
|
- README.md
|
28
|
-
has_rdoc: true
|
29
31
|
homepage: http://github.com/2suggestions/better_form
|
30
32
|
licenses: []
|
31
33
|
post_install_message:
|
@@ -46,7 +48,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
46
48
|
version: 1.3.6
|
47
49
|
requirements: []
|
48
50
|
rubyforge_project:
|
49
|
-
rubygems_version: 1.
|
51
|
+
rubygems_version: 1.8.10
|
50
52
|
signing_key:
|
51
53
|
specification_version: 3
|
52
54
|
summary: A Better Rails 3 FormBuilder
|