padrino_bootstrap_forms 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,8 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
5
+ .DS_Store
6
+ .rspec
7
+ .rvmrc
8
+ spec/dummy/log
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color
data/.travis.yml ADDED
@@ -0,0 +1,5 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.8.7
4
+ - 1.9.2
5
+ - 1.9.3
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source "http://rubygems.org"
2
+
3
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,7 @@
1
+ Copyright (c) 2012 Seth Vargo
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4
+
5
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6
+
7
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.markdown ADDED
@@ -0,0 +1,197 @@
1
+ Padrino Bootstrap Forms
2
+ ===============
3
+
4
+ [![Build Status](https://secure.travis-ci.org/sshaw/padrino_bootstrap_forms.png?branch=master)](http://travis-ci.org/sshaw/padrino_bootstrap_forms)
5
+
6
+ Padrino Bootstrap Forms is a port of [Seth Vargo's Bootstrap Forms for Rails](http://github.com/sethvargo/bootstrap_forms). Thanks Seth!
7
+
8
+ Bootstrap Forms is a nice generator that makes working with [Bootstrap (by Twitter)](http://twitter.github.com/bootstrap) even easier on Padrino.
9
+
10
+ Differences Between This & The Rails Version
11
+ ------------------------
12
+
13
+ * No `bootstrap` namespace for localization
14
+ * `@builder.error_messages` was removed and the Padrino version is not automatically called when there's an error
15
+ * Models with required attributes will not have the HTML5 `required` attribute automatically added to their `input`s
16
+ * The following helpers have been removed, as they are not available in Padrino
17
+ * `collection_select`
18
+ * `country_select`
19
+ * `time_zone_select`
20
+ * `range_field`
21
+
22
+ Bootstrap 2.0 Compliant!
23
+ ------------------------
24
+ A super special thanks to [vincenzor](https://github.com/vincenzor) for updating `bootstrap_forms` to comply with the new methods and features in Twitter Bootstrap 2.0.
25
+
26
+ Installation
27
+ ------------
28
+ Add it to your `Gemfile`:
29
+
30
+ gem 'padrino_bootstrap_forms', :require => 'bootstrap_forms'
31
+
32
+ Don't forget to run the `bundle` command.
33
+
34
+ Register it with your application:
35
+
36
+ class YourApplication < Padrino::Application
37
+ register BootstrapForms
38
+ # ...
39
+ end
40
+
41
+ This will add the method `bootstrap_form_for` for use in your project.
42
+
43
+ Why?
44
+ ----
45
+ With Bootstrap, you would need the following code for a form:
46
+
47
+ ```haml
48
+ / using HAML
49
+ = form_for @model do |f|
50
+ .clearfix
51
+ %label MyLabel
52
+ .input
53
+ = f.text_area :field, :opts => {...}
54
+ ```
55
+
56
+ Using Bootstrap Forms, this is **much** simpler:
57
+
58
+ ```haml
59
+ / using HAML
60
+ = bootstrap_form_for @model do |f|
61
+ = f.text_area :field, :opts => {...}
62
+ ```
63
+
64
+ The custom form builder will automatically wrap everything for you. This helps clean up your view layer significantly!
65
+
66
+ Additional Form Methods
67
+ -----------------------
68
+ Just when you thought you were done... Bootstrap Forms includes additional form helpers that make life **a lot** easier! For example, the markup required for a list of checkboxes is quite cumbersome... well, it used to be.
69
+
70
+ ### collection_check_boxes
71
+ `collection_check_boxes` behaves very similarly to `collection_select`:
72
+
73
+ ```haml
74
+ = f.collection_check_boxes :category_ids, Category.all, :id, :name
75
+ ```
76
+
77
+ ### collection_radio_buttons
78
+ See description above...
79
+
80
+ ```haml
81
+ = f.collection_radio_buttons :primary_category_id, Category.all, :id, :name
82
+ ```
83
+
84
+ ### radio_buttons
85
+
86
+ ```haml
87
+ = f.radio_buttons :published, { "Published" => true, "Unpublished" => false }
88
+ ```
89
+
90
+ Ruby 1.8 doesn't guarantee hashes are ordered. If you care, pass in nested arrays or `ActiveSupport::OrderedHash`.
91
+
92
+ Uneditable Input
93
+ ----------------
94
+ Bootstrap Forms adds another helper method that generates the necessary markup for uneditable inputs:
95
+
96
+ ```haml
97
+ = f.uneditable_input :name
98
+ ```
99
+
100
+ yields:
101
+
102
+ ```html
103
+ <div class="clearfix">
104
+ <label for="organization_name">Organization Name</label>
105
+ <div class="input">
106
+ <span class="uneditable-input">The Variety Hour</span>
107
+ </div>
108
+ </div>
109
+ ```
110
+
111
+ Submit Tag
112
+ ----------
113
+ Bootstrap Forms also adds a default actions panel when you call `f.submit`:
114
+
115
+ ```haml
116
+ = f.submit
117
+ ```
118
+
119
+ generates:
120
+
121
+ ```html
122
+ <div class="actions">
123
+ <input type="submit" value="..." class="btn primary" />
124
+ <a href="..." class="btn">Cancel</a>
125
+ </div>
126
+ ```
127
+
128
+ You can skip the cancel button by passing the `:include_cancel` button a `false` value.
129
+
130
+ Pretty swell if you ask me.
131
+
132
+ Adding More Options
133
+ -------------------
134
+ You can add as many options to any form helper tag. If they are interpreted by Bootstrap Forms, they are interpreted and rendered in the output. If not, they are passed along as values to the final HTML form object.
135
+
136
+ ### Available Options
137
+
138
+ <table>
139
+ <tr>
140
+ <th>Name</th>
141
+ <th>Description</th>
142
+ <th>Usage</th>
143
+ </tr>
144
+ <tr>
145
+ <th>help_inline</th>
146
+ <td>Add inline help text</td>
147
+ <td>= f.text_field :name, :help_inline => 'help me!'</td>
148
+ </tr>
149
+ <tr>
150
+ <th>help_block</th>
151
+ <td>Add block help text (below)</td>
152
+ <td>= f.text_field :name, :help_block => 'help me!'</td>
153
+ </tr>
154
+ <tr>
155
+ <th>error</th>
156
+ <td>Styles the field as error (red)</td>
157
+ <td>= f.text_field :name, :error => 'This is an error!'</td>
158
+ </tr>
159
+ <tr>
160
+ <th>success</th>
161
+ <td>Styles the field as success (green)</td>
162
+ <td>= f.text_field :name, :success => 'This checked out OK'</td>
163
+ </tr>
164
+ <tr>
165
+ <th>warning</th>
166
+ <td>Styles the field as warning (yellow)</td>
167
+ <td>= f.text_field :name, :warning => 'Take a look at this...'</td>
168
+ </tr>
169
+ <tr>
170
+ <th>prepend</th>
171
+ <td>Adds special text to the front of the input</td>
172
+ <td>= f.text_field :name, :prepend => '@'</td>
173
+ </tr>
174
+ <tr>
175
+ <th>append</th>
176
+ <td>Adds special text at the end of the input</td>
177
+ <td>= f.text_field :name, :append => '@'</td>
178
+ </tr>
179
+ </table>
180
+
181
+ Contributing
182
+ ------------
183
+ I'm pretty dam active on github. Fork and submit a pull request. Most of my pull requests are merged the same day. Make sure you:
184
+
185
+ - **Squash** into a single commit (unless it makes sense to have multiple commits)
186
+ - **Test/Spec** the changes
187
+ - **Document** your changes
188
+
189
+ License
190
+ -------
191
+ Copyright (c) 2012 Seth Vargo
192
+
193
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
194
+
195
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
196
+
197
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile ADDED
@@ -0,0 +1,18 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
3
+
4
+ desc 'Default: run specs.'
5
+ task :default => :spec
6
+
7
+ desc "Run specs"
8
+ RSpec::Core::RakeTask.new do |t|
9
+ t.pattern = "./spec/**/*_spec.rb" # don't need this, it's default.
10
+ # Put spec opts in a file named .rspec in root
11
+ end
12
+
13
+ desc "Generate code coverage"
14
+ RSpec::Core::RakeTask.new(:coverage) do |t|
15
+ t.pattern = "./spec/**/*_spec.rb" # don't need this, it's default.
16
+ t.rcov = true
17
+ t.rcov_opts = ['--exclude', 'spec']
18
+ end
@@ -0,0 +1,142 @@
1
+ module BootstrapForms
2
+ class FormBuilder < ::Padrino::Helpers::FormBuilder::AbstractFormBuilder
3
+ include BootstrapForms::Helpers::Wrappers
4
+
5
+ delegate :content_tag, :check_box_tag, :radio_button_tag, :link_to, :capture_html, :to => :template
6
+
7
+ %w(select email_field file_field number_field password_field search_field telephone_field text_area text_field url_field).each do |method_name|
8
+ define_method(method_name) do |name, *args|
9
+ @name = name
10
+ @field_options = args.extract_options!
11
+
12
+ control_group_div do
13
+ label_field + input_div do
14
+ extras { super(name, objectify_options(@field_options)) }
15
+ end
16
+ end
17
+ end
18
+ end
19
+
20
+ alias :phone_field :telephone_field
21
+
22
+ def check_box(name, *args)
23
+ @name = name
24
+ @field_options = args.extract_options!
25
+
26
+ control_group_div do
27
+ input_div do
28
+ if @field_options[:label] == false || @field_options[:label] == ''
29
+ extras { super(name, objectify_options(@field_options)) }
30
+ else
31
+ html = extras { super(name, objectify_options(@field_options)) + (@field_options[:label].blank? ? @name.to_s.humanize : @field_options[:label]) }
32
+ label(@name, :caption => html, :class => 'checkbox')
33
+ end
34
+ end
35
+ end
36
+ end
37
+
38
+ def radio_buttons(name, values = {}, opts = {})
39
+ @name = name
40
+ @field_options = opts
41
+
42
+ control_group_div do
43
+ label_field + input_div do
44
+ values.map do |text, value|
45
+ # Padrino does not stringify false values
46
+ options = objectify_options(@field_options).merge(:value => "#{value}")
47
+ if @field_options[:label] == '' || @field_options[:label] == false
48
+ extras { radio_button(name, options) + text }
49
+ else
50
+ html = extras { radio_button(name, options) + text }
51
+ label("#{name}_#{value}", :caption => html, :class => 'radio')
52
+ end
53
+ end.join('')
54
+ end
55
+ end
56
+ end
57
+
58
+ def collection_check_boxes(attribute, records, record_id, record_name, *args)
59
+ @name = attribute
60
+ @field_options = args.extract_options!
61
+
62
+ control_group_div do
63
+ label_field + extras do
64
+ content_tag(:div, :class => 'controls') do
65
+ records.collect do |record|
66
+ value = record.send(record_id)
67
+ element_id = "#{object_model_name}_#{attribute}_#{value}"
68
+
69
+ options = objectify_options(@field_options).merge(:id => element_id, :value => value)
70
+ options[:checked] = "checked" if [object.send(attribute)].flatten.include?(value)
71
+
72
+ checkbox = check_box_tag("#{object_model_name}[#{attribute}][]", options)
73
+ content_tag(:label, :class => ['checkbox', ('inline' if @field_options[:inline])].compact.join(' ')) do
74
+ checkbox + content_tag(:span, record.send(record_name))
75
+ end
76
+ end.join('')
77
+ end
78
+ end
79
+ end
80
+ end
81
+
82
+ def collection_radio_buttons(attribute, records, record_id, record_name, *args)
83
+ @name = attribute
84
+ @field_options = args.extract_options!
85
+ @args = args
86
+
87
+ control_group_div do
88
+ label_field + extras do
89
+ content_tag(:div, :class => 'controls') do
90
+ records.collect do |record|
91
+ value = record.send(record_id)
92
+ element_id = "#{object_model_name}_#{attribute}_#{value}"
93
+
94
+ options = objectify_options(@field_options).merge(:id => element_id, :value => value)
95
+ options[:checked] = "checked" if value == object.send(attribute)
96
+
97
+ radiobutton = radio_button_tag("#{object_model_name}[#{attribute}]", options)
98
+ content_tag(:label, :class => ['radio', ('inline' if @field_options[:inline])].compact.join(' ')) do
99
+ radiobutton + content_tag(:span, record.send(record_name))
100
+ end
101
+ end.join('')
102
+ end
103
+ end
104
+ end
105
+ end
106
+
107
+ def uneditable_input(name, *args)
108
+ @name = name
109
+ @field_options = args.extract_options!
110
+ @args = args
111
+
112
+ control_group_div do
113
+ label_field + input_div do
114
+ extras do
115
+ value = @field_options.delete(:value)
116
+ @field_options[:class] = [@field_options[:class], 'uneditable-input'].compact.join ' '
117
+
118
+ content_tag(:span, objectify_options(@field_options)) do
119
+ template.escape_html(value || object.send(@name.to_sym))
120
+ end
121
+ end
122
+ end
123
+ end
124
+ end
125
+
126
+ def button(*args)
127
+ template.bootstrap_button_tag(*args)
128
+ end
129
+
130
+ def submit(*args)
131
+ template.bootstrap_submit_tag(*args)
132
+ end
133
+
134
+ def cancel(*args)
135
+ template.bootstrap_cancel_tag(*args)
136
+ end
137
+
138
+ def actions(&block)
139
+ template.bootstrap_actions(&block)
140
+ end
141
+ end
142
+ end
@@ -0,0 +1,16 @@
1
+ module BootstrapForms
2
+ module Helpers
3
+ module FormHelper
4
+ def bootstrap_form_for(record, path, options = {}, &block)
5
+ options[:builder] = BootstrapForms::FormBuilder
6
+ form_for(record, path, options) do |f|
7
+ capture(f, &block)
8
+ end
9
+ end
10
+
11
+ def bootstrap_fields_for(record, instance_or_collection = nil, &block)
12
+ fields_for(record, instance_or_collection, &block)
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,78 @@
1
+ module BootstrapForms
2
+ module Helpers
3
+ module FormTagHelper
4
+ include BootstrapForms::Helpers::Wrappers
5
+
6
+ %w(check_box_tag email_field_tag file_field_tag number_field_tag password_field_tag radio_button_tag search_field_tag select_tag telephone_field_tag text_area_tag text_field_tag url_field_tag).each do |method_name|
7
+ # prefix each method with bootstrap_*
8
+ define_method("bootstrap_#{method_name}") do |name, *args|
9
+ @name = name
10
+ @field_options = args.extract_options!
11
+
12
+ control_group_div do
13
+ label_field + input_div do
14
+ extras { send(method_name.to_sym, name, objectify_options(@field_options)) }
15
+ end
16
+ end
17
+ end
18
+ end
19
+
20
+ alias :bootstrap_phone_field_tag :bootstrap_telephone_field_tag
21
+
22
+ def uneditable_input_tag(name, *args)
23
+ @name = name
24
+ @field_options = args.extract_options!
25
+ @args = args
26
+
27
+ control_group_div do
28
+ label_field + input_div do
29
+ extras do
30
+ value = @field_options.delete(:value)
31
+ @field_options[:class] = [@field_options[:class], 'uneditable-input'].compact.join ' '
32
+
33
+ content_tag(:span, objectify_options(@field_options)) do
34
+ escape_html(value)
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
40
+
41
+ def bootstrap_button_tag(*args)
42
+ options = args.extract_options!
43
+ options[:class] ||= 'btn btn-primary'
44
+
45
+ name = args.shift || 'Submit'
46
+ # button_tag() renders <input type="button">
47
+ content_tag(:button, name, options)
48
+ end
49
+
50
+ def bootstrap_submit_tag(*args)
51
+ options = args.extract_options!
52
+ options[:class] ||= 'btn btn-primary'
53
+
54
+ name = args.shift || 'Submit'
55
+ submit_tag(name, options)
56
+ end
57
+
58
+ def bootstrap_cancel_tag(*args)
59
+ options = args.extract_options!
60
+ options[:class] ||= 'btn cancel'
61
+ options[:back] ||= 'javascript:history.go(-1)'
62
+
63
+ name = args.shift || 'Cancel'
64
+ link_to(name, options[:back], options.except(:back))
65
+ end
66
+
67
+ def bootstrap_actions(&block)
68
+ content_tag(:div, :class => 'form-actions') do
69
+ if block_given?
70
+ capture_html(&block)
71
+ else
72
+ [bootstrap_submit_tag, bootstrap_cancel_tag].join(' ')
73
+ end
74
+ end
75
+ end
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,91 @@
1
+ require 'active_support/core_ext/hash/except'
2
+
3
+ module BootstrapForms
4
+ module Helpers
5
+ module Wrappers
6
+ private
7
+ def control_group_div(&block)
8
+ field_errors = error_string
9
+ if @field_options[:error]
10
+ (@field_options[:error] << ', ' << field_errors) if field_errors
11
+ else
12
+ @field_options[:error] = field_errors
13
+ end
14
+
15
+ klasses = ['control-group']
16
+ klasses << 'error' if @field_options[:error]
17
+ klasses << 'success' if @field_options[:success]
18
+ klasses << 'warning' if @field_options[:warning]
19
+ klass = klasses.join(' ')
20
+
21
+ content_tag(:div, :class => klass, &block)
22
+ end
23
+
24
+ def error_string
25
+ if respond_to?(:object)
26
+ errors = object.errors[@name]
27
+ if errors.any?
28
+ errors.map { |e|
29
+ "#{@options[:label] || @name.to_s.humanize} #{e}"
30
+ }.join(', ')
31
+ end
32
+ end
33
+ end
34
+
35
+ def input_div(&block)
36
+ content_tag(:div, :class => 'controls') do
37
+ if @field_options[:append] || @field_options[:prepend]
38
+ klasses = []
39
+ klasses << 'input-prepend' if @field_options[:prepend]
40
+ klasses << 'input-append' if @field_options[:append]
41
+ klass = klasses.join(' ')
42
+ content_tag(:div, :class => klass, &block)
43
+ else
44
+ capture_html(&block) if block_given?
45
+ end
46
+ end
47
+ end
48
+
49
+ def label_field(&block)
50
+ if @field_options[:label] == '' || @field_options[:label] == false
51
+ return ''
52
+ else
53
+ options = { :class => 'control-label' }
54
+ options[:caption] = @field_options[:label] if @field_options[:label]
55
+
56
+ if respond_to?(:object)
57
+ label(@name, options, &block)
58
+ else
59
+ label_tag(@name, options, &block)
60
+ end
61
+ end
62
+ end
63
+
64
+ %w(help_inline error success warning help_block append prepend).each do |method_name|
65
+ define_method(method_name) do |*args|
66
+ return '' unless value = @field_options[method_name.to_sym]
67
+ case method_name
68
+ when 'help_block'
69
+ element = :p
70
+ klass = 'help-block'
71
+ when 'append', 'prepend'
72
+ element = :span
73
+ klass = 'add-on'
74
+ else
75
+ element = :span
76
+ klass = 'help-inline'
77
+ end
78
+ content_tag(element, value, :class => klass)
79
+ end
80
+ end
81
+
82
+ def extras(&block)
83
+ [prepend, (capture_html(&block) if block_given?), append, help_inline, error, success, warning, help_block].join('')
84
+ end
85
+
86
+ def objectify_options(options)
87
+ options.except(:label, :help_inline, :error, :success, :warning, :help_block, :prepend, :append)
88
+ end
89
+ end
90
+ end
91
+ end
@@ -0,0 +1,7 @@
1
+ module BootstrapForms
2
+ module Helpers
3
+ autoload :FormHelper, 'bootstrap_forms/helpers/form_helper'
4
+ autoload :FormTagHelper, 'bootstrap_forms/helpers/form_tag_helper'
5
+ autoload :Wrappers, 'bootstrap_forms/helpers/wrappers'
6
+ end
7
+ end
@@ -0,0 +1,13 @@
1
+ require 'active_support'
2
+
3
+ module BootstrapForms
4
+ extend ActiveSupport::Autoload
5
+
6
+ autoload :FormBuilder
7
+ autoload :Helpers
8
+
9
+ def self.registered(app)
10
+ app.helpers Helpers::FormHelper
11
+ app.helpers Helpers::FormTagHelper
12
+ end
13
+ end
@@ -0,0 +1,22 @@
1
+ Gem::Specification.new do |s|
2
+ s.name = "padrino_bootstrap_forms"
3
+ s.version = "0.0.1"
4
+ s.authors = ["Seth Vargo", "Skye Shaw"]
5
+ s.email = "sshaw@lucas.cis.temple.edu"
6
+ s.homepage = "https://github.com/sshaw/padrino_bootstrap_forms"
7
+ s.summary = "Padrino Bootstrap Forms makes Twitter's Bootstrap on Padrino easy!"
8
+ s.description = <<-DESC
9
+ Padrino Bootstrap Forms is a port of Seth Vargo's Bootstrap Forms for Rails.
10
+ It makes Twitter's Bootstrap on Padrino easy to use by creating helpful form builders that minimize markup in your views.
11
+ DESC
12
+ s.files = `git ls-files`.split("\n")
13
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
14
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
15
+ s.require_paths = ["lib"]
16
+
17
+ s.add_dependency "padrino-helpers", "~> 0.10.6"
18
+ s.add_dependency "activesupport", "~> 3.0"
19
+ s.add_development_dependency "rake"
20
+ s.add_development_dependency "rack-test", "~> 0.6.1"
21
+ s.add_development_dependency "rspec", "~> 2.9.0"
22
+ end
@@ -0,0 +1,218 @@
1
+ require 'spec_helper'
2
+
3
+ describe "BootstrapForms::FormBuilder" do
4
+ # Note that Padrino label() and label_tag() gen labels differently, the former always appending a ":"
5
+ context "given a setup builder" do
6
+ before(:each) do
7
+ @project = Item.new
8
+ @builder = BootstrapForms::FormBuilder.new(self, @project)
9
+ end
10
+
11
+ describe "with no options" do
12
+ describe "text_area" do
13
+ before(:each) do
14
+ @result = @builder.text_area "name"
15
+ end
16
+
17
+ it "has textarea input" do
18
+ @result.should match /textarea/
19
+ end
20
+ end
21
+
22
+ describe "uneditable_input" do
23
+ it "generates wrapped input" do
24
+ @builder.uneditable_input("name").should == %|<div class="control-group"><label class="control-label" for="item_name">Name: </label><div class="controls"><span class="uneditable-input"></span></div></div>|
25
+ end
26
+
27
+ it "allows for an id" do
28
+ @builder.uneditable_input("name", :id => "myid").should match /<span.*id="myid"/
29
+ end
30
+ end
31
+
32
+ describe "check_box" do
33
+ it "generates wrapped input" do
34
+ @builder.check_box("name").should == %|<div class="control-group"><div class="controls"><label class="checkbox" for="item_name"><input value="0" name="item[name]" type="hidden" /><input id="item_name" value="1" name="item[name]" type="checkbox" />Name</label></div></div>|
35
+ end
36
+
37
+ it "allows custom label" do
38
+ @builder.check_box("name", :label => "custom label").should match /custom label<\/label>/
39
+ end
40
+
41
+ it "allows no label with :label => false " do
42
+ @builder.check_box("name", :label => false).should_not match /<\/label>/
43
+ end
44
+ it "allows no label with :label => '' " do
45
+ @builder.check_box("name", :label => '').should_not match /<\/label>/
46
+ end
47
+ end
48
+
49
+ describe "radio_buttons" do
50
+ before do
51
+ if RUBY_VERSION < '1.9'
52
+ @options = ActiveSupport::OrderedHash.new
53
+ @options['One'] = '1'
54
+ @options['Two'] = '2'
55
+ else
56
+ @options = {'One' => '1', 'Two' => '2'}
57
+ end
58
+ end
59
+
60
+ it "doesn't use field_options from previously generated field" do
61
+ @builder.text_field :name, :label => 'Heading', :help_inline => 'Inline help', :help_block => 'Block help'
62
+ @builder.radio_buttons(:name, @options).should == %|<div class="control-group"><label class="control-label" for="item_name">Name: </label><div class="controls"><label class="radio" for="item_name_1"><input value="1" id="item_name_1" name="item[name]" type="radio" />One</label><label class="radio" for="item_name_2"><input value="2" id="item_name_2" name="item[name]" type="radio" />Two</label></div></div>|
63
+ end
64
+
65
+ it "sets field_options" do
66
+ @builder.radio_buttons(:name, {"One" => "1", "Two" => "2"})
67
+ @builder.instance_variable_get("@field_options").should == {:error => nil}
68
+ end
69
+
70
+ it "generates wrapped input" do
71
+ @builder.radio_buttons(:name, @options).should == %|<div class="control-group"><label class="control-label" for="item_name">Name: </label><div class="controls"><label class="radio" for="item_name_1"><input value="1" id="item_name_1" name="item[name]" type="radio" />One</label><label class="radio" for="item_name_2"><input value="2" id="item_name_2" name="item[name]" type="radio" />Two</label></div></div>|
72
+ end
73
+
74
+ it "allows custom label" do
75
+ @builder.radio_buttons(:name, @options, {:label => "custom label"}).should match /custom label<\/label>/
76
+ end
77
+ end
78
+
79
+ # less range
80
+ (%w{email file number password search text url}.map{|field| ["#{field}_field",field]} + [["telephone_field", "tel"], ["phone_field", "tel"]]).each do |field, type|
81
+ describe "#{field}" do
82
+ context "result" do
83
+ before(:each) do
84
+ @result = @builder.send(field, "name")
85
+ end
86
+
87
+ it "is wrapped" do
88
+ @result.should match /^<div class=\"control-group\"><label class=\"control-label\" for=\"item_name\">Name: <\/label><div class=\"controls\">.*<\/div><\/div>$/
89
+ end
90
+
91
+ it "has an input of type: #{type}" do
92
+ @result.should match /<input.*type=["#{type}"]/
93
+ end
94
+ end # result
95
+
96
+ context "call expectations" do
97
+ %w(control_group_div label_field input_div extras).map(&:to_sym).each do |method|
98
+ it "calls #{method}" do
99
+ @builder.should_receive(method).and_return("")
100
+ end
101
+ end
102
+
103
+ after(:each) do
104
+ @builder.send(field, "name")
105
+ end
106
+ end # call expectations
107
+
108
+ end # field
109
+ end # fields
110
+ end # no options
111
+
112
+ describe "extras" do
113
+ context "text_field" do
114
+ it "adds span for inline help" do
115
+ @builder.text_field(:name, :help_inline => 'help me!').should == %|<div class="control-group"><label class="control-label" for="item_name">Name: </label><div class="controls"><input id="item_name" name="item[name]" type="text" /><span class="help-inline">help me!</span></div></div>|
116
+ end
117
+
118
+ it "adds help block" do
119
+ @builder.text_field(:name, :help_block => 'help me!').should == %|<div class="control-group"><label class="control-label" for="item_name">Name: </label><div class="controls"><input id="item_name" name="item[name]" type="text" /><p class="help-block">help me!</p></div></div>|
120
+ end
121
+
122
+ it "adds error message and class" do
123
+ @builder.text_field(:name, :error => 'This is an error!').should == %|<div class="control-group error"><label class="control-label" for="item_name">Name: </label><div class="controls"><input id="item_name" name="item[name]" type="text" /><span class="help-inline">This is an error!</span></div></div>|
124
+ end
125
+
126
+ it "adds success message and class" do
127
+ @builder.text_field(:name, :success => 'This checked out OK').should == %|<div class="control-group success"><label class="control-label" for="item_name">Name: </label><div class="controls"><input id="item_name" name="item[name]" type="text" /><span class="help-inline">This checked out OK</span></div></div>|
128
+ end
129
+
130
+ it "adds warning message and class" do
131
+ @builder.text_field(:name, :warning => 'Take a look at this...').should == %|<div class="control-group warning"><label class="control-label" for="item_name">Name: </label><div class="controls"><input id="item_name" name="item[name]" type="text" /><span class="help-inline">Take a look at this...</span></div></div>|
132
+ end
133
+
134
+ it "prepends passed text" do
135
+ @builder.text_field(:name, :prepend => '@').should == %|<div class="control-group"><label class="control-label" for="item_name">Name: </label><div class="controls"><div class="input-prepend"><span class="add-on">@</span><input id="item_name" name="item[name]" type="text" /></div></div></div>|
136
+ end
137
+
138
+ it "appends passed text" do
139
+ @builder.text_field(:name, :append => '@').should == %|<div class="control-group"><label class="control-label" for="item_name">Name: </label><div class="controls"><div class="input-append"><input id="item_name" name="item[name]" type="text" /><span class="add-on">@</span></div></div></div>|
140
+ end
141
+
142
+ it "prepends and appends passed text" do
143
+ @builder.text_field(:name, :append => '@', :prepend => '#').should == %|<div class="control-group"><label class="control-label" for="item_name">Name: </label><div class="controls"><div class="input-prepend input-append"><span class="add-on">\#</span><input id="item_name" name="item[name]" type="text" /><span class="add-on">@</span></div></div></div>|
144
+ end
145
+ end
146
+
147
+ context "label option" do
148
+ %w(select email_field file_field number_field password_field search_field text_area text_field url_field).each do |method_name|
149
+
150
+ it "should not add a label when ''" do
151
+ @builder.send(method_name.to_sym, 'name', :label => '').should_not match /<\/label>/
152
+ end
153
+
154
+ it "should not add a label when false" do
155
+ @builder.send(method_name.to_sym, 'name', :label => false).should_not match /<\/label>/
156
+ end
157
+ end
158
+ end
159
+ end # extras
160
+
161
+ describe "form actions" do
162
+ context "actions" do
163
+ it "adds additional block content" do
164
+ @builder.actions do
165
+ @builder.submit
166
+ end.should == %|<div class="form-actions"><input class="btn btn-primary" value="Submit" type="submit" /></div>|
167
+ end
168
+ end
169
+
170
+ context "submit" do
171
+ it "adds btn primary class" do
172
+ @builder.submit.should == %|<input class="btn btn-primary" value="Submit" type="submit" />|
173
+ end
174
+
175
+ it "allows for custom classes" do
176
+ @builder.submit(:class => 'btn btn-large btn-success').should match /class="btn btn-large btn-success"/
177
+ end
178
+ end
179
+
180
+ context "button" do
181
+ it "adds btn primary class" do
182
+ @builder.submit.should == %|<input class="btn btn-primary" value="Submit" type="submit" />|
183
+ end
184
+
185
+ it "allows for custom classes" do
186
+ @builder.submit(:class => 'btn btn-large btn-success').should match /class="btn btn-large btn-success"/
187
+ end
188
+ end
189
+
190
+ context "cancel" do
191
+ it "creates a link with the default link" do
192
+ @builder.template.should_receive(:link_to).with('Cancel', 'javascript:history.go(-1)', instance_of(Hash))
193
+ @builder.cancel
194
+ end
195
+
196
+ it "creates a link with a custom back link" do
197
+ @builder.template.should_receive(:link_to).with('Cancel', '/x', instance_of(Hash))
198
+ @builder.cancel(:back => '/x')
199
+ end
200
+
201
+ it "creates a link with a custom name" do
202
+ @builder.template.should_receive(:link_to).with('Back', instance_of(String), instance_of(Hash))
203
+ @builder.cancel('Back')
204
+ end
205
+
206
+ it "creates link with the default class" do
207
+ @builder.template.should_receive(:link_to).with('Cancel', instance_of(String), :class => 'btn cancel')
208
+ @builder.cancel
209
+ end
210
+
211
+ it "creates a link with custom classes" do
212
+ @builder.template.should_receive(:link_to).with('Cancel', instance_of(String), :class => 'btn btn-large my-cancel')
213
+ @builder.cancel(:class => 'btn btn-large my-cancel')
214
+ end
215
+ end
216
+ end # actions
217
+ end # setup builder
218
+ end
@@ -0,0 +1,20 @@
1
+ require 'spec_helper'
2
+
3
+ describe "BootstrapForms::Helpers::FormTagHelper" do
4
+ %w(check_box_tag email_field_tag file_field_tag number_field_tag password_field_tag radio_button_tag search_field_tag select_tag telephone_field_tag text_area_tag text_field_tag url_field_tag).each do |method_name|
5
+
6
+ describe "#bootstrap_#{method_name}" do
7
+ %w(control_group_div label_field input_div extras).each do |method|
8
+ it "calls #{method}" do
9
+ should_receive(method).and_return("")
10
+ end
11
+ end
12
+
13
+ it "calls #{method_name}" do
14
+ should_receive(method_name).with(method_name, :class => "my-class")
15
+ end
16
+
17
+ after { send("bootstrap_#{method_name}", method_name, :class => "my-class") }
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,35 @@
1
+ require "padrino-helpers"
2
+ require 'rack/test'
3
+
4
+ v = RUBY_VERSION.split('.').map { |n| n.to_i }
5
+ require 'active_support/ordered_hash' if v[0] <= 1 and v[1] < 9
6
+
7
+ require File.expand_path(File.join(File.dirname(__FILE__), '../lib/bootstrap_forms'))
8
+
9
+ RSpec.configure do |config|
10
+ config.include Padrino::Helpers::OutputHelpers
11
+ config.include Padrino::Helpers::FormatHelpers
12
+ config.include Padrino::Helpers::TagHelpers
13
+ config.include Padrino::Helpers::FormHelpers
14
+ config.include BootstrapForms::Helpers::FormTagHelper
15
+ end
16
+
17
+ class Item
18
+ attr_accessor :name
19
+ def errors
20
+ @errors ||= Errors.new
21
+ end
22
+ end
23
+
24
+ class Errors < Hash
25
+ def initialize
26
+ super { |h, v| h[v] = [] }
27
+ end
28
+
29
+ def each
30
+ super do |k, v|
31
+ v.each { |e| yield(k, e) }
32
+ end
33
+ end
34
+ end
35
+
metadata ADDED
@@ -0,0 +1,123 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: padrino_bootstrap_forms
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Seth Vargo
9
+ - Skye Shaw
10
+ autorequire:
11
+ bindir: bin
12
+ cert_chain: []
13
+ date: 2012-10-15 00:00:00.000000000Z
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: padrino-helpers
17
+ requirement: &70348692896680 !ruby/object:Gem::Requirement
18
+ none: false
19
+ requirements:
20
+ - - ~>
21
+ - !ruby/object:Gem::Version
22
+ version: 0.10.6
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: *70348692896680
26
+ - !ruby/object:Gem::Dependency
27
+ name: activesupport
28
+ requirement: &70348692895740 !ruby/object:Gem::Requirement
29
+ none: false
30
+ requirements:
31
+ - - ~>
32
+ - !ruby/object:Gem::Version
33
+ version: '3.0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: *70348692895740
37
+ - !ruby/object:Gem::Dependency
38
+ name: rake
39
+ requirement: &70348692894900 !ruby/object:Gem::Requirement
40
+ none: false
41
+ requirements:
42
+ - - ! '>='
43
+ - !ruby/object:Gem::Version
44
+ version: '0'
45
+ type: :development
46
+ prerelease: false
47
+ version_requirements: *70348692894900
48
+ - !ruby/object:Gem::Dependency
49
+ name: rack-test
50
+ requirement: &70348692893840 !ruby/object:Gem::Requirement
51
+ none: false
52
+ requirements:
53
+ - - ~>
54
+ - !ruby/object:Gem::Version
55
+ version: 0.6.1
56
+ type: :development
57
+ prerelease: false
58
+ version_requirements: *70348692893840
59
+ - !ruby/object:Gem::Dependency
60
+ name: rspec
61
+ requirement: &70348692892940 !ruby/object:Gem::Requirement
62
+ none: false
63
+ requirements:
64
+ - - ~>
65
+ - !ruby/object:Gem::Version
66
+ version: 2.9.0
67
+ type: :development
68
+ prerelease: false
69
+ version_requirements: *70348692892940
70
+ description: ! "\tPadrino Bootstrap Forms is a port of Seth Vargo's Bootstrap Forms
71
+ for Rails. \n It makes Twitter's Bootstrap on Padrino easy to use by creating
72
+ helpful form builders that minimize markup in your views.\n"
73
+ email: sshaw@lucas.cis.temple.edu
74
+ executables: []
75
+ extensions: []
76
+ extra_rdoc_files: []
77
+ files:
78
+ - .gitignore
79
+ - .rspec
80
+ - .travis.yml
81
+ - Gemfile
82
+ - LICENSE
83
+ - README.markdown
84
+ - Rakefile
85
+ - lib/bootstrap_forms.rb
86
+ - lib/bootstrap_forms/form_builder.rb
87
+ - lib/bootstrap_forms/helpers.rb
88
+ - lib/bootstrap_forms/helpers/form_helper.rb
89
+ - lib/bootstrap_forms/helpers/form_tag_helper.rb
90
+ - lib/bootstrap_forms/helpers/wrappers.rb
91
+ - padrino_bootstrap_forms.gemspec
92
+ - spec/lib/bootstrap_forms/form_builder_spec.rb
93
+ - spec/lib/bootstrap_forms/form_tag_helper_spec.rb
94
+ - spec/spec_helper.rb
95
+ homepage: https://github.com/sshaw/padrino_bootstrap_forms
96
+ licenses: []
97
+ post_install_message:
98
+ rdoc_options: []
99
+ require_paths:
100
+ - lib
101
+ required_ruby_version: !ruby/object:Gem::Requirement
102
+ none: false
103
+ requirements:
104
+ - - ! '>='
105
+ - !ruby/object:Gem::Version
106
+ version: '0'
107
+ required_rubygems_version: !ruby/object:Gem::Requirement
108
+ none: false
109
+ requirements:
110
+ - - ! '>='
111
+ - !ruby/object:Gem::Version
112
+ version: '0'
113
+ requirements: []
114
+ rubyforge_project:
115
+ rubygems_version: 1.8.10
116
+ signing_key:
117
+ specification_version: 3
118
+ summary: Padrino Bootstrap Forms makes Twitter's Bootstrap on Padrino easy!
119
+ test_files:
120
+ - spec/lib/bootstrap_forms/form_builder_spec.rb
121
+ - spec/lib/bootstrap_forms/form_tag_helper_spec.rb
122
+ - spec/spec_helper.rb
123
+ has_rdoc: