Skip to content
Browse files

Merge pull request #38 from mjbellantoni/v2.0.0-wip

Move v2.0.0-wip into master.
  • Loading branch information...
2 parents 66f4eb5 + 5daf79c commit 9a0be55ae68d8a584dbeb7e5165e81f8b27abaa1 @mjbellantoni committed
Showing with 3,022 additions and 2,536 deletions.
  1. +3 −2 Gemfile
  2. +65 −60 Gemfile.lock
  3. +4 −1 README.md
  4. +1 −1 Rakefile
  5. +16 −1 lib/formtastic-bootstrap.rb
  6. +10 −0 lib/formtastic-bootstrap/actions.rb
  7. +22 −0 lib/formtastic-bootstrap/actions/base.rb
  8. +13 −0 lib/formtastic-bootstrap/actions/button_action.rb
  9. +13 −0 lib/formtastic-bootstrap/actions/input_action.rb
  10. +12 −0 lib/formtastic-bootstrap/actions/link_action.rb
  11. +4 −2 lib/formtastic-bootstrap/form_builder.rb
  12. +6 −8 lib/formtastic-bootstrap/helpers.rb
  13. +12 −0 lib/formtastic-bootstrap/helpers/action_helper.rb
  14. +24 −0 lib/formtastic-bootstrap/helpers/actions_helper.rb
  15. +0 −52 lib/formtastic-bootstrap/helpers/buttons_helper.rb
  16. +2 −4 lib/formtastic-bootstrap/helpers/fieldset_wrapper.rb
  17. +0 −2 lib/formtastic-bootstrap/helpers/inputs_helper.rb
  18. +30 −23 lib/formtastic-bootstrap/inputs.rb
  19. +29 −6 lib/formtastic-bootstrap/inputs/base.rb
  20. +6 −35 lib/formtastic-bootstrap/inputs/base/choices.rb
  21. +9 −0 lib/formtastic-bootstrap/inputs/base/collections.rb
  22. +9 −0 lib/formtastic-bootstrap/inputs/base/grouped_collections.rb
  23. +1 −1 lib/formtastic-bootstrap/inputs/base/hints.rb
  24. +14 −3 lib/formtastic-bootstrap/inputs/base/labelling.rb
  25. +9 −0 lib/formtastic-bootstrap/inputs/base/numeric.rb
  26. +4 −5 lib/formtastic-bootstrap/inputs/base/stringish.rb
  27. +38 −18 lib/formtastic-bootstrap/inputs/base/timeish.rb
  28. +22 −34 lib/formtastic-bootstrap/inputs/base/wrapping.rb
  29. +14 −18 lib/formtastic-bootstrap/inputs/boolean_input.rb
  30. +16 −11 lib/formtastic-bootstrap/inputs/check_boxes_input.rb
  31. +3 −9 lib/formtastic-bootstrap/inputs/date_input.rb
  32. +8 −0 lib/formtastic-bootstrap/inputs/date_select_input.rb
  33. +3 −12 lib/formtastic-bootstrap/inputs/datetime_input.rb
  34. +8 −0 lib/formtastic-bootstrap/inputs/datetime_select_input.rb
  35. +1 −1 lib/formtastic-bootstrap/inputs/email_input.rb
  36. +1 −1 lib/formtastic-bootstrap/inputs/file_input.rb
  37. +1 −1 lib/formtastic-bootstrap/inputs/hidden_input.rb
  38. +3 −3 lib/formtastic-bootstrap/inputs/number_input.rb
  39. +1 −1 lib/formtastic-bootstrap/inputs/password_input.rb
  40. +1 −1 lib/formtastic-bootstrap/inputs/phone_input.rb
  41. +28 −14 lib/formtastic-bootstrap/inputs/radio_input.rb
  42. +1 −1 lib/formtastic-bootstrap/inputs/range_input.rb
  43. +1 −1 lib/formtastic-bootstrap/inputs/search_input.rb
  44. +3 −1 lib/formtastic-bootstrap/inputs/select_input.rb
  45. +0 −7 lib/formtastic-bootstrap/inputs/string_input.rb
  46. +1 −1 lib/formtastic-bootstrap/inputs/text_input.rb
  47. +3 −9 lib/formtastic-bootstrap/inputs/time_input.rb
  48. +8 −0 lib/formtastic-bootstrap/inputs/time_select_input.rb
  49. +1 −1 lib/formtastic-bootstrap/inputs/time_zone_input.rb
  50. +1 −1 lib/formtastic-bootstrap/inputs/url_input.rb
  51. +63 −0 spec/actions/button_action_spec.rb
  52. +59 −0 spec/actions/input_action_spec.rb
  53. +92 −0 spec/actions/link_action_spec.rb
  54. +0 −214 spec/builder/errors_spec.rb
  55. +368 −0 spec/helpers/action_helper_spec.rb
  56. +147 −0 spec/helpers/actions_helper_spec.rb
  57. +0 −149 spec/helpers/buttons_helper_spec.rb
  58. +238 −259 spec/helpers/input_helper_spec.rb
  59. +84 −25 spec/helpers/inputs_helper_spec.rb
  60. +108 −75 spec/inputs/boolean_input_spec.rb
  61. +106 −91 spec/inputs/check_boxes_input_spec.rb
  62. +0 −147 spec/inputs/date_input_spec.rb
  63. +164 −0 spec/inputs/date_select_input_spec.rb
  64. +0 −101 spec/inputs/datetime_input_spec.rb
  65. +112 −0 spec/inputs/datetime_select_input_spec.rb
  66. +48 −0 spec/inputs/deprecated_time_date_datetime_inputs_spec.rb
  67. +30 −3 spec/inputs/email_input_spec.rb
  68. +31 −4 spec/inputs/file_input_spec.rb
  69. +63 −32 spec/inputs/hidden_input_spec.rb
  70. +37 −8 spec/inputs/number_input_spec.rb
  71. +30 −3 spec/inputs/password_input_spec.rb
  72. +30 −3 spec/inputs/phone_input_spec.rb
  73. +87 −60 spec/inputs/radio_input_spec.rb
  74. +32 −5 spec/inputs/range_input_spec.rb
  75. +29 −3 spec/inputs/search_input_spec.rb
  76. +164 −107 spec/inputs/select_input_spec.rb
  77. +33 −22 spec/inputs/string_input_spec.rb
  78. +39 −14 spec/inputs/text_input_spec.rb
  79. +0 −206 spec/inputs/time_input_spec.rb
  80. +191 −0 spec/inputs/time_select_input_spec.rb
  81. +17 −19 spec/inputs/time_zone_input_spec.rb
  82. +30 −3 spec/inputs/url_input_spec.rb
  83. +21 −15 spec/spec_helper.rb
  84. +61 −228 spec/support/custom_macros.rb
  85. +0 −6 spec/support/depracation.rb
  86. +23 −0 spec/support/fb_custom_macros.rb
  87. +0 −382 spec/support/formtastic_spec_helper.rb
View
5 Gemfile
@@ -2,10 +2,11 @@ source "http://rubygems.org"
gemspec
-gem 'formtastic'
+gem 'formtastic', "~> 2.2"
group :development, :test do
- gem "rspec"
+ gem "ammeter"
+ gem "rspec-rails", "~> 2.8.0"
gem "bundler"
gem "jeweler"
gem "rcov", ">= 0"
View
125 Gemfile.lock
@@ -1,47 +1,51 @@
PATH
remote: .
specs:
- formtastic-bootstrap (1.1.2)
+ formtastic-bootstrap (1.2.0)
formtastic
rails (>= 3.1.0)
GEM
remote: http://rubygems.org/
specs:
- actionmailer (3.1.3)
- actionpack (= 3.1.3)
- mail (~> 2.3.0)
- actionpack (3.1.3)
- activemodel (= 3.1.3)
- activesupport (= 3.1.3)
+ actionmailer (3.2.3)
+ actionpack (= 3.2.3)
+ mail (~> 2.4.4)
+ actionpack (3.2.3)
+ activemodel (= 3.2.3)
+ activesupport (= 3.2.3)
builder (~> 3.0.0)
erubis (~> 2.7.0)
- i18n (~> 0.6)
- rack (~> 1.3.5)
- rack-cache (~> 1.1)
- rack-mount (~> 0.8.2)
+ journey (~> 1.0.1)
+ rack (~> 1.4.0)
+ rack-cache (~> 1.2)
rack-test (~> 0.6.1)
- sprockets (~> 2.0.3)
- activemodel (3.1.3)
- activesupport (= 3.1.3)
+ sprockets (~> 2.1.2)
+ activemodel (3.2.3)
+ activesupport (= 3.2.3)
builder (~> 3.0.0)
- i18n (~> 0.6)
- activerecord (3.1.3)
- activemodel (= 3.1.3)
- activesupport (= 3.1.3)
- arel (~> 2.2.1)
+ activerecord (3.2.3)
+ activemodel (= 3.2.3)
+ activesupport (= 3.2.3)
+ arel (~> 3.0.2)
tzinfo (~> 0.3.29)
- activeresource (3.1.3)
- activemodel (= 3.1.3)
- activesupport (= 3.1.3)
- activesupport (3.1.3)
+ activeresource (3.2.3)
+ activemodel (= 3.2.3)
+ activesupport (= 3.2.3)
+ activesupport (3.2.3)
+ i18n (~> 0.6)
multi_json (~> 1.0)
- arel (2.2.1)
+ ammeter (0.2.4)
+ activesupport (>= 3.0)
+ railties (>= 3.0)
+ rspec (>= 2.2)
+ rspec-rails (>= 2.2)
+ arel (3.0.2)
builder (3.0.0)
diff-lcs (1.1.3)
erubis (2.7.0)
- formtastic (2.0.2)
- rails (~> 3.0)
+ formtastic (2.2.0)
+ actionpack (>= 3.0)
git (1.2.5)
hike (1.2.1)
i18n (0.6.0)
@@ -49,35 +53,34 @@ GEM
bundler (~> 1.0)
git (>= 1.2.5)
rake
- json (1.6.3)
- mail (2.3.0)
+ journey (1.0.3)
+ json (1.7.3)
+ mail (2.4.4)
i18n (>= 0.4.0)
mime-types (~> 1.16)
treetop (~> 1.4.8)
- mime-types (1.17.2)
- multi_json (1.0.4)
- nokogiri (1.5.0)
+ mime-types (1.18)
+ multi_json (1.3.6)
+ nokogiri (1.5.3)
polyglot (0.3.3)
- rack (1.3.5)
- rack-cache (1.1)
+ rack (1.4.1)
+ rack-cache (1.2)
rack (>= 0.4)
- rack-mount (0.8.3)
- rack (>= 1.0.0)
rack-ssl (1.3.2)
rack
rack-test (0.6.1)
rack (>= 1.0)
- rails (3.1.3)
- actionmailer (= 3.1.3)
- actionpack (= 3.1.3)
- activerecord (= 3.1.3)
- activeresource (= 3.1.3)
- activesupport (= 3.1.3)
+ rails (3.2.3)
+ actionmailer (= 3.2.3)
+ actionpack (= 3.2.3)
+ activerecord (= 3.2.3)
+ activeresource (= 3.2.3)
+ activesupport (= 3.2.3)
bundler (~> 1.0)
- railties (= 3.1.3)
- railties (3.1.3)
- actionpack (= 3.1.3)
- activesupport (= 3.1.3)
+ railties (= 3.2.3)
+ railties (3.2.3)
+ actionpack (= 3.2.3)
+ activesupport (= 3.2.3)
rack-ssl (~> 1.3.2)
rake (>= 0.8.7)
rdoc (~> 3.4)
@@ -86,23 +89,23 @@ GEM
rcov (0.9.11)
rdoc (3.12)
json (~> 1.4)
- rspec (2.7.0)
- rspec-core (~> 2.7.0)
- rspec-expectations (~> 2.7.0)
- rspec-mocks (~> 2.7.0)
- rspec-core (2.7.1)
- rspec-expectations (2.7.0)
+ rspec (2.8.0)
+ rspec-core (~> 2.8.0)
+ rspec-expectations (~> 2.8.0)
+ rspec-mocks (~> 2.8.0)
+ rspec-core (2.8.0)
+ rspec-expectations (2.8.0)
diff-lcs (~> 1.1.2)
- rspec-mocks (2.7.0)
- rspec-rails (2.7.0)
- actionpack (~> 3.0)
- activesupport (~> 3.0)
- railties (~> 3.0)
- rspec (~> 2.7.0)
+ rspec-mocks (2.8.0)
+ rspec-rails (2.8.1)
+ actionpack (>= 3.0)
+ activesupport (>= 3.0)
+ railties (>= 3.0)
+ rspec (~> 2.8.0)
rspec_tag_matchers (1.0.0)
nokogiri (>= 1.4.0)
rspec-rails (>= 1.2.6)
- sprockets (2.0.3)
+ sprockets (2.1.3)
hike (~> 1.2)
rack (~> 1.0)
tilt (~> 1.1, != 1.3.0)
@@ -111,16 +114,18 @@ GEM
treetop (1.4.10)
polyglot
polyglot (>= 0.3.1)
- tzinfo (0.3.31)
+ tzinfo (0.3.33)
PLATFORMS
ruby
DEPENDENCIES
+ ammeter
bundler
- formtastic
+ formtastic (~> 2.2)
formtastic-bootstrap!
jeweler
rcov
rspec
+ rspec-rails (~> 2.8.0)
rspec_tag_matchers
View
5 README.md
@@ -8,7 +8,7 @@ You can follow [FormBoot on twitter](http://twitter.com/FormBoot) for update ann
### Dependencies
-Formtastic Bootstrap has only been tested with Ruby 1.9.2, Rails 3.1, Formtastic 2.0 and Twitter Bootstrap 1.3.
+Formtastic Bootstrap has only been tested with Ruby 1.9.2, Rails 3.2.x, Formtastic 2.2.x and Twitter Bootstrap 2.x.
#### Installation
@@ -39,6 +39,7 @@ Make sure you've already downloaded and installed Formtastic!
## Formtastic vs. Formtastic Bootstrap
+THIS SECTION IS OUT OF DATE.
### Overview
@@ -97,6 +98,8 @@ made to generate the HTML expected by Bootstrap while still generating the rich
### Major Difference in Behavior
+THIS SECTION IS OUT OF DATE
+
* Formtastic Bootstrap omits the <tt>label</tt> class on label tags since Twitter Bootstrap uses this tag in another context (and it makes bad things happen.)
* Formtastic Bootstrap puts the <tt>input</tt> label in a different place because it makes Bootstrap behave correctly.
* Formtastic Bootstrap renders <tt>:date</tt>, <tt>:datetime</tt> and <tt>:time</tt> as text fields since this is how Twitter Bootstrap presents these data types (Formtastic renders them as dropdowns.) Some Rails magic may have been lost here. Additionally:
View
2 Rakefile
@@ -38,7 +38,7 @@ end
task :default => :spec
-require 'rake/rdoctask'
+require 'rdoc/task'
Rake::RDocTask.new do |rdoc|
version = File.exist?('VERSION') ? File.read('VERSION') : ""
View
17 lib/formtastic-bootstrap.rb
@@ -1,6 +1,21 @@
require "formtastic"
require "formtastic-bootstrap/engine" if defined?(::Rails) # For tests
require "formtastic-bootstrap/helpers"
-require "formtastic-bootstrap/inputs"
require "formtastic-bootstrap/form_builder"
require "action_view/helpers/text_field_date_helper"
+
+module FormtasticBootstrap
+
+ extend ActiveSupport::Autoload
+
+ # autoload :FormBuilder
+ # autoload :Helpers
+ # autoload :HtmlAttributes
+ # autoload :I18n
+ autoload :Inputs, "formtastic-bootstrap/inputs"
+ autoload :Actions, "formtastic-bootstrap/actions"
+ # autoload :LocalizedString
+ # autoload :Localizer
+ # autoload :Util
+
+end
View
10 lib/formtastic-bootstrap/actions.rb
@@ -0,0 +1,10 @@
+module FormtasticBootstrap
+ module Actions
+ extend ActiveSupport::Autoload
+
+ autoload :Base, 'formtastic-bootstrap/actions/base'
+ autoload :InputAction, 'formtastic-bootstrap/actions/input_action'
+ autoload :LinkAction, 'formtastic-bootstrap/actions/link_action'
+ autoload :ButtonAction, 'formtastic-bootstrap/actions/button_action'
+ end
+end
View
22 lib/formtastic-bootstrap/actions/base.rb
@@ -0,0 +1,22 @@
+module FormtasticBootstrap
+ module Actions
+ module Base
+
+ # Bootstrap doesn't have wrappers.
+ def wrapper(&block)
+ # TODO Detect if user passed wrapper_html_options and issue
+ # a warning that they're ignored. (See the original in
+ # Formtastic.)
+ template.capture(&block)
+ end
+
+ def default_button_html
+ {
+ :accesskey => accesskey,
+ :class => "btn"
+ }
+ end
+
+ end
+ end
+end
View
13 lib/formtastic-bootstrap/actions/button_action.rb
@@ -0,0 +1,13 @@
+# <form...>
+# <fieldset class="form-actions">
+# <button class="btn" type="reset" value="Reset">
+# <button class="btn" type="submit" value="Create Post">
+# </fieldset>
+# </form>
+module FormtasticBootstrap
+ module Actions
+ class ButtonAction < Formtastic::Actions::ButtonAction
+ include Base
+ end
+ end
+end
View
13 lib/formtastic-bootstrap/actions/input_action.rb
@@ -0,0 +1,13 @@
+# <form...>
+# <fieldset class="form-actions">
+# <input class="btn" type="reset" value="Reset">
+# <input class="btn" type="submit" value="Create Post">
+# </fieldset>
+# </form>
+module FormtasticBootstrap
+ module Actions
+ class InputAction < Formtastic::Actions::InputAction
+ include Base
+ end
+ end
+end
View
12 lib/formtastic-bootstrap/actions/link_action.rb
@@ -0,0 +1,12 @@
+# <form...>
+# <fieldset class="form-actions">
+# <a class="btn" href="">Link</a>
+# </fieldset>
+# </form>
+module FormtasticBootstrap
+ module Actions
+ class LinkAction < Formtastic::Actions::LinkAction
+ include Base
+ end
+ end
+end
View
6 lib/formtastic-bootstrap/form_builder.rb
@@ -29,9 +29,11 @@ def self.default_hint_class=(hint_class)
raise
end
- include FormtasticBootstrap::Helpers::InputHelper
+ include FormtasticBootstrap::Helpers::InputHelper # Revisit
include FormtasticBootstrap::Helpers::InputsHelper
- include FormtasticBootstrap::Helpers::ButtonsHelper
+ include FormtasticBootstrap::Helpers::ActionHelper
+ include FormtasticBootstrap::Helpers::ActionsHelper
+ # include Formtastic::Helpers::ErrorsHelper
end
View
14 lib/formtastic-bootstrap/helpers.rb
@@ -1,16 +1,14 @@
-require "formtastic-bootstrap/helpers/buttons_helper"
-require "formtastic-bootstrap/helpers/fieldset_wrapper"
-require "formtastic-bootstrap/helpers/input_helper"
-require "formtastic-bootstrap/helpers/inputs_helper"
-
module FormtasticBootstrap
module Helpers
+
+ autoload :ActionHelper, 'formtastic-bootstrap/helpers/action_helper'
+ autoload :ActionsHelper, 'formtastic-bootstrap/helpers/actions_helper'
# autoload :ErrorsHelper, 'formtastic/helpers/errors_helper'
- # autoload :FieldsetWrapper, 'formtastic/helpers/fieldset_wrapper'
+ autoload :FieldsetWrapper, 'formtastic-bootstrap/helpers/fieldset_wrapper'
# autoload :FileColumnDetection, 'formtastic/helpers/file_column_detection'
# autoload :FormHelper, 'formtastic/helpers/form_helper'
- # autoload :InputHelper, 'formtastic/helpers/input_helper'
- # autoload :InputsHelper, 'formtastic/helpers/inputs_helper'
+ autoload :InputHelper, 'formtastic-bootstrap/helpers/input_helper'
+ autoload :InputsHelper, 'formtastic-bootstrap/helpers/inputs_helper'
# autoload :LabelHelper, 'formtastic/helpers/label_helper'
# autoload :SemanticFormHelper, 'formtastic/helpers/semantic_form_helper'
# autoload :Reflection, 'formtastic/helpers/reflection'
View
12 lib/formtastic-bootstrap/helpers/action_helper.rb
@@ -0,0 +1,12 @@
+module FormtasticBootstrap
+ module Helpers
+ module ActionHelper
+
+ # :as => :button # => FormtasticBootstrap::Actions::ButtonAction
+ def standard_action_class_name(as)
+ "FormtasticBootstrap::Actions::#{as.to_s.camelize}Action"
+ end
+
+ end
+ end
+end
View
24 lib/formtastic-bootstrap/helpers/actions_helper.rb
@@ -0,0 +1,24 @@
+module FormtasticBootstrap
+ module Helpers
+ module ActionsHelper
+
+ include Formtastic::Helpers::ActionsHelper
+ include FormtasticBootstrap::Helpers::FieldsetWrapper
+
+ def actions(*args, &block)
+
+ html_options = args.extract_options!
+ html_options[:class] ||= "form-actions"
+
+ if block_given?
+ field_set_and_list_wrapping(html_options, &block)
+ else
+ args = default_actions if args.empty?
+ contents = args.map { |action_name| action(action_name) }
+ field_set_and_list_wrapping(html_options, contents)
+ end
+ end
+
+ end
+ end
+end
View
52 lib/formtastic-bootstrap/helpers/buttons_helper.rb
@@ -1,52 +0,0 @@
-module FormtasticBootstrap
- module Helpers
- module ButtonsHelper
-
- include Formtastic::Helpers::ButtonsHelper
-
- def buttons(*args, &block)
-
- html_options = args.extract_options!
- html_options[:class] ||= "actions"
-
- if html_options.has_key?(:name)
- ActiveSupport::Deprecation.warn('The :name option is not supported')
- end
-
- if block_given?
- template.content_tag(:div, html_options) do
- yield
- end
- else
- args = [:commit] if args.empty?
- contents = args.map { |button_name| send(:"#{button_name}_button") }
- template.content_tag(:div, html_options.except(:builder, :parent, :name)) do
- Formtastic::Util.html_safe(contents.join)
- end
- end
-
- end
-
- def commit_button(*args)
- options = args.extract_options!
- text = options.delete(:label) || args.shift
-
- text = (localized_string(commit_button_i18n_key, text, :action, :model => commit_button_object_name) ||
- Formtastic::I18n.t(commit_button_i18n_key, :model => commit_button_object_name)) unless text.is_a?(::String)
-
- button_html = options.delete(:button_html) || {}
- button_html.merge!(:class => [button_html[:class], "btn commit", commit_button_i18n_key].compact.join(' '))
-
- # TODO We don't have a wrapper. Add deprecation message.
- # wrapper_html = options.delete(:wrapper_html) || {}
- # wrapper_html[:class] = (commit_button_wrapper_html_class << wrapper_html[:class]).flatten.compact.join(' ')
-
- accesskey = (options.delete(:accesskey) || default_commit_button_accesskey) unless button_html.has_key?(:accesskey)
- button_html = button_html.merge(:accesskey => accesskey) if accesskey
-
- Formtastic::Util.html_safe(submit(text, button_html))
- end
-
- end
- end
-end
View
6 lib/formtastic-bootstrap/helpers/fieldset_wrapper.rb
@@ -10,10 +10,6 @@ def field_set_and_list_wrapping(*args, &block) #:nodoc:
contents = args.last.is_a?(::Hash) ? '' : args.pop.flatten
html_options = args.extract_options!
- legend = (html_options[:name] || '').to_s
- legend %= parent_child_index(html_options[:parent]) if html_options[:parent]
- legend = template.content_tag(:legend, Formtastic::Util.html_safe(legend)) unless legend.blank?
-
if block_given?
contents = if template.respond_to?(:is_haml?) && template.is_haml?
template.capture_haml(&block)
@@ -24,6 +20,8 @@ def field_set_and_list_wrapping(*args, &block) #:nodoc:
# Ruby 1.9: String#to_s behavior changed, need to make an explicit join.
contents = contents.join if contents.respond_to?(:join)
+
+ legend = field_set_legend(html_options)
fieldset = template.content_tag(:fieldset,
Formtastic::Util.html_safe(legend) << Formtastic::Util.html_safe(contents),
html_options.except(:builder, :parent, :name)
View
2 lib/formtastic-bootstrap/helpers/inputs_helper.rb
@@ -1,7 +1,6 @@
module FormtasticBootstrap
module Helpers
module InputsHelper
- include FormtasticBootstrap::Helpers::FieldsetWrapper
def inputs(*args, &block)
wrap_it = @already_in_an_inputs_block ? true : false
@@ -26,7 +25,6 @@ def inputs(*args, &block)
end
end
- # out = template.content_tag(:li, out, :class => "input") if wrap_it
@already_in_an_inputs_block = false
out
end
View
53 lib/formtastic-bootstrap/inputs.rb
@@ -1,29 +1,36 @@
-require "formtastic-bootstrap/inputs/base"
-require "formtastic-bootstrap/inputs/boolean_input"
-require "formtastic-bootstrap/inputs/check_boxes_input"
-require "formtastic-bootstrap/inputs/date_input"
-require "formtastic-bootstrap/inputs/datetime_input"
-require "formtastic-bootstrap/inputs/email_input"
-require "formtastic-bootstrap/inputs/file_input"
-require "formtastic-bootstrap/inputs/hidden_input"
-require "formtastic-bootstrap/inputs/number_input"
-require "formtastic-bootstrap/inputs/password_input"
-require "formtastic-bootstrap/inputs/phone_input"
-require "formtastic-bootstrap/inputs/radio_input"
-require "formtastic-bootstrap/inputs/range_input"
-require "formtastic-bootstrap/inputs/search_input"
-require "formtastic-bootstrap/inputs/select_input"
-require "formtastic-bootstrap/inputs/string_input"
-require "formtastic-bootstrap/inputs/text_input"
-require "formtastic-bootstrap/inputs/time_input"
-require "formtastic-bootstrap/inputs/time_zone_input"
-require "formtastic-bootstrap/inputs/url_input"
-
module FormtasticBootstrap
module Inputs
- include Base
+ autoload :Base, "formtastic-bootstrap/inputs/base"
+ # autoload :Basic
+ autoload :BooleanInput, "formtastic-bootstrap/inputs/boolean_input"
+ autoload :CheckBoxesInput, "formtastic-bootstrap/inputs/check_boxes_input"
+ # autoload :CountryInput # TODO Come back to this.
+ autoload :DateInput, "formtastic-bootstrap/inputs/date_input"
+ # autoload :DatePickerInput # TODO Come back to this.
+ # autoload :DatetimePickerInput # TODO Come back to this.
+ autoload :DateSelectInput, "formtastic-bootstrap/inputs/date_select_input"
+ autoload :DatetimeInput, "formtastic-bootstrap/inputs/datetime_input"
+ autoload :DatetimeSelectInput, "formtastic-bootstrap/inputs/datetime_select_input"
+ autoload :EmailInput, "formtastic-bootstrap/inputs/email_input"
+ autoload :FileInput, "formtastic-bootstrap/inputs/file_input"
+ autoload :HiddenInput, "formtastic-bootstrap/inputs/hidden_input"
+ autoload :NumberInput, "formtastic-bootstrap/inputs/number_input"
+ # autoload :NumericInput # TODO Where does Formtastic actually define this?
+ autoload :PasswordInput, "formtastic-bootstrap/inputs/password_input"
+ autoload :PhoneInput, "formtastic-bootstrap/inputs/phone_input"
+ autoload :RadioInput, "formtastic-bootstrap/inputs/radio_input"
+ autoload :RangeInput, "formtastic-bootstrap/inputs/range_input"
+ autoload :SearchInput, "formtastic-bootstrap/inputs/search_input"
+ autoload :SelectInput, "formtastic-bootstrap/inputs/select_input"
+ autoload :StringInput, "formtastic-bootstrap/inputs/string_input"
+ autoload :TextInput, "formtastic-bootstrap/inputs/text_input"
+ autoload :TimeInput, "formtastic-bootstrap/inputs/time_input"
+ # autoload :TimePickerInput # TODO Come back to this.
+ autoload :TimeSelectInput, "formtastic-bootstrap/inputs/time_select_input"
+ autoload :TimeZoneInput, "formtastic-bootstrap/inputs/time_zone_input"
+ # autoload :Timeish # This seems like a mistake.
+ autoload :UrlInput, "formtastic-bootstrap/inputs/url_input"
end
end
-
View
35 lib/formtastic-bootstrap/inputs/base.rb
@@ -1,22 +1,45 @@
-require "formtastic-bootstrap/inputs/base/choices"
require "formtastic-bootstrap/inputs/base/errors"
require "formtastic-bootstrap/inputs/base/hints"
require "formtastic-bootstrap/inputs/base/html"
require "formtastic-bootstrap/inputs/base/labelling"
-require "formtastic-bootstrap/inputs/base/stringish"
-require "formtastic-bootstrap/inputs/base/timeish"
-require "formtastic-bootstrap/inputs/base/wrapping"
module FormtasticBootstrap
module Inputs
module Base
+ # autoload :DatetimePickerish
+ # autoload :Associations
+ autoload :Collections, "formtastic-bootstrap/inputs/base/collections"
+ autoload :Choices, "formtastic-bootstrap/inputs/base/choices"
+ # autoload :Database
+ # autoload :Errors
+ # autoload :Fileish
+ autoload :GroupedCollections, "formtastic-bootstrap/inputs/base/grouped_collections"
+ # autoload :Hints
+ # autoload :Html
+ # autoload :Labelling
+ # autoload :Naming
+ autoload :Numeric, "formtastic-bootstrap/inputs/base/numeric"
+ # autoload :Options
+ # autoload :Placeholder
+ autoload :Stringish, "formtastic-bootstrap/inputs/base/stringish"
+ autoload :Timeish, "formtastic-bootstrap/inputs/base/timeish"
+ # autoload :Validations
+ autoload :Wrapping, "formtastic-bootstrap/inputs/base/wrapping"
+
+ include Html
+ # include Options
+ # include Database
+ # include Database
include Errors
include Hints
- include Html
+ # include Naming
+ # include Validations
+ # include Fileish
+ # include Associations
include Labelling
include Wrapping
-
+
end
end
end
View
41 lib/formtastic-bootstrap/inputs/base/choices.rb
@@ -2,45 +2,16 @@ module FormtasticBootstrap
module Inputs
module Base
module Choices
+ include Formtastic::Inputs::Base::Choices
- def input_div_wrapping(&block)
- template.content_tag(:div, choices_wrapping_html_options) do
- [yield, error_html(:block), hint_html(:block)].join("\n").html_safe
+ def choice_wrapping_html_options(choice)
+ super(choice).tap do |options|
+ options[:for] = choice_input_dom_id(choice)
end
end
- def choices_wrapping_html_options
- # TODO Call the Formtastic one explicity and append?
- { :class => "choices input" }
- end
-
- def choices_group_wrapping(&block)
- template.content_tag(:ul,
- template.capture(&block),
- choices_group_wrapping_html_options
- )
- end
-
- def choices_group_wrapping_html_options
- { :class => "choices-group inputs-list" }
- end
-
- def choice_label(choice)
- "\n".html_safe + template.content_tag(:span) do
- # (choice.is_a?(Array) ? choice.first : choice).to_s
- (choice.is_a?(Array) ? choice.first : choice).to_s
- end
- end
-
- # This is actually a label in Bootstrap.
- def legend_html
- template.content_tag(:label, label_html_options) do
- render_label? ? label_text : "".html_safe
- end
- end
-
- def label_html_options
- super.merge(:for => nil)
+ def choice_label_html_options(choice)
+ choice_wrapping_html_options(choice)
end
end
View
9 lib/formtastic-bootstrap/inputs/base/collections.rb
@@ -0,0 +1,9 @@
+module FormtasticBootstrap
+ module Inputs
+ module Base
+ module Collections
+ include Formtastic::Inputs::Base::Collections
+ end
+ end
+ end
+end
View
9 lib/formtastic-bootstrap/inputs/base/grouped_collections.rb
@@ -0,0 +1,9 @@
+module FormtasticBootstrap
+ module Inputs
+ module Base
+ module GroupedCollections
+ include Formtastic::Inputs::Base::GroupedCollections
+ end
+ end
+ end
+end
View
2 lib/formtastic-bootstrap/inputs/base/hints.rb
@@ -5,7 +5,7 @@ module Hints
include Formtastic::Inputs::Base::Hints
- def hint_html(inline_or_block = :inline)
+ def hint_html(inline_or_block = :block)
if hint?
hint_class = if inline_or_block == :inline
options[:hint_class] || builder.default_inline_hint_class
View
17 lib/formtastic-bootstrap/inputs/base/labelling.rb
@@ -6,12 +6,23 @@ module Labelling
include Formtastic::Inputs::Base::Labelling
def label_html_options
- {}.tap do |opts|
- opts[:for] ||= input_html_options[:id]
- opts[:class] = [opts[:class]]
+ super.tap do |options|
+ # Bootstrap defines class 'label'
+ options[:class] = options[:class].reject { |c| c == 'label' }
+ # options[:class] << "control-label"
end
end
+ def control_label_html_options
+ label_html_options.tap do |options|
+ options[:class] << "control-label"
+ end
+ end
+
+ def control_label_html
+ render_label? ? builder.label(input_name, label_text, control_label_html_options) : "".html_safe
+ end
+
end
end
end
View
9 lib/formtastic-bootstrap/inputs/base/numeric.rb
@@ -0,0 +1,9 @@
+module FormtasticBootstrap
+ module Inputs
+ module Base
+ module Numeric
+ include Formtastic::Inputs::Base::Numeric
+ end
+ end
+ end
+end
View
9 lib/formtastic-bootstrap/inputs/base/stringish.rb
@@ -1,5 +1,3 @@
-# Alas, I need to duplicate code from Formtastic::Inputs::Base::Stringish because
-# there's no way to re-import that module.
module FormtasticBootstrap
module Inputs
module Base
@@ -7,9 +5,10 @@ module Stringish
include Formtastic::Inputs::Base::Stringish
- def wrapper_html_options
- new_class = [super[:class], "stringish"].compact.join(" ")
- super.merge(:class => new_class)
+ def to_html
+ bootstrap_wrapping do
+ builder.text_field(method, input_html_options)
+ end
end
end
View
56 lib/formtastic-bootstrap/inputs/base/timeish.rb
@@ -3,32 +3,52 @@ module Inputs
module Base
module Timeish
- def label_html
- # TODO Supress the "for" field?
- template.content_tag(:label, label_html_options) do
- render_label? ? label_text : "".html_safe
+ def to_html
+ control_group_wrapping do
+ control_label_html <<
+ controls_wrapping do
+ hidden_fragments <<
+ fragments.map do |fragment|
+ fragment_input_html(fragment)
+ end.join.html_safe
+ end
end
end
- def date_input_html
- fragment_input_html(:date, "small")
+ def controls_wrapper_html_options
+ super.tap do |options|
+ options[:class] = (options[:class].split << "controls-row").join(" ")
+ end
end
- def time_input_html
- fragment_input_html(:time, "mini")
+ def fragment_input_html(fragment)
+ opts = input_options.merge(:prefix => fragment_prefix, :field_name => fragment_name(fragment), :default => value, :include_blank => include_blank?)
+ template.send(:"select_#{fragment}", value, opts, fragment_input_html_options(fragment))
end
-
- def fragment_id(fragment)
- # TODO is this right?
- # "#{input_html_options[:id]}_#{position(fragment)}i"
- "#{input_html_options[:id]}[#{fragment}]"
+
+ def fragment_input_html_options(fragment)
+ input_html_options.tap do |options|
+ options[:id] = fragment_id(fragment)
+ options[:class] = ((options[:class] || "").split << fragment_class(fragment)).join(" ")
+ options[:placeholder] = fragment_placeholder(fragment)
+ end
end
-
- def fragment_input_html(fragment, klass)
- opts = input_options.merge(:prefix => object_name, :field_name => fragment_name(fragment), :default => value, :include_blank => include_blank?)
- template.send(:"text_field_#{fragment}", value, opts, input_html_options.merge(:id => fragment_id(fragment), :class => klass))
+
+ def fragment_class(fragment)
+ {
+ :year => "span1",
+ :month => "span2",
+ :day => "span1",
+ :hour => "span1",
+ :minute => "span1",
+ :second => "span1"
+ }[fragment]
end
-
+
+ def fragment_placeholder(fragment)
+ "." + fragment_class(fragment)
+ end
+
end
end
end
View
56 lib/formtastic-bootstrap/inputs/base/wrapping.rb
@@ -5,57 +5,45 @@ module Wrapping
include Formtastic::Inputs::Base::Wrapping
- def generic_input_wrapping(&block)
- clearfix_div_wrapping do
- label_html <<
- input_div_wrapping do
+ def bootstrap_wrapping(&block)
+ control_group_wrapping do
+ control_label_html <<
+ controls_wrapping do
if options[:prepend]
prepended_input_wrapping do
- [template.content_tag(:span, options[:prepend], :class => 'add-on'), yield].join("\n").html_safe
+ [template.content_tag(:span, options[:prepend], :class => 'add-on'), yield, hint_html].join("\n").html_safe
end
else
- yield
+ [yield, hint_html].join("\n").html_safe
end
end
end
end
- def clearfix_div_wrapping(&block)
- template.content_tag(:div, wrapper_html_options) do
- yield
- end
+ def control_group_wrapping(&block)
+ template.content_tag(:div,
+ [template.capture(&block), error_html].join("\n").html_safe,
+ wrapper_html_options
+ )
end
- def input_div_wrapping(inline_or_block_errors = :inline)
- template.content_tag(:div, :class => "input") do
- [yield, error_html(inline_or_block_errors), hint_html(inline_or_block_errors)].join("\n").html_safe
- end
+ def controls_wrapping(&block)
+ template.content_tag(:div, template.capture(&block).html_safe, controls_wrapper_html_options)
end
-
- def inline_inputs_div_wrapping(&block)
- template.content_tag(:div, :class => "inline-inputs") do
- yield
- end
+
+ def controls_wrapper_html_options
+ {
+ :class => "controls"
+ }
end
def wrapper_html_options
- opts = options[:wrapper_html] || {}
- opts[:class] ||= []
- opts[:class] = [opts[:class].to_s] unless opts[:class].is_a?(Array)
- opts[:class] << as
- opts[:class] << "clearfix"
- # opts[:class] << "input"
- opts[:class] << "error" if errors?
- opts[:class] << "optional" if optional?
- opts[:class] << "required" if required?
- opts[:class] << "autofocus" if autofocus?
- opts[:class] = opts[:class].join(' ')
-
- opts[:id] ||= wrapper_dom_id
-
- opts
+ super.tap do |options|
+ options[:class] << " control-group"
+ end
end
+ # Bootstrap prepend feature
def prepended_input_wrapping(&block)
template.content_tag(:div, :class => 'input-prepend') do
yield
View
32 lib/formtastic-bootstrap/inputs/boolean_input.rb
@@ -2,30 +2,26 @@
module FormtasticBootstrap
module Inputs
class BooleanInput < Formtastic::Inputs::BooleanInput
- include Base
-
+ include Base
+
def to_html
- clearfix_div_wrapping do
- empty_label <<
+ control_group_wrapping do
+ control_label_html <<
hidden_field_html <<
- input_div_wrapping(:block) do
- template.content_tag(:ul, :class => "inputs-list") do
- template.content_tag(:li) do
- label_with_nested_checkbox
- end
- end
+ controls_wrapping do
+ label_with_nested_checkbox
end
end
end
- def label_text_with_embedded_checkbox
- # That newline matters! Why, I do no not know.
- check_box_html << "\n" << template.content_tag(:span) do label_text end
- end
-
- # Need this for formatting to work.
- def empty_label
- template.content_tag(:label) do end
+ def label_with_nested_checkbox
+ builder.label(
+ method,
+ label_text_with_embedded_checkbox,
+ label_html_options.tap do |options|
+ options[:class] << "checkbox"
+ end
+ )
end
end
View
27 lib/formtastic-bootstrap/inputs/check_boxes_input.rb
@@ -4,29 +4,34 @@ class CheckBoxesInput < Formtastic::Inputs::CheckBoxesInput
include Base
include Base::Choices
+ # TODO Make sure help blocks work correctly.
+ # TODO Support .inline
+
def to_html
- clearfix_div_wrapping do
- legend_html <<
+ control_group_wrapping do
+ control_label_html <<
hidden_field_for_all <<
- input_div_wrapping do
- choices_group_wrapping do
- collection.map { |choice|
- choice_wrapping(choice_wrapping_html_options(choice)) do
- choice_html(choice)
- end
- }.join("\n").html_safe
- end
+ controls_wrapping do
+ collection.map { |choice|
+ choice_html(choice)
+ }.join("\n").html_safe
end
end
end
+ def choice_wrapping_html_options(choice)
+ super(choice).tap do |options|
+ options[:class] = ((options[:class].split) << "checkbox").join(" ")
+ end
+ end
+
def choice_html(choice)
template.content_tag(:label,
hidden_fields? ?
check_box_with_hidden_input(choice) :
check_box_without_hidden_input(choice) <<
choice_label(choice),
- label_html_options.merge(:for => choice_input_dom_id(choice), :class => nil)
+ label_html_options.merge(choice_label_html_options(choice))
)
end
View
12 lib/formtastic-bootstrap/inputs/date_input.rb
@@ -1,16 +1,10 @@
module FormtasticBootstrap
module Inputs
- class DateInput < Formtastic::Inputs::DateInput
- include Base
- include Base::Stringish
- include Base::Timeish
-
+ class DateInput < FormtasticBootstrap::Inputs::DateSelectInput
def to_html
- generic_input_wrapping do
- date_input_html
- end
+ ::ActiveSupport::Deprecation.warn("DateInput (:as => :date) has been renamed to DateSelectInput (:as => :date_select) and will be removed or changed in the next version of Formtastic, please update your forms.", caller(2))
+ super
end
-
end
end
end
View
8 lib/formtastic-bootstrap/inputs/date_select_input.rb
@@ -0,0 +1,8 @@
+module FormtasticBootstrap
+ module Inputs
+ class DateSelectInput < Formtastic::Inputs::DateSelectInput
+ include Base
+ include Base::Timeish
+ end
+ end
+end
View
15 lib/formtastic-bootstrap/inputs/datetime_input.rb
@@ -1,19 +1,10 @@
module FormtasticBootstrap
module Inputs
- class DatetimeInput < Formtastic::Inputs::DatetimeInput
- include Base
- include Base::Stringish
- include Base::Timeish
-
+ class DatetimeInput < FormtasticBootstrap::Inputs::DatetimeSelectInput
def to_html
- generic_input_wrapping do
- inline_inputs_div_wrapping do
- # This newline matters.
- date_input_html << "\n".html_safe << time_input_html
- end
- end
+ ::ActiveSupport::Deprecation.warn("DatetimeInput (:as => :datetime) has been renamed to DatetimeSelectInput (:as => :datetime_select) and will be removed or changed in the next version of Formtastic, please update your forms.", caller(2))
+ super
end
-
end
end
end
View
8 lib/formtastic-bootstrap/inputs/datetime_select_input.rb
@@ -0,0 +1,8 @@
+module FormtasticBootstrap
+ module Inputs
+ class DatetimeSelectInput < Formtastic::Inputs::DatetimeSelectInput
+ include Base
+ include Base::Timeish
+ end
+ end
+end
View
2 lib/formtastic-bootstrap/inputs/email_input.rb
@@ -5,7 +5,7 @@ class EmailInput < Formtastic::Inputs::EmailInput
include Base::Stringish
def to_html
- generic_input_wrapping do
+ bootstrap_wrapping do
builder.email_field(method, input_html_options)
end
end
View
2 lib/formtastic-bootstrap/inputs/file_input.rb
@@ -4,7 +4,7 @@ class FileInput < Formtastic::Inputs::FileInput
include Base
def to_html
- generic_input_wrapping do
+ bootstrap_wrapping do
builder.file_field(method, input_html_options)
end
end
View
2 lib/formtastic-bootstrap/inputs/hidden_input.rb
@@ -3,7 +3,7 @@ module Inputs
class HiddenInput < Formtastic::Inputs::HiddenInput
include Base
def to_html
- generic_input_wrapping do
+ bootstrap_wrapping do
builder.hidden_field(method, input_html_options)
end
end
View
6 lib/formtastic-bootstrap/inputs/number_input.rb
@@ -2,14 +2,14 @@ module FormtasticBootstrap
module Inputs
class NumberInput < Formtastic::Inputs::NumberInput
include Base
- include Base::Stringish
+ include Base::Numeric
def to_html
- generic_input_wrapping do
+ bootstrap_wrapping do
builder.number_field(method, input_html_options)
end
end
-
+
end
end
end
View
2 lib/formtastic-bootstrap/inputs/password_input.rb
@@ -5,7 +5,7 @@ class PasswordInput < Formtastic::Inputs::PasswordInput
include Base::Stringish
def to_html
- generic_input_wrapping do
+ bootstrap_wrapping do
builder.password_field(method, input_html_options)
end
end
View
2 lib/formtastic-bootstrap/inputs/phone_input.rb
@@ -5,7 +5,7 @@ class PhoneInput < Formtastic::Inputs::PhoneInput
include Base::Stringish
def to_html
- generic_input_wrapping do
+ bootstrap_wrapping do
builder.phone_field(method, input_html_options)
end
end
View
42 lib/formtastic-bootstrap/inputs/radio_input.rb
@@ -4,29 +4,43 @@ class RadioInput < Formtastic::Inputs::RadioInput
include Base
include Base::Choices
+ # TODO Make sure help blocks work correctly.
+ # TODO Support .inline
+
def to_html
- clearfix_div_wrapping do
- legend_html <<
- input_div_wrapping do
- choices_group_wrapping do
- collection.map { |choice|
- choice_wrapping(choice_wrapping_html_options(choice)) do
- choice_html(choice)
- end
- }.join("\n").html_safe
- end
+ control_group_wrapping do
+ control_label_html <<
+ controls_wrapping do
+ collection.map { |choice|
+ choice_html(choice)
+ }.join("\n").html_safe
end
end
end
- def choice_html(choice)
- template.content_tag(:label, label_html_options.merge(:for => choice_input_dom_id(choice), :class => nil)) do
- builder.radio_button(input_name, choice_value(choice), input_html_options.merge(choice_html_options(choice)).merge(:required => false)) <<
+ def wrapper_html_options
+ # Formtastic marks these as 'radio' but Bootstrap does something
+ # with that, so change it to 'radio_buttons'.
+ super.tap do |options|
+ options[:class] = options[:class].gsub("radio", "radio_buttons")
+ end
+ end
- choice_label(choice)
+ # This came from check_boxes. Do needed refactoring.
+ def choice_wrapping_html_options(choice)
+ super(choice).tap do |options|
+ options[:class] = ((options[:class].split) << "radio").join(" ")
end
end
+ def choice_html(choice)
+ template.content_tag(:label,
+ builder.radio_button(input_name, choice_value(choice), input_html_options.merge(choice_html_options(choice)).merge(:required => false)) <<
+ choice_label(choice),
+ label_html_options.merge(choice_label_html_options(choice))
+ )
+ end
+
end
end
end
View
2 lib/formtastic-bootstrap/inputs/range_input.rb
@@ -5,7 +5,7 @@ class RangeInput < Formtastic::Inputs::RangeInput
include Base::Stringish
def to_html
- generic_input_wrapping do
+ bootstrap_wrapping do
builder.range_field(method, input_html_options)
end
end
View
2 lib/formtastic-bootstrap/inputs/search_input.rb
@@ -5,7 +5,7 @@ class SearchInput < Formtastic::Inputs::SearchInput
include Base::Stringish
def to_html
- generic_input_wrapping do
+ bootstrap_wrapping do
builder.search_field(method, input_html_options)
end
end
View
4 lib/formtastic-bootstrap/inputs/select_input.rb
@@ -2,9 +2,11 @@ module FormtasticBootstrap
module Inputs
class SelectInput < Formtastic::Inputs::SelectInput
include Base
+ include Base::Collections
+ include Base::GroupedCollections
def to_html
- generic_input_wrapping do
+ bootstrap_wrapping do
options[:group_by] ? grouped_select_html : select_html
end
end
View
7 lib/formtastic-bootstrap/inputs/string_input.rb
@@ -3,13 +3,6 @@ module Inputs
class StringInput < Formtastic::Inputs::StringInput
include Base
include Base::Stringish
-
- def to_html
- generic_input_wrapping do
- builder.text_field(method, input_html_options)
- end
- end
-
end
end
end
View
2 lib/formtastic-bootstrap/inputs/text_input.rb
@@ -4,7 +4,7 @@ class TextInput < Formtastic::Inputs::TextInput
include Base
def to_html
- generic_input_wrapping do
+ bootstrap_wrapping do
builder.text_area(method, input_html_options)
end
end
View
12 lib/formtastic-bootstrap/inputs/time_input.rb
@@ -1,16 +1,10 @@
module FormtasticBootstrap
module Inputs
- class TimeInput < Formtastic::Inputs::TimeInput
- include Base
- include Base::Stringish
- include Base::Timeish
-
+ class TimeInput < FormtasticBootstrap::Inputs::TimeSelectInput
def to_html
- generic_input_wrapping do
- time_input_html
- end
+ ::ActiveSupport::Deprecation.warn("TimeInput (:as => :time) has been renamed to TimeSelectInput (:as => :time_select) and will be removed or changed in the next version of Formtastic, please update your forms.", caller(2))
+ super
end
-
end
end
end
View
8 lib/formtastic-bootstrap/inputs/time_select_input.rb
@@ -0,0 +1,8 @@
+module FormtasticBootstrap
+ module Inputs
+ class TimeSelectInput < Formtastic::Inputs::TimeSelectInput
+ include Base
+ include Base::Timeish
+ end
+ end
+end
View
2 lib/formtastic-bootstrap/inputs/time_zone_input.rb
@@ -4,7 +4,7 @@ class TimeZoneInput < Formtastic::Inputs::TimeZoneInput
include Base
def to_html
- generic_input_wrapping do
+ bootstrap_wrapping do
builder.time_zone_select(method, priority_zones, input_options, input_html_options)
end
end
View
2 lib/formtastic-bootstrap/inputs/url_input.rb
@@ -5,7 +5,7 @@ class UrlInput < Formtastic::Inputs::UrlInput
include Base::Stringish
def to_html
- generic_input_wrapping do
+ bootstrap_wrapping do
builder.url_field(method, input_html_options)
end
end
View
63 spec/actions/button_action_spec.rb
@@ -0,0 +1,63 @@
+# encoding: utf-8
+require 'spec_helper'
+
+describe 'ButtonAction', 'when submitting' do
+
+ include FormtasticSpecHelper
+
+ before do
+ @output_buffer = ''
+ mock_everything
+
+ concat(semantic_form_for(@new_post) do |builder|
+ concat(builder.action(:submit, :as => :button))
+ end)
+ end
+
+ it 'should render a submit type of button' do
+ output_buffer.should have_tag('button[@type="submit"].btn')
+ end
+
+end
+
+describe 'ButtonAction', 'when resetting' do
+
+ include FormtasticSpecHelper
+
+ before do
+ @output_buffer = ''
+ mock_everything
+
+ concat(semantic_form_for(@new_post) do |builder|
+ concat(builder.action(:reset, :as => :button))
+ end)
+ end
+
+ it 'should render a reset type of button' do
+ output_buffer.should have_tag('button[@type="reset"].btn', :text => "Reset Post")
+ end
+
+ it 'should not render a value attribute' do
+ output_buffer.should_not have_tag('button[@value].btn')
+ end
+
+end
+
+describe 'InputAction', 'when cancelling' do
+
+ include FormtasticSpecHelper
+
+ before do
+ @output_buffer = ''
+ mock_everything
+ end
+
+ it 'should raise an error' do
+ lambda {
+ concat(semantic_form_for(@new_post) do |builder|
+ concat(builder.action(:cancel, :as => :button))
+ end)
+ }.should raise_error(Formtastic::UnsupportedMethodForAction)
+ end
+
+end
View
59 spec/actions/input_action_spec.rb
@@ -0,0 +1,59 @@
+# encoding: utf-8
+require 'spec_helper'
+
+describe 'InputAction', 'when submitting' do
+
+ include FormtasticSpecHelper
+
+ before do
+ @output_buffer = ''
+ mock_everything
+
+ concat(semantic_form_for(@new_post) do |builder|
+ concat(builder.action(:submit, :as => :input))
+ end)
+ end
+
+ it 'should render a submit type of input' do
+ output_buffer.should have_tag('input[@type="submit"].btn')
+ end
+
+end
+
+describe 'InputAction', 'when resetting' do
+
+ include FormtasticSpecHelper
+
+ before do
+ @output_buffer = ''
+ mock_everything
+
+ concat(semantic_form_for(@new_post) do |builder|
+ concat(builder.action(:reset, :as => :input))
+ end)
+ end
+
+ it 'should render a reset type of input' do
+ output_buffer.should have_tag('input[@type="reset"].btn')
+ end
+
+end
+
+describe 'InputAction', 'when cancelling' do
+
+ include FormtasticSpecHelper
+
+ before do
+ @output_buffer = ''
+ mock_everything
+ end
+
+ it 'should raise an error' do
+ lambda {
+ concat(semantic_form_for(@new_post) do |builder|
+ concat(builder.action(:cancel, :as => :input))
+ end)
+ }.should raise_error(Formtastic::UnsupportedMethodForAction)
+ end
+
+end
View
92 spec/actions/link_action_spec.rb
@@ -0,0 +1,92 @@
+# encoding: utf-8
+require 'spec_helper'
+
+describe 'LinkAction', 'when cancelling' do
+
+ include FormtasticSpecHelper
+
+ before do
+ @output_buffer = ''
+ mock_everything
+ end
+
+ context 'without a :url' do
+ before do
+ concat(semantic_form_for(@new_post) do |builder|
+ concat(builder.action(:cancel, :as => :link))
+ end)
+ end
+
+ it 'should render a submit type of input' do
+ output_buffer.should have_tag('a[@href="javascript:history.back()"].btn')
+ end
+
+ end
+
+ context 'with a :url as String' do
+
+ before do
+ concat(semantic_form_for(@new_post) do |builder|
+ concat(builder.action(:cancel, :as => :link, :url => "http://foo.bah/baz"))
+ end)
+ end
+
+ it 'should render a submit type of input' do
+ output_buffer.should have_tag('a[@href="http://foo.bah/baz"].btn')
+ end
+
+ end
+
+ context 'with a :url as Hash' do
+
+ before do
+ concat(semantic_form_for(@new_post) do |builder|
+ concat(builder.action(:cancel, :as => :link, :url => { :action => "foo" }))
+ end)
+ end
+
+ it 'should render a submit type of input' do
+ output_buffer.should have_tag('a[@href="/mock/path"].btn')
+ end
+
+ end
+
+end
+
+describe 'LinkAction', 'when submitting' do
+
+ include FormtasticSpecHelper
+
+ before do
+ @output_buffer = ''
+ mock_everything
+ end
+
+ it 'should raise an error' do
+ lambda {
+ concat(semantic_form_for(@new_post) do |builder|
+ concat(builder.action(:submit, :as => :link))
+ end)
+ }.should raise_error(Formtastic::UnsupportedMethodForAction)
+ end
+
+end
+
+describe 'LinkAction', 'when submitting' do
+
+ include FormtasticSpecHelper
+
+ before do
+ @output_buffer = ''
+ mock_everything
+ end
+
+ it 'should raise an error' do
+ lambda {
+ concat(semantic_form_for(@new_post) do |builder|
+ concat(builder.action(:reset, :as => :link))
+ end)
+ }.should raise_error(Formtastic::UnsupportedMethodForAction)
+ end
+
+end
View
214 spec/builder/errors_spec.rb
@@ -1,214 +0,0 @@
-# encoding: utf-8
-require 'spec_helper'
-
-describe 'Formtastic::FormBuilder#errors_on' do
-
- include FormtasticSpecHelper
-
- before(:each) do
- @output_buffer = ''
- mock_everything
- Formtastic::Helpers::FormHelper.builder = FormtasticBootstrap::FormBuilder
- @title_errors = ['must not be blank', 'must be longer than 10 characters', 'must be awesome']
- @errors = mock('errors')
- @new_post.stub!(:errors).and_return(@errors)
-
- @orig_inline_errors = FormtasticBootstrap::FormBuilder.inline_errors
- @orig_inline_error_class = FormtasticBootstrap::FormBuilder.default_inline_error_class
- @orig_error_list_class = FormtasticBootstrap::FormBuilder.default_error_list_class
- end
-
- after(:each) do
- FormtasticBootstrap::FormBuilder.inline_errors = @orig_inline_errors
- FormtasticBootstrap::FormBuilder.default_inline_error_class = @orig_inline_error_class
- FormtasticBootstrap::FormBuilder.default_error_list_class = @orig_error_list_class
- end
-
- describe 'when there are errors' do
- before do
- @errors.stub!(:[]).with(:title).and_return(@title_errors)
- end
-
- # after do
- # FormtasticBootstrap::FormBuilder.default_inline_error_class = 'inline-errors'
- # FormtasticBootstrap::FormBuilder.default_inline_error_class = 'help-inline'
- # FormtasticBootstrap::FormBuilder.default_error_list_class = 'errors'
- # end
-
- it 'should render a paragraph with the errors joined into a sentence when inline_errors config is :sentence' do
- FormtasticBootstrap::FormBuilder.inline_errors = :sentence
- concat(semantic_form_for(@new_post) do |builder|
- builder.input :title
- end)
- output_buffer.should have_tag('span.help-inline', @title_errors.to_sentence)
- end
-
- it 'should render a paragraph with a overridden default class' do
- FormtasticBootstrap::FormBuilder.default_inline_error_class = 'better-errors'
- concat(semantic_form_for(@new_post) do |builder|
- builder.input(:title)
- end)
- output_buffer.should have_tag('span.better-errors', @title_errors.to_sentence)
- end
-
- it 'should render a paragraph with the errors joined into a sentence when inline_errors config is :sentence with a customized error class' do
- FormtasticBootstrap::FormBuilder.inline_errors = :sentence
- concat(semantic_form_for(@new_post) do |builder|
- builder.input(:title, :error_class => 'better-errors')
- end)
- output_buffer.should have_tag('span.better-errors', @title_errors.to_sentence)
- end
-
- it 'should render an unordered list with the class errors when inline_errors config is :list' do
- FormtasticBootstrap::FormBuilder.inline_errors = :list
- concat(semantic_form_for(@new_post) do |builder|
- builder.input(:title)
- end)
- output_buffer.should have_tag('ul.errors')
- @title_errors.each do |error|
- output_buffer.should have_tag('ul.errors li', error)
- end
- end
-
- it 'should render an unordered list with the class overridden default class' do
- FormtasticBootstrap::FormBuilder.inline_errors = :list
- FormtasticBootstrap::FormBuilder.default_error_list_class = "better-errors"
- concat(semantic_form_for(@new_post) do |builder|
- builder.input :title
- end)
- output_buffer.should have_tag('ul.better-errors')
- @title_errors.each do |error|
- output_buffer.should have_tag('ul.better-errors li', error)
- end
- end
-
- it 'should render an unordered list with the class errors when inline_errors config is :list with a customized error class' do
- FormtasticBootstrap::FormBuilder.inline_errors = :list
- concat(semantic_form_for(@new_post) do |builder|
- builder.input :title, :error_class => "better-errors"
- end)
- output_buffer.should have_tag('ul.better-errors')
- @title_errors.each do |error|
- output_buffer.should have_tag('ul.better-errors li', error)
- end
- end
-
- it 'should render a paragraph with the first error when inline_errors config is :first' do
- FormtasticBootstrap::FormBuilder.inline_errors = :first
- concat(semantic_form_for(@new_post) do |builder|
- builder.input :title
- end)
- output_buffer.should have_tag('span.help-inline', @title_errors.first)
- end
-
- it 'should render a paragraph with the first error when inline_errors config is :first with a customized error class' do
- FormtasticBootstrap::FormBuilder.inline_errors = :first
- concat(semantic_form_for(@new_post) do |builder|
- builder.input :title, :error_class => "better-errors"
- end)
- output_buffer.should have_tag('span.better-errors', @title_errors.first)
- end
-
- it 'should return nil when inline_errors config is :none' do
- FormtasticBootstrap::FormBuilder.inline_errors = :none
- concat(semantic_form_for(@new_post) do |builder|
- builder.input :title
- end)
- output_buffer.should_not have_tag('span.help-inline')
- output_buffer.should_not have_tag('span.help-block')
- output_buffer.should_not have_tag('ul.errors')
- end
-
- it 'should allow calling deprecated errors_on and inline_errors_for helpers' do
- FormtasticBootstrap::FormBuilder.inline_errors = :sentence
- with_deprecation_silenced do
- concat(semantic_form_for(@new_post) do |builder|
- builder.errors_on :title
- builder.inline_errors_for :title
- end)
- end
- end
- end
-
- describe 'when there are no errors (nil)' do
- before do
- @errors.stub!(:[]).with(:title).and_return(nil)
- end
-
- it 'should return nil when inline_errors config is :sentence, :list or :none' do
- with_deprecation_silenced do
- [:sentence, :list, :none].each do |config|
- with_config :inline_errors, config do
- semantic_form_for(@new_post) do |builder|
- builder.errors_on(:title).should be_nil
- end
- end
- end
- end
- end
- end
-
- describe 'when there are no errors (empty array)' do
-
- before(:each) do
- @errors.stub!(:[]).with(:title).and_return([])
- end
-
- it 'should return nil when inline_errors config is :sentence, :list or :none' do
- with_deprecation_silenced do
- [:sentence, :list, :none].each do |config|
- FormtasticBootstrap::FormBuilder.inline_errors = config
- semantic_form_for(@new_post) do |builder|
- builder.errors_on(:title).should be_nil
- end
- end
- end
- end
- end
-
- describe 'when file type columns have errors' do
- it "should list errors added on metadata fields" do
- @errors.stub!(:[]).with(:document_file_name).and_return(['must be provided'])
- @errors.stub!(:[]).with(:document_file_size).and_return(['must be less than 4mb'])
- @errors.stub!(:[]).with(:document_content_type).and_return(['must be an image'])
- @errors.stub!(:[]).with(:document).and_return(nil)
-
- with_config :inline_errors, :sentence do
- concat(semantic_form_for(@new_post) do |builder|
- concat(builder.input(:document))
- end)
- end
- output_buffer.should have_tag("div.error")
- output_buffer.should have_tag('span.help-inline', (['must be an image','must be provided', 'must be less than 4mb']).to_sentence)
- end
- end
-
- describe 'when there are errors on the association and column' do
-
- it "should list all unique errors" do
- ::Post.stub!(:reflections).and_return({:author => mock('reflection', :options => {}, :macro => :belongs_to)})
-
- @errors.stub!(:[]).with(:author).and_return(['must not be blank'])
- @errors.stub!(:[]).with(:author_id).and_return(['is already taken', 'must not be blank']) # note the duplicate of association
-
- with_config :inline_errors, :list do
- concat(semantic_form_for(@new_post) do |builder|
- concat(builder.input(:author))
- end)
- end
- output_buffer.should have_tag("ul.errors li", /must not be blank/, :count => 1)
- output_buffer.should have_tag("ul.errors li", /is already taken/, :count => 1)
- end
-
- end
-
- describe "when there are errors on a has_many association" do
- it "should include the association ids error messages" do
- semantic_form_for(@new_post) do |builder|
- builder.send(:error_keys, :sub_posts, {}).should include(:sub_post_ids)
- end
- end
- end
-
-end
-
View
368 spec/helpers/action_helper_spec.rb
@@ -0,0 +1,368 @@
+# encoding: utf-8
+require 'spec_helper'
+
+describe 'FormtasticBootstrap::FormBuilder#action' do
+
+ include FormtasticSpecHelper
+
+ before do
+ @output_buffer = ''
+ mock_everything
+ end
+
+ after do
+ ::I18n.backend.reload!
+ end
+
+ describe 'arguments and options' do
+
+ it 'should require the first argument (the action method)' do
+ lambda {
+ concat(semantic_form_for(@new_post) do |builder|
+ concat(builder.action()) # no args passed in at all
+ end)
+ }.should raise_error(ArgumentError)
+ end
+
+ describe ':as option' do
+
+ describe 'when not provided' do
+
+ it 'should default to a commit for commit' do
+ concat(semantic_form_for(:project, :url => 'http://test.host') do |builder|
+ concat(builder.action(:submit))
+ end)
+ output_buffer.should have_tag('form input.btn', :count => 1)
+ end
+
+ it 'should default to a button for reset' do
+ concat(semantic_form_for(:project, :url => 'http://test.host') do |builder|
+ concat(builder.action(:reset))
+ end)
+ output_buffer.should have_tag('form input.btn', :count => 1)
+ end
+
+ it 'should default to a link for cancel' do
+ concat(semantic_form_for(:project, :url => 'http://test.host') do |builder|
+ concat(builder.action(:cancel))
+ end)
+ output_buffer.should have_tag('form a.btn', :count => 1)
+ end
+ end
+
+ it 'should call the corresponding action class with .to_html' do
+ [:input, :button, :link].each do |action_style|
+ semantic_form_for(:project, :url => "http://test.host") do |builder|
+ action_instance = mock('Action instance')
+ action_class = "#{action_style.to_s}_action".classify
+ action_constant = "FormtasticBootstrap::Actions::#{action_class}".constantize
+
+ action_constant.should_receive(:new).and_return(action_instance)
+ action_instance.should_receive(:to_html).and_return("some HTML")
+
+ concat(builder.action(:submit, :as => action_style))
+ end
+ end
+ end
+
+ end
+
+ #describe ':label option' do
+ #
+ # describe 'when provided' do
+ # it 'should be passed down to the label tag' do
+ # concat(semantic_form_for(@new_post) do |builder|
+ # concat(builder.input(:title, :label => "Kustom"))
+ # end)
+ # output_buffer.should have_tag("form li label", /Kustom/)
+ # end
+ #
+ # it 'should not generate a label if false' do
+ # concat(semantic_form_for(@new_post) do |builder|
+ # concat(builder.input(:title, :label => false))
+ # end)
+ # output_buffer.should_not have_tag("form li label")
+ # end
+ #
+ # it 'should be dupped if frozen' do
+ # concat(semantic_form_for(@new_post) do |builder|
+ # concat(builder.input(:title, :label => "Kustom".freeze))
+ # end)
+ # output_buffer.should have_tag("form li label", /Kustom/)
+ # end
+ # end
+ #
+ # describe 'when not provided' do
+ # describe 'when localized label is provided' do
+ # describe 'and object is given' do
+ # describe 'and label_str_method not :humanize' do
+ # it 'should render a label with localized text and not apply the label_str_method' do
+ # with_config :label_str_method, :reverse do
+ # @localized_label_text = 'Localized title'
+ # @new_post.stub!(:meta_description)
+ # ::I18n.backend.store_translations :en,
+ # :formtastic => {
+ # :labels => {
+ # :meta_description => @localized_label_text
+ # }
+ # }
+ #
+ # concat(semantic_form_for(@new_post) do |builder|
+ # concat(builder.input(:meta_description))
+ # end)
+ # output_buffer.should have_tag('form li label', /Localized title/)
+ # end
+ # end
+ # end
+ # end
+ # end
+ #
+ # describe 'when localized label is NOT provided' do
+ # describe 'and object is not given' do
+ # it 'should default the humanized method name, passing it down to the label tag' do
+ # ::I18n.backend.store_translations :en, :formtastic => {}
+ # with_config :label_str_method, :humanize do
+ # concat(semantic_form_for(:project, :url => 'http://test.host') do |builder|
+ # concat(builder.input(:meta_description))
+ # end)
+ # output_buffer.should have_tag("form li label", /#{'meta_description'.humanize}/)
+ # end
+ # end
+ # end
+ #
+ # describe 'and object is given' do
+ # it 'should delegate the label logic to class human attribute name and pass it down to the label tag' do
+ # @new_post.stub!(:meta_description) # a two word method name
+ # @new_post.class.should_receive(:human_attribute_name).with('meta_description').and_return('meta_description'.humanize)
+ #
+ # concat(semantic_form_for(@new_post) do |builder|
+ # concat(builder.input(:meta_description))
+ # end)
+ # output_buffer.should have_tag("form li label", /#{'meta_description'.humanize}/)
+ # end
+ # end
+ #
+ # describe 'and object is given with label_str_method set to :capitalize' do
+ # it 'should capitalize method name, passing it down to the label tag' do
+ # with_config :label_str_method, :capitalize do
+ # @new_post.stub!(:meta_description)
+ #
+ # concat(semantic_form_for(@new_post) do |builder|
+ # concat(builder.input(:meta_description))
+ # end)
+ # output_buffer.should have_tag("form li label", /#{'meta_description'.capitalize}/)
+ # end
+ # end
+ # end
+ # end
+ #
+ # describe 'when localized label is provided' do
+ # before do
+ # @localized_label_text = 'Localized title'
+ # @default_localized_label_text = 'Default localized title'
+ # ::I18n.backend.store_translations :en,
+ # :formtastic => {
+ # :labels => {
+ # :title => @default_localized_label_text,
+ # :published => @default_localized_label_text,
+ # :post => {
+ # :title => @localized_label_text,
+ # :published => @default_localized_label_text
+ # }
+ # }
+ # }
+ # end