schedulable 0.0.7 → 0.0.8
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 +4 -4
- data/README.md +174 -42
- data/Rakefile +3 -0
- data/config/locales/de.yml +29 -0
- data/{lib/generators/schedulable/templates/locale/schedulable.en.yml → config/locales/en.yml} +2 -2
- data/lib/generators/schedulable/locale_generator.rb +1 -1
- data/lib/generators/schedulable/templates/config/schedulable.rb +5 -2
- data/lib/generators/schedulable/templates/inputs/schedule_input.rb +81 -51
- data/lib/generators/schedulable/templates/migrations/create_schedules.rb +2 -2
- data/lib/generators/schedulable/templates/models/schedule.rb +1 -12
- data/lib/locales/en.yml +29 -0
- data/lib/{generators/schedulable/templates/locale → locales}/schedulable.de.yml +0 -0
- data/lib/schedulable.rb +7 -5
- data/lib/schedulable/acts_as_schedulable.rb +66 -59
- data/lib/schedulable/form_helper.rb +228 -0
- data/lib/schedulable/railtie.rb +21 -0
- data/lib/schedulable/schedule.rb +115 -0
- data/lib/schedulable/schedule_support.rb +1 -60
- data/lib/schedulable/version.rb +1 -1
- data/lib/tasks/schedulable_tasks.rake +1 -1
- metadata +8 -4
@@ -1,13 +1,2 @@
|
|
1
|
-
class Schedule <
|
2
|
-
|
3
|
-
include Schedulable::ScheduleSupport
|
4
|
-
|
5
|
-
serialize :days
|
6
|
-
serialize :day_of_week, Hash
|
7
|
-
|
8
|
-
belongs_to :schedulable, polymorphic: true
|
9
|
-
|
10
|
-
after_initialize :init_schedule
|
11
|
-
after_save :init_schedule
|
12
|
-
|
1
|
+
class Schedule < Schedulable::Model::Schedule
|
13
2
|
end
|
data/lib/locales/en.yml
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
en:
|
2
|
+
model:
|
3
|
+
schedule: 'Schedule'
|
4
|
+
|
5
|
+
activerecord:
|
6
|
+
attributes:
|
7
|
+
schedule:
|
8
|
+
name: Name
|
9
|
+
rule: Regel
|
10
|
+
time: Time
|
11
|
+
date: Date
|
12
|
+
rule: Rule
|
13
|
+
day: Weekdays
|
14
|
+
day_of_week: Weekdays of nth week
|
15
|
+
until: Repeat until
|
16
|
+
count: Repetition count
|
17
|
+
|
18
|
+
schedulable:
|
19
|
+
monthly_week_names:
|
20
|
+
1st: '1st'
|
21
|
+
2nd: '2nd'
|
22
|
+
3rd: '3rd'
|
23
|
+
4th: '4th'
|
24
|
+
last: 'Last'
|
25
|
+
rules:
|
26
|
+
singular: Singular
|
27
|
+
monthly: Monthly
|
28
|
+
weekly: Weekly
|
29
|
+
daily: Daily
|
File without changes
|
data/lib/schedulable.rb
CHANGED
@@ -1,16 +1,18 @@
|
|
1
|
-
require 'schedulable/railtie
|
2
|
-
require 'schedulable/acts_as_schedulable
|
3
|
-
require 'schedulable/
|
1
|
+
require 'schedulable/railtie' if defined? ::Rails::Railtie
|
2
|
+
require 'schedulable/acts_as_schedulable'
|
3
|
+
require 'schedulable/schedule'
|
4
|
+
require 'schedulable/schedule_support'
|
5
|
+
require 'schedulable/form_helper'
|
4
6
|
require 'i18n'
|
5
7
|
|
6
8
|
module Schedulable
|
7
9
|
|
8
10
|
class Config
|
9
|
-
attr_accessor :max_build_count, :max_build_period
|
11
|
+
attr_accessor :max_build_count, :max_build_period, :form_helper, :update_mode
|
10
12
|
end
|
11
13
|
|
12
14
|
def self.config
|
13
|
-
@@config
|
15
|
+
@@config||= Config.new
|
14
16
|
end
|
15
17
|
|
16
18
|
def self.configure
|
@@ -9,9 +9,9 @@ module Schedulable
|
|
9
9
|
|
10
10
|
module ClassMethods
|
11
11
|
|
12
|
-
def acts_as_schedulable(options = {})
|
12
|
+
def acts_as_schedulable(name, options = {})
|
13
13
|
|
14
|
-
name
|
14
|
+
name||= :schedule
|
15
15
|
attribute = :date
|
16
16
|
|
17
17
|
has_one name, as: :schedulable, dependent: :destroy
|
@@ -37,8 +37,6 @@ module Schedulable
|
|
37
37
|
# table_name
|
38
38
|
occurrences_table_name = occurrences_association.to_s.tableize
|
39
39
|
|
40
|
-
puts "SCHEDULABLE OCCURRENCES TABLE NAME: " + occurrences_table_name.to_s
|
41
|
-
|
42
40
|
# remaining
|
43
41
|
remaining_occurrences_options = options[:occurrences].clone
|
44
42
|
remaining_occurrences_association = ("remaining_" << occurrences_association.to_s).to_sym
|
@@ -58,7 +56,6 @@ module Schedulable
|
|
58
56
|
# build occurrences for all events
|
59
57
|
# TODO: only invalid events
|
60
58
|
schedulables = self.all
|
61
|
-
puts "build occurrences for #{schedulables.length} #{self.name.tableize}"
|
62
59
|
schedulables.each do |schedulable|
|
63
60
|
schedulable.send("build_#{occurrences_association}")
|
64
61
|
end
|
@@ -67,93 +64,103 @@ module Schedulable
|
|
67
64
|
|
68
65
|
define_method "build_#{occurrences_association}" do
|
69
66
|
|
67
|
+
puts 'build occurrences...'
|
68
|
+
|
70
69
|
# build occurrences for events
|
71
70
|
|
72
71
|
schedule = self.send(name)
|
73
72
|
|
74
73
|
now = Time.now
|
75
|
-
|
74
|
+
|
75
|
+
# TODO: Make configurable
|
76
|
+
occurrence_attribute = :date
|
76
77
|
|
77
78
|
schedulable = schedule.schedulable
|
78
|
-
terminating = schedule.until.present? || schedule.count.present? && schedule.count >
|
79
|
-
|
80
|
-
|
81
|
-
max_date = now +
|
79
|
+
terminating = schedule.rule != 'singular' && (schedule.until.present? || schedule.count.present? && schedule.count > 1)
|
80
|
+
|
81
|
+
max_period = Schedulable.config.max_build_period || 1.year
|
82
|
+
max_date = now + max_period
|
83
|
+
|
82
84
|
max_date = terminating ? [max_date, schedule.last.to_time].min : max_date
|
83
85
|
|
84
|
-
|
85
|
-
|
86
|
+
max_count = Schedulable.config.max_build_count || 100
|
87
|
+
max_count = terminating && schedule.remaining_occurrences.any? ? [max_count, schedule.remaining_occurrences.count].min : max_count
|
86
88
|
|
87
|
-
|
88
|
-
|
89
|
-
#
|
90
|
-
occurrences = schedule.next_occurrences(max_build_count)
|
91
|
-
end
|
92
|
-
|
93
|
-
if !occurrences || occurrences.last && occurrences.last.to_time > max_date
|
94
|
-
# get next occurrences for max_date
|
89
|
+
if schedule.rule != 'singular'
|
90
|
+
|
91
|
+
# Get schedule occurrences
|
95
92
|
all_occurrences = schedule.occurrences(max_date)
|
96
93
|
occurrences = []
|
97
|
-
#
|
98
|
-
all_occurrences.
|
99
|
-
if occurrence_date.to_time > now
|
100
|
-
|
94
|
+
# Filter valid dates
|
95
|
+
all_occurrences.each_with_index do |occurrence_date, index|
|
96
|
+
if occurrence_date.present? && occurrence_date.to_time > now
|
97
|
+
if occurrence_date.to_time < max_date && index < max_count
|
98
|
+
occurrences << occurrence_date
|
99
|
+
else
|
100
|
+
max_date = [max_date, occurrence_date].min
|
101
|
+
end
|
101
102
|
end
|
102
103
|
end
|
104
|
+
|
105
|
+
else
|
106
|
+
singular_date_time = schedule.date.to_datetime + schedule.time.seconds_since_midnight.seconds
|
107
|
+
occurrences = [singular_date_time]
|
103
108
|
end
|
104
109
|
|
110
|
+
# Build occurrences
|
111
|
+
update_mode = Schedulable.config.update_mode || :datetime
|
105
112
|
|
106
|
-
|
113
|
+
# Get existing remaining records
|
114
|
+
occurrences_records = schedulable.send("remaining_#{occurrences_association}")
|
107
115
|
|
108
116
|
# build occurrences
|
109
|
-
|
110
|
-
|
111
|
-
|
117
|
+
existing_record = nil
|
118
|
+
occurrences.each_with_index do |occurrence, index|
|
119
|
+
|
120
|
+
# Pull an existing record
|
121
|
+
|
122
|
+
if update_mode == :index
|
123
|
+
existing_records = [occurrences_records[index]]
|
124
|
+
elsif update_mode == :datetime
|
125
|
+
existing_records = occurrences_records.select { |record|
|
126
|
+
record.date.to_datetime == occurrence.to_datetime
|
127
|
+
}
|
128
|
+
else
|
129
|
+
existing_records = []
|
130
|
+
end
|
131
|
+
|
132
|
+
if existing_records.any?
|
133
|
+
# Overwrite existing records
|
134
|
+
existing_records.each do |existing_record|
|
135
|
+
if !occurrences_records.update(existing_record.id, date: occurrence.to_datetime)
|
136
|
+
puts 'an error occurred while saving an existing occurrence record'
|
137
|
+
end
|
138
|
+
end
|
139
|
+
else
|
140
|
+
# Create new record
|
141
|
+
if !occurrences_records.create(date: occurrence.to_datetime)
|
142
|
+
puts 'an error occurred while creating an occurrence record'
|
143
|
+
end
|
144
|
+
end
|
112
145
|
end
|
113
146
|
|
114
|
-
occurrences_records = schedulable.send(occurrences_association)
|
115
147
|
|
116
|
-
#
|
148
|
+
# Clean up unused remaining occurrences
|
149
|
+
occurrences_records = schedulable.send("remaining_#{occurrences_association}")
|
117
150
|
record_count = 0
|
118
151
|
occurrences_records.each do |occurrence_record|
|
119
152
|
if occurrence_record.date > now
|
120
|
-
#
|
121
|
-
if !schedule.occurs_on?(occurrence_record.date) || occurrence_record.date > max_date || record_count >
|
122
|
-
|
123
|
-
puts 'an error occurred while destroying an unused occurrence record'
|
124
|
-
end
|
153
|
+
# Destroy occurrence if date or count lies beyond range
|
154
|
+
if schedule.rule != 'singular' && (!schedule.occurs_on?(occurrence_record.date.to_date) || !schedule.occurring_at?(occurrence_record.date.to_time) || occurrence_record.date > max_date) || schedule.rule == 'singular' && record_count > 0
|
155
|
+
occurrences_records.destroy(occurrence_record)
|
125
156
|
end
|
126
157
|
record_count = record_count + 1
|
127
158
|
end
|
128
159
|
end
|
129
160
|
|
130
|
-
# build occurrences
|
131
|
-
occurrences.each do |occurrence|
|
132
|
-
|
133
|
-
# filter existing occurrence records
|
134
|
-
existing = occurrences_records.select { |record|
|
135
|
-
record.date.to_date == occurrence.to_date
|
136
|
-
}
|
137
|
-
if existing.length > 0
|
138
|
-
# a record for this date already exists, adjust time
|
139
|
-
existing.each { |record|
|
140
|
-
#record.date = occurrence.to_datetime
|
141
|
-
if !occurrences_records.update(record, date: occurrence.to_datetime)
|
142
|
-
puts 'an error occurred while saving an existing occurrence record'
|
143
|
-
end
|
144
|
-
}
|
145
|
-
else
|
146
|
-
# create new record
|
147
|
-
if !occurrences_records.create(date: occurrence.to_datetime)
|
148
|
-
puts 'an error occurred while creating an occurrence record'
|
149
|
-
end
|
150
|
-
end
|
151
|
-
end
|
152
|
-
|
153
161
|
end
|
154
162
|
|
155
163
|
end
|
156
|
-
|
157
164
|
end
|
158
165
|
|
159
166
|
end
|
@@ -0,0 +1,228 @@
|
|
1
|
+
module Schedulable
|
2
|
+
module FormHelper
|
3
|
+
|
4
|
+
STYLES = {
|
5
|
+
default: {
|
6
|
+
field_html: {class: 'field'},
|
7
|
+
input_wrapper: {tag: 'div'}
|
8
|
+
},
|
9
|
+
bootstrap: {
|
10
|
+
field_html: {class: 'field form-group'},
|
11
|
+
num_field_html: {class: 'form-control'},
|
12
|
+
date_select_html: {class: 'form-control'},
|
13
|
+
date_select_wrapper: {tag: 'div', class: 'form-inline'},
|
14
|
+
collection_select_html: {class: 'form-control'},
|
15
|
+
collection_check_boxes_item_wrapper: {tag: 'span', class: 'checkbox'}
|
16
|
+
}
|
17
|
+
}
|
18
|
+
|
19
|
+
def self.included(base)
|
20
|
+
ActionView::Helpers::FormBuilder.instance_eval do
|
21
|
+
include FormBuilderMethods
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
module FormBuilderMethods
|
26
|
+
|
27
|
+
def schedule_select(attribute, input_options = {})
|
28
|
+
|
29
|
+
template = @template
|
30
|
+
|
31
|
+
weekdays = Date::DAYNAMES.map(&:downcase)
|
32
|
+
weekdays = weekdays.slice(1..7) << weekdays.slice(0)
|
33
|
+
|
34
|
+
day_names = I18n.t('date.day_names', default: "")
|
35
|
+
day_names = day_names.blank? ? weekdays.map { |day| day.capitalize } : day_names.slice(1..7) << day_names.slice(0)
|
36
|
+
day_labels = Hash[weekdays.zip(day_names)]
|
37
|
+
|
38
|
+
# Pass in default month names when missing in translations
|
39
|
+
month_names = I18n.t('date.month_names', default: "")
|
40
|
+
month_names = month_names.blank? ? Date::MONTHNAMES : month_names
|
41
|
+
|
42
|
+
# Pass in default order when missing in translations
|
43
|
+
date_order = I18n.t('date.order', default: [:year, :month, :day])
|
44
|
+
date_order = date_order.map { |order|
|
45
|
+
order.to_sym
|
46
|
+
}
|
47
|
+
|
48
|
+
date_options = {
|
49
|
+
order: date_order,
|
50
|
+
use_month_names: month_names
|
51
|
+
}
|
52
|
+
|
53
|
+
# form helper style options
|
54
|
+
|
55
|
+
config_options = Schedulable.config.form_helper.present? ? Schedulable.config.form_helper : {style: :default}
|
56
|
+
|
57
|
+
input_options = config_options.merge(input_options)
|
58
|
+
|
59
|
+
# Setup style options
|
60
|
+
if input_options[:style].is_a?(Symbol) || input_options[:style].is_a?(String)
|
61
|
+
style_options = STYLES.has_key?(input_options[:style]) ? STYLES[input_options[:style]] : STYLES[:default]
|
62
|
+
elsif input_options[:style].is_a?(Hash)
|
63
|
+
style_options = input_options[:style]
|
64
|
+
else
|
65
|
+
style_options = STYLES[:default]
|
66
|
+
end
|
67
|
+
|
68
|
+
# Merge with general options
|
69
|
+
style_options = style_options.merge(input_options)
|
70
|
+
|
71
|
+
style_options[:field_html]||= {}
|
72
|
+
|
73
|
+
style_options[:label_html]||= {}
|
74
|
+
style_options[:label_wrapper]||= {}
|
75
|
+
|
76
|
+
style_options[:input_html]||= {}
|
77
|
+
style_options[:input_wrapper]||= {}
|
78
|
+
|
79
|
+
style_options[:number_field_html]||= {}
|
80
|
+
style_options[:number_field_wrapper]||= {}
|
81
|
+
|
82
|
+
style_options[:date_select_html]||= {}
|
83
|
+
style_options[:date_select_wrapper]||= {}
|
84
|
+
|
85
|
+
style_options[:collection_select_html]||= {}
|
86
|
+
style_options[:collection_select_wrapper]||= {}
|
87
|
+
|
88
|
+
style_options[:collection_check_boxes_item_html]||= {}
|
89
|
+
style_options[:collection_check_boxes_item_wrapper]||= {}
|
90
|
+
|
91
|
+
# Merge with input options
|
92
|
+
style_options[:number_field_html] = style_options[:input_html].merge(style_options[:number_field_html])
|
93
|
+
style_options[:number_field_wrapper] = style_options[:input_wrapper].merge(style_options[:number_field_wrapper])
|
94
|
+
|
95
|
+
style_options[:date_select_html] = style_options[:input_html].merge(style_options[:date_select_html])
|
96
|
+
style_options[:date_select_wrapper] = style_options[:input_wrapper].merge(style_options[:date_select_wrapper])
|
97
|
+
|
98
|
+
style_options[:collection_select_html] = style_options[:input_html].merge(style_options[:collection_select_html])
|
99
|
+
style_options[:collection_select_wrapper] = style_options[:input_wrapper].merge(style_options[:collection_select_wrapper])
|
100
|
+
|
101
|
+
style_options[:collection_check_boxes_item_html] = style_options[:input_html].merge(style_options[:collection_check_boxes_item_html])
|
102
|
+
style_options[:collection_check_boxes_item_wrapper] = style_options[:input_wrapper].merge(style_options[:collection_check_boxes_item_wrapper])
|
103
|
+
|
104
|
+
|
105
|
+
# Javascript element id
|
106
|
+
field_id = @object_name.to_s.gsub(/\]\[|[^-a-zA-Z0-9:.]/,"_").sub(/_$/,"") + "_" + attribute.to_s
|
107
|
+
|
108
|
+
@template.content_tag("div", {id: field_id}) do
|
109
|
+
|
110
|
+
self.fields_for(attribute, @object.send(attribute.to_s) || @object.send("build_" + attribute.to_s)) do |f|
|
111
|
+
|
112
|
+
@template.content_tag("div", style_options[:field_html]) do
|
113
|
+
select_output = f.collection_select(:rule, ['singular', 'daily', 'weekly', 'monthly'], lambda { |v| return v}, lambda { |v| I18n.t("schedulable.rules.#{v}", default: v.capitalize) }, {include_blank: false}, style_options[:collection_select_html])
|
114
|
+
content_wrap(@template, select_output, style_options[:collection_select_wrapper])
|
115
|
+
end <<
|
116
|
+
|
117
|
+
@template.content_tag("div", style_options[:field_html].merge({data: {group: 'singular'}})) do
|
118
|
+
content_wrap(@template, f.label(:date, style_options[:label_html]), style_options[:label_wrapper]) <<
|
119
|
+
content_wrap(@template, f.date_select(:date, date_options, style_options[:date_select_html]), style_options[:date_select_wrapper])
|
120
|
+
end <<
|
121
|
+
|
122
|
+
@template.content_tag("div", style_options[:field_html].merge({data: {group: 'weekly'}})) do
|
123
|
+
content_wrap(@template, f.label(:day), style_options[:label_wrapper]) <<
|
124
|
+
f.collection_check_boxes(:day, weekdays, lambda { |v| return v}, lambda { |v| (" " + day_labels[v]).html_safe}) do |cb|
|
125
|
+
check_box_output = cb.check_box(style_options[:collection_check_boxes_item_html])
|
126
|
+
text = cb.text
|
127
|
+
nested_output = cb.label({}) do |l|
|
128
|
+
check_box_output + text
|
129
|
+
end
|
130
|
+
content_wrap(@template, nested_output, style_options[:collection_check_boxes_item_wrapper])
|
131
|
+
end
|
132
|
+
end <<
|
133
|
+
|
134
|
+
@template.content_tag("div", style_options[:field_html].merge({data: {group: 'monthly'}})) do
|
135
|
+
f.fields_for :day_of_week, OpenStruct.new(f.object.day_of_week || {}) do |db|
|
136
|
+
content_wrap(@template, f.label(:day_of_week), style_options[:label_wrapper]) <<
|
137
|
+
@template.content_tag("div", nil, style: 'min-width: 280px; display: table') do
|
138
|
+
@template.content_tag("div", nil, style: 'display: table-row') do
|
139
|
+
@template.content_tag("span", nil, style: 'display: table-cell;') <<
|
140
|
+
['1st', '2nd', '3rd', '4th', 'last'].reduce(''.html_safe) { | content, item |
|
141
|
+
content << @template.content_tag("span", I18n.t("schedulable.monthly_week_names.#{item}", default: item.to_s), style: 'display: table-cell; text-align: center')
|
142
|
+
}
|
143
|
+
end <<
|
144
|
+
weekdays.reduce(''.html_safe) do | content, weekday |
|
145
|
+
content << @template.content_tag("div", nil, style: 'display: table-row') do
|
146
|
+
@template.content_tag("span", day_labels[weekday] || weekday, style: 'display: table-cell') <<
|
147
|
+
db.collection_check_boxes(weekday.to_sym, [1, 2, 3, 4, -1], lambda { |i| i} , lambda { |i| " ".html_safe}, checked: db.object.send(weekday)) do |cb|
|
148
|
+
@template.content_tag("span", style: 'display: table-cell; text-align: center') { cb.check_box() }
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end <<
|
155
|
+
|
156
|
+
@template.content_tag("div", style_options[:field_html].merge({data: {group: 'singular,daily,weekly,monthly'}})) do
|
157
|
+
content_wrap(@template, f.label(:time, style_options[:label_html]), style_options[:label_wrapper]) <<
|
158
|
+
content_wrap(@template, f.time_select(:time, date_options, style_options[:date_select_html]), style_options[:date_select_wrapper])
|
159
|
+
end <<
|
160
|
+
|
161
|
+
(if input_options[:interval]
|
162
|
+
@template.content_tag("div", style_options[:field_html].merge({data: {group: 'daily,weekly,monthly'}})) do
|
163
|
+
content_wrap(@template, f.label(:interval, style_options[:label_html]), style_options[:label_wrapper]) <<
|
164
|
+
content_wrap(@template, f.number_field(:interval, style_options[:number_field_html]), style_options[:number_field_wrapper])
|
165
|
+
end
|
166
|
+
else
|
167
|
+
f.hidden_field(:interval, value: 1)
|
168
|
+
end) <<
|
169
|
+
|
170
|
+
(if input_options[:until]
|
171
|
+
@template.content_tag("div", style_options[:field_html].merge({data: {group: 'daily,weekly,monthly'}})) do
|
172
|
+
content_wrap(@template, f.label(:until, style_options[:label_html]), style_options[:label_wrapper]) <<
|
173
|
+
content_wrap(@template, f.datetime_select(:until, date_options, style_options[:date_select_html]), style_options[:date_select_wrapper])
|
174
|
+
end
|
175
|
+
else
|
176
|
+
f.hidden_field(:until, value: nil)
|
177
|
+
end) <<
|
178
|
+
|
179
|
+
if input_options[:count]
|
180
|
+
@template.content_tag("div", style_options[:field_html].merge({data: {group: 'daily,weekly,monthly'}})) do
|
181
|
+
content_wrap(@template, f.label(:count, style_options[:label_html]), style_options[:label_wrapper]) <<
|
182
|
+
content_wrap(@template, f.number_field(:count, style_options[:number_field_html]), style_options[:number_field_wrapper])
|
183
|
+
end
|
184
|
+
else
|
185
|
+
f.hidden_field(:count, value: 0)
|
186
|
+
end
|
187
|
+
|
188
|
+
end
|
189
|
+
|
190
|
+
end <<
|
191
|
+
|
192
|
+
template.javascript_tag(
|
193
|
+
"(function() {" <<
|
194
|
+
" var container = document.querySelectorAll('##{field_id}'); container = container[container.length - 1]; " <<
|
195
|
+
" var select = container.querySelector(\"select[name*='rule']\"); " <<
|
196
|
+
" function update() {" <<
|
197
|
+
" var value = this.value;" <<
|
198
|
+
" [].slice.call(container.querySelectorAll(\"*[data-group]\")).forEach(function(elem) { " <<
|
199
|
+
" var groups = elem.getAttribute('data-group').split(',');" <<
|
200
|
+
" if (groups.indexOf(value) >= 0) {" <<
|
201
|
+
" elem.style.display = ''" <<
|
202
|
+
" } else {" <<
|
203
|
+
" elem.style.display = 'none'" <<
|
204
|
+
" }" <<
|
205
|
+
" });" <<
|
206
|
+
" }" <<
|
207
|
+
" if (jQuery) { jQuery(select).on('change', update); } else { select.addEventListener('change', update); }" <<
|
208
|
+
" update.call(select);" <<
|
209
|
+
"})()"
|
210
|
+
)
|
211
|
+
|
212
|
+
end
|
213
|
+
|
214
|
+
|
215
|
+
private
|
216
|
+
def content_wrap(template, content, options = nil)
|
217
|
+
if options.present? && options.has_key?(:tag)
|
218
|
+
template.content_tag(options[:tag], content, options.except(:tag))
|
219
|
+
else
|
220
|
+
content
|
221
|
+
end
|
222
|
+
end
|
223
|
+
|
224
|
+
end
|
225
|
+
|
226
|
+
|
227
|
+
end
|
228
|
+
end
|