twitter-bootstrap-form-builder 0.0.2

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.
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in twitter-bootstrap-form-builder.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 Matthew Eagar
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,213 @@
1
+ # TwitterBootstrapFormBuilder
2
+
3
+ A gem for building **horzontal** (vertial/search/inline coming soon) Twitter Bootstrap forms, automagically handling the
4
+ control-group markup, field labels and inline-error messages.
5
+
6
+ ## Installation
7
+
8
+ Add this line to your application's Gemfile:
9
+
10
+ gem 'twitter-bootstrap-form-builder'
11
+
12
+ And then execute:
13
+
14
+ $ bundle
15
+
16
+ Or install it yourself as:
17
+
18
+ $ gem install twitter-bootstrap-form-builder
19
+
20
+ ## QuickStart
21
+
22
+ ### app/helpers/application_helper.rb
23
+
24
+ ```ruby
25
+ module ApplicationHelper
26
+ # Replace form_for
27
+ include MNE::TwitterBootstrapFormBuilder
28
+ end
29
+ ```
30
+
31
+ ### Using the form builder
32
+
33
+ ```erb
34
+ <% # Labels and control-group markup are handled by the form builder %>
35
+
36
+ <%= form_for @post do |f| %>
37
+ <%= f.text_field :topic %>
38
+ <%= f.text_area :body %>
39
+ <div class="form-actions">
40
+ <%= f.submit "Create Post" %>
41
+ </div>
42
+ <% end %>
43
+ ```
44
+
45
+
46
+ ## Usage
47
+
48
+ Twitter Bootstrap FormBuilder is designed to output all the markup required to build **horzontal** forms,
49
+ with minimal typing.
50
+
51
+ After installing the Gem, you can use the special `form_for` helper by mixing `TwitterBootstrapFormBuilder::Helper`
52
+ into your Helper modules, which will automatically add the `form-horizontal` class to your `<form>` tag,
53
+ and set the `:builder` to `TwitterBootstrapFormBuilder`. That is, the following are roughly equivalent:
54
+
55
+ ```ruby
56
+ # Using the TBFB helper:
57
+ form_for @post do |f|
58
+
59
+ # Using the regular form_for helper
60
+ form_for @post, :builder => MNE::TwitterBootstrapFormBuilder::FormBuilder, :html => { :class => "form-horizontal" } do |f|
61
+ ```
62
+
63
+ ### Using the FormBuilder:
64
+
65
+ The various `*_field` and `select` methods will output the full markup for a control group, including labels.
66
+
67
+ The following `text_field`...
68
+
69
+ ```erb
70
+ <%= form_for @post do |f| %>
71
+ <%= f.text_field :subject %>
72
+ ```
73
+
74
+ Outputs the following HTML:
75
+
76
+ ```html
77
+ <div class="text_field control-group subject">
78
+ <label for="post_subject">Subject</label>
79
+ <div class="controls">
80
+ <input type="text" name="post[subject]" id="post_subject" value="..." />
81
+ </div>
82
+ </div>
83
+ ```
84
+
85
+ If you need to override the text of the label, use `:label`:
86
+
87
+ ```erb
88
+ <%= f.text_field :email, :label => "Email Address" %>
89
+ ```
90
+
91
+ If you want to turn off the helper entirely and output *just* the text field, exactly as if you were calling
92
+ the regular `FormBuilder#text_field`, use `:label => false`:
93
+
94
+ ```erb
95
+ <%= f.text_field :email, :label => false %> # <input type="text" id="post_email" />
96
+ ```
97
+
98
+ ### Errors and validation
99
+
100
+ The TwitterBootstrapFormBuilder relies on the dynamic_form gem to output inline error messages.
101
+
102
+ Outputting a field with errors will add an inline error message and decorate the top-level control-group with an
103
+ `error` class, causing the field inside to be outlined in Red by bootstrap.css
104
+
105
+ Given a post with a "can't be blank" error on the topic field:
106
+
107
+ ```erb
108
+ <%= form_for @post do |f| %>
109
+ <%= f.text_field :topic %>
110
+ <% end %>
111
+ ```
112
+
113
+ The following will be produced (a mixture of Rail's `field_with_errors` and Bootstrap-specific classes):
114
+
115
+ ```html
116
+ <div class="text_field control-group topic error">
117
+ <div class="field_with_errors">
118
+ <label for="post_topic">Topic</label>
119
+ </div>
120
+ <div class="controls">
121
+ <div class="field_with_errors">
122
+ <input type="text" name="post[topic]" value="..." />
123
+ </div>
124
+ <p class="help-block">Topic can't be blank</p>
125
+ </div>
126
+ </div>
127
+ ```
128
+
129
+ Note that both the `label` and `input` elements are still wrapped in `<div class="field_with_errors">` by the base
130
+ FormBuilder. In addition, a `<p class="help-block">` is output below the field containing the error message.
131
+
132
+ ### Rendering just some fields:
133
+
134
+ ```erb
135
+ <%= fields_for @post, :builder => MNE::TwitterBootstrapFormBuilder::FormBuilder do |f| %>
136
+ ```
137
+
138
+ ### Other helpers
139
+
140
+ If you want to output your own control group, you can use the `control_group` method to help with the markup.
141
+
142
+ ```erb
143
+ <%= f.control_group :topic %> <!-- div class="control-group topic [error]" -->
144
+ <%= f.label :topic %>
145
+ <div class="controls">
146
+ <%= f.text_field :topic, :label => false %>
147
+ <div class="errors">
148
+ <%= f.errors_for :topic %><!-- as provided by dynamic_form -->
149
+ </div>
150
+ </div>
151
+ <% end %>
152
+ ```
153
+
154
+ ## Examples
155
+
156
+ Here is a basic form for a PhotoSet, which contains a title and description attribute.
157
+ The form has been posted back, causing a `validates_presence_of` validator to fail on the `title` field:
158
+
159
+ Form:
160
+
161
+ ```erb
162
+ <%= form_for [:admin, @photo_set] do |f| %>
163
+ <%= f.text_field :title %>
164
+ <%= f.text_area :description %>
165
+
166
+ <div class="form-actions">
167
+ <%= f.submit "Create Photo Set" %>
168
+ </div>
169
+ <% end %>
170
+ ```
171
+
172
+ Output (cleaned up and indented):
173
+
174
+ ```html
175
+ <form accept-charset="UTF-8" action="/admin/photo_sets" class="form-horizontal" id="new_photo_set" method="post">
176
+ <div style="margin:0;padding:0;display:inline">
177
+ <input name="utf8" type="hidden" value="&#x2713;" />
178
+ <input name="authenticity_token" type="hidden" value="nVRM9bXgeD2s/WGum+fJMy9dMYSNVCzYR6/U0Pg+068=" />
179
+ </div>
180
+ <div class="text_field control-group title error">
181
+ <div class="field_with_errors">
182
+ <label class="control-label" for="photo_set_title">Title</label>
183
+ </div>
184
+ <div class="controls">
185
+ <div class="field_with_errors">
186
+ <input id="photo_set_title" name="photo_set[title]" size="30" type="text" value="" />
187
+ </div>
188
+ <p class="help-block">Title can't be blank</p>
189
+ </div>
190
+ </div>
191
+ <div class="text_area control-group description">
192
+ <label class="control-label" for="photo_set_description">Description</label>
193
+ <div class="controls">
194
+ <textarea cols="40" id="photo_set_description" name="photo_set[description]" rows="20">
195
+
196
+ </textarea>
197
+ </div>
198
+ </div>
199
+ <div class="form-actions">
200
+ <input name="commit" type="submit" value="Create Photo Set" />
201
+ </div>
202
+ </form>
203
+ ```
204
+
205
+
206
+
207
+ ## Contributing
208
+
209
+ 1. Fork it
210
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
211
+ 3. Commit your changes (`git commit -am 'Added some feature'`)
212
+ 4. Push to the branch (`git push origin my-new-feature`)
213
+ 5. Create new Pull Request
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
@@ -0,0 +1,3 @@
1
+ require "twitter-bootstrap-form-builder/version"
2
+ require "twitter-bootstrap-form-builder/form_builder"
3
+ require "twitter-bootstrap-form-builder/helper"
@@ -0,0 +1,62 @@
1
+
2
+ require 'dynamic_form'
3
+
4
+ module MNE
5
+ module TwitterBootstrapFormBuilder
6
+ class FormBuilder < ActionView::Helpers::FormBuilder
7
+
8
+ include ActionView::Helpers::DynamicForm::FormBuilderMethods
9
+
10
+ def control_group(field = nil, opts = {}, &block)
11
+ raise "Expected hash for options, got #{opts.inspect}" unless opts.is_a? Hash
12
+
13
+ # wrap in array if not an array
14
+ opts[:class] = Array(opts[:class])
15
+ opts[:class] << "control-group"
16
+ opts[:class] << field if field
17
+
18
+ opts[:class] << "error" if @object.errors.messages.has_key? field
19
+
20
+ @template.content_tag(:div, opts) do
21
+ @template.capture &block
22
+ end
23
+ end
24
+
25
+ %w(text_field phone_field password_field email_field number_field file_field text_area select check_box).each do |method_name|
26
+ define_method method_name.to_sym do |field, *args|
27
+
28
+ # extract the options for the label tag
29
+ opts = args.find { |a| a.is_a?(Hash) && a.has_key?(:label) }
30
+ label_opts = opts ? opts[:label] : []
31
+
32
+ # If label is false, we're rendering the field without modification
33
+ return super(field, *args) if label_opts === false
34
+
35
+ # create a help-block if present
36
+ help_opts = args.find { |a| a.is_a?(Hash) && a.has_key?(:help_block) }
37
+ help_block = help_opts && help_opts[:help_block] ? @template.content_tag(:p, help_opts[:help_block], :class => "help-block") : ""
38
+
39
+ # propogate properties of control group up
40
+ h = args.find { |a| a.is_a?(Hash) && a.has_key?(:control_group) }
41
+ control_group_opts = (h && h[:control_group]) || {}
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" }
45
+
46
+ control_group(field, control_group_opts) do
47
+ label(field, *label_opts) + @template.content_tag(:div, :class => "controls") do
48
+ super(field, *args) + help_block + errors_for(field)
49
+ end
50
+ end.html_safe
51
+ end
52
+
53
+ end
54
+
55
+ def errors_for(field)
56
+ @template.content_tag(:span, "#{object.class.human_attribute_name(field)} #{object.errors.messages[field].join(",")}",
57
+ :class => "help-inline") if object.errors.messages[field].any?
58
+ end
59
+
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,21 @@
1
+
2
+ module MNE
3
+ module TwitterBootstrapFormBuilder
4
+ module Helper
5
+ def form_for (*args)
6
+ args << {} unless args.last.is_a? Hash
7
+
8
+ args.last[:builder] ||= MNE::TwitterBootstrapFormBuilder::FormBuilder
9
+ args.last[:html] ||= {}
10
+ args.last[:html][:class] ||= ""
11
+
12
+ if !args.last[:html][:class].match(/form-(horizontal|vertical)/)
13
+ args.last[:html][:class] = ["form-horizontal", args.last[:html][:class]].join(" ")
14
+ end
15
+
16
+ super
17
+ end
18
+ end
19
+ end
20
+ end
21
+
@@ -0,0 +1,5 @@
1
+ module MNE
2
+ module TwitterBootstrapFormBuilder
3
+ VERSION = "0.0.2"
4
+ end
5
+ end
@@ -0,0 +1,19 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/twitter-bootstrap-form-builder/version', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.authors = ["Matthew Eagar"]
6
+ gem.email = ["matthew.eagar@mosaic.com"]
7
+ gem.description = "Twitter Bootstrap form_for"
8
+ gem.summary = "Twitter Bootstrap form_for"
9
+ gem.homepage = ""
10
+
11
+ gem.files = `git ls-files`.split($\)
12
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
13
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
14
+ gem.name = "twitter-bootstrap-form-builder"
15
+ gem.require_paths = ["lib"]
16
+ gem.version = MNE::TwitterBootstrapFormBuilder::VERSION
17
+
18
+ gem.add_dependency 'dynamic_form', '~>1.1.4'
19
+ end
metadata ADDED
@@ -0,0 +1,85 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: twitter-bootstrap-form-builder
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 0
8
+ - 2
9
+ version: 0.0.2
10
+ platform: ruby
11
+ authors:
12
+ - Matthew Eagar
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2012-07-30 00:00:00 -04:00
18
+ default_executable:
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: dynamic_form
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ~>
26
+ - !ruby/object:Gem::Version
27
+ segments:
28
+ - 1
29
+ - 1
30
+ - 4
31
+ version: 1.1.4
32
+ type: :runtime
33
+ version_requirements: *id001
34
+ description: Twitter Bootstrap form_for
35
+ email:
36
+ - matthew.eagar@mosaic.com
37
+ executables: []
38
+
39
+ extensions: []
40
+
41
+ extra_rdoc_files: []
42
+
43
+ files:
44
+ - .gitignore
45
+ - Gemfile
46
+ - LICENSE
47
+ - README.md
48
+ - Rakefile
49
+ - lib/twitter-bootstrap-form-builder.rb
50
+ - lib/twitter-bootstrap-form-builder/form_builder.rb
51
+ - lib/twitter-bootstrap-form-builder/helper.rb
52
+ - lib/twitter-bootstrap-form-builder/version.rb
53
+ - twitter-bootstrap-form-builder.gemspec
54
+ has_rdoc: true
55
+ homepage: ""
56
+ licenses: []
57
+
58
+ post_install_message:
59
+ rdoc_options: []
60
+
61
+ require_paths:
62
+ - lib
63
+ required_ruby_version: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ segments:
68
+ - 0
69
+ version: "0"
70
+ required_rubygems_version: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - ">="
73
+ - !ruby/object:Gem::Version
74
+ segments:
75
+ - 0
76
+ version: "0"
77
+ requirements: []
78
+
79
+ rubyforge_project:
80
+ rubygems_version: 1.3.6
81
+ signing_key:
82
+ specification_version: 3
83
+ summary: Twitter Bootstrap form_for
84
+ test_files: []
85
+