bootstrap_form 1.0.0 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
-
![Example form](https://github.com/potenza/bootstrap_form/raw/master/examples/example_form.png)
|
64
|
-
|
65
|
-
Screenshot with errors:
|
66
|
-
|
67
|
-
![Example form with errors](https://github.com/potenza/bootstrap_form/raw/master/examples/example_form_errors.png)
|
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
|