formtastic-bootstrap 2.1.0 → 2.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (58) hide show
  1. data/VERSION +1 -1
  2. data/lib/action_view/helpers/text_field_date_helper.rb +166 -0
  3. data/lib/formtastic-bootstrap/actions.rb +10 -0
  4. data/lib/formtastic-bootstrap/actions/base.rb +22 -0
  5. data/lib/formtastic-bootstrap/actions/button_action.rb +13 -0
  6. data/lib/formtastic-bootstrap/actions/input_action.rb +13 -0
  7. data/lib/formtastic-bootstrap/actions/link_action.rb +12 -0
  8. data/lib/formtastic-bootstrap/engine.rb +4 -0
  9. data/lib/formtastic-bootstrap/form_builder.rb +41 -0
  10. data/lib/formtastic-bootstrap/helpers.rb +17 -0
  11. data/lib/formtastic-bootstrap/helpers/action_helper.rb +12 -0
  12. data/lib/formtastic-bootstrap/helpers/actions_helper.rb +24 -0
  13. data/lib/formtastic-bootstrap/helpers/errors_helper.rb +70 -0
  14. data/lib/formtastic-bootstrap/helpers/fieldset_wrapper.rb +35 -0
  15. data/lib/formtastic-bootstrap/helpers/input_helper.rb +12 -0
  16. data/lib/formtastic-bootstrap/helpers/inputs_helper.rb +34 -0
  17. data/lib/formtastic-bootstrap/inputs.rb +36 -0
  18. data/lib/formtastic-bootstrap/inputs/base.rb +45 -0
  19. data/lib/formtastic-bootstrap/inputs/base/choices.rb +20 -0
  20. data/lib/formtastic-bootstrap/inputs/base/collections.rb +9 -0
  21. data/lib/formtastic-bootstrap/inputs/base/datetime_pickerish.rb +10 -0
  22. data/lib/formtastic-bootstrap/inputs/base/errors.rb +48 -0
  23. data/lib/formtastic-bootstrap/inputs/base/grouped_collections.rb +9 -0
  24. data/lib/formtastic-bootstrap/inputs/base/hints.rb +27 -0
  25. data/lib/formtastic-bootstrap/inputs/base/html.rb +21 -0
  26. data/lib/formtastic-bootstrap/inputs/base/labelling.rb +29 -0
  27. data/lib/formtastic-bootstrap/inputs/base/numeric.rb +9 -0
  28. data/lib/formtastic-bootstrap/inputs/base/placeholder.rb +9 -0
  29. data/lib/formtastic-bootstrap/inputs/base/stringish.rb +17 -0
  30. data/lib/formtastic-bootstrap/inputs/base/timeish.rb +55 -0
  31. data/lib/formtastic-bootstrap/inputs/base/wrapping.rb +83 -0
  32. data/lib/formtastic-bootstrap/inputs/boolean_input.rb +29 -0
  33. data/lib/formtastic-bootstrap/inputs/check_boxes_input.rb +40 -0
  34. data/lib/formtastic-bootstrap/inputs/country_input.rb +14 -0
  35. data/lib/formtastic-bootstrap/inputs/date_input.rb +10 -0
  36. data/lib/formtastic-bootstrap/inputs/date_picker_input.rb +9 -0
  37. data/lib/formtastic-bootstrap/inputs/date_select_input.rb +8 -0
  38. data/lib/formtastic-bootstrap/inputs/datetime_input.rb +10 -0
  39. data/lib/formtastic-bootstrap/inputs/datetime_picker_input.rb +9 -0
  40. data/lib/formtastic-bootstrap/inputs/datetime_select_input.rb +8 -0
  41. data/lib/formtastic-bootstrap/inputs/email_input.rb +15 -0
  42. data/lib/formtastic-bootstrap/inputs/file_input.rb +14 -0
  43. data/lib/formtastic-bootstrap/inputs/hidden_input.rb +12 -0
  44. data/lib/formtastic-bootstrap/inputs/number_input.rb +15 -0
  45. data/lib/formtastic-bootstrap/inputs/password_input.rb +15 -0
  46. data/lib/formtastic-bootstrap/inputs/phone_input.rb +15 -0
  47. data/lib/formtastic-bootstrap/inputs/radio_input.rb +46 -0
  48. data/lib/formtastic-bootstrap/inputs/range_input.rb +15 -0
  49. data/lib/formtastic-bootstrap/inputs/search_input.rb +15 -0
  50. data/lib/formtastic-bootstrap/inputs/select_input.rb +16 -0
  51. data/lib/formtastic-bootstrap/inputs/string_input.rb +8 -0
  52. data/lib/formtastic-bootstrap/inputs/text_input.rb +14 -0
  53. data/lib/formtastic-bootstrap/inputs/time_input.rb +10 -0
  54. data/lib/formtastic-bootstrap/inputs/time_select_input.rb +8 -0
  55. data/lib/formtastic-bootstrap/inputs/time_zone_input.rb +14 -0
  56. data/lib/formtastic-bootstrap/inputs/url_input.rb +14 -0
  57. data/lib/formtastic-bootstrap/version.rb +3 -0
  58. metadata +62 -3
data/VERSION CHANGED
@@ -1 +1 @@
1
- 2.1.0
1
+ 2.1.1
@@ -0,0 +1,166 @@
1
+ require 'action_view/helpers/form_tag_helper'
2
+
3
+ module ActionView
4
+ module Helpers
5
+
6
+ module TextFieldDateHelper
7
+
8
+ # These two handle an object with a method that returns a Date or Time object.
9
+ def date_text_field(object_name, method, options = {}, html_options = {})
10
+ InstanceTag.new(object_name, method, self, options.delete(:object)).to_date_text_field_tag(options, html_options)
11
+ end
12
+
13
+ def time_text_field(object_name, method, options = {}, html_options = {})
14
+ InstanceTag.new(object_name, method, self, options.delete(:object)).to_time_text_field_tag(options, html_options)
15
+ end
16
+
17
+ # These two handle Date and Time objects.
18
+ def text_field_date(date = Date.current, options = {}, html_options = {})
19
+ DateTimeSelector.new(date, options, html_options).text_field_date
20
+ end
21
+
22
+ def text_field_time(time = Time.current, options = {}, html_options = {})
23
+ DateTimeSelector.new(time, options, html_options).text_field_time
24
+ end
25
+ end
26
+
27
+ class DateTimeSelector
28
+
29
+ include ActionView::Helpers::FormTagHelper
30
+
31
+ def text_field_date
32
+ order = date_order.dup
33
+
34
+ @options[:discard_hour] = true
35
+ @options[:discard_minute] = true
36
+ @options[:discard_second] = true
37
+
38
+ @options[:discard_year] ||= true unless order.include?(:year)
39
+ @options[:discard_month] ||= true unless order.include?(:month)
40
+ @options[:discard_day] ||= true if @options[:discard_month] || !order.include?(:day)
41
+
42
+ # Save this so we can restore it.
43
+ original_datetime_separator_separator = @options[:datetime_separator]
44
+ original_date_separator = @options[:date_separator]
45
+
46
+ @options[:datetime_separator] = ""
47
+ @options[:date_separator] = " "
48
+
49
+ # If the day is hidden and the month is visible, the day should be set to the 1st so all month choices are
50
+ # valid (otherwise it could be 31 and February wouldn't be a valid date)
51
+ if @datetime && @options[:discard_day] && !@options[:discard_month]
52
+ @datetime = @datetime.change(:day => 1)
53
+ end
54
+
55
+ [:day, :month, :year].each { |o| order.unshift(o) unless order.include?(o) }
56
+
57
+ build_text_field_from_types(order).tap do
58
+ # Restore.
59
+ @options[:datetime_separator] = original_datetime_separator_separator
60
+ @options[:date_separator] = original_date_separator
61
+ end
62
+ end
63
+
64
+ def text_field_time
65
+ order = []
66
+
67
+ @options[:discard_month] = true
68
+ @options[:discard_year] = true
69
+ @options[:discard_day] = true
70
+ @options[:discard_second] ||= true unless @options[:include_seconds]
71
+
72
+ # Save this so we can restore it.
73
+ original_datetime_separator = @options[:datetime_separator]
74
+ original_time_separator = @options[:time_separator]
75
+ original_date_separator = @options[:date_separator]
76
+
77
+ @options[:datetime_separator] = ''
78
+ @options[:time_separator] = ':'
79
+ @options[:date_separator] = " "
80
+
81
+ order += [:year, :month, :day] unless @options[:ignore_date]
82
+
83
+ order += [:hour, :minute]
84
+ order << :second if @options[:include_seconds]
85
+
86
+ build_text_field_from_types(order).tap do
87
+ # Restore.
88
+ @options[:datetime_separator] = original_datetime_separator
89
+ @options[:date_separator] = original_date_separator
90
+ @options[:time_separator] = original_time_separator
91
+ end
92
+ end
93
+
94
+ def text_field_second
95
+ unless @options[:use_hidden] || @options[:discard_second]
96
+ build_text(:second, sec)
97
+ end
98
+ end
99
+
100
+ def text_field_minute
101
+ unless @options[:use_hidden] || @options[:discard_minute]
102
+ build_text(:minute, min)
103
+ end
104
+ end
105
+
106
+ def text_field_hour
107
+ unless @options[:use_hidden] || @options[:discard_hour]
108
+ build_text(:hour, hour, :ampm => @options[:ampm])
109
+ end
110
+ end
111
+
112
+ def text_field_day
113
+ unless @options[:use_hidden] || @options[:discard_day]
114
+ build_text(:day, day, :leading_zeros => false)
115
+ end
116
+ end
117
+
118
+ def text_field_month
119
+ unless @options[:use_hidden] || @options[:discard_month]
120
+ build_text(:month, month.nil? ? "" : month_name(month), :leading_zeros => false)
121
+ end
122
+ end
123
+
124
+ def text_field_year
125
+ unless @options[:use_hidden] || @options[:discard_year]
126
+ build_text(:year, year, :leading_zeros => false)
127
+ end
128
+ end
129
+
130
+ def build_text_field_from_types(order)
131
+ input = ''
132
+ order.reverse.each do |type|
133
+ separator = separator(type) unless type == order.first # don't add on last field
134
+ input.insert(0, separator.to_s + send("text_field_#{type}").to_s)
135
+ end
136
+ text_field_tag("", input.html_safe, @html_options).html_safe
137
+ end
138
+
139
+ def build_text(selected, value, options = {})
140
+ unless value.nil?
141
+ options.reverse_merge!({:leading_zeros => true, :ampm => false})
142
+ leading_zeros = options.delete(:leading_zeros)
143
+ value = leading_zeros ? sprintf("%02d", value) : value
144
+ text = options[:ampm] ? AMPM_TRANSLATION[value] : value
145
+ else
146
+ ""
147
+ end
148
+ end
149
+
150
+ end
151
+
152
+ class InstanceTag #:nodoc:
153
+ def to_date_text_field_tag(options = {}, html_options = {})
154
+ datetime_selector(options, html_options).text_field_date.html_safe
155
+ end
156
+
157
+ def to_time_text_field_tag(options = {}, html_options = {})
158
+ datetime_selector(options, html_options).text_field_time.html_safe
159
+ end
160
+ end
161
+
162
+ autoload :TextFieldDateHelper
163
+ include TextFieldDateHelper
164
+
165
+ end
166
+ end
@@ -0,0 +1,10 @@
1
+ module FormtasticBootstrap
2
+ module Actions
3
+ extend ActiveSupport::Autoload
4
+
5
+ autoload :Base, 'formtastic-bootstrap/actions/base'
6
+ autoload :InputAction, 'formtastic-bootstrap/actions/input_action'
7
+ autoload :LinkAction, 'formtastic-bootstrap/actions/link_action'
8
+ autoload :ButtonAction, 'formtastic-bootstrap/actions/button_action'
9
+ end
10
+ end
@@ -0,0 +1,22 @@
1
+ module FormtasticBootstrap
2
+ module Actions
3
+ module Base
4
+
5
+ # Bootstrap doesn't have wrappers.
6
+ def wrapper(&block)
7
+ # TODO Detect if user passed wrapper_html_options and issue
8
+ # a warning that they're ignored. (See the original in
9
+ # Formtastic.)
10
+ template.capture(&block)
11
+ end
12
+
13
+ def default_button_html
14
+ {
15
+ :accesskey => accesskey,
16
+ :class => "btn"
17
+ }
18
+ end
19
+
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,13 @@
1
+ # <form...>
2
+ # <fieldset class="form-actions">
3
+ # <button class="btn" type="reset" value="Reset">
4
+ # <button class="btn" type="submit" value="Create Post">
5
+ # </fieldset>
6
+ # </form>
7
+ module FormtasticBootstrap
8
+ module Actions
9
+ class ButtonAction < Formtastic::Actions::ButtonAction
10
+ include Base
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,13 @@
1
+ # <form...>
2
+ # <fieldset class="form-actions">
3
+ # <input class="btn" type="reset" value="Reset">
4
+ # <input class="btn" type="submit" value="Create Post">
5
+ # </fieldset>
6
+ # </form>
7
+ module FormtasticBootstrap
8
+ module Actions
9
+ class InputAction < Formtastic::Actions::InputAction
10
+ include Base
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,12 @@
1
+ # <form...>
2
+ # <fieldset class="form-actions">
3
+ # <a class="btn" href="">Link</a>
4
+ # </fieldset>
5
+ # </form>
6
+ module FormtasticBootstrap
7
+ module Actions
8
+ class LinkAction < Formtastic::Actions::LinkAction
9
+ include Base
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,4 @@
1
+ module FormtasticBootstrap
2
+ class Engine < ::Rails::Engine
3
+ end
4
+ end
@@ -0,0 +1,41 @@
1
+ module FormtasticBootstrap
2
+
3
+ class FormBuilder < Formtastic::FormBuilder
4
+
5
+ configure :default_inline_error_class, 'help-inline'
6
+ configure :default_block_error_class, 'help-block'
7
+ configure :default_inline_hint_class, 'help-inline'
8
+ configure :default_block_hint_class, 'help-block'
9
+
10
+ def self.default_error_class
11
+ # self.default_inline_error_class
12
+ raise
13
+ end
14
+
15
+ def self.default_error_class=(error_class)
16
+ # self.default_inline_error_class = error_class
17
+ # self.default_block_error_class = error_class
18
+ raise
19
+ end
20
+
21
+ def self.default_hint_class
22
+ # self.default_inline_hint_class
23
+ raise
24
+ end
25
+
26
+ def self.default_hint_class=(hint_class)
27
+ # self.default_inline_hint_class = hint_class
28
+ # self.default_block_hint_class = hint_class
29
+ raise
30
+ end
31
+
32
+ include FormtasticBootstrap::Helpers::InputHelper # Revisit
33
+ include FormtasticBootstrap::Helpers::InputsHelper
34
+ include FormtasticBootstrap::Helpers::ErrorsHelper
35
+ include FormtasticBootstrap::Helpers::ActionHelper
36
+ include FormtasticBootstrap::Helpers::ActionsHelper
37
+ # include Formtastic::Helpers::ErrorsHelper
38
+
39
+ end
40
+
41
+ end
@@ -0,0 +1,17 @@
1
+ module FormtasticBootstrap
2
+ module Helpers
3
+
4
+ autoload :ActionHelper, 'formtastic-bootstrap/helpers/action_helper'
5
+ autoload :ActionsHelper, 'formtastic-bootstrap/helpers/actions_helper'
6
+ autoload :ErrorsHelper, 'formtastic-bootstrap/helpers/errors_helper'
7
+ autoload :FieldsetWrapper, 'formtastic-bootstrap/helpers/fieldset_wrapper'
8
+ # autoload :FileColumnDetection, 'formtastic/helpers/file_column_detection'
9
+ # autoload :FormHelper, 'formtastic/helpers/form_helper'
10
+ autoload :InputHelper, 'formtastic-bootstrap/helpers/input_helper'
11
+ autoload :InputsHelper, 'formtastic-bootstrap/helpers/inputs_helper'
12
+ # autoload :LabelHelper, 'formtastic/helpers/label_helper'
13
+ # autoload :SemanticFormHelper, 'formtastic/helpers/semantic_form_helper'
14
+ # autoload :Reflection, 'formtastic/helpers/reflection'
15
+ end
16
+ end
17
+
@@ -0,0 +1,12 @@
1
+ module FormtasticBootstrap
2
+ module Helpers
3
+ module ActionHelper
4
+
5
+ # :as => :button # => FormtasticBootstrap::Actions::ButtonAction
6
+ def standard_action_class_name(as)
7
+ "FormtasticBootstrap::Actions::#{as.to_s.camelize}Action"
8
+ end
9
+
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,24 @@
1
+ module FormtasticBootstrap
2
+ module Helpers
3
+ module ActionsHelper
4
+
5
+ include Formtastic::Helpers::ActionsHelper
6
+ include FormtasticBootstrap::Helpers::FieldsetWrapper
7
+
8
+ def actions(*args, &block)
9
+
10
+ html_options = args.extract_options!
11
+ html_options[:class] ||= "form-actions"
12
+
13
+ if block_given?
14
+ field_set_and_list_wrapping(html_options, &block)
15
+ else
16
+ args = default_actions if args.empty?
17
+ contents = args.map { |action_name| action(action_name) }
18
+ field_set_and_list_wrapping(html_options, contents)
19
+ end
20
+ end
21
+
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,70 @@
1
+ module FormtasticBootstrap
2
+ module Helpers
3
+ module ErrorsHelper
4
+ include Formtastic::Helpers::FileColumnDetection
5
+ include Formtastic::Helpers::Reflection
6
+ include Formtastic::LocalizedString
7
+
8
+ INLINE_ERROR_TYPES = [:sentence, :list, :first]
9
+
10
+ # Generates a bootstrap error alert element containing
11
+ # an unordered list of error messages on the base object and optionally for a given
12
+ # set of named attribute. This is idea for rendering a block of error messages at the top of
13
+ # the form for hidden/special/virtual attributes (the Paperclip Rails plugin does this), or
14
+ # errors on the base model.
15
+ #
16
+ # A hash can be used as the last set of arguments to pass HTML attributes to the `<ul>`
17
+ # wrapper.
18
+ #
19
+ # @example A list of errors on the base model
20
+ # <%= semantic_form_for ... %>
21
+ # <%= f.semantic_errors %>
22
+ # ...
23
+ # <% end %>
24
+ #
25
+ # @example A list of errors on the base and named attributes
26
+ # <%= semantic_form_for ... %>
27
+ # <%= f.semantic_errors :something_special %>
28
+ # ...
29
+ # <% end %>
30
+ #
31
+ # @example A list of errors on the base model, with custom HTML attributes
32
+ # <%= semantic_form_for ... %>
33
+ # <%= f.semantic_errors :class => "awesome" %>
34
+ # ...
35
+ # <% end %>
36
+ #
37
+ # @example A list of errors on the base model and named attributes, with custom HTML attributes
38
+ # <%= semantic_form_for ... %>
39
+ # <%= f.semantic_errors :something_special, :something_else, :class => "awesome", :onclick => "Awesome();" %>
40
+ # ...
41
+ # <% end %>
42
+ def semantic_errors(*args)
43
+ html_options = args.extract_options!
44
+ args = args - [:base]
45
+ full_errors = args.inject([]) do |array, method|
46
+ attribute = localized_string(method, method.to_sym, :label) || humanized_attribute_name(method)
47
+ errors = Array(@object.errors[method.to_sym]).to_sentence
48
+ errors.present? ? array << [attribute, errors].join(" ") : array ||= []
49
+ end
50
+ full_errors << @object.errors[:base]
51
+ full_errors.flatten!
52
+ full_errors.compact!
53
+ return nil if full_errors.blank?
54
+
55
+ if html_options[:class].blank?
56
+ html_options[:class] = "alert alert-error"
57
+ else
58
+ html_options[:class] = "alert alert-error " + html_options[:class]
59
+ end
60
+
61
+ template.content_tag(:div, html_options) do
62
+ template.content_tag(:button, "&times;".html_safe, :class => "close", "data-dismiss" => "alert") +
63
+ template.content_tag(:ul, {class: "error-list"}) do
64
+ Formtastic::Util.html_safe(full_errors.map { |error| template.content_tag(:li, Formtastic::Util.html_safe(error)) }.join)
65
+ end
66
+ end
67
+ end
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,35 @@
1
+ module FormtasticBootstrap
2
+ module Helpers
3
+ module FieldsetWrapper
4
+
5
+ include Formtastic::Helpers::FieldsetWrapper
6
+
7
+ protected
8
+
9
+ def field_set_and_list_wrapping(*args, &block) #:nodoc:
10
+ contents = args.last.is_a?(::Hash) ? '' : args.pop.flatten
11
+ html_options = args.extract_options!
12
+
13
+ if block_given?
14
+ contents = if template.respond_to?(:is_haml?) && template.is_haml?
15
+ template.capture_haml(&block)
16
+ else
17
+ template.capture(&block)
18
+ end
19
+ end
20
+
21
+ # Ruby 1.9: String#to_s behavior changed, need to make an explicit join.
22
+ contents = contents.join if contents.respond_to?(:join)
23
+
24
+ legend = field_set_legend(html_options)
25
+ fieldset = template.content_tag(:fieldset,
26
+ Formtastic::Util.html_safe(legend) << Formtastic::Util.html_safe(contents),
27
+ html_options.except(:builder, :parent, :name)
28
+ )
29
+
30
+ fieldset
31
+ end
32
+
33
+ end
34
+ end
35
+ end