bootstrap_forms 1.0.5 → 2.0.0

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.
Files changed (58) hide show
  1. data/.gitignore +3 -0
  2. data/.travis.yml +4 -0
  3. data/Guardfile +7 -0
  4. data/Rakefile +18 -1
  5. data/bootstrap_forms.gemspec +8 -1
  6. data/lib/bootstrap_forms.rb +9 -1
  7. data/lib/bootstrap_forms/engine.rb +12 -2
  8. data/lib/bootstrap_forms/form_builder.rb +28 -84
  9. data/lib/bootstrap_forms/helpers.rb +7 -0
  10. data/lib/bootstrap_forms/{initializer.rb → helpers/form_helper.rb} +7 -9
  11. data/lib/bootstrap_forms/helpers/form_tag_helper.rb +76 -0
  12. data/lib/bootstrap_forms/helpers/wrappers.rb +92 -0
  13. data/spec/dummy/Rakefile +7 -0
  14. data/spec/dummy/app/assets/javascripts/application.js +5 -0
  15. data/spec/dummy/app/assets/stylesheets/application.css +7 -0
  16. data/spec/dummy/app/controllers/application_controller.rb +3 -0
  17. data/spec/dummy/app/controllers/projects_controller.rb +5 -0
  18. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  19. data/spec/dummy/app/helpers/projects_helper.rb +2 -0
  20. data/spec/dummy/app/mailers/.gitkeep +0 -0
  21. data/spec/dummy/app/models/.gitkeep +0 -0
  22. data/spec/dummy/app/models/milestone.rb +3 -0
  23. data/spec/dummy/app/models/project.rb +4 -0
  24. data/spec/dummy/app/models/task.rb +3 -0
  25. data/spec/dummy/app/views/layouts/application.html.erb +11 -0
  26. data/spec/dummy/app/views/projects/new.html.erb +4 -0
  27. data/spec/dummy/config.ru +4 -0
  28. data/spec/dummy/config/application.rb +42 -0
  29. data/spec/dummy/config/boot.rb +10 -0
  30. data/spec/dummy/config/database.yml +25 -0
  31. data/spec/dummy/config/environment.rb +5 -0
  32. data/spec/dummy/config/environments/development.rb +27 -0
  33. data/spec/dummy/config/environments/production.rb +54 -0
  34. data/spec/dummy/config/environments/test.rb +39 -0
  35. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  36. data/spec/dummy/config/initializers/inflections.rb +10 -0
  37. data/spec/dummy/config/initializers/mime_types.rb +5 -0
  38. data/spec/dummy/config/initializers/secret_token.rb +7 -0
  39. data/spec/dummy/config/initializers/session_store.rb +8 -0
  40. data/spec/dummy/config/initializers/wrap_parameters.rb +12 -0
  41. data/spec/dummy/config/locales/en.yml +5 -0
  42. data/spec/dummy/config/routes.rb +59 -0
  43. data/spec/dummy/db/development.sqlite3 +0 -0
  44. data/spec/dummy/db/migrate/20110710143903_initial_tables.rb +23 -0
  45. data/spec/dummy/db/schema.rb +29 -0
  46. data/spec/dummy/db/test.sqlite3 +0 -0
  47. data/spec/dummy/log/development.log +0 -0
  48. data/spec/dummy/public/404.html +26 -0
  49. data/spec/dummy/public/422.html +26 -0
  50. data/spec/dummy/public/500.html +26 -0
  51. data/spec/dummy/public/favicon.ico +0 -0
  52. data/spec/dummy/script/rails +6 -0
  53. data/spec/dummy/test/functional/projects_controller_test.rb +7 -0
  54. data/spec/dummy/test/unit/helpers/projects_helper_test.rb +4 -0
  55. data/spec/dummy/tmp/cache/.gitkeep +0 -0
  56. data/spec/lib/bootstrap_forms/form_builder_spec.rb +180 -0
  57. data/spec/spec_helper.rb +20 -0
  58. metadata +198 -6
data/.gitignore CHANGED
@@ -2,3 +2,6 @@
2
2
  .bundle
3
3
  Gemfile.lock
4
4
  pkg/*
5
+ .DS_Store
6
+ .rspec
7
+ .rvmrc
data/.travis.yml ADDED
@@ -0,0 +1,4 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.9.2
4
+ - 1.9.3
data/Guardfile ADDED
@@ -0,0 +1,7 @@
1
+ # A sample Guardfile
2
+ # More info at https://github.com/guard/guard#readme
3
+ guard 'rspec', :version => 2 do
4
+ watch(%r{^spec/.+_spec\.rb$})
5
+ watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
6
+ watch('spec/spec_helper.rb') { "spec" }
7
+ end
data/Rakefile CHANGED
@@ -1 +1,18 @@
1
- require 'bundler/gem_tasks'
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
@@ -3,7 +3,7 @@ $:.push File.expand_path("../lib", __FILE__)
3
3
 
4
4
  Gem::Specification.new do |s|
5
5
  s.name = "bootstrap_forms"
6
- s.version = "1.0.5"
6
+ s.version = "2.0.0"
7
7
  s.author = "Seth Vargo"
8
8
  s.email = "sethvargo@gmail.com"
9
9
  s.homepage = "https://github.com/sethvargo/bootstrap_forms"
@@ -14,4 +14,11 @@ Gem::Specification.new do |s|
14
14
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
15
15
  s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
16
16
  s.require_paths = ["lib"]
17
+
18
+ s.add_development_dependency "rspec-rails", "~> 2.9.0"
19
+ s.add_development_dependency "capybara", "~> 1.1.0"
20
+ s.add_development_dependency "rake"
21
+ s.add_development_dependency "rails", "~> 3.2.0"
22
+ s.add_development_dependency "guard-rspec"
23
+ s.add_development_dependency "sqlite3"
17
24
  end
@@ -1 +1,9 @@
1
- require 'bootstrap_forms/engine' if defined?(Rails)
1
+ # encoding: utf-8
2
+ require 'bootstrap_forms/engine' if defined?(::Rails)
3
+
4
+ module BootstrapForms
5
+ extend ActiveSupport::Autoload
6
+
7
+ autoload :FormBuilder
8
+ autoload :Helpers
9
+ end
@@ -1,7 +1,17 @@
1
1
  module BootstrapForms
2
2
  class Engine < ::Rails::Engine
3
- config.after_initialize do |app|
4
- require 'bootstrap_forms/initializer'
3
+ initializer 'bootstrap_forms.initialize' do
4
+ config.to_prepare do
5
+ ActiveSupport.on_load(:action_view) do
6
+ include BootstrapForms::Helpers::FormHelper
7
+ include BootstrapForms::Helpers::FormTagHelper
8
+
9
+ # Do not wrap errors in the extra div
10
+ ::ActionView::Base.field_error_proc = Proc.new do |html_tag, instance_tag|
11
+ html_tag
12
+ end
13
+ end
14
+ end
5
15
  end
6
16
  end
7
17
  end
@@ -1,5 +1,7 @@
1
1
  module BootstrapForms
2
- class FormBuilder < ActionView::Helpers::FormBuilder
2
+ class FormBuilder < ::ActionView::Helpers::FormBuilder
3
+ include BootstrapForms::Helpers::Wrappers
4
+
3
5
  delegate :content_tag, :hidden_field_tag, :check_box_tag, :radio_button_tag, :button_tag, :link_to, :to => :@template
4
6
 
5
7
  def error_messages
@@ -17,7 +19,7 @@ module BootstrapForms
17
19
  end
18
20
  end
19
21
 
20
- %w(collection_select select email_field file_field number_field password_field phone_field range_field search_field telephone_field text_area text_field url_field).each do |method_name|
22
+ %w(collection_select select country_select time_zone_select email_field file_field number_field password_field phone_field range_field search_field telephone_field text_area text_field url_field).each do |method_name|
21
23
  define_method(method_name) do |name, *args|
22
24
  @name = name
23
25
  @field_options = args.extract_options!
@@ -39,16 +41,16 @@ module BootstrapForms
39
41
  control_group_div do
40
42
  input_div do
41
43
  label(@name, :class => [ 'checkbox', required_class ].compact.join(' ')) do
42
- extras { super(name, *(@args << @field_options)) + human_attribute_name }
44
+ extras { super(name, *(@args << @field_options)) + (@field_options[:label].blank? ? human_attribute_name : @field_options[:label])}
43
45
  end
44
46
  end
45
47
  end
46
48
  end
47
49
 
48
- def radio_buttons(name, values={}, opts={})
50
+ def radio_buttons(name, values = {}, opts = {})
49
51
  @name = name
50
52
  @options = opts
51
-
53
+ @field_options = opts
52
54
  control_group_div do
53
55
  label_field + input_div do
54
56
  values.map do |text, value|
@@ -91,7 +93,7 @@ module BootstrapForms
91
93
  content_tag(:div, :class => 'controls') do
92
94
  records.collect do |record|
93
95
  element_id = "#{object_name}_#{attribute}_#{record.send(record_id)}"
94
- radiobutton = radio_button_tag("#{object_name}[#{attribute}][]", record.send(record_id), object.send(attribute) == record.send(record_id), @field_options.merge({:id => element_id}))
96
+ radiobutton = radio_button_tag("#{object_name}[#{attribute}]", record.send(record_id), object.send(attribute) == record.send(record_id), @field_options.merge({:id => element_id}))
95
97
 
96
98
  content_tag(:label, :class => ['radio', ('inline' if @field_options[:inline])].compact.join(' ')) do
97
99
  radiobutton + content_tag(:span, record.send(record_name))
@@ -118,95 +120,37 @@ module BootstrapForms
118
120
  end
119
121
  end
120
122
 
121
- %w(submit button).each do |method_name|
122
- define_method(method_name) do |name=nil, *args|
123
- @name = name
124
- @field_options = args.extract_options!
125
- @args = args
126
-
127
- @field_options[:class] = 'btn btn-primary'
128
-
129
- content_tag(:div, :class => 'form-actions') do
130
- if @field_options[:include_cancel] == false
131
- super(name, *(args << @field_options))
132
- else
133
- super(name, *(args << @field_options)) + ' ' + link_to(I18n.t('bootstrap_forms.buttons.cancel'), (@field_options[:back] || :back), :class => 'btn cancel')
134
- end
135
- end
136
- end
137
- end
138
-
139
- private
140
- def control_group_div(&block)
141
- @field_options[:error] = error_string
142
-
143
- klasses = ['control-group']
144
- klasses << 'error' if @field_options[:error]
145
- klasses << 'success' if @field_options[:success]
146
- klasses << 'warning' if @field_options[:warning]
147
- klass = klasses.join(' ')
148
-
149
- content_tag(:div, :class => klass, &block)
150
- end
151
-
152
- def error_string
153
- errors = object.errors[@name]
154
- if errors.present?
155
- errors.map { |e|
156
- "#{@options[:label] || human_attribute_name} #{e}"
157
- }.join(", ")
158
- end
159
- end
123
+ def button(name = nil, *args)
124
+ @name = name
125
+ @field_options = args.extract_options!
126
+ @args = args
160
127
 
161
- def human_attribute_name
162
- object.class.human_attribute_name(@name)
128
+ @field_options[:class] = 'btn btn-primary'
129
+ super(name, *(args << @field_options))
163
130
  end
164
131
 
165
- def input_div(&block)
166
- content_tag(:div, :class => 'controls') do
167
- if @field_options[:append] || @field_options[:prepend]
168
- klass = 'input-prepend' if @field_options[:prepend]
169
- klass = 'input-append' if @field_options[:append]
170
- content_tag(:div, :class => klass, &block)
171
- else
172
- yield if block_given?
173
- end
174
- end
175
- end
132
+ def submit(name = nil, *args)
133
+ @name = name
134
+ @field_options = args.extract_options!
135
+ @args = args
176
136
 
177
- def label_field(&block)
178
- label(@name, block_given? ? block : @field_options[:label], :class => ['control-label', required_class].compact.join(' '))
137
+ @field_options[:class] = 'btn btn-primary'
138
+ super(name, *(args << @field_options))
179
139
  end
180
140
 
181
- def required_class
182
- return 'required' if object.class.validators_on(@name).any? { |v| v.kind_of? ActiveModel::Validations::PresenceValidator }
183
- nil
141
+ def cancel(*args)
142
+ @field_options = args.extract_options!
143
+ link_to(I18n.t('bootstrap_forms.buttons.cancel'), (@field_options[:back] || :back), :class => 'btn cancel')
184
144
  end
185
145
 
186
- %w(help_inline error success warning help_block append prepend).each do |method_name|
187
- define_method(method_name) do |*args|
188
- return '' unless value = @field_options[method_name.to_sym]
189
- case method_name
190
- when 'help_block'
191
- element = :p
192
- klass = 'help-block'
193
- when 'append', 'prepend'
194
- element = :span
195
- klass = 'add-on'
146
+ def actions(&block)
147
+ content_tag(:div, :class => 'form-actions') do
148
+ if block_given?
149
+ yield
196
150
  else
197
- element = :span
198
- klass = 'help-inline'
151
+ [submit, cancel].join(' ').html_safe
199
152
  end
200
- content_tag(element, value, :class => klass)
201
153
  end
202
154
  end
203
-
204
- def extras(&block)
205
- [prepend, (yield if block_given?), append, help_inline, error, success, warning, help_block].join('').html_safe
206
- end
207
-
208
- def objectify_options(options)
209
- super.except(:label, :help_inline, :error, :success, :warning, :help_block, :prepend, :append)
210
- end
211
155
  end
212
156
  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
@@ -1,19 +1,17 @@
1
- require 'bootstrap_forms/form_builder'
2
-
3
- module ActionView
1
+ module BootstrapForms
4
2
  module Helpers
5
- module FormHelper
3
+ module FormHelper
6
4
  def bootstrap_form_for(record, options = {}, &block)
7
5
  options[:builder] = BootstrapForms::FormBuilder
8
6
  form_for(record, options) do |f|
9
7
  f.error_messages.html_safe + capture(f, &block).html_safe
10
8
  end
11
9
  end
10
+
11
+ def bootstrap_fields_for(record, options = {}, &block)
12
+ options[:builder] = BootstrapForms::FormBuilder
13
+ fields_for(record, nil, options, &block)
14
+ end
12
15
  end
13
16
  end
14
- end
15
-
16
- # don't wrap in those special divs
17
- ActionView::Base.field_error_proc = Proc.new do |html_tag, instance_tag|
18
- html_tag
19
17
  end
@@ -0,0 +1,76 @@
1
+ module BootstrapForms
2
+ module Helpers
3
+ module FormTagHelper
4
+ include BootstrapForms::Helpers::Wrappers
5
+
6
+ def bootstrap_form_tag(url_for_options = {}, options = {}, &block)
7
+ form_tag(url_for_options, options, &block)
8
+ end
9
+
10
+ %w(button_tag check_box_tag email_field_tag field_set_tag file_field_tag image_submit_tag label_tag number_field_tag password_field_tag phone_field_tag radio_button_tag range_field_tag search_field_tag select_tag telephone_field_tag text_area_tag text_field_tag url_field_tag utf8_enforcer_tag).each do |method_name|
11
+ # prefix each method with bootstrap_*
12
+ define_method("bootstrap_#{method_name}") do |name, *args|
13
+ value = args.shift
14
+ @name = name
15
+ @field_options = args.extract_options!
16
+ @args = args
17
+
18
+ control_group_div do
19
+ label_field + input_div do
20
+ extras { send(method_name.to_sym, name, value, *(@args << @field_options)) }
21
+ end
22
+ end
23
+ end
24
+ end
25
+
26
+ def uneditable_input_tag(name, *args)
27
+ @name = name
28
+ @field_options = args.extract_options!
29
+ @args = args
30
+
31
+ control_group_div do
32
+ label_field + input_div do
33
+ extras do
34
+ content_tag(:span, :class => 'uneditable-input') do
35
+ @field_options[:value] || object.send(@name.to_sym)
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
41
+
42
+ def bootstrap_button_tag(name = nil, *args)
43
+ @name = name
44
+ @field_options = args.extract_options!
45
+ @args = args
46
+
47
+ @field_options[:class] = 'btn btn-primary'
48
+ button_tag(name, *(args << @field_options))
49
+ end
50
+
51
+ def bootstrap_submit_tag(name = nil, *args)
52
+ @name = name
53
+ @field_options = args.extract_options!
54
+ @args = args
55
+
56
+ @field_options[:class] = 'btn btn-primary'
57
+ submit_tag(name, *(args << @field_options))
58
+ end
59
+
60
+ def bootstrap_cancel_tag(*args)
61
+ @field_options = args.extract_options!
62
+ link_to(I18n.t('bootstrap_forms.buttons.cancel'), (@field_options[:back] || :back), :class => 'btn cancel')
63
+ end
64
+
65
+ def bootstrap_actions(&block)
66
+ content_tag(:div, :class => 'form-actions') do
67
+ if block_given?
68
+ yield
69
+ else
70
+ [bootstrap_submit_tag, bootstrap_cancel_tag].join(' ').html_safe
71
+ end
72
+ end
73
+ end
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,92 @@
1
+ module BootstrapForms
2
+ module Helpers
3
+ module Wrappers
4
+ private
5
+ def control_group_div(&block)
6
+ field_errors = error_string
7
+ if @field_options[:error]
8
+ (@field_options[:error] << ", " << field_errors) if field_errors
9
+ else
10
+ @field_options[:error] = field_errors
11
+ end
12
+
13
+ klasses = ['control-group']
14
+ klasses << 'error' if @field_options[:error]
15
+ klasses << 'success' if @field_options[:success]
16
+ klasses << 'warning' if @field_options[:warning]
17
+ klass = klasses.join(' ')
18
+
19
+ content_tag(:div, :class => klass, &block)
20
+ end
21
+
22
+ def error_string
23
+ if respond_to?(:object)
24
+ errors = object.errors[@name]
25
+ if errors.present?
26
+ errors.map { |e|
27
+ "#{@options[:label] || human_attribute_name} #{e}"
28
+ }.join(", ")
29
+ end
30
+ end
31
+ end
32
+
33
+ def human_attribute_name
34
+ object.class.human_attribute_name(@name)
35
+ end
36
+
37
+ def input_div(&block)
38
+ content_tag(:div, :class => 'controls') do
39
+ if @field_options[:append] || @field_options[:prepend]
40
+ klass = 'input-prepend' if @field_options[:prepend]
41
+ klass = 'input-append' if @field_options[:append]
42
+ content_tag(:div, :class => klass, &block)
43
+ else
44
+ yield if block_given?
45
+ end
46
+ end
47
+ end
48
+
49
+ def label_field(&block)
50
+ if respond_to?(:object)
51
+ label(@name, block_given? ? block : @field_options[:label], :class => ['control-label', required_class].compact.join(' '))
52
+ else
53
+ label_tag(@name, block_given? ? block : @field_options[:label], :class => ['control-label', required_class].compact.join(' '))
54
+ end
55
+ end
56
+
57
+ def required_class
58
+ return 'required' if @field_options[:required]
59
+ if respond_to?(:object)
60
+ return 'required' if object.class.validators_on(@name).any? { |v| v.kind_of? ActiveModel::Validations::PresenceValidator }
61
+ end
62
+ nil
63
+ end
64
+
65
+ %w(help_inline error success warning help_block append prepend).each do |method_name|
66
+ define_method(method_name) do |*args|
67
+ return '' unless value = @field_options[method_name.to_sym]
68
+ case method_name
69
+ when 'help_block'
70
+ element = :p
71
+ klass = 'help-block'
72
+ when 'append', 'prepend'
73
+ element = :span
74
+ klass = 'add-on'
75
+ else
76
+ element = :span
77
+ klass = 'help-inline'
78
+ end
79
+ content_tag(element, value, :class => klass)
80
+ end
81
+ end
82
+
83
+ def extras(&block)
84
+ [prepend, (yield if block_given?), append, help_inline, error, success, warning, help_block].join('').html_safe
85
+ end
86
+
87
+ def objectify_options(options)
88
+ super.except(:label, :help_inline, :error, :success, :warning, :help_block, :prepend, :append)
89
+ end
90
+ end
91
+ end
92
+ end