diff --git a/Gemfile b/Gemfile index f9e1be74..95492857 100644 --- a/Gemfile +++ b/Gemfile @@ -5,6 +5,7 @@ gem 'pg', platform: :ruby gem 'activerecord-jdbcpostgresql-adapter', platform: :jruby gem 'jquery-rails' +gem 'jquery-ui-rails', '>= 6.0' gem 'rails', '~> 4.0.12' gem 'sass-rails', '~> 4.0.5' diff --git a/Gemfile.lock b/Gemfile.lock index 0add2dbb..ab663096 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -5,6 +5,7 @@ PATH coffee-rails (>= 3.1) ice_cube (>= 0.11) jquery-rails (>= 3.0) + jquery-ui-rails (>= 6.0) rails (>= 3.2) sass-rails (>= 4.0) @@ -48,16 +49,18 @@ GEM erubis (2.7.0) execjs (2.7.0) hike (1.2.3) - i18n (0.7.0) + i18n (0.8.6) ice_cube (0.16.2) jquery-rails (3.1.2) railties (>= 3.0, < 5.0) thor (>= 0.14, < 2.0) + jquery-ui-rails (6.0.1) + railties (>= 3.2.16) mail (2.6.3) mime-types (>= 1.16, < 3) mime-types (2.6.2) minitest (4.7.5) - multi_json (1.11.2) + multi_json (1.12.1) pg (0.17.1) rack (1.5.5) rack-test (0.6.3) @@ -75,7 +78,7 @@ GEM activesupport (= 4.0.13) rake (>= 0.8.7) thor (>= 0.18.1, < 2.0) - rake (10.4.2) + rake (12.0.0) rspec (3.1.0) rspec-core (~> 3.1.0) rspec-expectations (~> 3.1.0) @@ -111,10 +114,10 @@ GEM actionpack (>= 3.0) activesupport (>= 3.0) sprockets (>= 2.8, < 4.0) - thor (0.19.1) - thread_safe (0.3.5) + thor (0.19.4) + thread_safe (0.3.6) tilt (1.4.1) - tzinfo (0.3.44) + tzinfo (0.3.53) PLATFORMS ruby @@ -123,6 +126,7 @@ DEPENDENCIES activerecord-jdbcpostgresql-adapter bundler (>= 1.3.5) jquery-rails + jquery-ui-rails (>= 6.0) pg rails (~> 4.0.12) rake (>= 0.9.6) diff --git a/app/assets/javascripts/recurring_select.js.coffee b/app/assets/javascripts/recurring_select.js.coffee index d4932139..7d671c85 100644 --- a/app/assets/javascripts/recurring_select.js.coffee +++ b/app/assets/javascripts/recurring_select.js.coffee @@ -1,3 +1,4 @@ +//= require jquery-ui/widgets/datepicker //= require recurring_select_dialog //= require_self @@ -95,6 +96,11 @@ $.fn.recurring_select.texts = { years: "year(s)" day_of_month: "Day of month" day_of_week: "Day of week" + ends: "Ends" + never: "Never" + after: "After" + occurrences: "occurrences" + on: "On" cancel: "Cancel" ok: "OK" summary: "Summary" diff --git a/app/assets/javascripts/recurring_select_dialog.js.coffee.erb b/app/assets/javascripts/recurring_select_dialog.js.coffee.erb index baeccd6a..03243aa0 100644 --- a/app/assets/javascripts/recurring_select_dialog.js.coffee.erb +++ b/app/assets/javascripts/recurring_select_dialog.js.coffee.erb @@ -20,6 +20,7 @@ window.RecurringSelectDialog = @positionDialogVert(true) @mainEventInit() @freqInit() + @terminationInit() @summaryInit() @outer_holder.trigger "recurring_select:dialog_opened" @freq_select.focus() @@ -141,6 +142,31 @@ window.RecurringSelectDialog = interval_input.on "change keyup", @intervalChanged section.show() + terminationInit: -> + @until_date = @outer_holder.find '#rs_until_date' + @until_date.datepicker({ dateFormat: 'yy-mm-dd', minDate: 0 }) + if @current_rule.hash? && @current_rule.hash.count? + @count_option = @outer_holder.find "input[name='rs_termination'][value='count']" + @count_option.prop('checked', true) + @occurrence_count = @outer_holder.find '#rs_occurrence_count' + @occurrence_count.val(@current_rule.hash.count) + else if @current_rule.hash? && @current_rule.hash.until? + @until_option = @outer_holder.find "input[name='rs_termination'][value='until']" + @until_option.prop('checked', true) + # IceCube::TimeUtil will serialize a TimeWithZone into a hash, such as: + # {time: Thu, 04 Sep 2014 06:59:59 +0000, zone: "Pacific Time (US & Canada)"} + # If we're initializing from an unsaved rule, until will be a string + if @current_rule.hash.until.time? + @until_val = new Date(@current_rule.hash.until.time) + @until_date.val(@until_val.getFullYear() + '-' + (@until_val.getMonth() + 1) + '-' + @until_val.getDate()) + else + @until_date.val(@current_rule.hash.until) + else + @never_option = @outer_holder.find "input[name='rs_termination'][value='never']" + @never_option.prop('checked', true) + + @all_termination_options = @outer_holder.find ".rs_termination_section input[type='radio'], #rs_occurrence_count, #rs_until_date" + @all_termination_options.on "change", @terminationChanged summaryInit: -> @summary = @outer_holder.find(".rs_summary") @@ -225,29 +251,24 @@ window.RecurringSelectDialog = freqChanged: => @current_rule.hash = null unless $.isPlainObject(@current_rule.hash) # for custom values + @current_rule.str = null @current_rule.hash ||= {} @current_rule.hash.interval = 1 - @current_rule.hash.until = null - @current_rule.hash.count = null @current_rule.hash.validations = null @content.find(".freq_option_section").hide(); - @content.find("input[type=radio], input[type=checkbox]").prop("checked", false) + @content.find(".freq_option_section input[type=radio], input[type=checkbox]").prop("checked", false) switch @freq_select.val() when "Weekly" @current_rule.hash.rule_type = "IceCube::WeeklyRule" - @current_rule.str = $.fn.recurring_select.texts["weekly"] @initWeeklyOptions() when "Monthly" @current_rule.hash.rule_type = "IceCube::MonthlyRule" - @current_rule.str = $.fn.recurring_select.texts["monthly"] @initMonthlyOptions() when "Yearly" @current_rule.hash.rule_type = "IceCube::YearlyRule" - @current_rule.str = $.fn.recurring_select.texts["yearly"] @initYearlyOptions() else @current_rule.hash.rule_type = "IceCube::DailyRule" - @current_rule.str = $.fn.recurring_select.texts["daily"] @initDailyOptions() @summaryUpdate() @positionDialogVert() @@ -298,6 +319,26 @@ window.RecurringSelectDialog = @summaryUpdate() false + terminationChanged: (event) => + @selected_termination_type = @outer_holder.find ".rs_termination_section input[type='radio']:checked" + if !@selected_termination_type? + return + @current_rule.str = null + @current_rule.hash ||= {} + switch @selected_termination_type.val() + when 'count' + @current_rule.hash.count = parseInt($('#rs_occurrence_count').val()) + if @current_rule.hash.count < 1 || isNaN(@current_rule.hash.count) + @current_rule.hash.count = 1 + @current_rule.hash.until = null + when 'until' + @current_rule.hash.until = $('#rs_until_date').val() + @current_rule.hash.count = null + else + @current_rule.hash.until = null + @current_rule.hash.count = null + @summaryUpdate() + # ========================= Change callbacks =============================== template: () -> @@ -359,6 +400,31 @@ window.RecurringSelectDialog = #{$.fn.recurring_select.texts["years"]}

+
+ + + + +
+ + +
+
+ +
+

diff --git a/app/assets/stylesheets/recurring_select.scss b/app/assets/stylesheets/recurring_select.scss index 4d5bd72f..265a970b 100644 --- a/app/assets/stylesheets/recurring_select.scss +++ b/app/assets/stylesheets/recurring_select.scss @@ -1,3 +1,6 @@ +/* + *= require jquery-ui/datepicker + */ @import "utilities.scss"; /* -------- resets ---------------*/ @@ -76,6 +79,23 @@ select { } } + .rs_termination_section { + table { + margin: 0; + padding-top: 5px; + td { + padding: 0; + vertical-align: top; + } + } + .rs_termination_label {margin-right:10px;} + .rs_count {width:30px; text-align:center; display: inline-block;} + } + + .rs_datepicker { + width: 80px; + text-align: center; + } .rs_summary { padding:0px; margin-top:15px; border-top:1px solid #ccc; span {font-weight:bold; border-top:1px solid #fff; display:block; padding:10px 0 5px 0;} diff --git a/app/helpers/recurring_select_helper.rb b/app/helpers/recurring_select_helper.rb index 807935f2..c431ad7f 100644 --- a/app/helpers/recurring_select_helper.rb +++ b/app/helpers/recurring_select_helper.rb @@ -12,7 +12,7 @@ def select_recurring(object, method, default_schedules = nil, options = {}, html end end end - + module FormBuilder def select_recurring(method, default_schedules = nil, options = {}, html_options = {}) if !@template.respond_to?(:select_recurring) diff --git a/lib/recurring_select.rb b/lib/recurring_select.rb index 5f727ed4..17ca2b8a 100644 --- a/lib/recurring_select.rb +++ b/lib/recurring_select.rb @@ -45,6 +45,7 @@ def self.filter_params(params) params[:interval] = params[:interval].to_i if params[:interval] params[:week_start] = params[:week_start].to_i if params[:week_start] + params[:count] = params[:count].to_i if params[:count] params[:validations] ||= {} params[:validations].symbolize_keys! @@ -78,6 +79,23 @@ def self.filter_params(params) params[:validations][:day_of_year] = params[:validations][:day_of_year].collect(&:to_i) end + begin + # IceCube::TimeUtil will serialize a TimeWithZone into a hash, such as: + # {time: Thu, 04 Sep 2014 06:59:59 +0000, zone: "Pacific Time (US & Canada)"} + # So don't try to DateTime.parse the hash. IceCube::TimeUtil will deserialize this for us. + if (until_param = params[:until]) + if until_param.is_a?(String) + # Set to 23:59:59 (in current TZ) to encompass all events on until day + params[:until] = Time.zone.parse(until_param).change(hour: 23, min: 59, sec: 59) + elsif until_param.is_a?(Hash) # ex: {time: Thu, 28 Aug 2014 06:59:590000, zone: "Pacific Time (US & Canada)"} + until_param = until_param.symbolize_keys + params[:until] = until_param[:time].in_time_zone(until_param[:zone]) + end + end + rescue ArgumentError + # Invalid date given, attempt to assign :until will fail silently + end + params end end diff --git a/recurring_select.gemspec b/recurring_select.gemspec index d881ddcd..49c620de 100644 --- a/recurring_select.gemspec +++ b/recurring_select.gemspec @@ -18,6 +18,7 @@ Gem::Specification.new do |s| s.add_dependency "rails", ">= 3.2" s.add_dependency "jquery-rails", ">= 3.0" + s.add_dependency "jquery-ui-rails", ">= 6.0" s.add_dependency "ice_cube", ">= 0.11" s.add_dependency "sass-rails", ">= 4.0" s.add_dependency "coffee-rails", ">= 3.1"