formtastic_rebootstrap 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.document +5 -0
- data/LICENSE.txt +20 -0
- data/README.md +200 -0
- data/VERSION +1 -0
- data/lib/action_view/helpers/text_field_date_helper.rb +166 -0
- data/lib/formtastic_rebootstrap/actions/base.rb +27 -0
- data/lib/formtastic_rebootstrap/actions/button_action.rb +13 -0
- data/lib/formtastic_rebootstrap/actions/input_action.rb +13 -0
- data/lib/formtastic_rebootstrap/actions/link_action.rb +12 -0
- data/lib/formtastic_rebootstrap/actions.rb +10 -0
- data/lib/formtastic_rebootstrap/engine.rb +4 -0
- data/lib/formtastic_rebootstrap/form_builder.rb +45 -0
- data/lib/formtastic_rebootstrap/helpers/actions_helper.rb +24 -0
- data/lib/formtastic_rebootstrap/helpers/errors_helper.rb +70 -0
- data/lib/formtastic_rebootstrap/helpers/fieldset_wrapper.rb +35 -0
- data/lib/formtastic_rebootstrap/helpers/inputs_helper.rb +34 -0
- data/lib/formtastic_rebootstrap/helpers.rb +19 -0
- data/lib/formtastic_rebootstrap/inputs/base/choices.rb +20 -0
- data/lib/formtastic_rebootstrap/inputs/base/collections.rb +9 -0
- data/lib/formtastic_rebootstrap/inputs/base/datetime_pickerish.rb +10 -0
- data/lib/formtastic_rebootstrap/inputs/base/errors.rb +48 -0
- data/lib/formtastic_rebootstrap/inputs/base/hints.rb +27 -0
- data/lib/formtastic_rebootstrap/inputs/base/html.rb +36 -0
- data/lib/formtastic_rebootstrap/inputs/base/labelling.rb +40 -0
- data/lib/formtastic_rebootstrap/inputs/base/numeric.rb +9 -0
- data/lib/formtastic_rebootstrap/inputs/base/placeholder.rb +9 -0
- data/lib/formtastic_rebootstrap/inputs/base/stringish.rb +17 -0
- data/lib/formtastic_rebootstrap/inputs/base/timeish.rb +71 -0
- data/lib/formtastic_rebootstrap/inputs/base/wrapping.rb +83 -0
- data/lib/formtastic_rebootstrap/inputs/base.rb +45 -0
- data/lib/formtastic_rebootstrap/inputs/boolean_input.rb +51 -0
- data/lib/formtastic_rebootstrap/inputs/check_boxes_input.rb +41 -0
- data/lib/formtastic_rebootstrap/inputs/color_input.rb +15 -0
- data/lib/formtastic_rebootstrap/inputs/country_input.rb +14 -0
- data/lib/formtastic_rebootstrap/inputs/date_input.rb +10 -0
- data/lib/formtastic_rebootstrap/inputs/date_picker_input.rb +9 -0
- data/lib/formtastic_rebootstrap/inputs/date_select_input.rb +14 -0
- data/lib/formtastic_rebootstrap/inputs/datetime_input.rb +10 -0
- data/lib/formtastic_rebootstrap/inputs/datetime_picker_input.rb +9 -0
- data/lib/formtastic_rebootstrap/inputs/datetime_select_input.rb +8 -0
- data/lib/formtastic_rebootstrap/inputs/email_input.rb +15 -0
- data/lib/formtastic_rebootstrap/inputs/file_input.rb +14 -0
- data/lib/formtastic_rebootstrap/inputs/hidden_input.rb +12 -0
- data/lib/formtastic_rebootstrap/inputs/number_input.rb +15 -0
- data/lib/formtastic_rebootstrap/inputs/password_input.rb +15 -0
- data/lib/formtastic_rebootstrap/inputs/phone_input.rb +15 -0
- data/lib/formtastic_rebootstrap/inputs/radio_input.rb +47 -0
- data/lib/formtastic_rebootstrap/inputs/range_input.rb +15 -0
- data/lib/formtastic_rebootstrap/inputs/search_input.rb +15 -0
- data/lib/formtastic_rebootstrap/inputs/select_input.rb +16 -0
- data/lib/formtastic_rebootstrap/inputs/string_input.rb +8 -0
- data/lib/formtastic_rebootstrap/inputs/text_input.rb +14 -0
- data/lib/formtastic_rebootstrap/inputs/time_input.rb +10 -0
- data/lib/formtastic_rebootstrap/inputs/time_select_input.rb +14 -0
- data/lib/formtastic_rebootstrap/inputs/time_zone_input.rb +14 -0
- data/lib/formtastic_rebootstrap/inputs/url_input.rb +14 -0
- data/lib/formtastic_rebootstrap/inputs.rb +38 -0
- data/lib/formtastic_rebootstrap/version.rb +3 -0
- data/lib/formtastic_rebootstrap.rb +23 -0
- data/vendor/assets/stylesheets/formtastic_rebootstrap.css +7 -0
- 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
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,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,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, "×".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
|