bootstrap_form 0.2.4 → 0.3.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/README.md CHANGED
@@ -1,45 +1,84 @@
1
- bootstrap_form
2
- ==============
1
+ # BootstrapForm
3
2
 
4
- bootstrap_form is a rails form builder that makes it super easy to create beautiful-looking forms using Twitter Bootstrap 2.0
3
+ **BootstrapForm** is a form builder that makes it super easy to
4
+ integrate Twitter Bootstrap-style forms into your Rails App.
5
5
 
6
-
7
- Requirements
8
- ------------
6
+ ## Requirements
9
7
 
10
8
  * Ruby 1.9+
11
9
  * Rails 3.1+
12
10
  * Twitter Bootstrap 2.0+
13
11
 
12
+ ## Installation
13
+
14
+ Add it to your Gemfile:
15
+
16
+ `gem 'bootstrap_form'`
17
+
18
+ Run the following command to install it:
19
+
20
+ `bundle`
21
+
22
+ Add this line to app/assets/stylesheets/application.css.scss:
23
+
24
+ ```css
25
+ /*
26
+ *= require bootstrap_form
27
+ */
28
+ ```
29
+
30
+ ## Example
14
31
 
15
- Installation
16
- ------------
32
+ Here's a quick example to get you started:
17
33
 
18
- Add the gem to your Gemfile
34
+ ```erb
35
+ <%= bootstrap_form_for(@user, html: { class: 'form-horizontal' }, help: :block) do |f| %>
36
+ <%= f.alert_message "Please fix the errors below." %>
19
37
 
20
- gem 'bootstrap_form'
38
+ <%= f.text_field :twitter_username, prepend: '@', label: 'Twitter' %>
39
+ <%= f.text_field :email %>
40
+ <%= f.password_field :password, help: 'Must be at least 6 characters long' %>
41
+ <%= f.password_field :password_confirmation, label: 'Confirm Password' %>
42
+ <%= f.control_group :terms do %>
43
+ <%= f.check_box :terms, label: 'I agree to the Terms of Service' %>
44
+ <% end %>
21
45
 
22
- Install the gem
46
+ <%= f.actions do %>
47
+ <%= f.primary 'Create My Account', disable_with: 'Saving...' %>
48
+ <% end %>
49
+ <% end %>
50
+ ```
23
51
 
24
- bundle
52
+ Screenshot:
25
53
 
26
- Add bootstrap_form to your application.css file
54
+ ![Example form](https://github.com/potenza/bootstrap_form/raw/master/examples/example_form.png)
27
55
 
28
- /*
29
- *= require bootstrap_form
30
- */
56
+ Screenshot with errors:
57
+
58
+ ![Example form with errors](https://github.com/potenza/bootstrap_form/raw/master/examples/example_form_errors.png)
31
59
 
32
- This brings in a couple of minor css classes that help format helper and
33
- error messages.
60
+ ## Usage
61
+
62
+ To get started, just use the **BootstrapForm** form helper:
63
+
64
+ ```erb
65
+ <%= bootstrap_form_for(@user) do |f| %>
66
+ ...
67
+ <% end %>
68
+ ```
69
+
70
+ To use a horizontal-style form with labels to the left of the inputs,
71
+ add the `.form-horizontal` class:
34
72
 
35
- Usage
36
- -----
73
+ ```erb
74
+ <%= bootstrap_form_for(@user, html: { class: 'form-horizontal' }) do |f| %>
75
+ ...
76
+ <% end %>
77
+ ```
37
78
 
38
- <%= bootstrap_form_for(@user) do |f| %>
39
- ...
40
- <% end %>
79
+ ### Form Helpers
41
80
 
42
- This plugin provides the following form helpers:
81
+ This gem wraps the following Rails form helpers:
43
82
 
44
83
  * text_field
45
84
  * password_field
@@ -47,7 +86,7 @@ This plugin provides the following form helpers:
47
86
  * file_field
48
87
  * number_field
49
88
  * email_field
50
- * telephone_field (phone_field)
89
+ * telephone_field / phone_field
51
90
  * url_field
52
91
  * select
53
92
  * collection_select
@@ -55,86 +94,160 @@ This plugin provides the following form helpers:
55
94
  * time_select
56
95
  * datetime_select
57
96
  * check_box
97
+ * radio_button
58
98
 
59
- These form helpers accept the same options as the Rails form helpers with the
60
- addition of the options `label`, `help`, and `prepend`. Here's an example form
61
- that also uses the `actions` helper for the submit button:
99
+ You can use the helpers like you're used to:
62
100
 
63
- <%= bootstrap_form_for(@user) do |f| %>
64
- <%= f.alert_message "Please fix the errors below." %>
101
+ ```erb
102
+ <%= bootstrap_form_for(@user) do |f| %>
103
+ <%= f.text_field :email %>
104
+ <%= f.password_field :password %>
105
+ <%= f.primary "Create My Account" %>
106
+ <% end %>
107
+ ```
65
108
 
66
- <%= f.text_field :email, autofocus: :true %>
67
- <%= f.password_field :password, help: 'Must be at least 6 characters long' %>
68
- <%= f.password_field :password_confirmation, label: 'Confirm Password' %>
69
- <%= f.text_field :website, prepend: 'http://' %>
70
- <%= f.check_box :terms, label: 'I agree to the Terms of Service' %>
109
+ This gem also wraps checkboxes and radios, which should be placed inside
110
+ of a `control_group` to render correctly. The following example ensures
111
+ that the entire control group will display an error if an associated
112
+ validations fails:
71
113
 
72
- <%= f.actions do %>
73
- <%= f.primary 'Sign Up', disable_with: 'Saving...' %>
74
- <% end %>
75
- <% end %>
114
+ ```erb
115
+ <%= f.control_group :skill_level, label: { text: 'Skill' } do %>
116
+ <%= f.radio_button :skill_level, 0, label: 'Novice', checked: true %>
117
+ <%= f.radio_button :skill_level, 1, label: 'Intermediate' %>
118
+ <%= f.radio_button :skill_level, 2, label: 'Advanced' %>
119
+ <% end %>
76
120
 
77
- ![Example Form](https://github.com/potenza/bootstrap_form/raw/master/examples/example_form.png)
121
+ <%= f.control_group :terms, label: { text: 'Terms' } do %>
122
+ <%= f.check_box :terms, label: 'I agree to the Terms of Service' %>
123
+ <% end %>
124
+ ```
78
125
 
126
+ You can display checkboxes and radios `inline` like this:
79
127
 
80
- Options
81
- -------
128
+ ```erb
129
+ <%= f.control_group :skill_level, label: { text: 'Skill' } do %>
130
+ <%= f.radio_button :skill_level, 0, label: 'Novice', inline: true %>
131
+ <%= f.radio_button :skill_level, 1, label: 'Intermediate', inline: true %>
132
+ <%= f.radio_button :skill_level, 2, label: 'Advanced', inline: true %>
133
+ <% end %>
134
+ ```
82
135
 
83
- To use a horizontal-style form with labels to the left of the inputs,
84
- add the `.form-horizontal` class:
136
+ ### Labels
85
137
 
86
- <%= bootstrap_form_for(@user, html: { class: 'form-horizontal' }) do |f| %>
138
+ Use the `label` option if you want to specify the field's label text:
87
139
 
88
- To place helper text underneath the fields, pass the option `help:
89
- :block`:
140
+ ```erb
141
+ <%= f.password_field :password_confirmation, label: 'Confirm Password' %>
142
+ ```
90
143
 
91
- <%= bootstrap_form_for(@user, help: block) do |f| %>
144
+ NOTE: To specify the label for a `control_group` you must do it like this:
92
145
 
93
- Here's an example of a horizontal-style form with block helpers:
146
+ ```erb
147
+ <%= f.control_group :terms, label: { text: 'Terms' } do %>
148
+ <%= f.check_box :terms, label: 'I agree to the Terms of Service' %>
149
+ <% end %>
150
+ ```
94
151
 
95
- ![Example Form](https://github.com/potenza/bootstrap_form/raw/master/examples/example_horizontal_block_form.png)
152
+ ### Help text
96
153
 
154
+ To add help text, use the `help` option, which will place it
155
+ to the right of the field:
97
156
 
98
- Custom Controls
99
- ---------------
157
+ ```erb
158
+ <%= f.password_field :password, help: 'Must be at least 6 characters long' %>
159
+ ```
100
160
 
101
- If you have a custom form control or content that you want to wrap
102
- in Bootstrap-style form markup, you can do the following:
103
-
104
- <%= f.control_group "Custom Field" do %>
105
- <span>My Custom Field</span>
106
- <% end %>
161
+ To place help text underneath a field, pass the option `help:
162
+ :block` to the `bootstrap_form_for` helper:
107
163
 
108
- which will output the following:
164
+ ```erb
165
+ <%= bootstrap_form_for(@user, help: :block) do |f| %>
166
+ <%= f.password_field :password, help: 'Must be at least 6 characters long' %>
167
+ <% end %>
168
+ ```
109
169
 
110
- <div class="control-group">
111
- <label class="control-label">Custom Field</label>
112
- <div class="controls">
113
- <span>My Custom Field</span>
114
- </div>
115
- </div>
170
+ ### Prepending inputs
116
171
 
117
- You can also specify the label's for attribute like this:
172
+ You can prepend an input file with the `prepend` option:
118
173
 
119
- <%= f.control_group "Custom Field", for: 'custom-control' do %>
120
- <span>My Custom Field</span>
121
- <% end %>
122
-
174
+ ```erb
175
+ <%= f.text_field :twitter_username, prepend: '@' %>
176
+ ```
123
177
 
124
- Validation Errors
125
- -----------------
178
+ ### Submit buttons
126
179
 
127
- When a validation error is triggered, the field will be outlined and the
128
- error will be displayed next to the field. Rails normally wraps fields
129
- in a div (field_with_errors), but this behavior is suppressed when `bootstrap_form_for` is called.
180
+ This gem provides a few different options for submit buttons.
181
+
182
+ You can use the `actions` helper, which wraps your submit button in a
183
+ `.form-actions` class.
184
+
185
+ ```erb
186
+ <%= f.actions do %>
187
+ <%= f.primary 'Create My Account' %>
188
+ <% end %>
189
+ ```
190
+
191
+ Here's a simple `primary` button (this applies the `.btn` and `.btn-primary` classes):
192
+
193
+ ```erb
194
+ <%= f.primary "Create My Account" %>
195
+ ```
196
+
197
+ Here's a `secondary` submit button (applies just the `.btn` class):
198
+
199
+ ```erb
200
+ <%= f.secondary "Create My Account" %>
201
+ ```
202
+
203
+ And if you don't want to use the `actions` helper, here's how you might
204
+ style a `primary` button with horizontal-style forms:
130
205
 
131
- ![Example form with errors](https://github.com/potenza/bootstrap_form/raw/master/examples/example_form_error.png)
206
+ ```erb
207
+ <%= bootstrap_form_for(@user, html: { class: 'form-horizontal' }) do |f| %>
208
+ <%= f.control_group do %>
209
+ <%= f.primary "Create My Account" %>
210
+ <% end %>
211
+ <% end %>
212
+ ```
213
+
214
+ ### Custom Control Groups
215
+
216
+ Sometimes you need to wrap a custom control in Bootstrap-style markup.
217
+ This is mostly needed when using horizontal-style forms. You can use the
218
+ `control_group` helper to do this:
219
+
220
+ ```erb
221
+ <%= bootstrap_form_for(@user, html: { class: 'form-horizontal' }) do |f| %>
222
+ <%= f.control_group do %>
223
+ <%= f.primary "Create My Account" %>
224
+ <% end %>
225
+ <% end %>
226
+ ```
227
+
228
+ To specify a label that isn't linked to an element you can do this:
229
+
230
+ ```erb
231
+ <%= f.control_group :nil, label: { text: 'Foo' } do %>
232
+ <span>Bar</span>
233
+ <% end %>
234
+ ```
235
+
236
+ ### Validation Errors
237
+
238
+ When a validation error is triggered, the field will be outlined and the
239
+ error will be displayed next to the field (or below it if you're using
240
+ block-style help text). Rails normally wraps fields in a div
241
+ (field_with_errors), but this behavior is suppressed when
242
+ `bootstrap_form_for` is called.
132
243
 
244
+ To display an error message wrapped in `.alert` and `.alert-error`
245
+ classes, you can use the `alert_message` helper:
133
246
 
134
- Credits
135
- -------
247
+ ```erb
248
+ <%= f.alert_message "Please fix the errors below." %>
249
+ ```
136
250
 
137
- Inspired by Ryan Bates' [Form Builder
138
- Railscast](http://railscasts.com/episodes/311-form-builders)
251
+ ## Credits
139
252
 
140
- bootstrap_form is Copyright (c) 2012 Stephen Potenza and is distributed under the MIT license.
253
+ bootstrap_form is Copyright (c) 2013 Stephen Potenza (https://github.com/potenza) and is distributed under the MIT license.
@@ -18,45 +18,66 @@ module BootstrapForm
18
18
  FORM_HELPERS.each do |method_name|
19
19
  define_method(method_name) do |name, *args|
20
20
  options = args.extract_options!.symbolize_keys!
21
- content_tag :div, class: "control-group#{(' error' if object.errors[name].any?)}" do
22
- label(name, options[:label], class: 'control-label') +
23
- content_tag(:div, class: 'controls') do
24
- help = object.errors[name].any? ? object.errors[name].join(', ') : options[:help]
25
- help = content_tag(@help_tag, class: @help_css) { help } if help
26
-
27
- args << options.except(:label, :help, :prepend)
28
- element = super(name, *args) + help
29
-
30
- if prepend = options.delete(:prepend)
31
- element = content_tag(:div, class: 'input-prepend') do
32
- content_tag(:span, prepend, class: 'add-on') + element
33
- end
34
- end
35
21
 
36
- element
22
+ control_group(name, label: { text: options[:label] }) do
23
+ help = object.errors[name].any? ? object.errors[name].join(', ') : options[:help]
24
+ help = content_tag(@help_tag, class: @help_css) { help } if help
25
+
26
+ args << options.except(:label, :help, :prepend)
27
+ element = super(name, *args) + help
28
+
29
+ if prepend = options.delete(:prepend)
30
+ element = content_tag(:div, class: 'input-prepend') do
31
+ content_tag(:span, prepend, class: 'add-on') + element
32
+ end
37
33
  end
34
+
35
+ element
38
36
  end
39
37
  end
40
38
  end
41
39
 
42
40
  def check_box(name, *args)
43
41
  options = args.extract_options!.symbolize_keys!
44
- content_tag :div, class: "control-group#{(' error' if object.errors[name].any?)}" do
45
- content_tag(:div, class: 'controls') do
46
- args << options.except(:label, :help)
47
- html = super(name, *args) + ' ' + options[:label]
48
- label(name, html, class: 'checkbox')
49
- end
50
- end
42
+ args << options.except(:label, :help, :inline)
43
+
44
+ html = super(name, *args) + ' ' + options[:label]
45
+
46
+ css = 'checkbox'
47
+ css << ' inline' if options[:inline]
48
+ label(name, html, class: css)
49
+ end
50
+
51
+ def radio_button(name, value, *args)
52
+ options = args.extract_options!.symbolize_keys!
53
+ args << options.except(:label, :help, :inline)
54
+
55
+ html = super(name, value, *args) + ' ' + options[:label]
56
+
57
+ css = 'radio'
58
+ css << ' inline' if options[:inline]
59
+ label("#{name}_#{value}", html, class: css)
51
60
  end
52
61
 
53
- def control_group(label_name, label_options = {}, &block)
54
- content_tag :div, class: "control-group" do
55
- label_options[:class] = 'control-label'
56
- content_tag(:label, label_name, label_options).html_safe +
57
- content_tag(:div, class: 'controls') do
62
+ def control_group(name = nil, options = {}, &block)
63
+ options[:class] ||= 'control-group'
64
+ options[:class] << ' error' if name && object.errors[name].any?
65
+
66
+ content_tag(:div, options.except(:label)) do
67
+ html = ''
68
+
69
+ if attrs = options.delete(:label)
70
+ attrs[:class] ||= 'control-label'
71
+ attrs[:for] ||= '' if name.nil?
72
+
73
+ html << label(name, attrs[:text], attrs.except(:text))
74
+ end
75
+
76
+ html << content_tag(:div, class: 'controls') do
58
77
  block.call.html_safe
59
78
  end
79
+
80
+ html.html_safe
60
81
  end
61
82
  end
62
83
 
@@ -68,7 +89,11 @@ module BootstrapForm
68
89
 
69
90
  def primary(name, options = {})
70
91
  options.merge! class: 'btn btn-primary'
92
+ submit name, options
93
+ end
71
94
 
95
+ def secondary(name, options = {})
96
+ options.merge! class: 'btn'
72
97
  submit name, options
73
98
  end
74
99
 
@@ -1,3 +1,3 @@
1
1
  module BootstrapForm
2
- VERSION = "0.2.4"
2
+ VERSION = "0.3.0"
3
3
  end
@@ -104,11 +104,26 @@ class BootstrapFormTest < ActionView::TestCase
104
104
  end
105
105
  end
106
106
 
107
- test "check_boxes are wrapped correctly" do
108
- expected = %{<div class=\"control-group\"><div class=\"controls\"><label class=\"checkbox\" for=\"user_misc\"><input name=\"user[misc]\" type=\"hidden\" value=\"0\" /><input id=\"user_misc\" name=\"user[misc]\" type=\"checkbox\" value=\"1\" /> This is a checkbox</label></div></div>}
107
+ test "check_box is wrapped correctly" do
108
+ expected = %{<label class=\"checkbox\" for=\"user_misc\"><input name=\"user[misc]\" type=\"hidden\" value=\"0\" /><input id=\"user_misc\" name=\"user[misc]\" type=\"checkbox\" value=\"1\" /> This is a checkbox</label>}
109
109
  assert_equal expected, @builder.check_box(:misc, label: 'This is a checkbox')
110
110
  end
111
111
 
112
+ test "check_box inline label is setted correctly" do
113
+ expected = %{<label class=\"checkbox inline\" for=\"user_misc\"><input name=\"user[misc]\" type=\"hidden\" value=\"0\" /><input id=\"user_misc\" name=\"user[misc]\" type=\"checkbox\" value=\"1\" /> This is a checkbox</label>}
114
+ assert_equal expected, @builder.check_box(:misc, label: 'This is a checkbox', inline: true)
115
+ end
116
+
117
+ test "radio_button is wrapped correctly" do
118
+ expected = %{<label class=\"radio\" for=\"user_misc_1\"><input id=\"user_misc_1\" name=\"user[misc]\" type=\"radio\" value=\"1\" /> This is a radio button</label>}
119
+ assert_equal expected, @builder.radio_button(:misc, '1', label: 'This is a radio button')
120
+ end
121
+
122
+ test "radio_button inline label is setted correctly" do
123
+ expected = %{<label class=\"radio inline\" for=\"user_misc_1\"><input id=\"user_misc_1\" name=\"user[misc]\" type=\"radio\" value=\"1\" /> This is a radio button</label>}
124
+ assert_equal expected, @builder.radio_button(:misc, '1', label: 'This is a radio button', inline: true)
125
+ end
126
+
112
127
  test "changing the label text" do
113
128
  expected = %{<div class=\"control-group\"><label class=\"control-label\" for=\"user_email\">Email Address</label><div class=\"controls\"><input id=\"user_email\" name=\"user[email]\" size=\"30\" type=\"text\" value=\"steve@example.com\" /></div></div>}
114
129
  assert_equal expected, @builder.text_field(:email, label: 'Email Address')
@@ -130,18 +145,68 @@ class BootstrapFormTest < ActionView::TestCase
130
145
  end
131
146
 
132
147
  test "control_group creates a valid structure and allows arbitrary html to be added via a block" do
133
- output = @builder.control_group "Custom Control" do
148
+ output = @builder.control_group do
134
149
  '<span>custom control here</span>'
135
150
  end
136
- expected = %{<div class="control-group"><label class="control-label">Custom Control</label><div class="controls"><span>custom control here</span></div></div>}
151
+
152
+ expected = %{<div class="control-group"><div class="controls"><span>custom control here</span></div></div>}
137
153
  assert_equal expected, output
138
154
  end
139
155
 
140
- test "control_group allows for the label's 'for' attribute to be set" do
141
- output = @builder.control_group "Custom Control", for: 'custom_control' do
156
+ test "control_group renders the options for div.control_group" do
157
+ output = @builder.control_group nil, id: 'foo' do
142
158
  '<span>custom control here</span>'
143
159
  end
144
- expected = %{<div class="control-group"><label class="control-label" for="custom_control">Custom Control</label><div class="controls"><span>custom control here</span></div></div>}
160
+
161
+ expected = %{<div class="control-group" id="foo"><div class="controls"><span>custom control here</span></div></div>}
162
+ assert_equal expected, output
163
+ end
164
+
165
+ test "control_group overrides the control-group class if another is passed" do
166
+ output = @builder.control_group nil, class: 'foo' do
167
+ '<span>custom control here</span>'
168
+ end
169
+
170
+ expected = %{<div class="foo"><div class="controls"><span>custom control here</span></div></div>}
171
+ assert_equal expected, output
172
+ end
173
+
174
+ test "control_group renders the label correctly" do
175
+ output = @builder.control_group :email, label: { text: 'Custom Control' } do
176
+ '<span>custom control here</span>'
177
+ end
178
+
179
+ expected = %{<div class="control-group"><label class="control-label" for="user_email">Custom Control</label><div class="controls"><span>custom control here</span></div></div>}
180
+ assert_equal expected, output
181
+ end
182
+
183
+ test "control_group overrides the label's 'class' and 'for' attributes if others are passed" do
184
+ output = @builder.control_group nil, label: { text: 'Custom Control', class: 'foo', for: 'bar' } do
185
+ '<span>custom control here</span>'
186
+ end
187
+
188
+ expected = %{<div class="control-group"><label class="foo" for="bar">Custom Control</label><div class="controls"><span>custom control here</span></div></div>}
189
+ assert_equal expected, output
190
+ end
191
+
192
+ test "control_group label's 'for' attribute should be empty if no name was passed" do
193
+ output = @builder.control_group nil, label: { text: 'Custom Control' } do
194
+ '<span>custom control here</span>'
195
+ end
196
+
197
+ expected = %{<div class="control-group"><label class="control-label" for="">Custom Control</label><div class="controls"><span>custom control here</span></div></div>}
198
+ assert_equal expected, output
199
+ end
200
+
201
+ test 'control_group renders the "error" class corrrectly when object is invalid' do
202
+ @user.email = nil
203
+ @user.valid?
204
+
205
+ output = @builder.control_group :email do
206
+ '<span>custom control here</span>'
207
+ end
208
+
209
+ expected = %{<div class="control-group error"><div class="controls"><span>custom control here</span></div></div>}
145
210
  assert_equal expected, output
146
211
  end
147
212
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bootstrap_form
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.4
4
+ version: 0.3.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-01-04 00:00:00.000000000 Z
12
+ date: 2013-01-16 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rails