active_form 0.0.1
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.
- data.tar.gz.sig +2 -0
- data/History.txt +4 -0
- data/License.txt +20 -0
- data/MIT-LICENSE +19 -0
- data/Manifest.txt +181 -0
- data/README.txt +1 -0
- data/Rakefile +4 -0
- data/config/hoe.rb +71 -0
- data/config/requirements.rb +17 -0
- data/init.rb +5 -0
- data/lib/active_form.rb +86 -0
- data/lib/active_form/core_extensions.rb +179 -0
- data/lib/active_form/definition.rb +72 -0
- data/lib/active_form/element.rb +50 -0
- data/lib/active_form/elements/base.rb +67 -0
- data/lib/active_form/elements/builder.rb +103 -0
- data/lib/active_form/elements/button.rb +15 -0
- data/lib/active_form/elements/checkbox.rb +18 -0
- data/lib/active_form/elements/file.rb +15 -0
- data/lib/active_form/elements/hidden.rb +9 -0
- data/lib/active_form/elements/image.rb +7 -0
- data/lib/active_form/elements/input.rb +23 -0
- data/lib/active_form/elements/password.rb +12 -0
- data/lib/active_form/elements/radio.rb +18 -0
- data/lib/active_form/elements/reset.rb +15 -0
- data/lib/active_form/elements/section.rb +37 -0
- data/lib/active_form/elements/select.rb +42 -0
- data/lib/active_form/elements/submit.rb +19 -0
- data/lib/active_form/elements/text.rb +9 -0
- data/lib/active_form/elements/textarea.rb +18 -0
- data/lib/active_form/errors.rb +73 -0
- data/lib/active_form/facets/checkbox_group.rb +11 -0
- data/lib/active_form/facets/collection_input.rb +96 -0
- data/lib/active_form/facets/radio_group.rb +11 -0
- data/lib/active_form/facets/select_date.rb +10 -0
- data/lib/active_form/facets/select_datetime.rb +10 -0
- data/lib/active_form/facets/select_day.rb +17 -0
- data/lib/active_form/facets/select_from_model.rb +60 -0
- data/lib/active_form/facets/select_hour.rb +17 -0
- data/lib/active_form/facets/select_minute.rb +17 -0
- data/lib/active_form/facets/select_month.rb +46 -0
- data/lib/active_form/facets/select_numeric_range.rb +59 -0
- data/lib/active_form/facets/select_second.rb +17 -0
- data/lib/active_form/facets/select_time.rb +10 -0
- data/lib/active_form/facets/select_timebased.rb +145 -0
- data/lib/active_form/facets/select_weekday.rb +46 -0
- data/lib/active_form/facets/select_year.rb +24 -0
- data/lib/active_form/mixins/attribute_methods.rb +33 -0
- data/lib/active_form/mixins/casting.rb +152 -0
- data/lib/active_form/mixins/collection_element_methods.rb +204 -0
- data/lib/active_form/mixins/common_methods.rb +350 -0
- data/lib/active_form/mixins/container_methods.rb +417 -0
- data/lib/active_form/mixins/css_methods.rb +70 -0
- data/lib/active_form/mixins/element_methods.rb +314 -0
- data/lib/active_form/mixins/javascript_methods.rb +99 -0
- data/lib/active_form/mixins/loader_methods.rb +72 -0
- data/lib/active_form/mixins/option_element_methods.rb +61 -0
- data/lib/active_form/mixins/validation_methods.rb +253 -0
- data/lib/active_form/validator.rb +47 -0
- data/lib/active_form/validators/alpha.rb +9 -0
- data/lib/active_form/validators/alphanum.rb +9 -0
- data/lib/active_form/validators/base.rb +132 -0
- data/lib/active_form/validators/digits.rb +9 -0
- data/lib/active_form/validators/email.rb +29 -0
- data/lib/active_form/validators/format.rb +15 -0
- data/lib/active_form/validators/length_range.rb +24 -0
- data/lib/active_form/validators/number.rb +9 -0
- data/lib/active_form/validators/option_count.rb +24 -0
- data/lib/active_form/validators/proc.rb +22 -0
- data/lib/active_form/validators/required.rb +9 -0
- data/lib/active_form/validators/set.rb +21 -0
- data/lib/active_form/validators/time_range.rb +30 -0
- data/lib/active_form/validators/uri.rb +54 -0
- data/lib/active_form/version.rb +9 -0
- data/lib/active_form/views/fieldsets.rb +34 -0
- data/lib/active_form/views/plain.rb +32 -0
- data/lib/active_form/views/tables.rb +28 -0
- data/lib/active_form/widget.rb +43 -0
- data/lib/active_form/widgets/base.rb +28 -0
- data/lib/loob/uri_validator.rb +140 -0
- data/lib/rails/acts_as_dropdown/MIT-LICENSE +20 -0
- data/lib/rails/acts_as_dropdown/acts_as_dropdown.rb +119 -0
- data/lib/rails/acts_as_dropdown/dropdown.rb +27 -0
- data/lib/rails/controller_helper.rb +19 -0
- data/lib/rails/model/loader.rb +206 -0
- data/lib/rails/view_helper.rb +20 -0
- data/samples/html/css/style.css +175 -0
- data/samples/html/js/effects.js +958 -0
- data/samples/html/js/prototype.js +2006 -0
- data/samples/html/js/validation.js +228 -0
- data/samples/html/plain_view.html +77 -0
- data/samples/html/sample001.html +158 -0
- data/samples/html/sample002.html +76 -0
- data/samples/html/sample003.html +34 -0
- data/samples/layouts/default.rhtml +18 -0
- data/samples/layouts/plain.rhtml +21 -0
- data/samples/layouts/sample003.rhtml +25 -0
- data/samples/plain_view.rb +58 -0
- data/samples/sample001.rb +111 -0
- data/samples/sample002.rb +92 -0
- data/samples/sample003.rb +30 -0
- data/script/destroy +14 -0
- data/script/generate +14 -0
- data/script/txt2html +74 -0
- data/setup.rb +1585 -0
- data/tasks/deployment.rake +34 -0
- data/tasks/environment.rake +7 -0
- data/tasks/website.rake +17 -0
- data/test/elements/test_base_element.rb +159 -0
- data/test/elements/test_builder_element.rb +81 -0
- data/test/elements/test_button_element.rb +12 -0
- data/test/elements/test_checkbox_element.rb +233 -0
- data/test/elements/test_file_element.rb +20 -0
- data/test/elements/test_hidden_element.rb +11 -0
- data/test/elements/test_image_element.rb +11 -0
- data/test/elements/test_input_element.rb +39 -0
- data/test/elements/test_password_element.rb +16 -0
- data/test/elements/test_radio_element.rb +197 -0
- data/test/elements/test_reset_element.rb +12 -0
- data/test/elements/test_section_element.rb +162 -0
- data/test/elements/test_select_element.rb +364 -0
- data/test/elements/test_submit_element.rb +12 -0
- data/test/elements/test_text_element.rb +91 -0
- data/test/elements/test_textarea_element.rb +23 -0
- data/test/facets/test_checkbox_group_element.rb +388 -0
- data/test/facets/test_radio_group_element.rb +312 -0
- data/test/facets/test_select_date_element.rb +211 -0
- data/test/facets/test_select_datetime_element.rb +56 -0
- data/test/facets/test_select_day_element.rb +37 -0
- data/test/facets/test_select_from_model_element.rb +86 -0
- data/test/facets/test_select_hour_element.rb +37 -0
- data/test/facets/test_select_minute_element.rb +52 -0
- data/test/facets/test_select_month_element.rb +79 -0
- data/test/facets/test_select_numeric_range_element.rb +14 -0
- data/test/facets/test_select_second_element.rb +48 -0
- data/test/facets/test_select_time_element.rb +148 -0
- data/test/facets/test_select_weekday_element.rb +71 -0
- data/test/facets/test_select_year_element.rb +73 -0
- data/test/fixtures/author.rb +11 -0
- data/test/fixtures/authors.yml +0 -0
- data/test/fixtures/book.rb +14 -0
- data/test/fixtures/books.yml +8 -0
- data/test/fixtures/categories.yml +0 -0
- data/test/fixtures/categorization.rb +2 -0
- data/test/fixtures/categorizations.yml +0 -0
- data/test/fixtures/category.rb +8 -0
- data/test/fixtures/publisher.rb +5 -0
- data/test/fixtures/publishers.yml +10 -0
- data/test/fixtures/schema.rb +43 -0
- data/test/rails/test_model_autodefinition.rb +121 -0
- data/test/rails/test_model_loader.rb +61 -0
- data/test/resources/elements/chunky.rb +11 -0
- data/test/resources/forms/demo.rb +5 -0
- data/test/resources/models/book.rb +8 -0
- data/test/resources/models/register_publisher.rb +5 -0
- data/test/resources/sections/demo.rb +6 -0
- data/test/resources/sections/foo.rb +6 -0
- data/test/resources/validators/foo.rb +9 -0
- data/test/resources/widgets/custom.rb +13 -0
- data/test/test_active_form.rb +1050 -0
- data/test/test_casting.rb +124 -0
- data/test/test_definition.rb +68 -0
- data/test/test_definition_class.rb +118 -0
- data/test/test_element_class.rb +201 -0
- data/test/test_helper.rb +74 -0
- data/test/test_javascript.rb +234 -0
- data/test/test_load_definition.rb +68 -0
- data/test/test_load_element.rb +35 -0
- data/test/test_load_section_element.rb +43 -0
- data/test/test_load_validator.rb +31 -0
- data/test/test_load_widget.rb +93 -0
- data/test/test_validation.rb +722 -0
- data/test/validators/test_validates_as_alpha.rb +26 -0
- data/test/validators/test_validates_as_alphanum.rb +26 -0
- data/test/validators/test_validates_as_digits.rb +26 -0
- data/test/validators/test_validates_as_email.rb +29 -0
- data/test/validators/test_validates_as_number.rb +26 -0
- data/test/validators/test_validates_as_uri.rb +128 -0
- data/test/validators/test_validates_with_format.rb +26 -0
- data/test/validators/test_validates_within_length_range.rb +46 -0
- data/test/validators/test_validates_within_set.rb +46 -0
- data/test/validators/test_validates_within_time_range.rb +53 -0
- metadata +307 -0
- metadata.gz.sig +4 -0
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
ActiveForm::Element::SelectNumericRange::create :select_minute do
|
|
2
|
+
|
|
3
|
+
def range
|
|
4
|
+
(0..59)
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
def casting_filter(value)
|
|
8
|
+
value = case value
|
|
9
|
+
when Date then value.to_time.min
|
|
10
|
+
when Time then value.min
|
|
11
|
+
when Array, Range then value.to_a
|
|
12
|
+
else value.to_i rescue 0
|
|
13
|
+
end
|
|
14
|
+
super(value)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
end
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
ActiveForm::Element::SelectNumericRange::create :select_month do
|
|
2
|
+
|
|
3
|
+
define_option_flags :use_short_month, :add_month_numbers, :use_month_numbers
|
|
4
|
+
|
|
5
|
+
def to_monthname
|
|
6
|
+
multiple? ? element_value.map { |i| number_to_label(i) } : number_to_label(element_value)
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def export_value
|
|
10
|
+
exp_value = super
|
|
11
|
+
if self.type_cast == :string
|
|
12
|
+
to_monthname
|
|
13
|
+
else
|
|
14
|
+
exp_value
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def range
|
|
19
|
+
(1..12)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def casting_for_string
|
|
23
|
+
[nil, nil]
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def casting_filter(value)
|
|
27
|
+
value = case value
|
|
28
|
+
when Date, Time then value.month
|
|
29
|
+
when Array, Range then value.to_a
|
|
30
|
+
else value.to_i rescue 0
|
|
31
|
+
end
|
|
32
|
+
super(value)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def number_to_label(month_number)
|
|
36
|
+
month_names = use_short_month? ? Date::ABBR_MONTHNAMES : Date::MONTHNAMES rescue {}
|
|
37
|
+
if use_month_numbers? || month_names.empty?
|
|
38
|
+
month_number.zero_padded(2)
|
|
39
|
+
elsif add_month_numbers?
|
|
40
|
+
month_number.zero_padded(2) + ' - ' + month_names[month_number]
|
|
41
|
+
else
|
|
42
|
+
month_names[month_number]
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
end
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
ActiveForm::Element::Select::create :select_numeric_range do
|
|
2
|
+
|
|
3
|
+
attr_accessor :increment, :range, :subset
|
|
4
|
+
|
|
5
|
+
def casting_filter(value)
|
|
6
|
+
multiple? && value.respond_to?(:map) ? value.map { |val| normalize_value(val) } : normalize_value(value)
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def element_value
|
|
10
|
+
v = [*super].compact.map { |val| normalize_value(val) }.uniq
|
|
11
|
+
multiple? ? v : v.first
|
|
12
|
+
end
|
|
13
|
+
alias :values :element_value
|
|
14
|
+
alias :value :element_value
|
|
15
|
+
|
|
16
|
+
def normalize_value(value)
|
|
17
|
+
integer = value.respond_to?(:to_i) ? value.to_i : 0
|
|
18
|
+
valid_opts = self.option_values
|
|
19
|
+
incr = (self.increment || 1)
|
|
20
|
+
min_value = self.range.first
|
|
21
|
+
max_value = self.range.last
|
|
22
|
+
min = min_value.nearest(incr)
|
|
23
|
+
min = min + incr if min < min_value && incr > 1
|
|
24
|
+
max = max_value.nearest(incr)
|
|
25
|
+
max = max - incr if max > max_value && incr > 1
|
|
26
|
+
if valid_opts.include?(integer)
|
|
27
|
+
val = integer
|
|
28
|
+
else
|
|
29
|
+
val = integer.nearest(incr)
|
|
30
|
+
if val > min && val < max && !valid_opts.include?(val)
|
|
31
|
+
val = valid_opts.detect { |v| v >= integer }
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
(val > min_value ? (val > max_value ? max : val) : min)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def options
|
|
38
|
+
opts = []
|
|
39
|
+
opts << ActiveForm::Element::CollectionOption.new('--', :blank) if include_empty?
|
|
40
|
+
option_range = self.subset.kind_of?(Array) ? self.subset & self.range.to_a : self.range
|
|
41
|
+
if self.increment > 1 && self.range.kind_of?(Range)
|
|
42
|
+
(option_range).step(self.increment) { |i| opts << ActiveForm::Element::CollectionOption.new(number_to_label(i), i) }
|
|
43
|
+
else
|
|
44
|
+
option_range.to_a.each { |i| opts << ActiveForm::Element::CollectionOption.new(number_to_label(i), i) }
|
|
45
|
+
end
|
|
46
|
+
opts
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def number_to_label(i)
|
|
50
|
+
i.zero_padded(2)
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def update_options_and_attributes(hash)
|
|
54
|
+
self.increment = hash.delete(:increment) || hash.delete('increment') || 1
|
|
55
|
+
self.range = hash.delete(:range) || hash.delete('range') unless self.range.blank?
|
|
56
|
+
super(hash)
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
ActiveForm::Element::SelectNumericRange::create :select_second do
|
|
2
|
+
|
|
3
|
+
def range
|
|
4
|
+
(0..59)
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
def casting_filter(value)
|
|
8
|
+
value = case value
|
|
9
|
+
when Date then value.to_time.sec
|
|
10
|
+
when Time then value.sec
|
|
11
|
+
when Array, Range then value.to_a
|
|
12
|
+
else value.to_i rescue 0
|
|
13
|
+
end
|
|
14
|
+
super(value)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
end
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
class ActiveForm::Element::SelectTimebased < ActiveForm::Element::Section
|
|
2
|
+
|
|
3
|
+
TIME_FORMAT = [:year, :month, :day, :hour, :minute, :second].freeze
|
|
4
|
+
DEFAULT_VALUES = { :year => 2000, :month => 1, :day => 1, :hour => 12, :minute => 0, :second => 0 }.freeze
|
|
5
|
+
VALUE_CALL_MAP = { :year => :year, :month => :month, :day => :day, :hour => :hour, :minute => :min, :second => :sec }.freeze
|
|
6
|
+
|
|
7
|
+
def self.inherited(derivative)
|
|
8
|
+
super
|
|
9
|
+
derivative.class_inheritable_accessor :default_format
|
|
10
|
+
derivative.class_inheritable_accessor :allowed_parts
|
|
11
|
+
derivative.default_format = TIME_FORMAT
|
|
12
|
+
derivative.allowed_parts = TIME_FORMAT
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
class_inheritable_accessor :default_format
|
|
16
|
+
class_inheritable_accessor :allowed_parts
|
|
17
|
+
self.default_format = TIME_FORMAT
|
|
18
|
+
self.allowed_parts = TIME_FORMAT
|
|
19
|
+
|
|
20
|
+
attr_reader :now
|
|
21
|
+
attr_accessor :format
|
|
22
|
+
attr_accessor :start_year, :end_year, :range
|
|
23
|
+
|
|
24
|
+
attr_accessor :year_label, :month_label, :day_label
|
|
25
|
+
attr_accessor :year_increment, :month_increment, :day_increment
|
|
26
|
+
|
|
27
|
+
attr_accessor :hour_label, :minute_label, :second_label
|
|
28
|
+
attr_accessor :hour_increment, :minute_increment, :second_increment
|
|
29
|
+
|
|
30
|
+
def self.element_type
|
|
31
|
+
:select_timebased
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def now=(value)
|
|
35
|
+
@now = case value
|
|
36
|
+
when Date then value.to_time
|
|
37
|
+
when Time then value
|
|
38
|
+
else nil
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def render_element(builder = create_builder)
|
|
43
|
+
builder.div(element_attributes) { render_elements(builder) }
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def include_empty=(bool = true)
|
|
47
|
+
self.update_elements(:include_empty => bool)
|
|
48
|
+
end
|
|
49
|
+
alias :include_empty :include_empty=
|
|
50
|
+
|
|
51
|
+
def update_from_params(params, force = false)
|
|
52
|
+
super(casting_filter(params), force)
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
alias :original_export_value :export_value
|
|
56
|
+
|
|
57
|
+
def export_value(values = ActiveForm::Values.new)
|
|
58
|
+
export_value_as(self.type_cast)
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def export_value_as(type)
|
|
62
|
+
cast_value_to(original_export_value, type)
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def cast_value_to(value, type = :string)
|
|
66
|
+
if [:date, :time, :hash, :array, :string, :yaml].include?(type)
|
|
67
|
+
time_hash = default_element_values.merge(time_to_values(self.now, true)).merge(value)
|
|
68
|
+
(self.class.allowed_parts - elements_format).each { |part| time_hash[part] = 0 }
|
|
69
|
+
return time_hash if type == :hash
|
|
70
|
+
time_array = TIME_FORMAT.collect { |part| time_hash[part] || 0 }
|
|
71
|
+
return time_array if type == :array
|
|
72
|
+
time = Time.send(ActiveForm::Element::Base.default_timezone, *time_array) rescue nil
|
|
73
|
+
return time.to_date if type == :date && time.respond_to?(:to_date)
|
|
74
|
+
return time.to_formatted_s(:db) if type == :string && time.respond_to?(:to_formatted_s)
|
|
75
|
+
return time.to_yaml if type == :yaml
|
|
76
|
+
time
|
|
77
|
+
else
|
|
78
|
+
value
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def type_cast=(type = :string)
|
|
83
|
+
@type_cast = type.to_sym
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def casting_filter(value)
|
|
87
|
+
time = case value
|
|
88
|
+
when Date then value.to_time
|
|
89
|
+
when Time then value
|
|
90
|
+
when String then self.class.string_to_time(value)
|
|
91
|
+
when Hash then return ActiveForm::Values.new(value)
|
|
92
|
+
else nil
|
|
93
|
+
end
|
|
94
|
+
return default_element_values if time.nil?
|
|
95
|
+
time_to_values(time)
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
def after_initialize
|
|
99
|
+
elements_format.each do |part|
|
|
100
|
+
if self.class.allowed_parts.include?(part)
|
|
101
|
+
defaults = {}
|
|
102
|
+
defaults[:label] = self.send("#{part}_label") rescue part.to_s
|
|
103
|
+
defaults[:increment] = self.send("#{part}_increment") || 1 rescue 1
|
|
104
|
+
if part == :year
|
|
105
|
+
defaults[:range] = self.range if self.range.kind_of?(Range)
|
|
106
|
+
defaults[:start_year] = self.start_year if self.start_year.kind_of?(Integer)
|
|
107
|
+
defaults[:end_year] = self.end_year if self.end_year.kind_of?(Integer)
|
|
108
|
+
end
|
|
109
|
+
self.define_element("select_#{part}", "#{part}", defaults) do |e|
|
|
110
|
+
e.define_element_wrapper do |builder, elem, render|
|
|
111
|
+
builder.span(:id => "elem_#{elem.identifier}", :class => elem.css, :style => elem.style) { render.call(builder) }
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
elsif !part.kind_of?(Symbol)
|
|
115
|
+
self << part
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
update_values(default_element_values)
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
private
|
|
122
|
+
|
|
123
|
+
def elements_format
|
|
124
|
+
(self.format || self.class.default_format)
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
def default_element_values
|
|
128
|
+
(elements_format & self.class.allowed_parts).inject(ActiveForm::Values.new) do |values, part|
|
|
129
|
+
values[part] = default_value_for(part)
|
|
130
|
+
values
|
|
131
|
+
end
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
def time_to_values(time, all = false)
|
|
135
|
+
(all ? TIME_FORMAT : (elements_format & self.class.allowed_parts)).inject(ActiveForm::Values.new) do |values, part|
|
|
136
|
+
values[part] = time.send(VALUE_CALL_MAP[part]) if time.respond_to?(VALUE_CALL_MAP[part])
|
|
137
|
+
values
|
|
138
|
+
end
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
def default_value_for(part)
|
|
142
|
+
(now.kind_of?(Time) && now.respond_to?(VALUE_CALL_MAP[part]) ? now.send(VALUE_CALL_MAP[part]) : DEFAULT_VALUES[part].to_i) rescue 0
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
end
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
ActiveForm::Element::SelectNumericRange::create :select_weekday do
|
|
2
|
+
|
|
3
|
+
define_option_flags :use_short_day, :weekend_only, :weekdays_only
|
|
4
|
+
|
|
5
|
+
def to_dayname
|
|
6
|
+
multiple? ? element_value.map { |i| number_to_label(i) } : number_to_label(element_value)
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def export_value
|
|
10
|
+
exp_value = super
|
|
11
|
+
if self.type_cast == :string
|
|
12
|
+
to_dayname
|
|
13
|
+
else
|
|
14
|
+
exp_value
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def range
|
|
19
|
+
if weekend_only?
|
|
20
|
+
[6, 0]
|
|
21
|
+
elsif weekdays_only?
|
|
22
|
+
(1..5)
|
|
23
|
+
else
|
|
24
|
+
(0..6)
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def casting_for_string
|
|
29
|
+
[nil, nil]
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def casting_filter(value)
|
|
33
|
+
value = case value
|
|
34
|
+
when Date, Time then value.wday
|
|
35
|
+
when Array, Range then value.to_a
|
|
36
|
+
else value.to_i rescue 0
|
|
37
|
+
end
|
|
38
|
+
super(value)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def number_to_label(day_number)
|
|
42
|
+
day_names = use_short_day? ? Date::ABBR_DAYNAMES : Date::DAYNAMES rescue {}
|
|
43
|
+
day_names[day_number]
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
ActiveForm::Element::SelectNumericRange::create :select_year do
|
|
2
|
+
|
|
3
|
+
def range
|
|
4
|
+
@range ||= Range.new(Time.now.year - 5, Time.now.year + 5)
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
def start_year=(int)
|
|
8
|
+
@range = Range.new(int.to_i, self.range.last)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def end_year=(int)
|
|
12
|
+
@range = Range.new(self.range.first, int.to_i)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def casting_filter(value)
|
|
16
|
+
value = case value
|
|
17
|
+
when Date, Time then value.year
|
|
18
|
+
when Array, Range then value.to_a
|
|
19
|
+
else value.to_i rescue 0
|
|
20
|
+
end
|
|
21
|
+
super(value)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
end
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
module ActiveForm::Mixins::AttributeMethods
|
|
2
|
+
|
|
3
|
+
def self.included(base)
|
|
4
|
+
[:type].each { |m| base.send(:undef_method, m) rescue nil }
|
|
5
|
+
base.send(:extend, ClassMethods)
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def attributes
|
|
9
|
+
@attributes ||= HashWithIndifferentAccess.new
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def default_attributes
|
|
13
|
+
{ :id => identifier, :class => css }
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def attribute_names
|
|
17
|
+
[:style, :javascript, :title, :lang] + self.class.element_attribute_names.to_a
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
module ClassMethods
|
|
21
|
+
|
|
22
|
+
def define_attributes(*attrs)
|
|
23
|
+
attrs.push(:lang) unless self.element_attribute_names.include?(:lang)
|
|
24
|
+
attrs.flatten.each do |attribute|
|
|
25
|
+
self.element_attribute_names += [attribute.to_sym]
|
|
26
|
+
define_method("#{attribute}=") { |value| attributes[attribute] = value } unless instance_methods.include?("#{attribute}=")
|
|
27
|
+
define_method("#{attribute}") { attributes[attribute] } unless instance_methods.include?("#{attribute}")
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
end
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
module ActiveForm
|
|
2
|
+
module Mixins
|
|
3
|
+
module Casting
|
|
4
|
+
|
|
5
|
+
def self.included(base)
|
|
6
|
+
base.send(:extend, ClassMethods)
|
|
7
|
+
base.send(:attr_reader, :type_cast)
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def cast_value(value)
|
|
11
|
+
if self.respond_to?(:casting_filter)
|
|
12
|
+
self.casting_filter(value)
|
|
13
|
+
elsif self.class.respond_to?(:casting_filter)
|
|
14
|
+
self.class.casting_filter(value)
|
|
15
|
+
else
|
|
16
|
+
value
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def type_cast=(type = :string)
|
|
21
|
+
if self.respond_to?("casting_for_#{type}")
|
|
22
|
+
@type_cast = type.to_sym
|
|
23
|
+
cast, intern = self.send("casting_for_#{type}")
|
|
24
|
+
define_casting_filter(cast) if cast
|
|
25
|
+
define_formatting_filter(intern) if intern
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def casting_for_string
|
|
30
|
+
[lambda { |value| value.is_a?(String) ? value : value.to_s }, nil]
|
|
31
|
+
end
|
|
32
|
+
alias :casting_for_text :casting_for_string
|
|
33
|
+
|
|
34
|
+
def casting_for_integer
|
|
35
|
+
[lambda { |value| value.is_a?(Integer) ? value : value.to_i rescue value ? 1 : 0 }, nil]
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def casting_for_yaml
|
|
39
|
+
[self.class.method_to_proc(:yaml_to_data), self.class.method_to_proc(:data_to_yaml)]
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def casting_for_float
|
|
43
|
+
[lambda { |value| value.is_a?(Float) ? value : value.to_f rescue 0 }, nil]
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def casting_for_array
|
|
47
|
+
[lambda { |value| value.is_a?(Array) ? value : [*value] }, lambda { |value| [*value].join(', ') }]
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def casting_for_datetime
|
|
51
|
+
[self.class.method_to_proc(:string_to_time), self.class.method_to_proc(:time_to_string)]
|
|
52
|
+
end
|
|
53
|
+
alias :casting_for_timestamp :casting_for_datetime
|
|
54
|
+
|
|
55
|
+
def casting_for_time
|
|
56
|
+
[self.class.method_to_proc(:string_to_dummy_time), self.class.method_to_proc(:time_to_string)]
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def casting_for_date
|
|
60
|
+
[self.class.method_to_proc(:string_to_date), self.class.method_to_proc(:date_to_string)]
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def casting_for_boolean
|
|
64
|
+
[self.class.method_to_proc(:value_to_boolean), self.class.method_to_proc(:boolean_to_value)]
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def define_casting_filter(prc = nil, &block)
|
|
68
|
+
define_singleton_method(:casting_filter, &(block_given? ? block : prc))
|
|
69
|
+
end
|
|
70
|
+
alias :casting_filter= :define_casting_filter
|
|
71
|
+
|
|
72
|
+
def reset_casting_filter
|
|
73
|
+
define_singleton_method(:casting_filter) rescue nil
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
module ClassMethods
|
|
77
|
+
|
|
78
|
+
def define_casting_filter(prc = nil, &block)
|
|
79
|
+
define_singleton_method(:casting_filter, &(block_given? ? block : prc))
|
|
80
|
+
end
|
|
81
|
+
alias :casting_filter= :define_casting_filter
|
|
82
|
+
|
|
83
|
+
def reset_casting_filter
|
|
84
|
+
define_singleton_method(:casting_filter) rescue nil
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
# type casting methods
|
|
88
|
+
|
|
89
|
+
def binary_to_string(value)
|
|
90
|
+
value
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def data_to_yaml(value)
|
|
94
|
+
value.to_yaml
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
def yaml_to_data(value)
|
|
98
|
+
return value unless value.is_a?(String)
|
|
99
|
+
YAML::load(value) rescue nil
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
def string_to_date(string)
|
|
103
|
+
return string unless string.is_a?(String)
|
|
104
|
+
date_array = ParseDate.parsedate(string)
|
|
105
|
+
# treat 0000-00-00 as nil
|
|
106
|
+
Date.new(date_array[0], date_array[1], date_array[2]) rescue nil
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
def date_to_string(date)
|
|
110
|
+
date.respond_to?(:to_formatted_s) ? date.to_formatted_s(:long) : date.to_s
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
def string_to_time(string)
|
|
114
|
+
return string unless string.is_a?(String)
|
|
115
|
+
if string.strip.match(/^(\d{1,2})[:\.](\d{1,2})([:\.](\d{1,2}))?$/)
|
|
116
|
+
current_time = Time.now
|
|
117
|
+
string = "#{current_time.year}-#{current_time.month}-#{current_time.day} #{string}"
|
|
118
|
+
end
|
|
119
|
+
# treat 0000-00-00 00:00:00 as nil
|
|
120
|
+
time_array = ParseDate.parsedate(string)[0..5]
|
|
121
|
+
Time.send(ActiveForm::Element::Base.default_timezone, *time_array) rescue nil
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
def time_to_string(time)
|
|
125
|
+
time.respond_to?(:to_formatted_s) ? time.to_formatted_s(:long) : time.to_s
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
def string_to_dummy_time(string)
|
|
129
|
+
return string unless string.is_a?(String)
|
|
130
|
+
time_array = ParseDate.parsedate(string)
|
|
131
|
+
# pad the resulting array with dummy date information
|
|
132
|
+
time_array[0] = 2000; time_array[1] = 1; time_array[2] = 1;
|
|
133
|
+
Time.send(ActiveForm::Element::Base.default_timezone, *time_array) rescue nil
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
def value_to_boolean(value)
|
|
137
|
+
return value if value==true || value==false
|
|
138
|
+
case value.to_s.downcase
|
|
139
|
+
when "true", "t", "1" then true
|
|
140
|
+
else false
|
|
141
|
+
end
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
def boolean_to_value(boolean)
|
|
145
|
+
boolean ? "true" : "false"
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
end
|
|
151
|
+
end
|
|
152
|
+
end
|