schedulable 0.0.7 → 0.0.8

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 2f7a4518050fa937ff52f0e063aaaadba2947c90
4
- data.tar.gz: c3b07ace00ddf8dca91141e3c9042f2389acf033
3
+ metadata.gz: cf160baa485b91e6566ffb4a3d4914058237f634
4
+ data.tar.gz: edfc6d3c758cbdef642e633a1a32869f6a386327
5
5
  SHA512:
6
- metadata.gz: 5be2519e0114ea58aa2180ecf6373b62aab37f730baa32e0afa01e5ddfc747f7733dd447e862ad448efccb6d5b6d9aacfe1d60e6b2f881cc416cedc1a4a73b13
7
- data.tar.gz: 16a5641da65cb17518bb19e9f8219a9300e0a6afa9b813928c58345d02876bdd52ab14bc01971b2ac76474256b3fceaba61843e665c917932cec24a9c195a2eb
6
+ metadata.gz: 555836580530752b1eecf9cf85cf9b8f7a44f5d12fb62254555930f895608d7a644a3f555a5c98e09b1fdb366466733952eea3afd31d053a4567406d074145c7
7
+ data.tar.gz: a47bd73ac68eeff77a1dcecbcebab3d32c4e41a04fe429efe13d862d54397475f08f50f8a51ab3a2a8755e343c1d65090d031ed95b3904ca7593ec4fd98741a4
data/README.md CHANGED
@@ -1,9 +1,10 @@
1
1
  schedulable
2
2
  ===========
3
3
 
4
- Handling recurring events in rails.
4
+ > Handling recurring events in rails.
5
5
 
6
- ### Install
6
+
7
+ ## Install
7
8
 
8
9
  Put the following into your Gemfile and run `bundle install`
9
10
  ```cli
@@ -16,7 +17,7 @@ Install schedule migration and model
16
17
  rails g schedulable:install
17
18
  ```
18
19
 
19
- ### Basic Usage
20
+ ## Basic Usage
20
21
 
21
22
  Create an event model
22
23
  ```cli
@@ -27,15 +28,13 @@ Configure your model to be schedulable:
27
28
  ```
28
29
  # app/models/event.rb
29
30
  class Event < ActiveRecord::Base
30
- acts_as_schedulable
31
+ acts_as_schedulable :schedule
31
32
  end
32
33
  ```
33
34
  This will add an association to the model named 'schedule' which holds the schedule information.
34
35
 
35
- Now you're ready to setup form fields for the schedule association using the fields_for-form_helper.
36
-
37
- ### Attributes
38
- The schedule object respects the following attributes:
36
+ ### Schedule Model
37
+ The schedule-object respects the following attributes.
39
38
  <table>
40
39
  <tr>
41
40
  <th>Name</th><th>Type</th><th>Description</th>
@@ -50,10 +49,10 @@ The schedule object respects the following attributes:
50
49
  <td>time</td><td>Time</td><td>The time-attribute is used for singular events and also as starttime of the schedule</td>
51
50
  </tr>
52
51
  <tr>
53
- <td>days</td><td>Array</td><td>An array of weekday-names, i.e. ['monday', 'wednesday']</td>
52
+ <td>day</td><td>Array</td><td>Day of week. An array of weekday-names, i.e. ['monday', 'wednesday']</td>
54
53
  </tr>
55
54
  <tr>
56
- <td>day_of_week</td><td>Hash</td><td>A hash of weekday-names, containing arrays with indices, i.e. {:monday => [1, -1]} ('every first and last monday in month')</td>
55
+ <td>day_of_week</td><td>Hash</td><td>Day of nth week. A hash of weekday-names, containing arrays with indices, i.e. {:monday => [1, -1]} ('every first and last monday in month')</td>
57
56
  </tr>
58
57
  <tr>
59
58
  <td>interval</td><td>Integer</td><td>Specifies the interval of the recurring rule, i.e. every two weeks</td>
@@ -66,8 +65,83 @@ The schedule object respects the following attributes:
66
65
  </tr>
67
66
  </table>
68
67
 
69
- #### SimpleForm
70
- A custom input for simple_form is provided with the plugin. Make sure, you installed [SimpleForm](https://github.com/plataformatec/simple_form) and executed `rails generate simple_form:install`.
68
+ ## Forms
69
+
70
+ Use schedulable's built-in helpers to setup your form.
71
+
72
+ ### FormBuilder
73
+
74
+ Schedulable extends FormBuilder with a 'schedule_select'-helper and should therefore seamlessly integrate it with your existing views:
75
+
76
+ ```erb
77
+ <%# app/views/events/_form.html.erb %>
78
+ <%= form_for(@event) do |f| %>
79
+
80
+ <div class="field">
81
+ <%= f.label :name %><br>
82
+ <%= f.text_field :name %>
83
+ </div>
84
+
85
+ <div class="field">
86
+ <%= f.label :schedule %><br>
87
+ <%= f.schedule_select :schedule %>
88
+ </div>
89
+
90
+ <div class="actions">
91
+ <%= f.submit %>
92
+ </div>
93
+ <% end %>
94
+ ```
95
+
96
+ #### Customize markup
97
+ You can customize the generated markup by providing a hash of html-attributes as `style`-option. For wrappers, also provide a `tag`-attribute.
98
+ * field_html
99
+ * input_html
100
+ * input_wrapper
101
+ * label_html
102
+ * label_wrapper
103
+ * number_field_html
104
+ * number_field_wrapper
105
+ * date_select_html
106
+ * date_select_wrapper
107
+ * collection_select_html
108
+ * collection_select_wrapper
109
+ * collection_check_boxes_item_html
110
+ * collection_check_boxes_item_wrapper
111
+
112
+ #### Integrate with Bootstrap
113
+
114
+ The schedulable-formhelper has built-in-support for Bootstrap. Simply point the style-option of schedule_input to `bootstrap` or set it as default in config.
115
+
116
+ ```erb
117
+
118
+ <%= f.schedule_select :schedule, style: :bootstrap %>
119
+ ```
120
+
121
+ #### Options
122
+
123
+ <table>
124
+ <tr>
125
+ <th>Name</th><th>Type</th><th>Description</th>
126
+ </tr>
127
+ <tr>
128
+ <tr>
129
+ <td>count</td><td>Boolean</td><td>Specifies whether to show 'count'-field</td>
130
+ </tr>
131
+ <tr>
132
+ <td>interval</td><td>Boolean</td><td>Specifies whether to show 'interval'-field</td>
133
+ </tr>
134
+ <tr>
135
+ <td>style</td><td>Hash</td><td>Specifies a hash of options to customize markup. By providing a string, you can point to a prefined set of options. Built-in styles are :bootstrap and :default.
136
+ </tr>
137
+ <tr>
138
+ <td>until</td><td>Boolean</td><td>Specifies whether to show 'until'-field</td>
139
+ </tr>
140
+ </table>
141
+
142
+ ### SimpleForm
143
+ Also provided with the plugin is a custom input for simple_form. Make sure, you installed [SimpleForm](https://github.com/plataformatec/simple_form) and executed `rails generate simple_form:install`.
144
+
71
145
 
72
146
  ```cli
73
147
  rails g schedulable:simple_form
@@ -92,11 +166,57 @@ rails g schedulable:simple_form
92
166
  </div>
93
167
 
94
168
  <% end %>
169
+ ```
95
170
 
171
+ #### Integrate with Bootstrap
172
+
173
+ Simple Form has built-in support for Bootstrap as of version 3.0.0.
174
+ At time of writing it requires some a little extra portion of configuration to make it look as expected:
175
+
176
+ ```ruby
177
+ # config/initializers/simple_form_bootstrap.rb
178
+
179
+ # Inline date_select-wrapper for Bootstrap
180
+ config.wrappers :horizontal_select_date, tag: 'div', class: 'form-group', error_class: 'has-error' do |b|
181
+ b.use :html5
182
+ b.optional :readonly
183
+ b.use :label, class: 'control-label'
184
+ b.wrapper tag: 'div', class: 'form-inline' do |ba|
185
+ ba.use :input, class: 'form-control'
186
+ ba.use :error, wrap_with: { tag: 'span', class: 'help-block' }
187
+ ba.use :hint, wrap_with: { tag: 'p', class: 'help-block' }
188
+ end
189
+ end
190
+
191
+ # Include date_select-wrapper in mappings
192
+ config.wrapper_mappings = {
193
+ datetime: :horizontal_select_date,
194
+ date: :horizontal_select_date,
195
+ time: :horizontal_select_date
196
+ }
96
197
  ```
97
198
 
98
- #### Strong parameters
199
+ #### Options
200
+
201
+ <table>
202
+ <tr>
203
+ <th>Name</th><th>Type</th><th>Description</th>
204
+ </tr>
205
+ <tr>
206
+ <tr>
207
+ <td>count</td><td>Boolean</td><td>Specifies whether to show 'count'-field</td>
208
+ </tr>
209
+ <tr>
210
+ <td>interval</td><td>Boolean</td><td>Specifies whether to show 'interval'-field</td>
211
+ </tr>
212
+ <tr>
213
+ <td>until</td><td>Boolean</td><td>Specifies whether to show 'until'-field</td>
214
+ </tr>
215
+ </table>
216
+
217
+ ### Sanitize parameters
99
218
 
219
+ Add schedule-attributes to the list of strong parameters in your controller:
100
220
  ```
101
221
  # app/controllers/event_controller.rb
102
222
  def event_params
@@ -104,50 +224,52 @@ def event_params
104
224
  end
105
225
  ```
106
226
 
107
- ### IceCube
108
- The schedulable plugin uses ice_cube for calculating occurrences.
109
- You can access ice_cube-methods via the schedule association:
227
+ ## Accessing IceCube
228
+ You can access ice_cube-methods directly via the schedule association:
110
229
 
111
230
  ```ruby
112
231
  <%# app/views/events/show.html.erb %>
113
232
  <p>
114
233
  <strong>Schedule:</strong>
115
- <%# prints out a human-friendly description of the schedule, such as %>
234
+ <%# Prints out a human-friendly description of the schedule, such as %>
116
235
  <%= @event.schedule %>
117
236
  </p>
118
237
  ```
119
238
 
120
239
  ```
121
- # prints all occurrences of the event until one year from now
240
+ # Prints all occurrences of the event until one year from now
122
241
  puts @event.schedule.occurrences(Time.now + 1.year)
123
- # export to ical
242
+ # Export to ical
124
243
  puts @event.schedule.to_ical
125
244
  ```
126
245
  See [IceCube](https://github.com/seejohnrun/ice_cube) for more information.
127
246
 
128
- ### Internationalization
247
+ ## Internationalization
129
248
 
130
- At first you need to make sure you included all neccessary datetime translations.
131
- A basic setup can be found [here](https://github.com/svenfuchs/rails-i18n/tree/master/rails/locale).
249
+ Schedulable is bundled with translations in english and german which will be automatically initialized with your app.
250
+ You can customize these messages by running the locale generator and edit the created yml-files:
132
251
 
133
- #### Localize Schedulable
134
- Use the locale-generator to create a .yml-file containing schedulable messages in english:
135
252
  ```cli
136
- rails g schedulable:locale en
253
+ rails g schedulable:locale de
137
254
  ```
138
255
 
139
- Schedulable has also bundled messages in german. Use `de` as identifier.
256
+ ### Date- and Time-Messages
257
+ Appropriate datetime translations should be included.
258
+ Basic setup for many languages can be found here:
259
+ [https://github.com/svenfuchs/rails-i18n/tree/master/rails/locale](https://github.com/svenfuchs/rails-i18n/tree/master/rails/locale).
260
+
261
+
262
+ ### IceCube-Messages
263
+ An internationalization-branch of ice_cube can be found here:
264
+ [https://github.com/joelmeyerhamme/ice_cube](https://github.com/joelmeyerhamme/ice_cube):
140
265
 
141
- #### Localize Ice-Cube
142
- Internationalization of ice-cube itself can be integrated by using [this fork](https://github.com/joelmeyerhamme/ice_cube):
143
266
  ```ruby
144
267
  gem 'ice_cube', git: 'git://github.com/joelmeyerhamme/ice_cube.git', branch: 'international'
145
268
  ```
146
269
 
270
+ ## Persist Occurrences
147
271
 
148
- ### Persist event occurrences
149
- We need to have the occurrences persisted because we want to query the database for all occurrences of all instances of an event model or need to add additional attributes and functionality, such as allowing users to attend to a specific occurrence of an event.
150
- The schedulable gem handles this for you.
272
+ Schedulable allows for persisting occurrences and associate them with your model.
151
273
  Your occurrence model must include an attribute of type 'datetime' with name 'date' as well as a reference to your event model to setup up the association properly:
152
274
 
153
275
  ```ruby
@@ -161,19 +283,22 @@ class EventOccurrence < ActiveRecord::Base
161
283
  end
162
284
  ```
163
285
 
164
- Then you can simply declare your occurrences with the acts_as_schedule-method like this:
286
+ Declare occurrence-model with the acts_as_schedule-method like this:
165
287
  ```
166
288
  # app/models/event.rb
167
289
  class Event < ActiveRecord::Base
168
- acts_as_schedulable occurrences: :event_occurrences
290
+ acts_as_schedulable :schedule, occurrences: :event_occurrences
169
291
  end
170
292
  ```
171
- This will add a has_many-association with the name 'event_occurences' to your event-model.
172
- Instances of remaining occurrences are built when the schedule is saved.
173
- If the schedule has changed, the occurrences will be rebuilt if dates have also changed. Otherwise the time of the occurrence record will be adjusted to the new time.
174
- As in real life, previous occurrences will always stay untouched.
175
293
 
176
- #### Terminating and non-terminating events
294
+ This will add a `event_occurrences`-association to the model as well as `remaining_event_occurrences` and `previous_event_occurrences`-associations.
295
+
296
+ Instances of remaining occurrences are persisted when the parent-model is saved.
297
+
298
+ Occurrences records will be reused if their datetime matches the saved schedule.
299
+ Previous occurrences stay untouched.
300
+
301
+ ### Terminating and non-terminating events
177
302
  An event is terminating if an until- or count-attribute has been specified.
178
303
  Since non-terminating events have infinite occurrences, we cannot build all occurrences at once ;-)
179
304
  So we need to limit the number of occurrences in the database.
@@ -181,7 +306,7 @@ By default this will be one year from now.
181
306
  This can be configured via the 'build_max_count' and 'build_max_period'-options.
182
307
  See notes on configuration.
183
308
 
184
- #### Automate build of occurrences
309
+ ### Automate build of occurrences
185
310
  Since we cannot build all occurrences at once, we will need a task that adds occurrences as time goes by.
186
311
  Schedulable comes with a rake-task that performs an update on all scheduled occurrences.
187
312
 
@@ -191,7 +316,7 @@ rake schedulable:build_occurrences
191
316
 
192
317
  You may add this task to crontab.
193
318
 
194
- ##### Using 'whenever' to schedule build of occurrences
319
+ #### Using 'whenever' to schedule build of occurrences
195
320
 
196
321
  With the 'whenever' gem this can be easily achieved.
197
322
 
@@ -222,18 +347,25 @@ Write to crontab:
222
347
  whenever -w
223
348
  ```
224
349
 
225
- ### Configuration
350
+ ## Configuration
226
351
  Generate the configuration file
227
352
 
228
353
  ```cli
229
354
  rails g schedulable:config
230
355
  ```
231
356
 
232
- Open 'config/initializers/schedulable.rb' and edit options as you need:
357
+ Open 'config/initializers/schedulable.rb' and edit options as needed:
233
358
 
234
359
  ```ruby
235
360
  Schedulable.configure do |config|
236
361
  config.max_build_count = 0
237
362
  config.max_build_period = 1.year
363
+ config.form_helper = {
364
+ style: :default
365
+ }
238
366
  end
239
367
  ```
368
+
369
+
370
+ ## Changelog
371
+ See the [Changelog](CHANGELOG.md) for recent enhancements, bugfixes and deprecations.
data/Rakefile CHANGED
@@ -21,6 +21,9 @@ Bundler::GemHelper.install_tasks
21
21
 
22
22
  require 'rake/testtask'
23
23
 
24
+ APP_RAKEFILE = File.expand_path("../test/dummy/Rakefile", __FILE__)
25
+ load 'rails/tasks/engine.rake'
26
+
24
27
  Rake::TestTask.new(:test) do |t|
25
28
  t.libs << 'lib'
26
29
  t.libs << 'test'
@@ -0,0 +1,29 @@
1
+ de:
2
+ model:
3
+ schedule: 'Zeitplan'
4
+
5
+ activerecord:
6
+ attributes:
7
+ schedule:
8
+ name: Name
9
+ rule: Regel
10
+ time: Uhrzeit
11
+ date: Datum
12
+ day: Wochentage
13
+ day_of_week: "Wochentage im Monat"
14
+ interval: Intervall
15
+ until: Wiederholen bis
16
+ count: Anzahl Wiederholungen
17
+
18
+ schedulable:
19
+ monthly_week_names:
20
+ 1st: '1.'
21
+ 2nd: '2.'
22
+ 3rd: '3.'
23
+ 4th: '4.'
24
+ last: 'L'
25
+ rules:
26
+ singular: Einmalig
27
+ monthly: Monatlich
28
+ weekly: Wöchentlich
29
+ daily: Täglich
@@ -10,8 +10,8 @@ en:
10
10
  time: Time
11
11
  date: Date
12
12
  rule: Rule
13
- days: Weekdays
14
- day_of_week: Weekdays
13
+ day: Weekdays
14
+ day_of_week: Weekdays of nth week
15
15
  until: Repeat until
16
16
  count: Repetition count
17
17
 
@@ -8,7 +8,7 @@ module Schedulable
8
8
 
9
9
  def create_locale
10
10
  puts 'install locale'
11
- template "locale/schedulable.#{locale}.yml", "config/locales/schedulable.#{locale}.yml"
11
+ template "../../../../config/locales/#{locale}.yml", "config/locales/schedulable.#{locale}.yml"
12
12
  end
13
13
 
14
14
  end
@@ -1,4 +1,7 @@
1
1
  Schedulable.configure do |config|
2
- config.max_build_count = 0
3
- config.max_build_period = 1.year
2
+ config.max_count = 0
3
+ config.max_until = 1.year
4
+ config.form_helper = {
5
+ style: :default
6
+ }
4
7
  end
@@ -1,31 +1,52 @@
1
1
  class ScheduleInput < SimpleForm::Inputs::Base
2
2
 
3
-
4
- def input
3
+ def input(wrapper_options)
4
+
5
+
6
+ # I18n
5
7
  weekdays = Date::DAYNAMES.map(&:downcase)
6
- daynames = I18n.t('date.day_names')
7
- daylabels = Hash[weekdays.zip(daynames)]
8
8
  weekdays = weekdays.slice(1..7) << weekdays.slice(0)
9
-
10
- input_html_options[:type] ||= input_type if html5?
11
9
 
12
- # options
13
- input_options[:interval] = !input_options[:interval].nil? ? input_options[:interval] : true
14
- input_options[:until] = !input_options[:until].nil? ? input_options[:until] : true
15
- input_options[:count] = !input_options[:count].nil? ? input_options[:count] : true
10
+ day_names = I18n.t('date.day_names', default: "")
11
+ day_names = day_names.blank? ? weekdays.map { |day| day.capitalize } : day_names.slice(1..7) << day_names.slice(0)
12
+ day_labels = Hash[weekdays.zip(day_names)]
13
+
14
+ # Pass in default month names when missing in translations
15
+ month_names = I18n.t('date.month_names', default: "")
16
+ month_names = month_names.blank? ? Date::MONTHNAMES : month_names
17
+
18
+ # Pass in default order when missing in translations
19
+ date_order = I18n.t('date.order', default: "")
20
+ date_order = date_order.blank? ? [:year, :month, :day] : date_order
21
+
22
+ date_options = {
23
+ order: date_order,
24
+ use_month_names: month_names
25
+ }
16
26
 
27
+ # Input html options
28
+ input_html_options[:type] ||= input_type if html5?
29
+
30
+ # Input options
31
+ input_options[:interval] = !input_options[:interval].nil? ? input_options[:interval] : false
32
+ input_options[:until] = !input_options[:until].nil? ? input_options[:until] : false
33
+ input_options[:count] = !input_options[:count].nil? ? input_options[:count] : false
34
+
17
35
  @builder.simple_fields_for(:schedule, @builder.object.schedule || @builder.object.build_schedule) do |b|
36
+
37
+ # Javascript element id
38
+ field_id = b.object_name.to_s.gsub(/\]\[|[^-a-zA-Z0-9:.]/,"_").sub(/_$/,"")
18
39
 
19
- b.template.content_tag("div", {id: b.object_name.to_s.gsub(/\]\[|[^-a-zA-Z0-9:.]/,"_").sub(/_$/,"")}) do
40
+ b.template.content_tag("div", {id: field_id}) do
20
41
 
21
- b.input(:rule, collection: ['singular', 'daily', 'weekly', 'monthly'], label_method: lambda { |i| I18n.t("schedulable.rules.#{i}") || i.capitalize }, label: false) <<
42
+ b.input(:rule, collection: ['singular', 'daily', 'weekly', 'monthly'], label_method: lambda { |v| I18n.t("schedulable.rules.#{v}", default: v.capitalize) }, label: false, include_blank: false) <<
22
43
 
23
44
  template.content_tag("div", {data: {group: 'singular'}}) do
24
- b.input :date
45
+ b.input :date, date_options
25
46
  end <<
26
47
 
27
48
  template.content_tag("div", {data: {group: 'weekly'}}) do
28
- b.input :days, collection: weekdays, label_method: lambda { |v| ("&nbsp;" + daylabels[v]).html_safe}, as: :check_boxes
49
+ b.input :day, collection: weekdays, label_method: lambda { |v| ("&nbsp;" + day_labels[v]).html_safe}, boolean_style: :nested, as: :check_boxes
29
50
  end <<
30
51
 
31
52
  template.content_tag("div", {data: {group: 'monthly'}}) do
@@ -33,70 +54,79 @@ class ScheduleInput < SimpleForm::Inputs::Base
33
54
  b.simple_fields_for :day_of_week, OpenStruct.new(b.object.day_of_week || {}) do |db|
34
55
  template.content_tag("div", class: 'form-group' + (b.object.errors[:day_of_week].any? ? " has-error" : "")) do
35
56
  b.label(:day_of_week, error: true) <<
36
- template.content_tag("table", style: 'min-width: 280px') do
37
- template.content_tag("tr") do
38
- template.content_tag("td") <<
39
- ['1st', '2nd', '3rd', '4th', 'last'].reduce(''.html_safe) { | x, item |
40
- x << template.content_tag("td") do
41
- db.label(I18n.t("schedulable.monthly_week_names.#{item}") || item, required: false)
42
- end
57
+ template.content_tag("div", nil, style: 'min-width: 280px; display: table') do
58
+ template.content_tag("div", nil, style: 'display: table-row') do
59
+ template.content_tag("span", nil, style: 'display: table-cell;') <<
60
+ ['1st', '2nd', '3rd', '4th', 'last'].reduce(''.html_safe) { | content, item |
61
+ content << template.content_tag("span", I18n.t("schedulable.monthly_week_names.#{item}", default: item.to_s), style: 'display: table-cell; text-align: center')
43
62
  }
44
63
  end <<
45
- weekdays.reduce(''.html_safe) do | x, weekday |
46
- x << template.content_tag("tr") do
47
- template.content_tag("td") do
48
- db.label daylabels[weekday] || weekday, required: false
49
- end <<
50
- db.collection_check_boxes(weekday.to_sym, [1, 2, 3, 4, -1], lambda { |i| i} , lambda { |i| "&nbsp;".html_safe}, item_wrapper_tag: :td, checked: db.object.send(weekday))
64
+ weekdays.reduce(''.html_safe) do | content, weekday |
65
+ content << template.content_tag("div", nil, style: 'display: table-row') do
66
+ template.content_tag("span", day_labels[weekday] || weekday, style: 'display: table-cell') <<
67
+ db.collection_check_boxes(weekday.to_sym, [1, 2, 3, 4, -1], lambda { |i| i} , lambda { |i| "&nbsp;".html_safe}, checked: db.object.send(weekday), item_wrapper_tag: nil) do |cb|
68
+ template.content_tag("span", cb.check_box(), style: 'display: table-cell; text-align: center')
69
+ end
51
70
  end
52
71
  end
53
- end <<
72
+ end <<
54
73
  b.error(:day_of_week)
55
74
  end
56
75
  end
57
76
  end <<
58
77
 
59
- template.content_tag("div", {data: {group: 'singular,daily,weekly,monthly'}}) do
60
- b.input :time
78
+ template.content_tag("div", data: {group: 'singular,daily,weekly,monthly'}) do
79
+ b.input :time, date_options
61
80
  end <<
62
81
 
63
- (template.content_tag("div", {data: {group: 'daily,weekly,monthly'}}) do
64
- b.input :interval
65
- end if input_options[:interval]) <<
82
+ (if input_options[:interval]
83
+ template.content_tag("div", data: {group: 'daily,weekly,monthly'}) do
84
+ b.input :interval
85
+ end
86
+ else
87
+ b.input(:interval, as: :hidden, input_html: {value: 1})
88
+ end) <<
66
89
 
67
- (template.content_tag("div", {data: {group: 'daily,weekly,monthly'}}) do
68
- b.input :until
69
- end if input_options[:until]) <<
90
+ (if input_options[:until]
91
+ template.content_tag("div", data: {group: 'daily,weekly,monthly'}) do
92
+ b.input :until, date_options
93
+ end
94
+ else
95
+ b.input(:until, as: :hidden, input_html: {value: nil})
96
+ end) <<
70
97
 
71
- (template.content_tag("div", {data: {group: 'daily,weekly,monthly'}}) do
72
- b.input :count
73
- end if input_options[:count])
98
+ if input_options[:count]
99
+ template.content_tag("div", data: {group: 'daily,weekly,monthly'}) do
100
+ b.input :count
101
+ end
102
+ else
103
+ b.input(:count, as: :hidden, input_html: {value: 0})
104
+ end
74
105
 
75
106
 
76
107
 
77
108
  end <<
78
109
 
79
110
  template.javascript_tag(
80
- "$(function() {" <<
81
- " var container = $(\"*[id='#{b.object_name.to_s.gsub(/\]\[|[^-a-zA-Z0-9:.]/,"_").sub(/_$/,"")}']\");" <<
82
- " var select = container.find(\"select[name*='rule']\");" <<
111
+ "(function() {" <<
112
+ " var container = document.querySelectorAll('##{field_id}'); container = container[container.length - 1]; " <<
113
+ " var select = container.querySelector(\"select[name*='rule']\"); " <<
83
114
  " function update() {" <<
84
115
  " var value = this.value;" <<
85
- " container.find(\"*[data-group]\").each(function() {" <<
86
- " var groups = $(this).data('group').split(',');" <<
87
- " if ($.inArray(value, groups) >= 0) {" <<
88
- " $(this).css('display', '');" <<
116
+ " [].slice.call(container.querySelectorAll(\"*[data-group]\")).forEach(function(elem) { " <<
117
+ " var groups = elem.getAttribute('data-group').split(',');" <<
118
+ " if (groups.indexOf(value) >= 0) {" <<
119
+ " elem.style.display = ''" <<
89
120
  " } else {" <<
90
- " $(this).css('display', 'none');" <<
121
+ " elem.style.display = 'none'" <<
91
122
  " }" <<
92
123
  " });" <<
93
124
  " }" <<
94
- " select.on('change', update);" <<
95
- " update.call(select[0]);" <<
96
- "})"
125
+ " if (jQuery) { jQuery(select).on('change', update); } else { select.addEventListener('change', update); }" <<
126
+ " update.call(select);" <<
127
+ "})()"
97
128
  )
98
129
 
99
-
100
130
  end
101
131
 
102
132