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.
@@ -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
- integrate Twitter Bootstrap-style forms into your Rails App.
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 4.0+
12
- * Twitter Bootstrap 2.0+
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
- ### Rails 3.1+
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
- <% end %>
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
- You can use the helpers like you're used to:
57
+ ### Default Form Style
109
58
 
110
- ```erb
111
- <%= bootstrap_form_for(@user) do |f| %>
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
- <%= f.control_group :terms, label: { text: 'Terms' } do %>
131
- <%= f.check_box :terms, label: 'I agree to the Terms of Service' %>
132
- <% end %>
133
- ```
62
+ ### Inline Forms
134
63
 
135
- You can display checkboxes and radios `inline` like this:
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
- <%= f.control_group :skill_level, label: { text: 'Skill' } do %>
139
- <%= f.radio_button :skill_level, 0, label: 'Novice', inline: true %>
140
- <%= f.radio_button :skill_level, 1, label: 'Intermediate', inline: true %>
141
- <%= f.radio_button :skill_level, 2, label: 'Advanced', inline: true %>
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
- ### Labels
77
+ ### Horizontal Forms
146
78
 
147
- Use the `label` option if you want to specify the field's label text:
148
-
149
- ```erb
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
- If you don't want to render the field's label, pass `:none` to the option:
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
- <%= f.text_area :comment, label: :none, placeholder: 'Leave a comment...' %>
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
- NOTE: To specify the label for a `control_group` you must do it like this:
99
+ To create a static control in a horizontal form, use the following markup:
160
100
 
161
101
  ```erb
162
- <%= f.control_group :terms, label: { text: 'Terms' } do %>
163
- <%= f.check_box :terms, label: 'I agree to the Terms of Service' %>
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
- ### Help text
109
+ ### Labels
168
110
 
169
- To add help text, use the `help` option, which will place it
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 :password, help: 'Must be at least 6 characters long' %>
114
+ <%= f.password_field :password_confirmation, label: "Confirm Password" %>
174
115
  ```
175
116
 
176
- To place help text underneath a field, pass the option `help:
177
- :block` to the `bootstrap_form_for` helper:
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
- <%= bootstrap_form_for(@user, help: :block) do |f| %>
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
- ### Prepending inputs
124
+ ### Help Text
186
125
 
187
- You can prepend an input file with the `prepend` option:
126
+ To add help text, use the `help` option:
188
127
 
189
128
  ```erb
190
- <%= f.text_field :twitter_username, prepend: '@' %>
129
+ <%= f.password_field :password, help: "Must be at least 6 characters long" %>
191
130
  ```
192
131
 
193
- ### Appending inputs
132
+ ### Submit Buttons
194
133
 
195
- You can append an input file with the `append` option:
134
+ The `btn btn-default` css classes are automatically added to your submit
135
+ buttons.
196
136
 
197
137
  ```erb
198
- <%= f.text_field :amount, append: '.00' %>
138
+ <%= f.submit "Log In" %>
199
139
  ```
200
140
 
201
- ### Submit buttons
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.primary "Create My Account" %>
144
+ <%= f.submit "Log In", class: "btn btn-primary" %>
209
145
  ```
210
146
 
211
- Here's a `secondary` submit button (applies just the `.btn` class):
147
+ ### Checkboxes and Radios
212
148
 
213
- ```erb
214
- <%= f.secondary "Create My Account" %>
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.actions do %>
222
- <%= f.primary 'Create My Account' %>
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
- And if you don't want to use the `actions` helper, here's how you might
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
- <%= bootstrap_form_for(@user, html: { class: 'form-horizontal' }) do |f| %>
231
- <%= f.control_group do %>
232
- <%= f.primary "Create My Account" %>
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
- ### Custom Control Groups
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
- <%= bootstrap_form_for(@user, html: { class: 'form-horizontal' }) do |f| %>
245
- <%= f.control_group do %>
246
- <%= f.primary "Create My Account" %>
247
- <% end %>
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
- To specify a label that isn't linked to an element you can do this:
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.control_group :nil, label: { text: 'Foo' } do %>
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 called.
199
+ `bootstrap_form_for` is used.
266
200
 
267
- To display an error message wrapped in `.alert` and `.alert-error`
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
@@ -1,6 +1,5 @@
1
1
  require 'bootstrap_form/form_builder'
2
2
  require 'bootstrap_form/helper'
3
- require 'bootstrap_form/engine'
4
3
 
5
4
  module BootstrapForm
6
5
  end
@@ -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
- help = options.fetch(:help, nil)
12
- @help_class = help.eql?(:block) ? 'help-block' : 'help-inline'
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
- help = options.delete(:help)
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
- element = super(name, *args)
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 = "1", unchecked_value = "0")
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 += ' ' + (options[:label] || name.to_s.humanize)
39
+ html = super(name, options.except(:label, :help, :inline), checked_value, unchecked_value)
40
+ html << ' ' + (options[:label] || name.to_s.humanize)
51
41
 
52
- css = 'checkbox'
53
- css << ' inline' if options[:inline]
54
- label(name, html, class: css)
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 << ' inline' if options[:inline]
58
+ css << '-inline' if options[:inline]
65
59
  label("#{name}_#{value}", html, class: css)
66
60
  end
67
61
 
68
- def control_group(name = nil, options = {}, &block)
69
- errors_has_name = object.respond_to?(:errors) && !(name.nil? || object.errors[name].empty?)
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
- options[:class] ||= 'control-group'
72
- options[:class] << ' error' if errors_has_name
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
- label = options.delete(:label)
75
- _help = options.delete(:help)
76
-
77
- content_tag(:div, options) do
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
- if label && label[:text] != :none
81
- label[:class] ||= 'control-label'
82
- label[:for] ||= '' if name.nil?
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
- html << label(name, label[:text], label.except(:text))
85
- end
80
+ def alert_message(title, *args)
81
+ options = args.extract_options!
82
+ css = options[:class] || 'alert alert-danger'
86
83
 
87
- html << content_tag(:div, class: 'controls') do
88
- controls = capture(&block)
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
- help = errors_has_name ? object.errors[name].join(', ') : _help
91
- controls << content_tag(:span, help, class: @help_class) if help
89
+ private
92
90
 
93
- controls.html_safe
94
- end
91
+ def horizontal?
92
+ style == :horizontal
93
+ end
95
94
 
96
- html.html_safe
97
- end
95
+ def default_left_class
96
+ "col-sm-2"
98
97
  end
99
98
 
100
- def actions(&block)
101
- content_tag :div, class: "form-actions" do
102
- capture(&block)
103
- end
99
+ def default_right_class
100
+ "col-sm-10"
104
101
  end
105
102
 
106
- def primary(name, options = {})
107
- options.merge! class: 'btn btn-primary'
108
- submit name, options
103
+ def hide_class
104
+ "sr-only" # still accessible for screen readers
109
105
  end
110
106
 
111
- def secondary(name, options = {})
112
- options.merge! class: 'btn'
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 alert_message(title, *args)
117
- options = args.extract_options!
118
- css = options[:class] || "alert alert-error"
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
- if object.respond_to?(:errors) && object.errors.full_messages.any?
121
- content_tag :div, class: css do
122
- title
123
- end
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