twitter-bootstrap-form-builder 0.0.2 → 0.0.3
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,8 +1,12 @@
|
|
1
1
|
# TwitterBootstrapFormBuilder
|
2
2
|
|
3
|
-
A gem for building **
|
3
|
+
A gem for building **horizontal** (vertial/search/inline coming soon) Twitter Bootstrap forms, automagically handling the
|
4
4
|
control-group markup, field labels and inline-error messages.
|
5
5
|
|
6
|
+
## Changes
|
7
|
+
|
8
|
+
This fork displays error messages with .to_sentence instead of .join(',')
|
9
|
+
|
6
10
|
## Installation
|
7
11
|
|
8
12
|
Add this line to your application's Gemfile:
|
@@ -45,7 +49,7 @@ end
|
|
45
49
|
|
46
50
|
## Usage
|
47
51
|
|
48
|
-
Twitter Bootstrap FormBuilder is designed to output all the markup required to build **
|
52
|
+
Twitter Bootstrap FormBuilder is designed to output all the markup required to build **horizontal** forms,
|
49
53
|
with minimal typing.
|
50
54
|
|
51
55
|
After installing the Gem, you can use the special `form_for` helper by mixing `TwitterBootstrapFormBuilder::Helper`
|
@@ -95,6 +99,34 @@ the regular `FormBuilder#text_field`, use `:label => false`:
|
|
95
99
|
<%= f.text_field :email, :label => false %> # <input type="text" id="post_email" />
|
96
100
|
```
|
97
101
|
|
102
|
+
Checkboxes are a special case. They can contain two labels in a horizontal form, on to the left and
|
103
|
+
one to the right.
|
104
|
+
|
105
|
+
The left label uses the `:label` option and works as expected.
|
106
|
+
|
107
|
+
The right label is controled by the `:about` option.
|
108
|
+
|
109
|
+
Example:
|
110
|
+
|
111
|
+
```erb
|
112
|
+
<%= f.check_box :hide_email, :about => "Do not display my email in my post" %>
|
113
|
+
```
|
114
|
+
|
115
|
+
Produces the following HTML:
|
116
|
+
|
117
|
+
```html
|
118
|
+
<div class="control-group hide_email">
|
119
|
+
<label class="control-label" for="post_hide_email">Hide email</label>
|
120
|
+
<div class="controls">
|
121
|
+
<label class="checkbox" for="post_hide_email">
|
122
|
+
<input name="post[hide_email]" type="hidden" value="0" />
|
123
|
+
<input id="post_hide_email" name="post[hide_email]" type="checkbox" value="1" />
|
124
|
+
Do not display my email in my post
|
125
|
+
</label>
|
126
|
+
</div>
|
127
|
+
</div>
|
128
|
+
```
|
129
|
+
|
98
130
|
### Errors and validation
|
99
131
|
|
100
132
|
The TwitterBootstrapFormBuilder relies on the dynamic_form gem to output inline error messages.
|
@@ -1,4 +1,3 @@
|
|
1
|
-
|
2
1
|
require 'dynamic_form'
|
3
2
|
|
4
3
|
module MNE
|
@@ -15,33 +14,32 @@ module MNE
|
|
15
14
|
opts[:class] << "control-group"
|
16
15
|
opts[:class] << field if field
|
17
16
|
|
18
|
-
opts[:class] << "error" if @object.errors.messages.has_key? field
|
17
|
+
opts[:class] << "error" if @object.errors.messages.has_key?(field) && @object.errors.messages[field].any?
|
19
18
|
|
20
19
|
@template.content_tag(:div, opts) do
|
21
20
|
@template.capture &block
|
22
21
|
end
|
23
22
|
end
|
24
23
|
|
25
|
-
%w(text_field phone_field password_field email_field number_field file_field text_area select
|
24
|
+
%w(text_field phone_field password_field email_field number_field file_field text_area select).each do |method_name|
|
26
25
|
define_method method_name.to_sym do |field, *args|
|
27
26
|
|
28
|
-
# extract the options for the label tag
|
29
|
-
opts
|
30
|
-
label_opts = opts
|
31
|
-
|
27
|
+
# find the options hash, and extract the options for the label tag
|
28
|
+
opts = extract_options(args)
|
29
|
+
label_opts = extract_sub_options(opts, :label)
|
30
|
+
|
32
31
|
# If label is false, we're rendering the field without modification
|
33
32
|
return super(field, *args) if label_opts === false
|
34
|
-
|
33
|
+
|
34
|
+
# Add the TB class to the label
|
35
|
+
label_opts << { :class => "control-label" }
|
36
|
+
|
35
37
|
# create a help-block if present
|
36
|
-
|
37
|
-
|
38
|
-
|
38
|
+
help_block = opts[:help_block] ? @template.content_tag(:p, opts[:help_block], :class => "help-block") : ""
|
39
|
+
|
39
40
|
# propogate properties of control group up
|
40
|
-
|
41
|
-
control_group_opts =
|
42
|
-
control_group_opts[:class] = control_group_opts[:class] ? control_group_opts[:class] + " #{method_name}" : "#{method_name}"
|
43
|
-
|
44
|
-
label_opts = Array[label_opts] << { :class => "control-label" }
|
41
|
+
control_group_opts = opts[:control_group] || {}
|
42
|
+
control_group_opts[:class] = control_group_opts[:class] ? control_group_opts[:class] + " #{method_name}" : "#{method_name}"
|
45
43
|
|
46
44
|
control_group(field, control_group_opts) do
|
47
45
|
label(field, *label_opts) + @template.content_tag(:div, :class => "controls") do
|
@@ -49,12 +47,56 @@ module MNE
|
|
49
47
|
end
|
50
48
|
end.html_safe
|
51
49
|
end
|
50
|
+
end
|
51
|
+
|
52
|
+
|
53
|
+
# Special handling for check boxes, which can have two labels
|
54
|
+
def check_box(field, options = {}, checked_value = "1", unchecked_value = "0")
|
55
|
+
label_opts = extract_sub_options(options, :label)
|
56
|
+
about_opts = extract_sub_options(options, :about)
|
57
|
+
|
58
|
+
return super if label_opts == false
|
59
|
+
|
60
|
+
#raise [object.errors.messages, errors_for(field)].inspect
|
61
|
+
# Add the TB class to the thelabel
|
62
|
+
label_opts << { :class => "control-label" } unless label_opts.nil?
|
63
|
+
about_opts << { :class => "checkbox" } if about_opts.any?
|
64
|
+
|
65
|
+
control_group_opts = options[:control_group] || {}
|
66
|
+
|
67
|
+
label_tag = (label_opts ? label(field, *label_opts) : "").html_safe
|
68
|
+
check_box = super(field, options, checked_value, unchecked_value).html_safe
|
69
|
+
|
70
|
+
control_group(field, control_group_opts) do
|
71
|
+
label_tag + @template.content_tag(:div, :class => "controls") do
|
72
|
+
check_box = label(field, *about_opts) { check_box + about_opts[0] } if about_opts
|
73
|
+
check_box + errors_for(field)
|
74
|
+
end
|
75
|
+
end.html_safe
|
76
|
+
end
|
77
|
+
|
78
|
+
protected
|
79
|
+
|
80
|
+
def extract_options(args)
|
81
|
+
args.find { |a| a.is_a?(Hash) && a.has_key?(:label) } || {}
|
82
|
+
end
|
83
|
+
|
84
|
+
def extract_sub_options(opts, key = :label)
|
85
|
+
sub_opts = opts.keys.include?(key) ? opts[key] : []
|
86
|
+
opts.delete(key)
|
87
|
+
return false if sub_opts === false
|
88
|
+
return nil if sub_opts.nil?
|
89
|
+
Array(sub_opts)
|
90
|
+
end
|
52
91
|
|
92
|
+
def label_opts(opts, key = :label)
|
93
|
+
label_opts = extract_sub_options(opts, key)
|
94
|
+
label_opts << { :class => "control-label" }
|
53
95
|
end
|
54
96
|
|
55
97
|
def errors_for(field)
|
56
|
-
@template.content_tag(:span, "#{object.class.human_attribute_name(field)} #{object.errors.messages[field].
|
57
|
-
:class => "help-inline") if object.errors.messages[field].any?
|
98
|
+
@template.content_tag(:span, "#{object.class.human_attribute_name(field)} #{object.errors.messages[field].to_sentence}",
|
99
|
+
:class => "help-inline") if object.errors.messages.has_key?(field) && object.errors.messages[field].any?
|
58
100
|
end
|
59
101
|
|
60
102
|
end
|
metadata
CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
segments:
|
6
6
|
- 0
|
7
7
|
- 0
|
8
|
-
-
|
9
|
-
version: 0.0.
|
8
|
+
- 3
|
9
|
+
version: 0.0.3
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Matthew Eagar
|
@@ -14,7 +14,7 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2012-
|
17
|
+
date: 2012-08-03 00:00:00 -04:00
|
18
18
|
default_executable:
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|