formtastic 2.1.0 → 4.0.0
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/.gitattributes +1 -0
- data/.github/workflows/test.yml +61 -0
- data/.gitignore +4 -2
- data/CHANGELOG.md +52 -0
- data/Gemfile +1 -1
- data/Gemfile.lock +105 -0
- data/MIT-LICENSE +1 -1
- data/{README.textile → README.md} +204 -219
- data/RELEASE_PROCESS +3 -1
- data/Rakefile +27 -29
- data/app/assets/stylesheets/formtastic.css +3 -2
- data/bin/appraisal +8 -0
- data/formtastic.gemspec +11 -14
- data/gemfiles/rails_5.2/Gemfile +5 -0
- data/gemfiles/rails_6.0/Gemfile +5 -0
- data/gemfiles/rails_6.1/Gemfile +5 -0
- data/gemfiles/rails_edge/Gemfile +13 -0
- data/lib/formtastic/action_class_finder.rb +18 -0
- data/lib/formtastic/actions/button_action.rb +55 -60
- data/lib/formtastic/actions/input_action.rb +59 -57
- data/lib/formtastic/actions/link_action.rb +68 -67
- data/lib/formtastic/actions.rb +6 -3
- data/lib/formtastic/deprecation.rb +5 -0
- data/lib/formtastic/engine.rb +3 -1
- data/lib/formtastic/form_builder.rb +35 -16
- data/lib/formtastic/helpers/action_helper.rb +34 -28
- data/lib/formtastic/helpers/enum.rb +13 -0
- data/lib/formtastic/helpers/errors_helper.rb +2 -2
- data/lib/formtastic/helpers/fieldset_wrapper.rb +16 -12
- data/lib/formtastic/helpers/form_helper.rb +19 -16
- data/lib/formtastic/helpers/input_helper.rb +69 -97
- data/lib/formtastic/helpers/inputs_helper.rb +35 -25
- data/lib/formtastic/helpers/reflection.rb +4 -4
- data/lib/formtastic/helpers.rb +1 -2
- data/lib/formtastic/html_attributes.rb +12 -1
- data/lib/formtastic/i18n.rb +1 -1
- data/lib/formtastic/input_class_finder.rb +18 -0
- data/lib/formtastic/inputs/base/choices.rb +2 -2
- data/lib/formtastic/inputs/base/collections.rb +46 -14
- data/lib/formtastic/inputs/base/database.rb +7 -2
- data/lib/formtastic/inputs/base/datetime_pickerish.rb +85 -0
- data/lib/formtastic/inputs/base/errors.rb +7 -7
- data/lib/formtastic/inputs/base/hints.rb +2 -2
- data/lib/formtastic/inputs/base/html.rb +10 -9
- data/lib/formtastic/inputs/base/labelling.rb +5 -8
- data/lib/formtastic/inputs/base/naming.rb +4 -4
- data/lib/formtastic/inputs/base/numeric.rb +1 -1
- data/lib/formtastic/inputs/base/options.rb +3 -4
- data/lib/formtastic/inputs/base/stringish.rb +10 -2
- data/lib/formtastic/inputs/base/timeish.rb +34 -22
- data/lib/formtastic/inputs/base/validations.rb +41 -13
- data/lib/formtastic/inputs/base/wrapping.rb +29 -26
- data/lib/formtastic/inputs/base.rb +22 -15
- data/lib/formtastic/inputs/boolean_input.rb +26 -12
- data/lib/formtastic/inputs/check_boxes_input.rb +39 -31
- data/lib/formtastic/inputs/color_input.rb +41 -0
- data/lib/formtastic/inputs/country_input.rb +24 -5
- data/lib/formtastic/inputs/datalist_input.rb +41 -0
- data/lib/formtastic/inputs/date_picker_input.rb +93 -0
- data/lib/formtastic/inputs/{date_input.rb → date_select_input.rb} +1 -1
- data/lib/formtastic/inputs/datetime_picker_input.rb +103 -0
- data/lib/formtastic/inputs/{datetime_input.rb → datetime_select_input.rb} +1 -1
- data/lib/formtastic/inputs/file_input.rb +2 -2
- data/lib/formtastic/inputs/hidden_input.rb +2 -6
- data/lib/formtastic/inputs/radio_input.rb +28 -22
- data/lib/formtastic/inputs/select_input.rb +36 -39
- data/lib/formtastic/inputs/time_picker_input.rb +99 -0
- data/lib/formtastic/inputs/{time_input.rb → time_select_input.rb} +6 -2
- data/lib/formtastic/inputs/time_zone_input.rb +16 -6
- data/lib/formtastic/inputs.rb +32 -21
- data/lib/formtastic/localized_string.rb +1 -1
- data/lib/formtastic/localizer.rb +24 -24
- data/lib/formtastic/namespaced_class_finder.rb +99 -0
- data/lib/formtastic/version.rb +1 -1
- data/lib/formtastic.rb +20 -10
- data/lib/generators/formtastic/form/form_generator.rb +10 -4
- data/lib/generators/formtastic/input/input_generator.rb +46 -0
- data/lib/generators/formtastic/install/install_generator.rb +5 -19
- data/lib/generators/templates/_form.html.slim +2 -2
- data/lib/generators/templates/formtastic.rb +46 -25
- data/lib/generators/templates/input.rb +19 -0
- data/sample/basic_inputs.html +23 -3
- data/script/integration-template.rb +74 -0
- data/script/integration.sh +19 -0
- data/spec/action_class_finder_spec.rb +12 -0
- data/spec/actions/button_action_spec.rb +8 -8
- data/spec/actions/generic_action_spec.rb +92 -56
- data/spec/actions/input_action_spec.rb +7 -7
- data/spec/actions/link_action_spec.rb +10 -10
- data/spec/builder/custom_builder_spec.rb +36 -20
- data/spec/builder/error_proc_spec.rb +4 -4
- data/spec/builder/semantic_fields_for_spec.rb +28 -29
- data/spec/fast_spec_helper.rb +12 -0
- data/spec/generators/formtastic/form/form_generator_spec.rb +45 -32
- data/spec/generators/formtastic/input/input_generator_spec.rb +124 -0
- data/spec/generators/formtastic/install/install_generator_spec.rb +9 -9
- data/spec/helpers/action_helper_spec.rb +75 -103
- data/spec/helpers/actions_helper_spec.rb +17 -17
- data/spec/helpers/form_helper_spec.rb +84 -33
- data/spec/helpers/input_helper_spec.rb +333 -285
- data/spec/helpers/inputs_helper_spec.rb +167 -121
- data/spec/helpers/reflection_helper_spec.rb +3 -3
- data/spec/helpers/semantic_errors_helper_spec.rb +23 -23
- data/spec/i18n_spec.rb +26 -26
- 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 +480 -0
- data/spec/inputs/boolean_input_spec.rb +100 -65
- data/spec/inputs/check_boxes_input_spec.rb +200 -101
- data/spec/inputs/color_input_spec.rb +85 -0
- data/spec/inputs/country_input_spec.rb +20 -20
- data/spec/inputs/custom_input_spec.rb +3 -4
- 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 +249 -0
- data/spec/inputs/datetime_picker_input_spec.rb +490 -0
- data/spec/inputs/datetime_select_input_spec.rb +209 -0
- data/spec/inputs/email_input_spec.rb +5 -5
- data/spec/inputs/file_input_spec.rb +6 -6
- data/spec/inputs/hidden_input_spec.rb +22 -35
- data/spec/inputs/include_blank_spec.rb +11 -11
- data/spec/inputs/label_spec.rb +62 -25
- data/spec/inputs/number_input_spec.rb +112 -112
- data/spec/inputs/password_input_spec.rb +5 -5
- data/spec/inputs/phone_input_spec.rb +5 -5
- data/spec/inputs/placeholder_spec.rb +6 -6
- data/spec/inputs/radio_input_spec.rb +99 -55
- data/spec/inputs/range_input_spec.rb +66 -66
- data/spec/inputs/readonly_spec.rb +50 -0
- data/spec/inputs/search_input_spec.rb +5 -5
- data/spec/inputs/select_input_spec.rb +170 -170
- data/spec/inputs/string_input_spec.rb +68 -16
- data/spec/inputs/text_input_spec.rb +16 -16
- data/spec/inputs/time_picker_input_spec.rb +455 -0
- data/spec/inputs/time_select_input_spec.rb +261 -0
- data/spec/inputs/time_zone_input_spec.rb +54 -28
- data/spec/inputs/url_input_spec.rb +5 -5
- data/spec/inputs/with_options_spec.rb +7 -7
- data/spec/localizer_spec.rb +39 -17
- data/spec/namespaced_class_finder_spec.rb +79 -0
- data/spec/schema.rb +21 -0
- data/spec/spec_helper.rb +254 -221
- data/spec/support/custom_macros.rb +128 -95
- data/spec/support/shared_examples.rb +12 -0
- data/spec/support/specialized_class_finder_shared_example.rb +27 -0
- data/spec/support/test_environment.rb +26 -10
- metadata +177 -238
- data/.travis.yml +0 -8
- data/Appraisals +0 -11
- data/CHANGELOG +0 -371
- data/gemfiles/rails-3.0.gemfile +0 -7
- data/gemfiles/rails-3.1.gemfile +0 -7
- data/gemfiles/rails-3.2.gemfile +0 -7
- data/lib/formtastic/helpers/buttons_helper.rb +0 -310
- data/lib/formtastic/inputs/base/grouped_collections.rb +0 -77
- data/lib/formtastic/util.rb +0 -25
- data/lib/tasks/verify_rcov.rb +0 -44
- data/spec/helpers/buttons_helper_spec.rb +0 -166
- data/spec/helpers/commit_button_helper_spec.rb +0 -530
- data/spec/inputs/date_input_spec.rb +0 -227
- data/spec/inputs/datetime_input_spec.rb +0 -185
- data/spec/inputs/time_input_spec.rb +0 -267
- data/spec/support/deferred_garbage_collection.rb +0 -21
|
@@ -4,13 +4,15 @@ module Formtastic
|
|
|
4
4
|
# Rails doesn't come with a `country_select` helper by default any more, so you'll need to do
|
|
5
5
|
# one of the following:
|
|
6
6
|
#
|
|
7
|
-
# * install the [
|
|
8
|
-
# * install the no longer maintained [official Rails plugin](http://github.com/rails/iso-3166-country-select)
|
|
7
|
+
# * install the [country_select](https://github.com/stefanpenner/country_select) gem
|
|
9
8
|
# * install any other country_select plugin that behaves in a similar way
|
|
10
9
|
# * roll your own `country_select` helper with the same args and options as the Rails one
|
|
11
10
|
#
|
|
11
|
+
# Formtastic supports both 1.x and 2.x of stefanpenner/country_select, but if you're upgrading
|
|
12
|
+
# from 1.x, they behave quite differently, so please see their [upgrade instructions](https://github.com/stefanpenner/country_select/blob/master/UPGRADING.md).
|
|
13
|
+
#
|
|
12
14
|
# By default, Formtastic includes a handful of English-speaking countries as "priority
|
|
13
|
-
#
|
|
15
|
+
# countries", which can be set in the `priority_countries` configuration array in the
|
|
14
16
|
# formtastic.rb initializer to suit your market and user base (see README for more info on
|
|
15
17
|
# configuration). Additionally, it is possible to set the :priority_countries on a per-input
|
|
16
18
|
# basis through the `:priority_countries` option. These priority countries will be passed down
|
|
@@ -31,7 +33,7 @@ module Formtastic
|
|
|
31
33
|
# # ...
|
|
32
34
|
# </li>
|
|
33
35
|
#
|
|
34
|
-
# @example `:priority_countries` set on a specific input
|
|
36
|
+
# @example `:priority_countries` set on a specific input (country_select 1.x)
|
|
35
37
|
#
|
|
36
38
|
# <%= semantic_form_for @user do |f| %>
|
|
37
39
|
# <%= f.inputs do %>
|
|
@@ -46,12 +48,29 @@ module Formtastic
|
|
|
46
48
|
# # ...
|
|
47
49
|
# </li>
|
|
48
50
|
#
|
|
51
|
+
# @example `:priority_countries` set on a specific input (country_select 2.x)
|
|
52
|
+
#
|
|
53
|
+
# <%= semantic_form_for @user do |f| %>
|
|
54
|
+
# <%= f.inputs do %>
|
|
55
|
+
# <%= f.input :nationality, :as => :country, :priority_countries => ["AU", "NZ"] %>
|
|
56
|
+
# <% end %>
|
|
57
|
+
# <% end %>
|
|
58
|
+
#
|
|
59
|
+
# <li class='country'>
|
|
60
|
+
# <label for="user_nationality">Country</label>
|
|
61
|
+
# <select id="user_nationality" name="user[nationality]">
|
|
62
|
+
# <option value="...">...</option>
|
|
63
|
+
# # ...
|
|
64
|
+
# </li>
|
|
65
|
+
#
|
|
49
66
|
# @see Formtastic::Helpers::InputsHelper#input InputsHelper#input for full documentation of all possible options.
|
|
50
67
|
class CountryInput
|
|
51
68
|
include Base
|
|
52
69
|
|
|
70
|
+
CountrySelectPluginMissing = Class.new(StandardError)
|
|
71
|
+
|
|
53
72
|
def to_html
|
|
54
|
-
raise "To use the :country input, please install a country_select plugin, like this one: https://github.com/
|
|
73
|
+
raise CountrySelectPluginMissing, "To use the :country input, please install a country_select plugin, like this one: https://github.com/stefanpenner/country_select" unless builder.respond_to?(:country_select)
|
|
55
74
|
input_wrapping do
|
|
56
75
|
label_html <<
|
|
57
76
|
builder.country_select(method, priority_countries, input_options, input_html_options)
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
module Formtastic
|
|
2
|
+
module Inputs
|
|
3
|
+
# Outputs a label and a text field, along with a datalist tag
|
|
4
|
+
# datalist tag provides a list of options which drives a simple autocomplete
|
|
5
|
+
# on the text field. This is a HTML5 feature, more info can be found at
|
|
6
|
+
# {https://developer.mozilla.org/en/docs/Web/HTML/Element/datalist <datalist> at MDN}
|
|
7
|
+
# This input accepts a :collection option which takes data in all the usual formats accepted by
|
|
8
|
+
# {http://apidock.com/rails/ActionView/Helpers/FormOptionsHelper/options_for_select options_for_select}
|
|
9
|
+
#
|
|
10
|
+
# @example Input is used as follows
|
|
11
|
+
# f.input :fav_book, :as => :datalist, :collection => Book.pluck(:name)
|
|
12
|
+
#
|
|
13
|
+
class DatalistInput
|
|
14
|
+
include Base
|
|
15
|
+
include Base::Stringish
|
|
16
|
+
include Base::Collections
|
|
17
|
+
|
|
18
|
+
def to_html
|
|
19
|
+
@name = input_html_options[:id].gsub(/_id$/, "")
|
|
20
|
+
input_wrapping do
|
|
21
|
+
label_html <<
|
|
22
|
+
builder.text_field(method, input_html_options) << # standard input
|
|
23
|
+
data_list_html # append new datalist element
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def input_html_options
|
|
28
|
+
super.merge(:list => html_id_of_datalist)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def html_id_of_datalist
|
|
32
|
+
"#{@name}_datalist"
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def data_list_html
|
|
36
|
+
html = builder.template.options_for_select(collection)
|
|
37
|
+
builder.template.content_tag(:datalist,html, { :id => html_id_of_datalist }, false)
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
module Formtastic
|
|
2
|
+
module Inputs
|
|
3
|
+
|
|
4
|
+
# Outputs a simple `<label>` with a HTML5 `<input type="date">` wrapped in the standard
|
|
5
|
+
# `<li>` wrapper. This is an alternative to `:date_select` for `:date`, `:time`, `:datetime`
|
|
6
|
+
# database columns. You can use this input with `:as => :date_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 => :date_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 10 for YYYY-MM-DD)
|
|
34
|
+
# <%= f.input :publish_at, :as => :date_picker, :size => 20 %>
|
|
35
|
+
# <%= f.input :publish_at, :as => :date_picker, :input_html => { :size => 20 } %>
|
|
36
|
+
#
|
|
37
|
+
# @example Setting the maxlength (defaults to 10 for YYYY-MM-DD)
|
|
38
|
+
# <%= f.input :publish_at, :as => :date_picker, :maxlength => 20 %>
|
|
39
|
+
# <%= f.input :publish_at, :as => :date_picker, :input_html => { :maxlength => 20 } %>
|
|
40
|
+
#
|
|
41
|
+
# @example Setting the value (defaults to YYYY-MM-DD for Date and Time objects, otherwise renders string)
|
|
42
|
+
# <%= f.input :publish_at, :as => :date_picker, :input_html => { :value => "1970-01-01" } %>
|
|
43
|
+
#
|
|
44
|
+
# @example Setting the step attribute (defaults to 1)
|
|
45
|
+
# <%= f.input :publish_at, :as => :date_picker, :step => 7 %>
|
|
46
|
+
# <%= f.input :publish_at, :as => :date_picker, :input_html => { :step => 7 } %>
|
|
47
|
+
#
|
|
48
|
+
# @example Setting the step attribute with a macro
|
|
49
|
+
# <%= f.input :publish_at, :as => :date_picker, :step => :day %>
|
|
50
|
+
# <%= f.input :publish_at, :as => :date_picker, :step => :week %>
|
|
51
|
+
# <%= f.input :publish_at, :as => :date_picker, :step => :seven_days %>
|
|
52
|
+
# <%= f.input :publish_at, :as => :date_picker, :step => :fortnight %>
|
|
53
|
+
# <%= f.input :publish_at, :as => :date_picker, :step => :two_weeks %>
|
|
54
|
+
# <%= f.input :publish_at, :as => :date_picker, :step => :four_weeks %>
|
|
55
|
+
# <%= f.input :publish_at, :as => :date_picker, :step => :thirty_days %>
|
|
56
|
+
#
|
|
57
|
+
# @example Setting the min attribute
|
|
58
|
+
# <%= f.input :publish_at, :as => :date_picker, :min => "2012-01-01" %>
|
|
59
|
+
# <%= f.input :publish_at, :as => :date_picker, :input_html => { :min => "2012-01-01" } %>
|
|
60
|
+
#
|
|
61
|
+
# @example Setting the max attribute
|
|
62
|
+
# <%= f.input :publish_at, :as => :date_picker, :max => "2012-12-31" %>
|
|
63
|
+
# <%= f.input :publish_at, :as => :date_picker, :input_html => { :max => "2012-12-31" } %>
|
|
64
|
+
#
|
|
65
|
+
# @example Setting the placeholder attribute
|
|
66
|
+
# <%= f.input :publish_at, :as => :date_picker, :placeholder => 20 %>
|
|
67
|
+
# <%= f.input :publish_at, :as => :date_picker, :input_html => { :placeholder => "YYYY-MM-DD" } %>
|
|
68
|
+
#
|
|
69
|
+
# @see Formtastic::Helpers::InputsHelper#input InputsHelper#input for full documentation of all possible options.
|
|
70
|
+
class DatePickerInput
|
|
71
|
+
include Base
|
|
72
|
+
include Base::Stringish
|
|
73
|
+
include Base::DatetimePickerish
|
|
74
|
+
|
|
75
|
+
def html_input_type
|
|
76
|
+
"date"
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def default_size
|
|
80
|
+
10
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def value
|
|
84
|
+
return options[:input_html][:value] if options[:input_html] && options[:input_html].key?(:value)
|
|
85
|
+
val = object.send(method)
|
|
86
|
+
return Date.new(val.year, val.month, val.day).to_s if val.is_a?(Time)
|
|
87
|
+
return val if val.nil?
|
|
88
|
+
val.to_s
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
end
|
|
@@ -3,7 +3,7 @@ module Formtastic
|
|
|
3
3
|
# Outputs a series of select boxes for the fragments that make up a date (year, month, day).
|
|
4
4
|
#
|
|
5
5
|
# @see Formtastic::Inputs::Base::Timeish Timeish module for documentation of date, time and datetime input options.
|
|
6
|
-
class
|
|
6
|
+
class DateSelectInput
|
|
7
7
|
include Base
|
|
8
8
|
include Base::Timeish
|
|
9
9
|
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
module Formtastic
|
|
2
|
+
module Inputs
|
|
3
|
+
|
|
4
|
+
# Outputs a simple `<label>` with a HTML5 `<input type="datetime-local">` (or
|
|
5
|
+
# `<input type="datetime">`) wrapped in the standard `<li>` wrapper. This is an alternative to
|
|
6
|
+
# `:date_select` for `:date`, `:time`, `:datetime` database columns. You can use this input with
|
|
7
|
+
# `:as => :datetime_picker`.
|
|
8
|
+
#
|
|
9
|
+
# *Please note:* Formtastic only provides suitable markup for a date picker, but does not supply
|
|
10
|
+
# any additional CSS or Javascript to render calendar-style date pickers. Browsers that support
|
|
11
|
+
# this input type (such as Mobile Webkit and Opera on the desktop) will render a native widget.
|
|
12
|
+
# Browsers that don't will default to a plain text field`<input type="text">` and can be
|
|
13
|
+
# poly-filled with some Javascript and a UI library of your choice.
|
|
14
|
+
#
|
|
15
|
+
# @example Full form context and output
|
|
16
|
+
#
|
|
17
|
+
# <%= semantic_form_for(@post) do |f| %>
|
|
18
|
+
# <%= f.inputs do %>
|
|
19
|
+
# <%= f.input :publish_at, :as => :datetime_picker %>
|
|
20
|
+
# <% end %>
|
|
21
|
+
# <% end %>
|
|
22
|
+
#
|
|
23
|
+
# <form...>
|
|
24
|
+
# <fieldset>
|
|
25
|
+
# <ol>
|
|
26
|
+
# <li class="string">
|
|
27
|
+
# <label for="post_publish_at">First name</label>
|
|
28
|
+
# <input type="date" id="post_publish_at" name="post[publish_at]">
|
|
29
|
+
# </li>
|
|
30
|
+
# </ol>
|
|
31
|
+
# </fieldset>
|
|
32
|
+
# </form>
|
|
33
|
+
#
|
|
34
|
+
# @example Setting the size (defaults to 16 for YYYY-MM-DD HH:MM)
|
|
35
|
+
# <%= f.input :publish_at, :as => :datetime_picker, :size => 20 %>
|
|
36
|
+
# <%= f.input :publish_at, :as => :datetime_picker, :input_html => { :size => 20 } %>
|
|
37
|
+
#
|
|
38
|
+
# @example Setting the maxlength (defaults to 16 for YYYY-MM-DD HH:MM)
|
|
39
|
+
# <%= f.input :publish_at, :as => :datetime_picker, :maxlength => 20 %>
|
|
40
|
+
# <%= f.input :publish_at, :as => :datetime_picker, :input_html => { :maxlength => 20 } %>
|
|
41
|
+
#
|
|
42
|
+
# @example Setting the value (defaults to YYYY-MM-DD HH:MM for Date and Time objects, otherwise renders string)
|
|
43
|
+
# <%= f.input :publish_at, :as => :datetime_picker, :input_html => { :value => "1970-01-01 00:00" } %>
|
|
44
|
+
#
|
|
45
|
+
# @example Setting the step attribute (defaults to 1)
|
|
46
|
+
# <%= f.input :publish_at, :as => :datetime_picker, :step => 60 %>
|
|
47
|
+
# <%= f.input :publish_at, :as => :datetime_picker, :input_html => { :step => 60 } %>
|
|
48
|
+
#
|
|
49
|
+
# @example Setting the step attribute with a macro
|
|
50
|
+
# <%= f.input :publish_at, :as => :datetime_picker, :step => :second %>
|
|
51
|
+
# <%= f.input :publish_at, :as => :datetime_picker, :step => :minute %>
|
|
52
|
+
# <%= f.input :publish_at, :as => :datetime_picker, :step => :quarter_hour %>
|
|
53
|
+
# <%= f.input :publish_at, :as => :datetime_picker, :step => :fifteen_minutes %>
|
|
54
|
+
# <%= f.input :publish_at, :as => :datetime_picker, :step => :half_hour %>
|
|
55
|
+
# <%= f.input :publish_at, :as => :datetime_picker, :step => :thirty_minutes %>
|
|
56
|
+
# <%= f.input :publish_at, :as => :datetime_picker, :step => :hour %>
|
|
57
|
+
# <%= f.input :publish_at, :as => :datetime_picker, :step => :sixty_minutes %>
|
|
58
|
+
#
|
|
59
|
+
# @example Setting the min attribute
|
|
60
|
+
# <%= f.input :publish_at, :as => :datetime_picker, :min => "2012-01-01 09:00" %>
|
|
61
|
+
# <%= f.input :publish_at, :as => :datetime_picker, :input_html => { :min => "2012-01-01 09:00" } %>
|
|
62
|
+
#
|
|
63
|
+
# @example Setting the max attribute
|
|
64
|
+
# <%= f.input :publish_at, :as => :datetime_picker, :max => "2012-12-31 16:00" %>
|
|
65
|
+
# <%= f.input :publish_at, :as => :datetime_picker, :input_html => { :max => "2012-12-31 16:00" } %>
|
|
66
|
+
#
|
|
67
|
+
# @example Setting the placeholder attribute
|
|
68
|
+
# <%= f.input :publish_at, :as => :datetime_picker, :placeholder => "YYYY-MM-DD HH:MM" %>
|
|
69
|
+
# <%= f.input :publish_at, :as => :datetime_picker, :input_html => { :placeholder => "YYYY-MM-DD HH:MM" } %>
|
|
70
|
+
#
|
|
71
|
+
# @example Using `type=datetime-local` with `:local` option (this is the default, and recommended for browser support on iOS7 and Chrome)
|
|
72
|
+
# <%= f.input :publish_at, :as => :datetime_picker, :local => true %>
|
|
73
|
+
#
|
|
74
|
+
# @example Using `type=datetime` with `:local` option (not recommended)
|
|
75
|
+
# <%= f.input :publish_at, :as => :datetime_picker, :local => false %>
|
|
76
|
+
#
|
|
77
|
+
# @see Formtastic::Helpers::InputsHelper#input InputsHelper#input for full documentation of all possible options.
|
|
78
|
+
class DatetimePickerInput
|
|
79
|
+
include Base
|
|
80
|
+
include Base::Stringish
|
|
81
|
+
include Base::DatetimePickerish
|
|
82
|
+
|
|
83
|
+
def html_input_type
|
|
84
|
+
options[:local] = true unless options.key?(:local)
|
|
85
|
+
options[:local] ? "datetime-local" : "datetime"
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def default_size
|
|
89
|
+
16
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def value
|
|
93
|
+
return options[:input_html][:value] if options[:input_html] && options[:input_html].key?(:value)
|
|
94
|
+
val = object.send(method)
|
|
95
|
+
return val.strftime("%Y-%m-%dT%H:%M:%S") if val.is_a?(Time)
|
|
96
|
+
return "#{val.year}-#{val.month}-#{val.day}T00:00:00" if val.is_a?(Date)
|
|
97
|
+
return val if val.nil?
|
|
98
|
+
val.to_s
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
end
|
|
@@ -4,7 +4,7 @@ module Formtastic
|
|
|
4
4
|
# Outputs a series of select boxes for the fragments that make up a date and time (year, month, day, hour, minute, second).
|
|
5
5
|
#
|
|
6
6
|
# @see Formtastic::Inputs::Base::Timeish Timeish module for documentation of date, time and datetime input options.
|
|
7
|
-
class
|
|
7
|
+
class DatetimeSelectInput
|
|
8
8
|
include Base
|
|
9
9
|
include Base::Timeish
|
|
10
10
|
end
|
|
@@ -20,7 +20,7 @@ module Formtastic
|
|
|
20
20
|
# <form...>
|
|
21
21
|
# <fieldset>
|
|
22
22
|
# <ol>
|
|
23
|
-
# <li class="
|
|
23
|
+
# <li class="file">
|
|
24
24
|
# <label for="user_avatar">Avatar</label>
|
|
25
25
|
# <input type="file" id="user_avatar" name="user[avatar]">
|
|
26
26
|
# </li>
|
|
@@ -29,7 +29,7 @@ module Formtastic
|
|
|
29
29
|
# </form>
|
|
30
30
|
#
|
|
31
31
|
# @see Formtastic::Helpers::InputsHelper#input InputsHelper#input for full documentation of all possible options.
|
|
32
|
-
class FileInput
|
|
32
|
+
class FileInput
|
|
33
33
|
include Base
|
|
34
34
|
def to_html
|
|
35
35
|
input_wrapping do
|
|
@@ -31,12 +31,8 @@ module Formtastic
|
|
|
31
31
|
class HiddenInput
|
|
32
32
|
include Base
|
|
33
33
|
|
|
34
|
-
# Override to include :value set directly from options hash. The :value set in :input_html
|
|
35
|
-
# hash will be preferred over :value set directly in the options.
|
|
36
|
-
#
|
|
37
|
-
# @todo this is inconsistent with all other inputs, deprecate and remove
|
|
38
34
|
def input_html_options
|
|
39
|
-
|
|
35
|
+
super.merge(:required => nil).merge(:autofocus => nil)
|
|
40
36
|
end
|
|
41
37
|
|
|
42
38
|
def to_html
|
|
@@ -63,4 +59,4 @@ module Formtastic
|
|
|
63
59
|
|
|
64
60
|
end
|
|
65
61
|
end
|
|
66
|
-
end
|
|
62
|
+
end
|
|
@@ -20,7 +20,7 @@ module Formtastic
|
|
|
20
20
|
#
|
|
21
21
|
# * a `:string` input (where you want to force the user to choose from a few specific strings rather than entering anything)
|
|
22
22
|
# * a `:boolean` checkbox input (where the user could choose yes or no, rather than checking a box)
|
|
23
|
-
# * a `:
|
|
23
|
+
# * a `:date_select`, `:time_select` or `:datetime_select` input (where the user could choose from a small set of pre-determined dates)
|
|
24
24
|
# * a `:number` input (where the user could choose from a small set of pre-defined numbers)
|
|
25
25
|
# * a `:time_zone` input (where you want to provide your own small set of choices instead of relying on Rails)
|
|
26
26
|
# * a `:country` input (where you want to provide a small set of choices, no need for a plugin really)
|
|
@@ -31,10 +31,13 @@ module Formtastic
|
|
|
31
31
|
# `Section.all` for a `Post` form with an input for a `belongs_to :section` association.
|
|
32
32
|
# You can override or customise this collection through the `:collection` option (see examples).
|
|
33
33
|
#
|
|
34
|
-
#
|
|
35
|
-
#
|
|
36
|
-
#
|
|
37
|
-
#
|
|
34
|
+
# For radio inputs that map to ActiveRecord `enum` attributes, Formtastic will automatically
|
|
35
|
+
# load in your enum options to be used as the radio button choices. This can be overridden with
|
|
36
|
+
# the `:collection` option, or augmented with I18n translations. See examples below.
|
|
37
|
+
#
|
|
38
|
+
# The way on which Formtastic renders the `value` attribute and label for each choice in the `:collection` is
|
|
39
|
+
# customisable (see examples below). When not provided, we fall back to a list of methods to try on each
|
|
40
|
+
# object such as `:to_label`, `:name` and `:to_s`, which are defined in the configurations
|
|
38
41
|
# `collection_label_methods` and `collection_value_methods`.
|
|
39
42
|
#
|
|
40
43
|
# @example Basic `belongs_to` example with full form context
|
|
@@ -78,30 +81,17 @@ module Formtastic
|
|
|
78
81
|
# <%= f.input :author, :as => :radio, :collection => @authors %>
|
|
79
82
|
# <%= f.input :author, :as => :radio, :collection => Author.all %>
|
|
80
83
|
# <%= f.input :author, :as => :radio, :collection => Author.some_named_scope %>
|
|
84
|
+
# <%= f.input :author, :as => :radio, :collection => Author.pluck(:full_name, :id) %>
|
|
85
|
+
# <%= f.input :author, :as => :radio, :collection => Author.pluck(Arel.sql("CONCAT(`first_name`, ' ', `last_name`)"), :id)) %>
|
|
81
86
|
# <%= f.input :author, :as => :radio, :collection => [Author.find_by_login("justin"), Category.find_by_name("kate")] %>
|
|
82
87
|
# <%= f.input :author, :as => :radio, :collection => ["Justin", "Kate"] %>
|
|
83
88
|
# <%= f.input :author, :as => :radio, :collection => [["Justin", "justin"], ["Kate", "kate"]] %>
|
|
84
89
|
# <%= f.input :author, :as => :radio, :collection => [["Justin", "1"], ["Kate", "3"]] %>
|
|
85
90
|
# <%= f.input :author, :as => :radio, :collection => [["Justin", 1], ["Kate", 3]] %>
|
|
91
|
+
# <%= f.input :author, :as => :radio, :collection => [["Justin", :justin], ["Kate", :kate]] %>
|
|
92
|
+
# <%= f.input :author, :as => :radio, :collection => [:justin, :kate] %>
|
|
86
93
|
# <%= f.input :author, :as => :radio, :collection => 1..5 %>
|
|
87
94
|
#
|
|
88
|
-
# @example The `:member_label` can be used to call a different method (or a Proc) on each object in the collection for rendering the label text (it'll try the methods like `to_s` in `collection_label_methods` config by default)
|
|
89
|
-
# <%= f.input :author, :as => :radio, :member_label => :name %>
|
|
90
|
-
# <%= f.input :author, :as => :radio, :member_label => :name_with_post_count
|
|
91
|
-
# <%= f.input :author, :as => :radio, :member_label => Proc.new { |a| "#{c.name} (#{pluralize("post", a.posts.count)})" }
|
|
92
|
-
#
|
|
93
|
-
# @example `:member_label` can be used with a helper method (both examples have the same result)
|
|
94
|
-
# <%= f.input :author, :as => :radio, :member_label => method(:fancy_label)
|
|
95
|
-
# <%= f.input :author, :as => :radio, :member_label => Proc.new { |author| fancy_label(author) }
|
|
96
|
-
#
|
|
97
|
-
# @example The `:member_value` can be used to call a different method (or a Proc) on each object in the collection for rendering the value for each checkbox (it'll try the methods like `id` in `collection_value_methods` config by default)
|
|
98
|
-
# <%= f.input :author, :as => :radio, :member_value => :login %>
|
|
99
|
-
# <%= f.input :author, :as => :radio, :member_value => Proc.new { |c| c.full_name.downcase.underscore }
|
|
100
|
-
#
|
|
101
|
-
# @example `:member_value` can be used with a helper method (both examples have the same result)
|
|
102
|
-
# <%= f.input :author, :as => :radio, :member_value => method(:some_helper)
|
|
103
|
-
# <%= f.input :author, :as => :radio, :member_value => Proc.new { |author| some_helper(author) }
|
|
104
|
-
#
|
|
105
95
|
# @example Set HTML attributes on each `<input type="radio">` tag with `:input_html`
|
|
106
96
|
# <%= f.input :author, :as => :radio, :input_html => { :size => 20, :multiple => true, :class => "special" } %>
|
|
107
97
|
#
|
|
@@ -114,6 +104,22 @@ module Formtastic
|
|
|
114
104
|
# @example Set HTML options on a specific radio input option with a 3rd element in the array for a collection member
|
|
115
105
|
# <%= f.input :author, :as => :radio, :collection => [["Test", 'test'], ["Try", "try", {:disabled => true}]]
|
|
116
106
|
#
|
|
107
|
+
# @example Using ActiveRecord enum attribute with i18n translation:
|
|
108
|
+
# # post.rb
|
|
109
|
+
# class Post < ActiveRecord::Base
|
|
110
|
+
# enum :status => [ :active, :archived ]
|
|
111
|
+
# end
|
|
112
|
+
# # en.yml
|
|
113
|
+
# en:
|
|
114
|
+
# activerecord:
|
|
115
|
+
# attributes:
|
|
116
|
+
# post:
|
|
117
|
+
# statuses:
|
|
118
|
+
# active: I am active!
|
|
119
|
+
# archived: I am archived!
|
|
120
|
+
# # form
|
|
121
|
+
# <%= f.input :status, :as => :radio %>
|
|
122
|
+
#
|
|
117
123
|
# @see Formtastic::Helpers::InputsHelper#input InputsHelper#input for full documentation of all possible options.
|
|
118
124
|
# @see Formtastic::Inputs::RadioInput as an alternative for `belongs_to` associations
|
|
119
125
|
#
|
|
@@ -8,6 +8,7 @@ module Formtastic
|
|
|
8
8
|
# This is the default input choice when:
|
|
9
9
|
#
|
|
10
10
|
# * the database column type is an `:integer` and there is an association (`belongs_to`)
|
|
11
|
+
# * the database column type is an `:integer` and there is an enum defined (`enum`)
|
|
11
12
|
# * the database column type is a `:string` and the `:collection` option is used
|
|
12
13
|
# * there an object with an association, but no database column on the object (`has_many`, etc)
|
|
13
14
|
# * there is no object and the `:collection` option is used
|
|
@@ -17,7 +18,7 @@ module Formtastic
|
|
|
17
18
|
#
|
|
18
19
|
# * a `:string` input (where you want to force the user to choose from a few specific strings rather than entering anything)
|
|
19
20
|
# * a `:boolean` checkbox input (where the user could choose yes or no, rather than checking a box)
|
|
20
|
-
# * a `:
|
|
21
|
+
# * a `:date_select`, `:time_select` or `:datetime_select` input (where the user could choose from pre-selected dates)
|
|
21
22
|
# * a `:number` input (where the user could choose from a set of pre-defined numbers)
|
|
22
23
|
# * a `:time_zone` input (where you want to provide your own set of choices instead of relying on Rails)
|
|
23
24
|
# * a `:country` input (no need for a plugin really)
|
|
@@ -38,6 +39,13 @@ module Formtastic
|
|
|
38
39
|
# `:to_s`, which are defined in the configurations `collection_label_methods` and
|
|
39
40
|
# `collection_value_methods` (see examples below).
|
|
40
41
|
#
|
|
42
|
+
# For select inputs that map to ActiveRecord `enum` attributes, Formtastic will automatically
|
|
43
|
+
# load in your enum options to be used as the select's options. This can be overridden with
|
|
44
|
+
# the `:collection` option, or augmented with I18n translations. See examples below.
|
|
45
|
+
# An error is raised if you try to render a multi-select with an enum, as ActiveRecord can
|
|
46
|
+
# only store one choice in the database.
|
|
47
|
+
#
|
|
48
|
+
#
|
|
41
49
|
# @example Basic `belongs_to` example with full form context
|
|
42
50
|
#
|
|
43
51
|
# <%= semantic_form_for @post do |f| %>
|
|
@@ -94,6 +102,8 @@ module Formtastic
|
|
|
94
102
|
# <%= f.input :author, :as => :select, :collection => @authors %>
|
|
95
103
|
# <%= f.input :author, :as => :select, :collection => Author.all %>
|
|
96
104
|
# <%= f.input :author, :as => :select, :collection => Author.some_named_scope %>
|
|
105
|
+
# <%= f.input :author, :as => :select, :collection => Author.pluck(:full_name, :id) %>
|
|
106
|
+
# <%= f.input :author, :as => :select, :collection => Author.pluck(Arel.sql("CONCAT(`first_name`, ' ', `last_name`)"), :id)) %>
|
|
97
107
|
# <%= f.input :author, :as => :select, :collection => [Author.find_by_login("justin"), Category.find_by_name("kate")] %>
|
|
98
108
|
# <%= f.input :author, :as => :select, :collection => ["Justin", "Kate"] %>
|
|
99
109
|
# <%= f.input :author, :as => :select, :collection => [["Justin", "justin"], ["Kate", "kate"]] %>
|
|
@@ -106,15 +116,6 @@ module Formtastic
|
|
|
106
116
|
# <%= f.input :author, :as => :select, :collection => grouped_options_for_select(...) %>
|
|
107
117
|
# <%= f.input :author, :as => :select, :collection => time_zone_options_for_select(...) %>
|
|
108
118
|
#
|
|
109
|
-
# @example The `:member_label` can be used to call a different method (or a Proc) on each object in the collection for rendering the label text (it'll try the methods like `to_s` in `collection_label_methods` config by default)
|
|
110
|
-
# <%= f.input :author, :as => :select, :member_label => :name %>
|
|
111
|
-
# <%= f.input :author, :as => :select, :member_label => :name_with_post_count %>
|
|
112
|
-
# <%= f.input :author, :as => :select, :member_label => Proc.new { |a| "#{c.name} (#{pluralize("post", a.posts.count)})" } %>
|
|
113
|
-
#
|
|
114
|
-
# @example The `:member_value` can be used to call a different method (or a Proc) on each object in the collection for rendering the value for each checkbox (it'll try the methods like `id` in `collection_value_methods` config by default)
|
|
115
|
-
# <%= f.input :author, :as => :select, :member_value => :login %>
|
|
116
|
-
# <%= f.input :author, :as => :select, :member_value => Proc.new { |c| c.full_name.downcase.underscore } %>
|
|
117
|
-
#
|
|
118
119
|
# @example Set HTML attributes on the `<select>` tag with `:input_html`
|
|
119
120
|
# <%= f.input :authors, :as => :select, :input_html => { :size => 20, :multiple => true, :class => "special" } %>
|
|
120
121
|
#
|
|
@@ -131,9 +132,21 @@ module Formtastic
|
|
|
131
132
|
# <%= f.input :author, :as => :select, :prompt => true %> => <option value="">Please select</option>
|
|
132
133
|
# <%= f.input :author, :as => :select, :prompt => "Please select an author" %>
|
|
133
134
|
#
|
|
134
|
-
#
|
|
135
|
-
#
|
|
136
|
-
#
|
|
135
|
+
# @example Using ActiveRecord enum attribute with i18n translation:
|
|
136
|
+
# # post.rb
|
|
137
|
+
# class Post < ActiveRecord::Base
|
|
138
|
+
# enum :status => [ :active, :archived ]
|
|
139
|
+
# end
|
|
140
|
+
# # en.yml
|
|
141
|
+
# en:
|
|
142
|
+
# activerecord:
|
|
143
|
+
# attributes:
|
|
144
|
+
# post:
|
|
145
|
+
# statuses:
|
|
146
|
+
# active: I am active!
|
|
147
|
+
# archived: I am archived!
|
|
148
|
+
# # form
|
|
149
|
+
# <%= f.input :status, :as => :select %>
|
|
137
150
|
#
|
|
138
151
|
# @see Formtastic::Helpers::InputsHelper#input InputsHelper#input for full documentation of all possible options.
|
|
139
152
|
# @see Formtastic::Inputs::CheckBoxesInput CheckBoxesInput as an alternative for `has_many` and `has_and_belongs_to_many` associations
|
|
@@ -143,13 +156,16 @@ module Formtastic
|
|
|
143
156
|
class SelectInput
|
|
144
157
|
include Base
|
|
145
158
|
include Base::Collections
|
|
146
|
-
|
|
159
|
+
|
|
160
|
+
def initialize(*args)
|
|
161
|
+
super
|
|
162
|
+
raise Formtastic::UnsupportedEnumCollection if collection_from_enum? && multiple?
|
|
163
|
+
end
|
|
147
164
|
|
|
148
165
|
def to_html
|
|
149
166
|
input_wrapping do
|
|
150
|
-
hidden_input <<
|
|
151
167
|
label_html <<
|
|
152
|
-
|
|
168
|
+
select_html
|
|
153
169
|
end
|
|
154
170
|
end
|
|
155
171
|
|
|
@@ -157,31 +173,10 @@ module Formtastic
|
|
|
157
173
|
builder.select(input_name, collection, input_options, input_html_options)
|
|
158
174
|
end
|
|
159
175
|
|
|
160
|
-
def grouped_select_html
|
|
161
|
-
builder.grouped_collection_select(
|
|
162
|
-
input_name,
|
|
163
|
-
grouped_collection,
|
|
164
|
-
group_association,
|
|
165
|
-
group_label_method,
|
|
166
|
-
value_method,
|
|
167
|
-
label_method,
|
|
168
|
-
input_options,
|
|
169
|
-
input_html_options
|
|
170
|
-
)
|
|
171
|
-
end
|
|
172
|
-
|
|
173
176
|
def include_blank
|
|
174
177
|
options.key?(:include_blank) ? options[:include_blank] : (single? && builder.include_blank_for_select_by_default)
|
|
175
178
|
end
|
|
176
179
|
|
|
177
|
-
def hidden_input
|
|
178
|
-
if multiple?
|
|
179
|
-
template.hidden_field_tag(input_html_options_name_multiple, '', :id => nil)
|
|
180
|
-
else
|
|
181
|
-
"".html_safe
|
|
182
|
-
end
|
|
183
|
-
end
|
|
184
|
-
|
|
185
180
|
def prompt?
|
|
186
181
|
!!options[:prompt]
|
|
187
182
|
end
|
|
@@ -195,7 +190,7 @@ module Formtastic
|
|
|
195
190
|
end
|
|
196
191
|
|
|
197
192
|
def input_html_options
|
|
198
|
-
extra_input_html_options.merge(super)
|
|
193
|
+
extra_input_html_options.merge(super.reject {|k,v| k==:name && v.nil?} )
|
|
199
194
|
end
|
|
200
195
|
|
|
201
196
|
def extra_input_html_options
|
|
@@ -203,6 +198,8 @@ module Formtastic
|
|
|
203
198
|
:multiple => multiple?,
|
|
204
199
|
:name => multiple? ? input_html_options_name_multiple : input_html_options_name
|
|
205
200
|
}
|
|
201
|
+
|
|
202
|
+
|
|
206
203
|
end
|
|
207
204
|
|
|
208
205
|
def input_html_options_name
|
|
@@ -235,4 +232,4 @@ module Formtastic
|
|
|
235
232
|
|
|
236
233
|
end
|
|
237
234
|
end
|
|
238
|
-
end
|
|
235
|
+
end
|