bootstrap_form 1.0.0 → 2.0.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.
- checksums.yaml +7 -0
- data/README.md +86 -152
- data/lib/bootstrap_form.rb +0 -1
- data/lib/bootstrap_form/form_builder.rb +73 -67
- data/lib/bootstrap_form/helper.rb +11 -4
- data/lib/bootstrap_form/version.rb +1 -1
- data/test/bootstrap_form_test.rb +101 -122
- data/test/dummy/app/models/user.rb +2 -0
- data/test/dummy/db/migrate/20130912171202_add_preferences_to_user.rb +5 -0
- data/test/dummy/db/schema.rb +2 -1
- data/test/dummy/db/test.sqlite3 +0 -0
- data/test/dummy/log/test.log +45352 -992
- metadata +18 -27
- data/app/assets/stylesheets/bootstrap_form.css +0 -7
- data/lib/bootstrap_form/engine.rb +0 -5
- data/lib/tasks/bootstrap_form_tasks.take +0 -4
- data/test/dummy/log/development.log +0 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 78f6f16a42dc3bd71205a9474b10836f344c76c4
|
4
|
+
data.tar.gz: e5ef1c16c2c0fd3a5fc8d1a3ed484d05efcaa383
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: a877f20198877308837384bd79f1fe6aff438691aa9fda349c557d614ce685dbca69b8b618e39b6a4e486431d793d8a1621308d78ea7ac5daa02337704511b9d
|
7
|
+
data.tar.gz: 667fd4a3fc7b7aad50ceb5135590c5eae81ab1c6de25cca47af5904d199b1461b111c1a6ded6c588232db1b8416548fd14a0f150e75a83f206218fe1e9660769
|
data/README.md
CHANGED
@@ -2,90 +2,39 @@
|
|
2
2
|
|
3
3
|
# BootstrapForm
|
4
4
|
|
5
|
-
**BootstrapForm** is a form builder that makes it super easy to
|
6
|
-
|
5
|
+
**BootstrapForm** is a rails form builder that makes it super easy to integrate
|
6
|
+
twitter bootstrap-style forms into your rails application.
|
7
7
|
|
8
8
|
## Requirements
|
9
9
|
|
10
10
|
* Ruby 1.9+
|
11
|
-
* Rails
|
12
|
-
* Twitter Bootstrap
|
11
|
+
* Rails 3+
|
12
|
+
* Twitter Bootstrap 3.0+
|
13
13
|
|
14
14
|
## Installation
|
15
15
|
|
16
16
|
Add it to your Gemfile:
|
17
17
|
|
18
|
-
### Rails 4.0+
|
19
|
-
|
20
18
|
`gem 'bootstrap_form'`
|
21
19
|
|
22
|
-
|
23
|
-
|
24
|
-
`gem 'bootstrap_form', '~> 0.3.2'`
|
25
|
-
|
26
|
-
|
27
|
-
Run the following command to install it:
|
20
|
+
Then:
|
28
21
|
|
29
22
|
`bundle`
|
30
23
|
|
31
|
-
Add this line to app/assets/stylesheets/application.css.scss:
|
32
|
-
|
33
|
-
```css
|
34
|
-
/*
|
35
|
-
*= require bootstrap_form
|
36
|
-
*/
|
37
|
-
```
|
38
|
-
|
39
|
-
## Example
|
40
|
-
|
41
|
-
Here's a quick example to get you started:
|
42
|
-
|
43
|
-
```erb
|
44
|
-
<%= bootstrap_form_for(@user, html: { class: 'form-horizontal' }, help: :block) do |f| %>
|
45
|
-
<%= f.alert_message "Please fix the errors below." %>
|
46
|
-
|
47
|
-
<%= f.text_field :twitter_username, prepend: '@', label: 'Twitter' %>
|
48
|
-
<%= f.text_field :email %>
|
49
|
-
<%= f.password_field :password, help: 'Must be at least 6 characters long' %>
|
50
|
-
<%= f.password_field :password_confirmation, label: 'Confirm Password' %>
|
51
|
-
<%= f.control_group :terms do %>
|
52
|
-
<%= f.check_box :terms, label: 'I agree to the Terms of Service' %>
|
53
|
-
<% end %>
|
54
|
-
|
55
|
-
<%= f.actions do %>
|
56
|
-
<%= f.primary 'Create My Account', disable_with: 'Saving...' %>
|
57
|
-
<% end %>
|
58
|
-
<% end %>
|
59
|
-
```
|
60
|
-
|
61
|
-
Screenshot:
|
62
|
-
|
63
|
-

|
64
|
-
|
65
|
-
Screenshot with errors:
|
66
|
-
|
67
|
-

|
68
|
-
|
69
24
|
## Usage
|
70
25
|
|
71
|
-
To get started, just use the **BootstrapForm** form helper:
|
26
|
+
To get started, just use the **BootstrapForm** form helper. Here's an example:
|
72
27
|
|
73
28
|
```erb
|
74
29
|
<%= bootstrap_form_for(@user) do |f| %>
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
To use a horizontal-style form with labels to the left of the inputs,
|
80
|
-
add the `.form-horizontal` class:
|
81
|
-
|
82
|
-
```erb
|
83
|
-
<%= bootstrap_form_for(@user, html: { class: 'form-horizontal' }) do |f| %>
|
84
|
-
...
|
30
|
+
<%= f.email_field :email %>
|
31
|
+
<%= f.password_field :password %>
|
32
|
+
<%= f.check_box :remember_me %>
|
33
|
+
<%= f.submit "Log In" %>
|
85
34
|
<% end %>
|
86
35
|
```
|
87
36
|
|
88
|
-
### Form Helpers
|
37
|
+
### Supported Form Helpers
|
89
38
|
|
90
39
|
This gem wraps the following Rails form helpers:
|
91
40
|
|
@@ -105,155 +54,140 @@ This gem wraps the following Rails form helpers:
|
|
105
54
|
* check_box
|
106
55
|
* radio_button
|
107
56
|
|
108
|
-
|
57
|
+
### Default Form Style
|
109
58
|
|
110
|
-
|
111
|
-
|
112
|
-
<%= f.text_field :email %>
|
113
|
-
<%= f.password_field :password %>
|
114
|
-
<%= f.primary "Create My Account" %>
|
115
|
-
<% end %>
|
116
|
-
```
|
117
|
-
|
118
|
-
This gem also wraps checkboxes and radios, which should be placed inside
|
119
|
-
of a `control_group` to render correctly. The following example ensures
|
120
|
-
that the entire control group will display an error if an associated
|
121
|
-
validations fails:
|
122
|
-
|
123
|
-
```erb
|
124
|
-
<%= f.control_group :skill_level, label: { text: 'Skill' }, help: 'This is optional' do %>
|
125
|
-
<%= f.radio_button :skill_level, 0, label: 'Novice', checked: true %>
|
126
|
-
<%= f.radio_button :skill_level, 1, label: 'Intermediate' %>
|
127
|
-
<%= f.radio_button :skill_level, 2, label: 'Advanced' %>
|
128
|
-
<% end %>
|
59
|
+
By default, your forms will stack labels on top of controls and your controls
|
60
|
+
will grow to 100% of the available width.
|
129
61
|
|
130
|
-
|
131
|
-
<%= f.check_box :terms, label: 'I agree to the Terms of Service' %>
|
132
|
-
<% end %>
|
133
|
-
```
|
62
|
+
### Inline Forms
|
134
63
|
|
135
|
-
|
64
|
+
To use an inline-style form, use the `style: :inline` option. To hide labels,
|
65
|
+
use the `hide_label: true` option, which keeps your labels accessible to those
|
66
|
+
using screen readers.
|
136
67
|
|
137
68
|
```erb
|
138
|
-
<%=
|
139
|
-
<%= f.
|
140
|
-
<%= f.
|
141
|
-
<%= f.
|
69
|
+
<%= bootstrap_form_for(@user, style: :inline) do |f| %>
|
70
|
+
<%= f.email_field :email, hide_label: true %>
|
71
|
+
<%= f.password_field :password, hide_label: true %>
|
72
|
+
<%= f.check_box :remember_me %>
|
73
|
+
<%= f.submit "Log In" %>
|
142
74
|
<% end %>
|
143
75
|
```
|
144
76
|
|
145
|
-
###
|
77
|
+
### Horizontal Forms
|
146
78
|
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
<%= f.password_field :password_confirmation, label: 'Confirm Password' %>
|
151
|
-
```
|
79
|
+
To use a horizontal-style form with labels to the left of the inputs, use the
|
80
|
+
`style: :horizontal` option. You should specify both `left` and `right` css
|
81
|
+
classes as well (they default to `col-sm-2` and `col-sm-10`).
|
152
82
|
|
153
|
-
|
83
|
+
In the example below, the checkbox and submit button have been wrapped in a
|
84
|
+
`form_group` to keep them properly aligned.
|
154
85
|
|
155
86
|
```erb
|
156
|
-
<%=
|
87
|
+
<%= bootstrap_form_for(@user, style: :horizontal, left: "col-sm-2", right: "col-sm-10") do |f| %>
|
88
|
+
<%= f.email_field :email %>
|
89
|
+
<%= f.password_field :password %>
|
90
|
+
<%= f.form_group do %>
|
91
|
+
<%= f.check_box :remember_me %>
|
92
|
+
<% end %>
|
93
|
+
<%= f.form_group do %>
|
94
|
+
<%= f.submit "Log In" %>
|
95
|
+
<% end %>
|
96
|
+
<% end %>
|
157
97
|
```
|
158
98
|
|
159
|
-
|
99
|
+
To create a static control in a horizontal form, use the following markup:
|
160
100
|
|
161
101
|
```erb
|
162
|
-
<%= f.
|
163
|
-
|
102
|
+
<%= f.form_group :nil, label: { text: "Foo" } do %>
|
103
|
+
<p class="form-control-static">
|
104
|
+
Bar
|
105
|
+
</p>
|
164
106
|
<% end %>
|
165
107
|
```
|
166
108
|
|
167
|
-
###
|
109
|
+
### Labels
|
168
110
|
|
169
|
-
|
170
|
-
to the right of the field:
|
111
|
+
Use the `label` option if you want to specify the field's label text:
|
171
112
|
|
172
113
|
```erb
|
173
|
-
<%= f.password_field :
|
114
|
+
<%= f.password_field :password_confirmation, label: "Confirm Password" %>
|
174
115
|
```
|
175
116
|
|
176
|
-
To
|
177
|
-
|
117
|
+
To hide a label, use the `hide_label: true` option. This adds the `sr-only`
|
118
|
+
class, which keeps your labels accessible to those using screen readers.
|
178
119
|
|
179
120
|
```erb
|
180
|
-
<%=
|
181
|
-
<%= f.password_field :password, help: 'Must be at least 6 characters long' %>
|
182
|
-
<% end %>
|
121
|
+
<%= f.text_area :comment, hide_label: :true, placeholder: "Leave a comment..." %>
|
183
122
|
```
|
184
123
|
|
185
|
-
###
|
124
|
+
### Help Text
|
186
125
|
|
187
|
-
|
126
|
+
To add help text, use the `help` option:
|
188
127
|
|
189
128
|
```erb
|
190
|
-
<%= f.
|
129
|
+
<%= f.password_field :password, help: "Must be at least 6 characters long" %>
|
191
130
|
```
|
192
131
|
|
193
|
-
###
|
132
|
+
### Submit Buttons
|
194
133
|
|
195
|
-
|
134
|
+
The `btn btn-default` css classes are automatically added to your submit
|
135
|
+
buttons.
|
196
136
|
|
197
137
|
```erb
|
198
|
-
<%= f.
|
138
|
+
<%= f.submit "Log In" %>
|
199
139
|
```
|
200
140
|
|
201
|
-
|
202
|
-
|
203
|
-
This gem provides a few different options for submit buttons.
|
204
|
-
|
205
|
-
Here's a simple `primary` button (this applies the `.btn` and `.btn-primary` classes):
|
141
|
+
You can specify your own classes like this:
|
206
142
|
|
207
143
|
```erb
|
208
|
-
<%= f.
|
144
|
+
<%= f.submit "Log In", class: "btn btn-primary" %>
|
209
145
|
```
|
210
146
|
|
211
|
-
|
147
|
+
### Checkboxes and Radios
|
212
148
|
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
You can use the `actions` helper, which wraps your submit button in a
|
218
|
-
`.form-actions` class.
|
149
|
+
Checkboxes and radios should be placed inside of a `form_group` to render
|
150
|
+
properly. The following example ensures that the entire form group will display
|
151
|
+
an error if an associated validations fails:
|
219
152
|
|
220
153
|
```erb
|
221
|
-
<%= f.
|
222
|
-
<%= f.
|
154
|
+
<%= f.form_group :skill_level, label: { text: "Skill" }, help: "Optional Help Text" do %>
|
155
|
+
<%= f.radio_button :skill_level, 0, label: "Novice", checked: true %>
|
156
|
+
<%= f.radio_button :skill_level, 1, label: "Intermediate" %>
|
157
|
+
<%= f.radio_button :skill_level, 2, label: "Advanced" %>
|
158
|
+
<% end %>
|
159
|
+
|
160
|
+
<%= f.form_group :terms do %>
|
161
|
+
<%= f.check_box :terms, label: "I agree to the Terms of Service" %>
|
223
162
|
<% end %>
|
224
163
|
```
|
225
164
|
|
226
|
-
|
227
|
-
style a `primary` button with horizontal-style forms:
|
165
|
+
You can also create a checkbox using a block:
|
228
166
|
|
229
167
|
```erb
|
230
|
-
<%=
|
231
|
-
<%= f.
|
232
|
-
|
168
|
+
<%= f.form_group :terms, label: { text: "Optional Label" } do %>
|
169
|
+
<%= f.check_box :terms do %>
|
170
|
+
You need to check this box to accept our terms of service and privacy policy
|
233
171
|
<% end %>
|
234
172
|
<% end %>
|
235
173
|
```
|
236
174
|
|
237
|
-
|
238
|
-
|
239
|
-
Sometimes you need to wrap an element in Bootstrap-style markup.
|
240
|
-
This is mostly needed to align submit buttons when using horizontal-style
|
241
|
-
forms (also shown above):
|
175
|
+
To display checkboxes and radios inline, pass the `inline: true` option:
|
242
176
|
|
243
177
|
```erb
|
244
|
-
<%=
|
245
|
-
<%= f.
|
246
|
-
|
247
|
-
|
178
|
+
<%= f.form_group :skill_level, label: { text: "Skill" } do %>
|
179
|
+
<%= f.radio_button :skill_level, 0, label: "Novice", inline: true %>
|
180
|
+
<%= f.radio_button :skill_level, 1, label: "Intermediate", inline: true %>
|
181
|
+
<%= f.radio_button :skill_level, 2, label: "Advanced", inline: true %>
|
248
182
|
<% end %>
|
249
183
|
```
|
250
184
|
|
251
|
-
|
185
|
+
### Prepending and Appending Inputs
|
186
|
+
|
187
|
+
Pass the `prepend` and/or `append` options to the input field:
|
252
188
|
|
253
189
|
```erb
|
254
|
-
<%= f.
|
255
|
-
<span>Bar</span>
|
256
|
-
<% end %>
|
190
|
+
<%= f.text_field :price, prepend: "$", append: ".00" %>
|
257
191
|
```
|
258
192
|
|
259
193
|
### Validation Errors
|
@@ -262,9 +196,9 @@ When a validation error is triggered, the field will be outlined and the
|
|
262
196
|
error will be displayed next to the field (or below it if you're using
|
263
197
|
block-style help text). Rails normally wraps fields in a div
|
264
198
|
(field_with_errors), but this behavior is suppressed when
|
265
|
-
`bootstrap_form_for` is
|
199
|
+
`bootstrap_form_for` is used.
|
266
200
|
|
267
|
-
To display an error message wrapped in `.alert` and `.alert-
|
201
|
+
To display an error message wrapped in `.alert` and `.alert-danger`
|
268
202
|
classes, you can use the `alert_message` helper:
|
269
203
|
|
270
204
|
```erb
|
data/lib/bootstrap_form.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
module BootstrapForm
|
2
2
|
class FormBuilder < ActionView::Helpers::FormBuilder
|
3
|
+
attr_reader :style, :left_class, :right_class, :has_error
|
4
|
+
|
3
5
|
FORM_HELPERS = %w{text_field password_field text_area file_field
|
4
6
|
number_field email_field telephone_field phone_field url_field
|
5
7
|
select collection_select date_select time_select datetime_select}
|
@@ -8,9 +10,9 @@ module BootstrapForm
|
|
8
10
|
delegate :capture, to: :@template
|
9
11
|
|
10
12
|
def initialize(object_name, object, template, options, proc=nil)
|
11
|
-
|
12
|
-
@
|
13
|
-
|
13
|
+
@style = options[:style]
|
14
|
+
@left_class = (options[:left] || default_left_class) + " control-label"
|
15
|
+
@right_class = options[:right] || default_right_class
|
14
16
|
super
|
15
17
|
end
|
16
18
|
|
@@ -19,39 +21,31 @@ module BootstrapForm
|
|
19
21
|
options = args.extract_options!.symbolize_keys!
|
20
22
|
|
21
23
|
label = options.delete(:label)
|
22
|
-
|
23
|
-
|
24
|
-
control_group(name, label: { text: label }, help: help) do
|
24
|
+
label_class = hide_class if options.delete(:hide_label)
|
25
|
+
help = options.delete(:help)
|
25
26
|
|
27
|
+
form_group(name, label: { text: label, class: label_class }, help: help) do
|
28
|
+
options[:class] = "form-control #{options[:class]}".rstrip
|
26
29
|
args << options.except(:prepend, :append)
|
27
|
-
|
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
|
33
|
-
end
|
34
|
-
|
35
|
-
if append = options.delete(:append)
|
36
|
-
element = content_tag(:div, class: 'input-append') do
|
37
|
-
element + content_tag(:span, append, class: 'add-on')
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
element
|
30
|
+
input = super(name, *args)
|
31
|
+
prepend_and_append_input(input, options[:prepend], options[:append])
|
42
32
|
end
|
43
33
|
end
|
44
34
|
end
|
45
35
|
|
46
|
-
def check_box(name, options = {}, checked_value =
|
36
|
+
def check_box(name, options = {}, checked_value = '1', unchecked_value = '0')
|
47
37
|
options = options.symbolize_keys!
|
48
38
|
|
49
|
-
html = super(name, options.except(:label, :help, :inline), checked_value, unchecked_value)
|
50
|
-
html
|
39
|
+
html = super(name, options.except(:label, :help, :inline), checked_value, unchecked_value)
|
40
|
+
html << ' ' + (options[:label] || name.to_s.humanize)
|
51
41
|
|
52
|
-
|
53
|
-
|
54
|
-
|
42
|
+
if options[:inline]
|
43
|
+
label(name, html, class: "checkbox-inline")
|
44
|
+
else
|
45
|
+
content_tag(:div, class: "checkbox") do
|
46
|
+
label(name, html)
|
47
|
+
end
|
48
|
+
end
|
55
49
|
end
|
56
50
|
|
57
51
|
def radio_button(name, value, *args)
|
@@ -61,67 +55,79 @@ module BootstrapForm
|
|
61
55
|
html = super(name, value, *args) + ' ' + options[:label]
|
62
56
|
|
63
57
|
css = 'radio'
|
64
|
-
css << '
|
58
|
+
css << '-inline' if options[:inline]
|
65
59
|
label("#{name}_#{value}", html, class: css)
|
66
60
|
end
|
67
61
|
|
68
|
-
def
|
69
|
-
|
62
|
+
def form_group(name = nil, options = {}, &block)
|
63
|
+
options[:class] = 'form-group'
|
64
|
+
options[:class] << ' has-error' if has_error?(name)
|
70
65
|
|
71
|
-
|
72
|
-
options[:
|
66
|
+
html = capture(&block)
|
67
|
+
html << generate_help(name, options[:help])
|
68
|
+
html = content_tag(:div, html, class: right_class) if horizontal?
|
73
69
|
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
html = ''
|
70
|
+
content_tag(:div, options.except(:label, :help)) do
|
71
|
+
"#{generate_label(name, options[:label])}#{html}".html_safe
|
72
|
+
end
|
73
|
+
end
|
79
74
|
|
80
|
-
|
81
|
-
|
82
|
-
|
75
|
+
def submit(name, options = {})
|
76
|
+
options.merge! class: 'btn btn-default' unless options.has_key? :class
|
77
|
+
super name, options
|
78
|
+
end
|
83
79
|
|
84
|
-
|
85
|
-
|
80
|
+
def alert_message(title, *args)
|
81
|
+
options = args.extract_options!
|
82
|
+
css = options[:class] || 'alert alert-danger'
|
86
83
|
|
87
|
-
|
88
|
-
|
84
|
+
if object.respond_to?(:errors) && object.errors.full_messages.any?
|
85
|
+
content_tag :div, title, class: css
|
86
|
+
end
|
87
|
+
end
|
89
88
|
|
90
|
-
|
91
|
-
controls << content_tag(:span, help, class: @help_class) if help
|
89
|
+
private
|
92
90
|
|
93
|
-
|
94
|
-
|
91
|
+
def horizontal?
|
92
|
+
style == :horizontal
|
93
|
+
end
|
95
94
|
|
96
|
-
|
97
|
-
|
95
|
+
def default_left_class
|
96
|
+
"col-sm-2"
|
98
97
|
end
|
99
98
|
|
100
|
-
def
|
101
|
-
|
102
|
-
capture(&block)
|
103
|
-
end
|
99
|
+
def default_right_class
|
100
|
+
"col-sm-10"
|
104
101
|
end
|
105
102
|
|
106
|
-
def
|
107
|
-
|
108
|
-
submit name, options
|
103
|
+
def hide_class
|
104
|
+
"sr-only" # still accessible for screen readers
|
109
105
|
end
|
110
106
|
|
111
|
-
def
|
112
|
-
|
113
|
-
submit name, options
|
107
|
+
def has_error?(name)
|
108
|
+
object.respond_to?(:errors) && !(name.nil? || object.errors[name].empty?)
|
114
109
|
end
|
115
110
|
|
116
|
-
def
|
117
|
-
|
118
|
-
|
111
|
+
def prepend_and_append_input(input, prepend, append)
|
112
|
+
input = content_tag(:span, prepend, class: 'input-group-addon') + input if prepend
|
113
|
+
input << content_tag(:span, append, class: 'input-group-addon') if append
|
114
|
+
input = content_tag(:div, input, class: 'input-group') if prepend || append
|
115
|
+
input
|
116
|
+
end
|
119
117
|
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
118
|
+
def generate_label(name, options)
|
119
|
+
if options
|
120
|
+
options[:class] = "#{options[:class]} #{left_class}".lstrip if horizontal?
|
121
|
+
label(name, options[:text], options.except(:text))
|
122
|
+
elsif horizontal?
|
123
|
+
# no label. create an empty one to keep proper form alignment.
|
124
|
+
content_tag(:label, "", class: left_class)
|
124
125
|
end
|
125
126
|
end
|
127
|
+
|
128
|
+
def generate_help(name, help_text)
|
129
|
+
help_text = object.errors[name].join(', ') if has_error?(name)
|
130
|
+
content_tag(:span, help_text, class: 'help-block') if help_text
|
131
|
+
end
|
126
132
|
end
|
127
133
|
end
|