formtastic 1.2.4 → 3.1.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +17 -0
- data/.rspec +2 -0
- data/.travis.yml +46 -0
- data/.yardopts +1 -0
- data/Appraisals +43 -0
- data/CHANGELOG +54 -0
- data/DEPRECATIONS +52 -0
- data/Gemfile +3 -0
- data/README.md +629 -0
- data/RELEASE_PROCESS +6 -0
- data/Rakefile +35 -0
- data/app/assets/stylesheets/formtastic.css +289 -0
- data/app/assets/stylesheets/formtastic_ie6.css +33 -0
- data/app/assets/stylesheets/formtastic_ie7.css +23 -0
- data/formtastic.gemspec +42 -0
- data/gemfiles/rails_3.2.gemfile +9 -0
- data/gemfiles/rails_4.0.4.gemfile +8 -0
- data/gemfiles/rails_4.1.gemfile +8 -0
- data/gemfiles/rails_4.2.gemfile +8 -0
- data/gemfiles/rails_4.gemfile +8 -0
- data/gemfiles/rails_5.0.gemfile +8 -0
- data/gemfiles/rails_edge.gemfile +15 -0
- data/lib/formtastic.rb +40 -1945
- data/lib/formtastic/action_class_finder.rb +18 -0
- data/lib/formtastic/actions.rb +11 -0
- data/lib/formtastic/actions/base.rb +156 -0
- data/lib/formtastic/actions/button_action.rb +67 -0
- data/lib/formtastic/actions/buttonish.rb +17 -0
- data/lib/formtastic/actions/input_action.rb +70 -0
- data/lib/formtastic/actions/link_action.rb +88 -0
- data/lib/formtastic/deprecation.rb +42 -0
- data/lib/formtastic/engine.rb +11 -0
- data/lib/formtastic/form_builder.rb +124 -0
- data/lib/formtastic/helpers.rb +16 -0
- data/lib/formtastic/helpers/action_helper.rb +162 -0
- data/lib/formtastic/helpers/actions_helper.rb +168 -0
- data/lib/formtastic/helpers/enum.rb +13 -0
- data/lib/formtastic/helpers/errors_helper.rb +81 -0
- data/lib/formtastic/helpers/fieldset_wrapper.rb +80 -0
- data/lib/formtastic/helpers/file_column_detection.rb +16 -0
- data/lib/formtastic/helpers/form_helper.rb +203 -0
- data/lib/formtastic/helpers/input_helper.rb +407 -0
- data/lib/formtastic/helpers/inputs_helper.rb +411 -0
- data/lib/formtastic/helpers/reflection.rb +37 -0
- data/lib/formtastic/html_attributes.rb +32 -0
- data/lib/formtastic/i18n.rb +4 -2
- data/lib/formtastic/input_class_finder.rb +18 -0
- data/lib/formtastic/inputs.rb +39 -0
- data/lib/formtastic/inputs/base.rb +76 -0
- data/lib/formtastic/inputs/base/associations.rb +31 -0
- data/lib/formtastic/inputs/base/choices.rb +108 -0
- data/lib/formtastic/inputs/base/collections.rb +159 -0
- data/lib/formtastic/inputs/base/database.rb +22 -0
- data/lib/formtastic/inputs/base/datetime_pickerish.rb +85 -0
- data/lib/formtastic/inputs/base/errors.rb +58 -0
- data/lib/formtastic/inputs/base/fileish.rb +23 -0
- data/lib/formtastic/inputs/base/hints.rb +31 -0
- data/lib/formtastic/inputs/base/html.rb +53 -0
- data/lib/formtastic/inputs/base/labelling.rb +52 -0
- data/lib/formtastic/inputs/base/naming.rb +42 -0
- data/lib/formtastic/inputs/base/numeric.rb +50 -0
- data/lib/formtastic/inputs/base/options.rb +17 -0
- data/lib/formtastic/inputs/base/placeholder.rb +17 -0
- data/lib/formtastic/inputs/base/stringish.rb +38 -0
- data/lib/formtastic/inputs/base/timeish.rb +241 -0
- data/lib/formtastic/inputs/base/validations.rb +215 -0
- data/lib/formtastic/inputs/base/wrapping.rb +50 -0
- data/lib/formtastic/inputs/boolean_input.rb +118 -0
- data/lib/formtastic/inputs/check_boxes_input.rb +197 -0
- data/lib/formtastic/inputs/color_input.rb +42 -0
- data/lib/formtastic/inputs/country_input.rb +86 -0
- data/lib/formtastic/inputs/datalist_input.rb +41 -0
- data/lib/formtastic/inputs/date_picker_input.rb +93 -0
- data/lib/formtastic/inputs/date_select_input.rb +34 -0
- data/lib/formtastic/inputs/datetime_picker_input.rb +103 -0
- data/lib/formtastic/inputs/datetime_select_input.rb +12 -0
- data/lib/formtastic/inputs/email_input.rb +41 -0
- data/lib/formtastic/inputs/file_input.rb +42 -0
- data/lib/formtastic/inputs/hidden_input.rb +62 -0
- data/lib/formtastic/inputs/number_input.rb +88 -0
- data/lib/formtastic/inputs/password_input.rb +41 -0
- data/lib/formtastic/inputs/phone_input.rb +42 -0
- data/lib/formtastic/inputs/radio_input.rb +163 -0
- data/lib/formtastic/inputs/range_input.rb +95 -0
- data/lib/formtastic/inputs/search_input.rb +41 -0
- data/lib/formtastic/inputs/select_input.rb +235 -0
- data/lib/formtastic/inputs/string_input.rb +36 -0
- data/lib/formtastic/inputs/text_input.rb +48 -0
- data/lib/formtastic/inputs/time_picker_input.rb +99 -0
- data/lib/formtastic/inputs/time_select_input.rb +38 -0
- data/lib/formtastic/inputs/time_zone_input.rb +58 -0
- data/lib/formtastic/inputs/url_input.rb +41 -0
- data/lib/formtastic/localized_string.rb +17 -0
- data/lib/formtastic/localizer.rb +152 -0
- data/lib/formtastic/namespaced_class_finder.rb +99 -0
- data/lib/formtastic/util.rb +35 -16
- data/lib/formtastic/version.rb +3 -0
- data/lib/generators/formtastic/form/form_generator.rb +64 -37
- data/lib/generators/formtastic/input/input_generator.rb +46 -0
- data/lib/generators/formtastic/install/install_generator.rb +13 -5
- data/lib/generators/templates/_form.html.erb +10 -4
- data/lib/generators/templates/_form.html.haml +8 -4
- data/lib/generators/templates/_form.html.slim +8 -0
- data/lib/generators/templates/formtastic.rb +77 -44
- data/lib/generators/templates/input.rb +19 -0
- data/lib/locale/en.yml +3 -0
- data/sample/basic_inputs.html +224 -0
- data/sample/config.ru +69 -0
- data/sample/index.html +14 -0
- data/spec/action_class_finder_spec.rb +12 -0
- data/spec/actions/button_action_spec.rb +63 -0
- data/spec/actions/generic_action_spec.rb +521 -0
- data/spec/actions/input_action_spec.rb +59 -0
- data/spec/actions/link_action_spec.rb +92 -0
- data/spec/builder/custom_builder_spec.rb +116 -0
- data/spec/builder/error_proc_spec.rb +27 -0
- data/spec/builder/semantic_fields_for_spec.rb +142 -0
- data/spec/fast_spec_helper.rb +12 -0
- data/spec/generators/formtastic/form/form_generator_spec.rb +131 -0
- data/spec/generators/formtastic/input/input_generator_spec.rb +124 -0
- data/spec/generators/formtastic/install/install_generator_spec.rb +47 -0
- data/spec/helpers/action_helper_spec.rb +19 -0
- data/spec/helpers/actions_helper_spec.rb +143 -0
- data/spec/helpers/form_helper_spec.rb +218 -0
- data/spec/helpers/input_helper_spec.rb +6 -0
- data/spec/helpers/inputs_helper_spec.rb +655 -0
- data/spec/helpers/namespaced_action_helper_spec.rb +43 -0
- data/spec/helpers/namespaced_input_helper_spec.rb +36 -0
- data/spec/helpers/reflection_helper_spec.rb +32 -0
- data/spec/helpers/semantic_errors_helper_spec.rb +112 -0
- data/spec/i18n_spec.rb +210 -0
- data/spec/input_class_finder_spec.rb +10 -0
- data/spec/inputs/base/collections_spec.rb +76 -0
- data/spec/inputs/base/validations_spec.rb +342 -0
- data/spec/inputs/boolean_input_spec.rb +254 -0
- data/spec/inputs/check_boxes_input_spec.rb +546 -0
- data/spec/inputs/color_input_spec.rb +97 -0
- data/spec/inputs/country_input_spec.rb +133 -0
- data/spec/inputs/custom_input_spec.rb +55 -0
- data/spec/inputs/datalist_input_spec.rb +61 -0
- data/spec/inputs/date_picker_input_spec.rb +449 -0
- data/spec/inputs/date_select_input_spec.rb +235 -0
- data/spec/inputs/datetime_picker_input_spec.rb +490 -0
- data/spec/inputs/datetime_select_input_spec.rb +193 -0
- data/spec/inputs/email_input_spec.rb +85 -0
- data/spec/inputs/file_input_spec.rb +89 -0
- data/spec/inputs/hidden_input_spec.rb +135 -0
- data/spec/inputs/include_blank_spec.rb +78 -0
- data/spec/inputs/label_spec.rb +149 -0
- data/spec/inputs/number_input_spec.rb +815 -0
- data/spec/inputs/password_input_spec.rb +99 -0
- data/spec/inputs/phone_input_spec.rb +85 -0
- data/spec/inputs/placeholder_spec.rb +71 -0
- data/spec/inputs/radio_input_spec.rb +328 -0
- data/spec/inputs/range_input_spec.rb +505 -0
- data/spec/inputs/readonly_spec.rb +50 -0
- data/spec/inputs/search_input_spec.rb +84 -0
- data/spec/inputs/select_input_spec.rb +615 -0
- data/spec/inputs/string_input_spec.rb +260 -0
- data/spec/inputs/text_input_spec.rb +187 -0
- data/spec/inputs/time_picker_input_spec.rb +455 -0
- data/spec/inputs/time_select_input_spec.rb +248 -0
- data/spec/inputs/time_zone_input_spec.rb +143 -0
- data/spec/inputs/url_input_spec.rb +85 -0
- data/spec/inputs/with_options_spec.rb +43 -0
- data/spec/localizer_spec.rb +130 -0
- data/spec/namespaced_class_finder_spec.rb +79 -0
- data/spec/spec.opts +2 -0
- data/spec/spec_helper.rb +525 -0
- data/spec/support/custom_macros.rb +564 -0
- data/spec/support/deprecation.rb +6 -0
- data/spec/support/shared_examples.rb +1313 -0
- data/spec/support/specialized_class_finder_shared_example.rb +27 -0
- data/spec/support/test_environment.rb +31 -0
- data/spec/util_spec.rb +66 -0
- metadata +434 -161
- data/README.textile +0 -682
- data/generators/form/USAGE +0 -16
- data/generators/form/form_generator.rb +0 -111
- data/generators/formtastic/formtastic_generator.rb +0 -26
- data/init.rb +0 -5
- data/lib/formtastic/layout_helper.rb +0 -12
- data/lib/formtastic/railtie.rb +0 -14
- data/lib/generators/templates/formtastic.css +0 -145
- data/lib/generators/templates/formtastic_changes.css +0 -14
- data/lib/generators/templates/rails2/_form.html.erb +0 -5
- data/lib/generators/templates/rails2/_form.html.haml +0 -4
- data/rails/init.rb +0 -2
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
module Formtastic
|
|
2
|
+
module Inputs
|
|
3
|
+
|
|
4
|
+
# Outputs a simple `<label>` with a `<input type="text">` wrapped in the standard
|
|
5
|
+
# `<li>` wrapper. This is the default input choice for database columns of the `:string` type,
|
|
6
|
+
# and is the default choice for all inputs when no other logical input type can be inferred.
|
|
7
|
+
# You can force any input to be a string input with `:as => :string`.
|
|
8
|
+
#
|
|
9
|
+
# @example Full form context and output
|
|
10
|
+
#
|
|
11
|
+
# <%= semantic_form_for(@user) do |f| %>
|
|
12
|
+
# <%= f.inputs do %>
|
|
13
|
+
# <%= f.input :first_name, :as => :string %>
|
|
14
|
+
# <% end %>
|
|
15
|
+
# <% end %>
|
|
16
|
+
#
|
|
17
|
+
# <form...>
|
|
18
|
+
# <fieldset>
|
|
19
|
+
# <ol>
|
|
20
|
+
# <li class="string">
|
|
21
|
+
# <label for="user_first_name">First name</label>
|
|
22
|
+
# <input type="text" id="user_first_name" name="user[first_name]">
|
|
23
|
+
# </li>
|
|
24
|
+
# </ol>
|
|
25
|
+
# </fieldset>
|
|
26
|
+
# </form>
|
|
27
|
+
#
|
|
28
|
+
# @see Formtastic::Helpers::InputsHelper#input InputsHelper#input for full documentation of all possible options.
|
|
29
|
+
class StringInput
|
|
30
|
+
include Base
|
|
31
|
+
include Base::Stringish
|
|
32
|
+
include Base::Placeholder
|
|
33
|
+
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
module Formtastic
|
|
2
|
+
module Inputs
|
|
3
|
+
|
|
4
|
+
# Outputs a simple `<label>` with a `<textarea>` wrapped in the standard
|
|
5
|
+
# `<li>` wrapper. This is the default input choice for database columns of the `:text` type,
|
|
6
|
+
# but can forced on any text-like input with `:as => :text`.
|
|
7
|
+
#
|
|
8
|
+
# @example Full form context and output
|
|
9
|
+
#
|
|
10
|
+
# <%= semantic_form_for(@user) do |f| %>
|
|
11
|
+
# <%= f.inputs do %>
|
|
12
|
+
# <%= f.input :first_name, :as => :text %>
|
|
13
|
+
# <% end %>
|
|
14
|
+
# <% end %>
|
|
15
|
+
#
|
|
16
|
+
# <form...>
|
|
17
|
+
# <fieldset>
|
|
18
|
+
# <ol>
|
|
19
|
+
# <li class="text">
|
|
20
|
+
# <label for="user_first_name">First name</label>
|
|
21
|
+
# <textarea cols="30" id="user_first_name" name="user[first_name]" rows="20"></textarea>
|
|
22
|
+
# </li>
|
|
23
|
+
# </ol>
|
|
24
|
+
# </fieldset>
|
|
25
|
+
# </form>
|
|
26
|
+
#
|
|
27
|
+
# @see Formtastic::Helpers::InputsHelper#input InputsHelper#input for full documentation of all possible options.
|
|
28
|
+
class TextInput
|
|
29
|
+
include Base
|
|
30
|
+
include Base::Placeholder
|
|
31
|
+
|
|
32
|
+
def input_html_options
|
|
33
|
+
{
|
|
34
|
+
:cols => builder.default_text_area_width,
|
|
35
|
+
:rows => builder.default_text_area_height
|
|
36
|
+
}.merge(super)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def to_html
|
|
40
|
+
input_wrapping do
|
|
41
|
+
label_html <<
|
|
42
|
+
builder.text_area(method, input_html_options)
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
module Formtastic
|
|
2
|
+
module Inputs
|
|
3
|
+
|
|
4
|
+
# Outputs a simple `<label>` with a HTML5 `<input type="time">` wrapped in the standard
|
|
5
|
+
# `<li>` wrapper. This is an alternative to `:time_select` for `:date`, `:time`, `:datetime`
|
|
6
|
+
# database columns. You can use this input with `:as => :time_picker`.
|
|
7
|
+
#
|
|
8
|
+
# *Please note:* Formtastic only provides suitable markup for a date picker, but does not supply
|
|
9
|
+
# any additional CSS or Javascript to render calendar-style date pickers. Browsers that support
|
|
10
|
+
# this input type (such as Mobile Webkit and Opera on the desktop) will render a native widget.
|
|
11
|
+
# Browsers that don't will default to a plain text field`<input type="text">` and can be
|
|
12
|
+
# poly-filled with some Javascript and a UI library of your choice.
|
|
13
|
+
#
|
|
14
|
+
# @example Full form context and output
|
|
15
|
+
#
|
|
16
|
+
# <%= semantic_form_for(@post) do |f| %>
|
|
17
|
+
# <%= f.inputs do %>
|
|
18
|
+
# <%= f.input :publish_at, :as => :time_picker %>
|
|
19
|
+
# <% end %>
|
|
20
|
+
# <% end %>
|
|
21
|
+
#
|
|
22
|
+
# <form...>
|
|
23
|
+
# <fieldset>
|
|
24
|
+
# <ol>
|
|
25
|
+
# <li class="string">
|
|
26
|
+
# <label for="post_publish_at">First name</label>
|
|
27
|
+
# <input type="date" id="post_publish_at" name="post[publish_at]">
|
|
28
|
+
# </li>
|
|
29
|
+
# </ol>
|
|
30
|
+
# </fieldset>
|
|
31
|
+
# </form>
|
|
32
|
+
#
|
|
33
|
+
# @example Setting the size (defaults to 5 for HH:MM)
|
|
34
|
+
# <%= f.input :publish_at, :as => :time_picker, :size => 20 %>
|
|
35
|
+
# <%= f.input :publish_at, :as => :time_picker, :input_html => { :size => 20 } %>
|
|
36
|
+
#
|
|
37
|
+
# @example Setting the maxlength (defaults to 5 for HH:MM)
|
|
38
|
+
# <%= f.input :publish_at, :as => :time_picker, :maxlength => 20 %>
|
|
39
|
+
# <%= f.input :publish_at, :as => :time_picker, :input_html => { :maxlength => 20 } %>
|
|
40
|
+
#
|
|
41
|
+
# @example Setting the value (defaults to HH:MM for Date and Time objects, otherwise renders string)
|
|
42
|
+
# <%= f.input :publish_at, :as => :time_picker, :input_html => { :value => "14:14" } %>
|
|
43
|
+
#
|
|
44
|
+
# @example Setting the step attribute (defaults to 60)
|
|
45
|
+
# <%= f.input :publish_at, :as => :time_picker, :step => 120 %>
|
|
46
|
+
# <%= f.input :publish_at, :as => :time_picker, :input_html => { :step => 120 } %>
|
|
47
|
+
#
|
|
48
|
+
# @example Setting the step attribute with a macro
|
|
49
|
+
# <%= f.input :publish_at, :as => :time_picker, :step => :second %>
|
|
50
|
+
# <%= f.input :publish_at, :as => :time_picker, :step => :minute %>
|
|
51
|
+
# <%= f.input :publish_at, :as => :time_picker, :step => :quarter_hour %>
|
|
52
|
+
# <%= f.input :publish_at, :as => :time_picker, :step => :fifteen_minutes %>
|
|
53
|
+
# <%= f.input :publish_at, :as => :time_picker, :step => :half_hour %>
|
|
54
|
+
# <%= f.input :publish_at, :as => :time_picker, :step => :thirty_minutes %>
|
|
55
|
+
# <%= f.input :publish_at, :as => :time_picker, :step => :hour %>
|
|
56
|
+
# <%= f.input :publish_at, :as => :time_picker, :step => :sixty_minutes %>
|
|
57
|
+
#
|
|
58
|
+
# @example Setting the min attribute
|
|
59
|
+
# <%= f.input :publish_at, :as => :time_picker, :min => "09:00" %>
|
|
60
|
+
# <%= f.input :publish_at, :as => :time_picker, :input_html => { :min => "01:00" } %>
|
|
61
|
+
#
|
|
62
|
+
# @example Setting the max attribute
|
|
63
|
+
# <%= f.input :publish_at, :as => :time_picker, :max => "18:00" %>
|
|
64
|
+
# <%= f.input :publish_at, :as => :time_picker, :input_html => { :max => "18:00" } %>
|
|
65
|
+
#
|
|
66
|
+
# @example Setting the placeholder attribute
|
|
67
|
+
# <%= f.input :publish_at, :as => :time_picker, :placeholder => "HH:MM" %>
|
|
68
|
+
# <%= f.input :publish_at, :as => :time_picker, :input_html => { :placeholder => "HH:MM" } %>
|
|
69
|
+
#
|
|
70
|
+
# @see Formtastic::Helpers::InputsHelper#input InputsHelper#input for full documentation of all possible options.
|
|
71
|
+
class TimePickerInput
|
|
72
|
+
include Base
|
|
73
|
+
include Base::Stringish
|
|
74
|
+
include Base::DatetimePickerish
|
|
75
|
+
|
|
76
|
+
def html_input_type
|
|
77
|
+
"time"
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def default_size
|
|
81
|
+
5
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def value
|
|
85
|
+
return options[:input_html][:value] if options[:input_html] && options[:input_html].key?(:value)
|
|
86
|
+
val = object.send(method)
|
|
87
|
+
return "00:00" if val.is_a?(Date)
|
|
88
|
+
return val.strftime("%H:%M") if val.is_a?(Time)
|
|
89
|
+
return val if val.nil?
|
|
90
|
+
val.to_s
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def default_step
|
|
94
|
+
60
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
end
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
module Formtastic
|
|
2
|
+
module Inputs
|
|
3
|
+
# Outputs a series of select boxes for the fragments that make up a time (hour, minute, second).
|
|
4
|
+
# Unless `:ignore_date` is true, it will render hidden inputs for the year, month and day as
|
|
5
|
+
# well, defaulting to `Time.current` if the form object doesn't have a value, much like Rails'
|
|
6
|
+
# own `time_select`.
|
|
7
|
+
#
|
|
8
|
+
# @see Formtastic::Inputs::Base::Timeish Timeish module for documentation of date, time and datetime input options.
|
|
9
|
+
class TimeSelectInput
|
|
10
|
+
include Base
|
|
11
|
+
include Base::Timeish
|
|
12
|
+
|
|
13
|
+
# we don't want year / month / day fragments if :ignore_date => true
|
|
14
|
+
def fragments
|
|
15
|
+
time_fragments
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def value_or_default_value
|
|
19
|
+
value ? value : Time.current
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def fragment_value(fragment)
|
|
23
|
+
value_or_default_value.send(fragment)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def hidden_fragments
|
|
27
|
+
if !options[:ignore_date]
|
|
28
|
+
date_fragments.map do |fragment|
|
|
29
|
+
template.hidden_field_tag(hidden_field_name(fragment), fragment_value(fragment), :id => fragment_id(fragment), :disabled => input_html_options[:disabled] )
|
|
30
|
+
end.join.html_safe
|
|
31
|
+
else
|
|
32
|
+
super
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
module Formtastic
|
|
2
|
+
module Inputs
|
|
3
|
+
|
|
4
|
+
# Outputs a `<label>` with a `<select>` containing a series of time zones (using Rails' own
|
|
5
|
+
# `time_zone_select` helper), wrapped in the standard `<li>` wrapper.
|
|
6
|
+
|
|
7
|
+
# This is the default input choice for attributes matching /time_zone/, but can be applied to
|
|
8
|
+
# any text-like input with `:as => :time_zone`.
|
|
9
|
+
#
|
|
10
|
+
# @example Full form context and output
|
|
11
|
+
#
|
|
12
|
+
# <%= semantic_form_for(@user) do |f| %>
|
|
13
|
+
# <%= f.inputs do %>
|
|
14
|
+
# <%= f.input :time_zone, :as => :time_zone %>
|
|
15
|
+
# <% end %>
|
|
16
|
+
# <% end %>
|
|
17
|
+
#
|
|
18
|
+
# <form...>
|
|
19
|
+
# <fieldset>
|
|
20
|
+
# <ol>
|
|
21
|
+
# <li class="time_zone">
|
|
22
|
+
# <label for="user_time_zone">Time zone</label>
|
|
23
|
+
# <input type="text" id="user_time_zone" name="user[time_zone]">
|
|
24
|
+
# </li>
|
|
25
|
+
# </ol>
|
|
26
|
+
# </fieldset>
|
|
27
|
+
# </form>
|
|
28
|
+
#
|
|
29
|
+
# @see Formtastic::Helpers::InputsHelper#input InputsHelper#input for full documentation of all possible options.
|
|
30
|
+
#
|
|
31
|
+
# The priority_zones option:
|
|
32
|
+
# Since this input actually uses Rails' `time_zone_select` helper, the :priority_zones
|
|
33
|
+
# option needs to be an array of ActiveSupport::TimeZone objects.
|
|
34
|
+
#
|
|
35
|
+
# And you can configure default value using
|
|
36
|
+
#
|
|
37
|
+
# ```
|
|
38
|
+
# Formtastic::FormBuilder.priority_time_zones = [timezone1, timezone2]
|
|
39
|
+
# ```
|
|
40
|
+
#
|
|
41
|
+
# See http://apidock.com/rails/ActionView/Helpers/FormOptionsHelper/time_zone_select for more information.
|
|
42
|
+
#
|
|
43
|
+
class TimeZoneInput
|
|
44
|
+
include Base
|
|
45
|
+
|
|
46
|
+
def to_html
|
|
47
|
+
input_wrapping do
|
|
48
|
+
label_html <<
|
|
49
|
+
builder.time_zone_select(method, priority_zones, input_options, input_html_options)
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def priority_zones
|
|
54
|
+
options[:priority_zones] || Formtastic::FormBuilder.priority_time_zones
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
module Formtastic
|
|
2
|
+
module Inputs
|
|
3
|
+
|
|
4
|
+
# Outputs a simple `<label>` with a HTML5 `<input type="url">` wrapped in the standard
|
|
5
|
+
# `<li>` wrapper. This is the default input choice for all attributes matching
|
|
6
|
+
# `/^url$|^website$|_url$/`, but can be applied to any text-like input with `:as => :url`.
|
|
7
|
+
#
|
|
8
|
+
# @example Full form context and output
|
|
9
|
+
#
|
|
10
|
+
# <%= semantic_form_for(@user) do |f| %>
|
|
11
|
+
# <%= f.inputs do %>
|
|
12
|
+
# <%= f.input :home_page, :as => :url %>
|
|
13
|
+
# <% end %>
|
|
14
|
+
# <% end %>
|
|
15
|
+
#
|
|
16
|
+
# <form...>
|
|
17
|
+
# <fieldset>
|
|
18
|
+
# <ol>
|
|
19
|
+
# <li class="url">
|
|
20
|
+
# <label for="user_home_page">Home page</label>
|
|
21
|
+
# <input type="number" id="user_home_page" name="user[home_page]">
|
|
22
|
+
# </li>
|
|
23
|
+
# </ol>
|
|
24
|
+
# </fieldset>
|
|
25
|
+
# </form>
|
|
26
|
+
#
|
|
27
|
+
# @see Formtastic::Helpers::InputsHelper#input InputsHelper#input for full documentation of all possible options.
|
|
28
|
+
class UrlInput
|
|
29
|
+
include Base
|
|
30
|
+
include Base::Stringish
|
|
31
|
+
include Base::Placeholder
|
|
32
|
+
|
|
33
|
+
def to_html
|
|
34
|
+
input_wrapping do
|
|
35
|
+
label_html <<
|
|
36
|
+
builder.url_field(method, input_html_options)
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
module Formtastic
|
|
2
|
+
module LocalizedString
|
|
3
|
+
|
|
4
|
+
def model_name
|
|
5
|
+
@object.present? ? @object.class.name : @object_name.to_s.classify
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
protected
|
|
9
|
+
|
|
10
|
+
def localized_string(key, value, type, options = {}) # @private
|
|
11
|
+
current_builder = respond_to?(:builder) ? builder : self
|
|
12
|
+
localizer = Formtastic::FormBuilder.i18n_localizer.new(current_builder)
|
|
13
|
+
localizer.localize(key, value, type, options)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
module Formtastic
|
|
2
|
+
# Implementation for looking up localized values within Formtastic using I18n, if no
|
|
3
|
+
# explicit value (like the `:label` option) is set and I18n-lookups are enabled in the
|
|
4
|
+
# configuration.
|
|
5
|
+
#
|
|
6
|
+
# You can subclass this to implement your own Localizer, and configure Formtastic to use this
|
|
7
|
+
# localizer with:
|
|
8
|
+
#
|
|
9
|
+
# Formtastic::FormBuilder.i18n_localizer
|
|
10
|
+
#
|
|
11
|
+
# Enabled/disable i18n lookups completely with:
|
|
12
|
+
#
|
|
13
|
+
# Formtastic::FormBuilder.i18n_lookups_by_default = true/false
|
|
14
|
+
#
|
|
15
|
+
# Lookup priority:
|
|
16
|
+
#
|
|
17
|
+
# 'formtastic.%{type}.%{model}.%{action}.%{attribute}'
|
|
18
|
+
# 'formtastic.%{type}.%{model}.%{attribute}'
|
|
19
|
+
# 'formtastic.%{type}.%{attribute}'
|
|
20
|
+
#
|
|
21
|
+
# Example:
|
|
22
|
+
#
|
|
23
|
+
# 'formtastic.labels.post.edit.title'
|
|
24
|
+
# 'formtastic.labels.post.title'
|
|
25
|
+
# 'formtastic.labels.title'
|
|
26
|
+
class Localizer
|
|
27
|
+
class Cache
|
|
28
|
+
def get(key)
|
|
29
|
+
cache[key]
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def has_key?(key)
|
|
33
|
+
cache.has_key?(key)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def set(key, result)
|
|
37
|
+
cache[key] = result
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def cache
|
|
41
|
+
@cache ||= {}
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def clear!
|
|
45
|
+
cache.clear
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
attr_accessor :builder
|
|
50
|
+
|
|
51
|
+
def self.cache
|
|
52
|
+
@cache ||= Cache.new
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def initialize(current_builder)
|
|
56
|
+
self.builder = current_builder
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def localize(key, value, type, options = {}) # @private
|
|
60
|
+
key = value if value.is_a?(::Symbol)
|
|
61
|
+
|
|
62
|
+
if value.is_a?(::String)
|
|
63
|
+
escape_html_entities(value)
|
|
64
|
+
else
|
|
65
|
+
use_i18n = value.nil? ? i18n_lookups_by_default : (value != false)
|
|
66
|
+
use_cache = i18n_cache_lookups
|
|
67
|
+
cache = self.class.cache
|
|
68
|
+
|
|
69
|
+
if use_i18n
|
|
70
|
+
model_name, nested_model_name = normalize_model_name(builder.model_name.underscore)
|
|
71
|
+
|
|
72
|
+
action_name = builder.template.params[:action].to_s rescue ''
|
|
73
|
+
attribute_name = key.to_s
|
|
74
|
+
|
|
75
|
+
# look in the cache first
|
|
76
|
+
if use_cache
|
|
77
|
+
cache_key = [::I18n.locale, action_name, model_name, nested_model_name, attribute_name, key, value, type, options]
|
|
78
|
+
return cache.get(cache_key) if cache.has_key?(cache_key)
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
defaults = Formtastic::I18n::SCOPES.reject do |i18n_scope|
|
|
82
|
+
nested_model_name.nil? && i18n_scope.match(/nested_model/)
|
|
83
|
+
end.collect do |i18n_scope|
|
|
84
|
+
i18n_path = i18n_scope.dup
|
|
85
|
+
i18n_path.gsub!('%{action}', action_name)
|
|
86
|
+
i18n_path.gsub!('%{model}', model_name)
|
|
87
|
+
i18n_path.gsub!('%{nested_model}', nested_model_name) unless nested_model_name.nil?
|
|
88
|
+
i18n_path.gsub!('%{attribute}', attribute_name)
|
|
89
|
+
i18n_path.tr!('..', '.')
|
|
90
|
+
i18n_path.to_sym
|
|
91
|
+
end
|
|
92
|
+
defaults << ''
|
|
93
|
+
|
|
94
|
+
defaults.uniq!
|
|
95
|
+
|
|
96
|
+
default_key = defaults.shift
|
|
97
|
+
i18n_value = Formtastic::I18n.t(default_key,
|
|
98
|
+
options.merge(:default => defaults, :scope => type.to_s.pluralize.to_sym))
|
|
99
|
+
i18n_value = i18n_value.is_a?(::String) ? i18n_value : nil
|
|
100
|
+
if i18n_value.blank? && type == :label
|
|
101
|
+
# This is effectively what Rails label helper does for i18n lookup
|
|
102
|
+
options[:scope] = [:helpers, type]
|
|
103
|
+
options[:default] = defaults
|
|
104
|
+
i18n_value = ::I18n.t(default_key, options)
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
# save the result to the cache
|
|
108
|
+
result = (i18n_value.is_a?(::String) && i18n_value.present?) ? escape_html_entities(i18n_value) : nil
|
|
109
|
+
cache.set(cache_key, result) if use_cache
|
|
110
|
+
result
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
protected
|
|
116
|
+
|
|
117
|
+
def normalize_model_name(name)
|
|
118
|
+
if !name =~ /\[/ && builder.respond_to?(:parent_builder) && builder.parent_builder.object_name
|
|
119
|
+
# Rails 3.1 nested builder case
|
|
120
|
+
[builder.parent_builder.object_name.to_s, name]
|
|
121
|
+
elsif name =~ /(.+)\[(.+)\]/
|
|
122
|
+
# Rails 3 (and 3.1?) nested builder case with :post rather than @post
|
|
123
|
+
[$1, $2]
|
|
124
|
+
elsif builder.respond_to?(:options) && builder.options.key?(:as)
|
|
125
|
+
[builder.options[:as].to_s]
|
|
126
|
+
elsif builder.respond_to?(:options) && builder.options.key?(:parent_builder)
|
|
127
|
+
# Rails 3.0 nested builder work-around case, where :parent_builder is provided by f.semantic_form_for
|
|
128
|
+
[builder.options[:parent_builder].object_name.to_s, name]
|
|
129
|
+
else
|
|
130
|
+
# Non-nested case
|
|
131
|
+
[name]
|
|
132
|
+
end
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
def escape_html_entities(string) # @private
|
|
136
|
+
if (builder.escape_html_entities_in_hints_and_labels) ||
|
|
137
|
+
(self.respond_to?(:escape_html_entities_in_hints_and_labels) && escape_html_entities_in_hints_and_labels)
|
|
138
|
+
string = builder.template.escape_once(string) unless string.respond_to?(:html_safe?) && string.html_safe? == true # Accept html_safe flag as indicator to skip escaping
|
|
139
|
+
end
|
|
140
|
+
string
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
def i18n_lookups_by_default
|
|
144
|
+
builder.i18n_lookups_by_default
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
def i18n_cache_lookups
|
|
148
|
+
builder.i18n_cache_lookups
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
end
|
|
152
|
+
end
|