formtastic_rebootstrap 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (62) hide show
  1. checksums.yaml +7 -0
  2. data/.document +5 -0
  3. data/LICENSE.txt +20 -0
  4. data/README.md +200 -0
  5. data/VERSION +1 -0
  6. data/lib/action_view/helpers/text_field_date_helper.rb +166 -0
  7. data/lib/formtastic_rebootstrap/actions/base.rb +27 -0
  8. data/lib/formtastic_rebootstrap/actions/button_action.rb +13 -0
  9. data/lib/formtastic_rebootstrap/actions/input_action.rb +13 -0
  10. data/lib/formtastic_rebootstrap/actions/link_action.rb +12 -0
  11. data/lib/formtastic_rebootstrap/actions.rb +10 -0
  12. data/lib/formtastic_rebootstrap/engine.rb +4 -0
  13. data/lib/formtastic_rebootstrap/form_builder.rb +45 -0
  14. data/lib/formtastic_rebootstrap/helpers/actions_helper.rb +24 -0
  15. data/lib/formtastic_rebootstrap/helpers/errors_helper.rb +70 -0
  16. data/lib/formtastic_rebootstrap/helpers/fieldset_wrapper.rb +35 -0
  17. data/lib/formtastic_rebootstrap/helpers/inputs_helper.rb +34 -0
  18. data/lib/formtastic_rebootstrap/helpers.rb +19 -0
  19. data/lib/formtastic_rebootstrap/inputs/base/choices.rb +20 -0
  20. data/lib/formtastic_rebootstrap/inputs/base/collections.rb +9 -0
  21. data/lib/formtastic_rebootstrap/inputs/base/datetime_pickerish.rb +10 -0
  22. data/lib/formtastic_rebootstrap/inputs/base/errors.rb +48 -0
  23. data/lib/formtastic_rebootstrap/inputs/base/hints.rb +27 -0
  24. data/lib/formtastic_rebootstrap/inputs/base/html.rb +36 -0
  25. data/lib/formtastic_rebootstrap/inputs/base/labelling.rb +40 -0
  26. data/lib/formtastic_rebootstrap/inputs/base/numeric.rb +9 -0
  27. data/lib/formtastic_rebootstrap/inputs/base/placeholder.rb +9 -0
  28. data/lib/formtastic_rebootstrap/inputs/base/stringish.rb +17 -0
  29. data/lib/formtastic_rebootstrap/inputs/base/timeish.rb +71 -0
  30. data/lib/formtastic_rebootstrap/inputs/base/wrapping.rb +83 -0
  31. data/lib/formtastic_rebootstrap/inputs/base.rb +45 -0
  32. data/lib/formtastic_rebootstrap/inputs/boolean_input.rb +51 -0
  33. data/lib/formtastic_rebootstrap/inputs/check_boxes_input.rb +41 -0
  34. data/lib/formtastic_rebootstrap/inputs/color_input.rb +15 -0
  35. data/lib/formtastic_rebootstrap/inputs/country_input.rb +14 -0
  36. data/lib/formtastic_rebootstrap/inputs/date_input.rb +10 -0
  37. data/lib/formtastic_rebootstrap/inputs/date_picker_input.rb +9 -0
  38. data/lib/formtastic_rebootstrap/inputs/date_select_input.rb +14 -0
  39. data/lib/formtastic_rebootstrap/inputs/datetime_input.rb +10 -0
  40. data/lib/formtastic_rebootstrap/inputs/datetime_picker_input.rb +9 -0
  41. data/lib/formtastic_rebootstrap/inputs/datetime_select_input.rb +8 -0
  42. data/lib/formtastic_rebootstrap/inputs/email_input.rb +15 -0
  43. data/lib/formtastic_rebootstrap/inputs/file_input.rb +14 -0
  44. data/lib/formtastic_rebootstrap/inputs/hidden_input.rb +12 -0
  45. data/lib/formtastic_rebootstrap/inputs/number_input.rb +15 -0
  46. data/lib/formtastic_rebootstrap/inputs/password_input.rb +15 -0
  47. data/lib/formtastic_rebootstrap/inputs/phone_input.rb +15 -0
  48. data/lib/formtastic_rebootstrap/inputs/radio_input.rb +47 -0
  49. data/lib/formtastic_rebootstrap/inputs/range_input.rb +15 -0
  50. data/lib/formtastic_rebootstrap/inputs/search_input.rb +15 -0
  51. data/lib/formtastic_rebootstrap/inputs/select_input.rb +16 -0
  52. data/lib/formtastic_rebootstrap/inputs/string_input.rb +8 -0
  53. data/lib/formtastic_rebootstrap/inputs/text_input.rb +14 -0
  54. data/lib/formtastic_rebootstrap/inputs/time_input.rb +10 -0
  55. data/lib/formtastic_rebootstrap/inputs/time_select_input.rb +14 -0
  56. data/lib/formtastic_rebootstrap/inputs/time_zone_input.rb +14 -0
  57. data/lib/formtastic_rebootstrap/inputs/url_input.rb +14 -0
  58. data/lib/formtastic_rebootstrap/inputs.rb +38 -0
  59. data/lib/formtastic_rebootstrap/version.rb +3 -0
  60. data/lib/formtastic_rebootstrap.rb +23 -0
  61. data/vendor/assets/stylesheets/formtastic_rebootstrap.css +7 -0
  62. metadata +218 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 4257feb469a591ff347eb41048290169545d08cc
4
+ data.tar.gz: ce32a54cad31512eac1f11291a4b0f378b8660c4
5
+ SHA512:
6
+ metadata.gz: 48bed131e59562159107d4bd5710db9d07c24dff4c4b22cdc831d8063d41f51f602f88aae15e9c9f736fc97348120b5b5265358c804bfe88209b0e811ea12086
7
+ data.tar.gz: cc00dd0baa5cf519ca45d1b13f97fe0f517777b7e96261d712914f63ea2c375fa44d9f30defe6d5decaaa80a86162519d007781bb727e65b3430d8fecd99f037
data/.document ADDED
@@ -0,0 +1,5 @@
1
+ lib/**/*.rb
2
+ bin/*
3
+ -
4
+ features/**/*.feature
5
+ LICENSE.txt
data/LICENSE.txt ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2011 Matthew Bellantoni
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,200 @@
1
+ # Formtastic Bootstrap
2
+
3
+ A [Formtastic](https://github.com/justinfrench/formtastic) form builder that creates markup suitable for the [Twitter Bootstrap](http://twitter.github.com/bootstrap/) framework. In theory, it should just work. Two great tastes in one!
4
+
5
+ You can follow [FormBoot on twitter](http://twitter.com/FormBoot) for update announcements and other relevant info.
6
+
7
+ ## Getting Started
8
+
9
+ ### Dependencies
10
+
11
+ This version of Formtastic Bootstrap should support the following:
12
+
13
+ *Bootstrap*
14
+
15
+ * Bootstrap 3.x
16
+
17
+ *Rails*
18
+
19
+ * Rails 3.2.x
20
+ * Rails 4.x.x
21
+
22
+ *Formtastic*
23
+
24
+ * Formtastic 2.2.x
25
+ * Formtastic 2.3.x
26
+
27
+ *Ruby*
28
+
29
+ * 1.9.2
30
+ * 1.9.3
31
+ * 2.x.x
32
+
33
+ #### Installation
34
+
35
+ Install the gem with
36
+
37
+ gem install formtastic_rebootstrap
38
+
39
+ Or add it to your Gemfile:
40
+
41
+ gem 'formtastic_rebootstrap'
42
+
43
+ And install it with <tt>bundle install</tt>.
44
+
45
+ #### Configuration
46
+
47
+ Add the following line to your Formtastic initialization file:
48
+
49
+ # config/initializers/formtastic.rb
50
+ Formtastic::Helpers::FormHelper.builder = FormtasticRebootstrap::FormBuilder
51
+
52
+ Add the following line to the top of your <tt>application.css</tt> file:
53
+
54
+ # app/assets/stylesheets/application.css
55
+ *= require formtastic_rebootstrap
56
+
57
+ Make sure you've already downloaded and installed Formtastic! Do *not* however require formtastic in your `application.css` file or you will have many bootstrap/formtastic_rebootstrap styles overwritten.
58
+
59
+
60
+ ## Formtastic vs. Formtastic Bootstrap
61
+
62
+ THIS SECTION IS OUT OF DATE.
63
+
64
+ ### Overview
65
+
66
+ In general, Formtastic creates very verbose HTML whereas
67
+ Bootstrap expects (ever) simpler HTML. Every attempt has been
68
+ made to generate the HTML expected by Bootstrap while still
69
+ generating the rich HTML provided by Formtastic. When there
70
+ is a conflict, Bootstrap wins.
71
+
72
+
73
+ ### Major Difference in Behavior
74
+
75
+ THIS SECTION IS OUT OF DATE
76
+
77
+ * 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.)
78
+ * Formtastic Bootstrap puts the <tt>input</tt> label in a different place because it makes Bootstrap behave correctly.
79
+ * 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:
80
+ * <tt>:date</tt> et al are tagged with the <tt>stringish</tt> class.
81
+ * Hidden fields are not generated.
82
+ * Fieldsets are simply nested.
83
+ * <tt>f.buttons :name</tt> is not supported. This generates a <tt>fieldset</tt> and <tt>legend</tt> tag which will cause the wrong thing to happen in Bootstrap.
84
+
85
+ Bootstrap is somewhat incomplete, and in a few cases an inference needed to be drawn to determine a course of action. If you disagree with any of these choices, feel free to let me know.
86
+
87
+ The gem also provides some "shim" CSS where Bootstrap is missing styles provided Formtastic.
88
+
89
+ ### Other
90
+
91
+ A lot of the code (especially the test suite) was copied
92
+ over from Formtastic and then beaten into submission. I'm
93
+ sure you'll find some ugliness in there. In general, I
94
+ mimicked the Formtastic code structure as much as possible.
95
+
96
+ In particular:
97
+
98
+ * Bootstrap doesn't say anything about nested <tt>formfields</tt>.
99
+ * Bootstrap doesn't explicitly lay out a <tt>:boolean</tt> control.
100
+ * Bootstrap doesn't explicitly say everything that needs to be said about <tt>:datetime</tt>, <tt>:date</tt>, and <tt>:time</tt>.
101
+ * I've inferred what <tt>:datetime</tt> should do since there's not example of a single <tt>:datetime</tt>.
102
+ * In some places the markup is tortuous (e.g. <tt>:boolean</tt>.) Hopefully as Bootstrap evolves these can get simplified!
103
+ * Bootstrap uses different HTML classes for sentence-based inline/block error messages.
104
+
105
+ ### What's Missing
106
+
107
+ Contributions are welcome!
108
+
109
+ * Formtastic's <tt>:country</tt> has not yet been implemented.
110
+ * I'm sure there's lots ...
111
+
112
+ ## Usage
113
+
114
+ In general, the usage should be identical to Formtastic's. Some changes have been introduced in order to support Bootstrap-specific controls.
115
+
116
+ ### Bootstrap-specific Controls
117
+
118
+ #### Prepended Text
119
+ To create a Prepended Text field, use the ```:prepend``` option. This works on any text field input type, like ```:url```, ```:search```, and of course ```:string```
120
+
121
+ <%= semantic_form_for @user do |f| %>
122
+ <%= f.inputs do %>
123
+ <%= f.input :handle, :prepend => '@' %>
124
+ <% end %>
125
+ <% end %>
126
+
127
+ #### Appended Text
128
+ To create an Appended Text field, use the ```:append``` option. This works on any text field input type, like ```:url```, ```:search```, and of course ```:string```
129
+
130
+ <%= semantic_form_for @user do |f| %>
131
+ <%= f.inputs do %>
132
+ <%= f.input :handle, :append => '%' %>
133
+ <% end %>
134
+ <% end %>
135
+
136
+ #### Appended Content
137
+ To add appended elements that are not contained within an add-on span
138
+ use the ```:append_content``` or ```:prepend_content``` option.
139
+
140
+ <%= semantic_form_for @user do |f| %>
141
+ <%= f.inputs do %>
142
+ <%= f.input :handle, :append_content => content_tag(:a, "Click Here", :class => 'btn') %>
143
+ <% end %>
144
+ <% end %>
145
+
146
+ ## Contributing
147
+
148
+ ### Contributors
149
+
150
+ A big thank you [to all contributors](https://github.com/mjbellantoni/formtastic_rebootstrap/contributors)!
151
+
152
+ ### Submitting Issues
153
+
154
+ If you're filing a bug, thank you! Secondly, in the report please include:
155
+
156
+ * The version of Formtastic you're using.
157
+ * The version of Twitter Bootstrap you're using.
158
+ * The code for your form.
159
+ * Anything else you think will help!
160
+
161
+ ### Source Contributions
162
+
163
+ Source contributions are very welcome! Most of the recent work on this package has been done by the community.
164
+
165
+ * Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet
166
+ * Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it
167
+ * Fork the project
168
+ * Start a feature/bugfix branch
169
+ * Commit and push until you are happy with your contribution
170
+ * Make sure to add tests for it and to run the test suite. **If you don't have tests, I won't accept the pull.** If you need help with this, please ask.
171
+ * Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
172
+
173
+
174
+ ### To Do
175
+
176
+ * Field Types
177
+ * Basic Formtastic
178
+ * :country
179
+ * :time_zone
180
+ * Fancy Bootstrap Fields
181
+ * Date Range
182
+ * Prepend Checkbox
183
+ * Appended Checkbox
184
+ * :datetime, :date, :time
185
+ * As rich functionally as their Rails counterparts.
186
+ * Extract into a standalone gem.
187
+ * Tests
188
+ * Fill in all pending specs
189
+ * Refactor
190
+ * More -- See if I'm making sure the Bootstrap classes are present.
191
+ * Documentation
192
+ * Refactor :boolean to use common "choices" code (if possible.) (Not sure it is.)
193
+ * Boostrap
194
+ * Why 'help-inline' and 'help-block' when they could have done p.help and span.help?
195
+
196
+
197
+ ## Copyright
198
+
199
+ Copyright (c) 2013-2015 Matthew Bellantoni. See LICENSE.txt for further details.
200
+
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.0.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,27 @@
1
+ module FormtasticRebootstrap
2
+ module Actions
3
+ module Base
4
+
5
+ # Bootstrap doesn't have wrappers.
6
+ def wrapper(&block)
7
+ template.capture(&block)
8
+ end
9
+
10
+ # Default button class
11
+ def default_wrapper_classes
12
+ ["btn"]
13
+ end
14
+
15
+ # :wrapper_html member :class is prefixed with btn
16
+ # :button_html member :class is all encompassing
17
+ def default_button_html
18
+ {
19
+ :accesskey => accesskey,
20
+ :class => wrapper_class.strip,
21
+ :id => wrapper_id
22
+ }
23
+ end
24
+
25
+ end
26
+ end
27
+ 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 FormtasticRebootstrap
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 FormtasticRebootstrap
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 FormtasticRebootstrap
7
+ module Actions
8
+ class LinkAction < Formtastic::Actions::LinkAction
9
+ include Base
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,10 @@
1
+ module FormtasticRebootstrap
2
+ module Actions
3
+ extend ActiveSupport::Autoload
4
+
5
+ autoload :Base, 'formtastic_rebootstrap/actions/base'
6
+ autoload :InputAction, 'formtastic_rebootstrap/actions/input_action'
7
+ autoload :LinkAction, 'formtastic_rebootstrap/actions/link_action'
8
+ autoload :ButtonAction, 'formtastic_rebootstrap/actions/button_action'
9
+ end
10
+ end
@@ -0,0 +1,4 @@
1
+ module FormtasticRebootstrap
2
+ class Engine < ::Rails::Engine
3
+ end
4
+ end
@@ -0,0 +1,45 @@
1
+ module FormtasticRebootstrap
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
+ self.input_namespaces = [::Object, ::FormtasticRebootstrap::Inputs, ::Formtastic::Inputs]
11
+ self.action_namespaces = [::Object, ::FormtasticRebootstrap::Actions, ::Formtastic::Actions]
12
+
13
+ # TODO: remove both class finders after formtastic 4 (where it will be default)
14
+ self.input_class_finder = ::Formtastic::InputClassFinder
15
+ self.action_class_finder = ::Formtastic::ActionClassFinder
16
+
17
+ def self.default_error_class
18
+ # self.default_inline_error_class
19
+ raise
20
+ end
21
+
22
+ def self.default_error_class=(error_class)
23
+ # self.default_inline_error_class = error_class
24
+ # self.default_block_error_class = error_class
25
+ raise
26
+ end
27
+
28
+ def self.default_hint_class
29
+ # self.default_inline_hint_class
30
+ raise
31
+ end
32
+
33
+ def self.default_hint_class=(hint_class)
34
+ # self.default_inline_hint_class = hint_class
35
+ # self.default_block_hint_class = hint_class
36
+ raise
37
+ end
38
+
39
+ include FormtasticRebootstrap::Helpers::InputsHelper
40
+ include FormtasticRebootstrap::Helpers::ErrorsHelper
41
+ include FormtasticRebootstrap::Helpers::ActionsHelper
42
+
43
+ end
44
+
45
+ end
@@ -0,0 +1,24 @@
1
+ module FormtasticRebootstrap
2
+ module Helpers
3
+ module ActionsHelper
4
+
5
+ include Formtastic::Helpers::ActionsHelper
6
+ include FormtasticRebootstrap::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 FormtasticRebootstrap
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-danger"
57
+ else
58
+ html_options[:class] = "alert alert-danger " + html_options[:class]
59
+ end
60
+
61
+ template.content_tag(:div, html_options) do
62
+ template.content_tag(:a, "&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 FormtasticRebootstrap
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