fullcalendar_engine 1.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.
Files changed (55) hide show
  1. data/MIT-LICENSE +20 -0
  2. data/Rakefile +34 -0
  3. data/app/assets/javascripts/fullcalendar_engine/application.js +13 -0
  4. data/app/assets/javascripts/fullcalendar_engine/events.js +197 -0
  5. data/app/assets/javascripts/fullcalendar_engine/fullcalendar.js +6110 -0
  6. data/app/assets/javascripts/fullcalendar_engine/gcal.js +107 -0
  7. data/app/assets/javascripts/fullcalendar_engine/jquery-ui-1.10.3.custom.min.js +7 -0
  8. data/app/assets/stylesheets/fullcalendar_engine/application.css +13 -0
  9. data/app/assets/stylesheets/fullcalendar_engine/fullcalendar.css +589 -0
  10. data/app/assets/stylesheets/fullcalendar_engine/images/animated-overlay.gif +0 -0
  11. data/app/assets/stylesheets/fullcalendar_engine/images/ui-bg_diagonals-thick_18_b81900_40x40.png +0 -0
  12. data/app/assets/stylesheets/fullcalendar_engine/images/ui-bg_diagonals-thick_20_666666_40x40.png +0 -0
  13. data/app/assets/stylesheets/fullcalendar_engine/images/ui-bg_flat_10_000000_40x100.png +0 -0
  14. data/app/assets/stylesheets/fullcalendar_engine/images/ui-bg_glass_100_f6f6f6_1x400.png +0 -0
  15. data/app/assets/stylesheets/fullcalendar_engine/images/ui-bg_glass_100_fdf5ce_1x400.png +0 -0
  16. data/app/assets/stylesheets/fullcalendar_engine/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
  17. data/app/assets/stylesheets/fullcalendar_engine/images/ui-bg_gloss-wave_35_f6a828_500x100.png +0 -0
  18. data/app/assets/stylesheets/fullcalendar_engine/images/ui-bg_highlight-soft_100_eeeeee_1x100.png +0 -0
  19. data/app/assets/stylesheets/fullcalendar_engine/images/ui-bg_highlight-soft_75_ffe45c_1x100.png +0 -0
  20. data/app/assets/stylesheets/fullcalendar_engine/images/ui-icons_222222_256x240.png +0 -0
  21. data/app/assets/stylesheets/fullcalendar_engine/images/ui-icons_228ef1_256x240.png +0 -0
  22. data/app/assets/stylesheets/fullcalendar_engine/images/ui-icons_ef8c08_256x240.png +0 -0
  23. data/app/assets/stylesheets/fullcalendar_engine/images/ui-icons_ffd27a_256x240.png +0 -0
  24. data/app/assets/stylesheets/fullcalendar_engine/images/ui-icons_ffffff_256x240.png +0 -0
  25. data/app/assets/stylesheets/fullcalendar_engine/jquery-ui-1.10.3.custom.css +1177 -0
  26. data/app/assets/stylesheets/fullcalendar_engine/style.css +23 -0
  27. data/app/controllers/fullcalendar_engine/application_controller.rb +4 -0
  28. data/app/controllers/fullcalendar_engine/events_controller.rb +106 -0
  29. data/app/models/fullcalendar_engine/event.rb +56 -0
  30. data/app/models/fullcalendar_engine/event_series.rb +50 -0
  31. data/app/views/fullcalendar_engine/events/_edit_form.html.erb +40 -0
  32. data/app/views/fullcalendar_engine/events/_form.html.erb +38 -0
  33. data/app/views/fullcalendar_engine/events/index.html.erb +27 -0
  34. data/app/views/fullcalendar_engine/events/new.js.erb +1 -0
  35. data/config/full-calendar.yml.dummy +57 -0
  36. data/config/initializers/configuration.rb +17 -0
  37. data/config/initializers/constants.rb +1 -0
  38. data/config/routes.rb +12 -0
  39. data/db/migrate/20131203105320_create_fullcalendar_engine_events.rb +13 -0
  40. data/db/migrate/20131203105529_create_fullcalendar_engine_event_series.rb +12 -0
  41. data/lib/fullcalendar_engine.rb +4 -0
  42. data/lib/fullcalendar_engine/engine.rb +5 -0
  43. data/lib/fullcalendar_engine/version.rb +3 -0
  44. data/lib/generators/fullcalendar_engine/install/install_generator.rb +29 -0
  45. data/lib/tasks/fullcalendar_engine_tasks.rake +4 -0
  46. data/test/controllers/fullcalendar_engine/events_controller_test.rb +9 -0
  47. data/test/fixtures/fullcalendar_engine/event_series.yml +11 -0
  48. data/test/fixtures/fullcalendar_engine/events.yml +11 -0
  49. data/test/fullcalendar_engine_test.rb +7 -0
  50. data/test/helpers/fullcalendar_engine/events_helper_test.rb +6 -0
  51. data/test/integration/navigation_test.rb +10 -0
  52. data/test/models/fullcalendar_engine/event_series_test.rb +9 -0
  53. data/test/models/fullcalendar_engine/event_test.rb +9 -0
  54. data/test/test_helper.rb +15 -0
  55. metadata +127 -0
@@ -0,0 +1,23 @@
1
+ body{
2
+ font-size: 12px;
3
+ font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;
4
+ }
5
+
6
+ #loading{
7
+ position: absolute;
8
+ right: 0px;
9
+ top: 0px;
10
+ background-color: #dd0000;
11
+ font-weight:bold;
12
+ color: white;
13
+ margin: 5px;
14
+ padding: 3px;
15
+ }
16
+
17
+ span > div#loading {
18
+ position: fixed;
19
+ }
20
+
21
+ h1{
22
+ font-size: 16px;
23
+ }
@@ -0,0 +1,4 @@
1
+ module FullcalendarEngine
2
+ class ApplicationController < ActionController::Base
3
+ end
4
+ end
@@ -0,0 +1,106 @@
1
+ require_dependency "fullcalendar_engine/application_controller"
2
+
3
+ module FullcalendarEngine
4
+ class EventsController < ApplicationController
5
+
6
+ layout FullcalendarEngine::Configuration['layout'] || "application"
7
+
8
+ before_filter :load_event, :only => [:edit, :update, :destroy, :move, :resize]
9
+ before_filter :determine_event_type, :only => :create
10
+
11
+ def create
12
+ if @event.save
13
+ render :nothing => true
14
+ else
15
+ render :text => event.errors.full_messages.to_sentence, :status => 422
16
+ end
17
+ end
18
+
19
+ def new
20
+ respond_to do |format|
21
+ format.js
22
+ end
23
+ end
24
+
25
+ def get_events
26
+ @events = Event.where("starttime >= '#{Time.at(params['start'].to_i).to_formatted_s(:db)}' and endtime <= '#{Time.at(params['end'].to_i).to_formatted_s(:db)}'")
27
+ events = []
28
+ @events.each do |event|
29
+ events << {:id => event.id, :title => event.title, :description => event.description || "Some cool description here...", :start => "#{event.starttime.iso8601}", :end => "#{event.endtime.iso8601}", :allDay => event.all_day, :recurring => (event.event_series_id)? true: false}
30
+ end
31
+ render :json => events.to_json
32
+ end
33
+
34
+ def move
35
+ if @event
36
+ @event.starttime = (params[:minute_delta].to_i).minutes.from_now((params[:day_delta].to_i).days.from_now(@event.starttime))
37
+ @event.endtime = (params[:minute_delta].to_i).minutes.from_now((params[:day_delta].to_i).days.from_now(@event.endtime))
38
+ @event.all_day = params[:all_day]
39
+ @event.save
40
+ end
41
+ render :nothing => true
42
+ end
43
+
44
+ def resize
45
+ if @event
46
+ @event.endtime = (params[:minute_delta].to_i).minutes.from_now((params[:day_delta].to_i).days.from_now(@event.endtime))
47
+ @event.save
48
+ end
49
+ render :nothing => true
50
+ end
51
+
52
+ def edit
53
+ render :json => { :form => render_to_string(:partial => 'edit_form') }
54
+ end
55
+
56
+ def update
57
+ case params[:event][:commit_button]
58
+ when "Update All Occurrence"
59
+ @events = @event.event_series.events #.find(:all, :conditions => ["starttime > '#{@event.starttime.to_formatted_s(:db)}' "])
60
+ @event.update_events(@events, event_params)
61
+ when "Update All Following Occurrence"
62
+ @events = @event.event_series.events.find(:all, :conditions => ["starttime > '#{@event.starttime.to_formatted_s(:db)}' "])
63
+ @event.update_events(@events, event_params)
64
+ else
65
+ @event.attributes = event_params
66
+ @event.save
67
+ end
68
+ render :nothing => true
69
+ end
70
+
71
+ def destroy
72
+ case params[:delete_all]
73
+ when "true"
74
+ @event.event_series.destroy
75
+ when "future"
76
+ @events = @event.event_series.events.find(:all, :conditions => ["starttime > '#{@event.starttime.to_formatted_s(:db)}' "])
77
+ @event.event_series.events.delete(@events)
78
+ else
79
+ @event.destroy
80
+ end
81
+ render :nothing => true
82
+ end
83
+
84
+ private
85
+
86
+ def load_event
87
+ @event = Event.where(:id => params[:id]).first
88
+ unless @event
89
+ render :json => {:message => "Event Not Found.."}, :status => 404 and return
90
+ end
91
+ end
92
+
93
+ def event_params
94
+ params.require(:event).permit('title', 'description', 'starttime(1i)', 'starttime(2i)', 'starttime(3i)', 'starttime(4i)', 'starttime(5i)', 'endtime(1i)', 'endtime(2i)', 'endtime(3i)', 'endtime(4i)', 'endtime(5i)', 'all_day', 'period', 'frequency', 'commit_button')
95
+ end
96
+
97
+ def determine_event_type
98
+ if params[:event][:period] == "Does not repeat"
99
+ @event = Event.new(event_params)
100
+ else
101
+ @event = EventSeries.new(event_params)
102
+ end
103
+ end
104
+
105
+ end
106
+ end
@@ -0,0 +1,56 @@
1
+ module FullcalendarEngine
2
+ class Event < ActiveRecord::Base
3
+
4
+ attr_accessor :period, :frequency, :commit_button
5
+
6
+ validates :title, :description, :presence => true
7
+ validate :validate_timings
8
+
9
+ belongs_to :event_series
10
+
11
+ REPEATS = {
12
+ :no_repeat => "Does not repeat",
13
+ :days => "Daily",
14
+ :weeks => "Weekly",
15
+ :months => "Monthly",
16
+ :years => "Yearly"
17
+ }
18
+
19
+ def validate_timings
20
+ if (starttime >= endtime) and !all_day
21
+ errors[:base] << "Start Time must be less than End Time"
22
+ end
23
+ end
24
+
25
+ def update_events(events, event)
26
+ events.each do |e|
27
+ begin
28
+ old_start_time, old_end_time = e.starttime, e.endtime
29
+ e.attributes = event
30
+ if event_series.period.downcase == 'monthly' or event_series.period.downcase == 'yearly'
31
+ new_start_time = make_date_time(e.starttime, old_start_time)
32
+ new_end_time = make_date_time(e.starttime, old_end_time, e.endtime)
33
+ else
34
+ new_start_time = make_date_time(e.starttime, old_end_time)
35
+ new_end_time = make_date_time(e.endtime, old_end_time)
36
+ end
37
+ rescue
38
+ new_start_time = new_end_time = nil
39
+ end
40
+ if new_start_time and new_end_time
41
+ e.starttime, e.endtime = new_start_time, new_end_time
42
+ e.save
43
+ end
44
+ end
45
+
46
+ event_series.attributes = event
47
+ event_series.save
48
+ end
49
+
50
+ private
51
+
52
+ def make_date_time(original_time, difference_time, event_time = nil)
53
+ DateTime.parse("#{original_time.hour}:#{original_time.min}:#{original_time.sec}, #{event_time.try(:day) || difference_time.day}-#{difference_time.month}-#{difference_time.year}")
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,50 @@
1
+ module FullcalendarEngine
2
+ class EventSeries < ActiveRecord::Base
3
+
4
+ attr_accessor :title, :description, :commit_button
5
+
6
+ validates :frequency, :period, :starttime, :endtime, :title, :description, :presence => true
7
+
8
+ has_many :events, :dependent => :destroy
9
+
10
+ after_create :create_events_until_end_time
11
+
12
+ def create_events_until_end_time(end_time=RECURRING_EVENTS_UPTO)
13
+ old_start_time = starttime
14
+ old_end_time = endtime
15
+ frequency_period = recurring_period(period)
16
+ new_start_time, new_end_time = old_start_time, old_end_time
17
+
18
+ while frequency.send(frequency_period).from_now(old_start_time) <= end_time
19
+ self.events.create(
20
+ :title => title,
21
+ :description => description,
22
+ :all_day => all_day,
23
+ :starttime => new_start_time,
24
+ :endtime => new_end_time
25
+ )
26
+ new_start_time = old_start_time = frequency.send(frequency_period).from_now(old_start_time)
27
+ new_end_time = old_end_time = frequency.send(frequency_period).from_now(old_end_time)
28
+
29
+ if period.downcase == 'monthly' or period.downcase == 'yearly'
30
+ begin
31
+ new_start_time = make_date_time(starttime, old_start_time)
32
+ new_end_time = make_date_time(endtime, old_end_time)
33
+ rescue
34
+ new_start_time = new_end_time = nil
35
+ end
36
+ end
37
+ end
38
+ end
39
+
40
+ def recurring_period(period)
41
+ Event::REPEATS.key(period).to_s.downcase
42
+ end
43
+
44
+ private
45
+
46
+ def make_date_time(original_time, difference_time)
47
+ DateTime.parse("#{original_time.hour}:#{original_time.min}:#{original_time.sec}, #{original_time.day}-#{difference_time.month}-#{difference_time.year}")
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,40 @@
1
+ <%= form_for @event, :html => { :id => 'event_form' } do |f| %>
2
+ <p>
3
+ <%=f.label :title %>
4
+ <br/>
5
+ <%=f.text_field :title %>
6
+ </p>
7
+ <p>
8
+ <%=f.label :description %>
9
+ <br/>
10
+ <%=f.text_area :description, :rows => 4, :cols => 30 %>
11
+ </p>
12
+ <p>
13
+ <%=f.label :starttime, 'Start Time' %>
14
+ <br/>
15
+ <%=f.datetime_select :starttime %>
16
+ </p>
17
+ <p>
18
+ <%=f.label :endtime, 'End Time' %>
19
+ <br/>
20
+ <%=f.datetime_select :endtime %>
21
+ </p>
22
+ <p>
23
+ <%=f.label :all_day %>
24
+ <%=f.check_box :all_day %>
25
+ </p>
26
+
27
+ <%=f.hidden_field :id, :value => @event.id%>
28
+ <%=f.hidden_field :commit_button, :value => ""%>
29
+ <p>
30
+ <%if @event.event_series -%>
31
+ <%=f.submit 'Update Only This Occurrence', :onclick => "document.getElementById('event_commit_button').value = this.value"%>
32
+ <%=f.submit 'Update All Occurrence', :onclick => "document.getElementById('event_commit_button').value = this.value"%>
33
+ <%=f.submit 'Update All Following Occurrence', :onclick => "document.getElementById('event_commit_button').value = this.value"%>
34
+ <%else-%>
35
+ <%=f.submit 'Update', :onclick => "document.getElementById('event_commit_button').value = this.value"%>
36
+ <%end-%>
37
+
38
+ <span id = "updating_events" class="spinner" style = "display:none;">Updating, Please wait...</span>
39
+ </p>
40
+ <%end %>
@@ -0,0 +1,38 @@
1
+ <%= form_for @event ||= FullcalendarEngine::Event.new, :html => { :id => 'event_form' } do |f| %>
2
+ <p>
3
+ <%=f.label :title %>
4
+ <br/>
5
+ <%=f.text_field :title %>
6
+ </p>
7
+ <p>
8
+ <%=f.label :description %>
9
+ <br/>
10
+ <%=f.text_area :description, :rows => 4, :cols => 30 %>
11
+ </p>
12
+ <p>
13
+ <%=f.label :starttime, 'Start Time' %>
14
+ <br/>
15
+ <%=f.datetime_select :starttime %>
16
+ </p>
17
+ <p>
18
+ <%=f.label :endtime, 'End Time' %>
19
+ <br/>
20
+ <%=f.datetime_select :endtime %>
21
+ </p>
22
+ <p>
23
+ <%=f.label :all_day %>
24
+ <%=f.check_box :all_day %>
25
+ </p>
26
+ <p>
27
+ <%=f.label :period, "Repeats" %>
28
+ <%=f.select :period, FullcalendarEngine::Event::REPEATS.values,{}, :onchange => "FullcalendarEngine.Events.showPeriodAndFrequency(this.value);" %>
29
+ </p>
30
+ <p id = "frequency" style = "display:none;">
31
+ <%=f.label :frequency, "Repeat every" %>
32
+ <%=f.select :frequency, (1..30).to_a %> <span id = "period"></span>
33
+ </p>
34
+ <%=f.hidden_field :id, :value => @event.id %>
35
+ <p>
36
+ <%=f.submit 'Create' %> <span id = "creating_events" class="spinner" style = "display:none;">Creating, Please wait...</span>
37
+ </p>
38
+ <%end %>
@@ -0,0 +1,27 @@
1
+ <p>
2
+ <%= link_to 'Create Event', 'javascript:void()', :id => 'new_event' %>
3
+ </p>
4
+
5
+ <%= content_tag :script do %>
6
+ full_calendar_options = <%= FullcalendarEngine::Configuration.to_json.html_safe %>
7
+ app_path = full_calendar_options["mount_path"]
8
+ <% end %>
9
+
10
+ <div>
11
+ <div id='calendar'></div>
12
+ </div>
13
+ <div id="event_desc_dialog" class="dialog" style="display:none;"></div>
14
+ <div id="create_event_dialog" class="dialog" style ="display:none;">
15
+ <%= render 'form' %>
16
+ </div>
17
+
18
+ <script>
19
+ $(document).ready(function(){
20
+ $('#calendar').fullCalendar(full_calendar_options);
21
+ // page is now ready, initialize the calendar...
22
+ $('#new_event').click(function(event) {
23
+ FullcalendarEngine.Form.display()
24
+ event.preventDefault();
25
+ });
26
+ });
27
+ </script>
@@ -0,0 +1 @@
1
+ $("#create_event_dialog").html("<%= escape_javascript( render partial: 'form') %>")
@@ -0,0 +1,57 @@
1
+ # Refer to the http://arshaw.com/fullcalendar/docs/ to know more about the following options in greater depth
2
+ # defaultView: 'agendaWeek'
3
+ # aspectRatio: 1.35
4
+ # header:
5
+ # left: 'prev,next today'
6
+ # center: 'title'
7
+ # right: 'month,agendaWeek,agendaDay'
8
+ # weekends: true
9
+ # weekNumbers: false
10
+ # weekNumberCalculation: 'iso'
11
+ # weekNumberTitle: 'W'
12
+
13
+ # editable: true
14
+ # disableDragging: false
15
+ # disableResizing: false
16
+ # allDayDefault: true
17
+ # ignoreTimezone: true
18
+
19
+ # lazyFetching: true
20
+ # startParam: 'start'
21
+ # endParam: 'end'
22
+
23
+ # titleFormat:
24
+ # month: 'MMMM yyyy'
25
+ # week: "MMM d[ yyyy]{ '&#8212;'[ MMM] d yyyy}"
26
+ # day: 'dddd, MMM d, yyyy'
27
+ # columnFormat:
28
+ # month: 'ddd'
29
+ # week: 'ddd M/d'
30
+ # day: 'dddd M/d'
31
+ # timeFormat:
32
+ # '': 'h(:mm)t' # default
33
+
34
+ # isRTL: false
35
+ # firstDay: 0
36
+ # monthNames: ['January','February','March','April','May','June','July','August','September','October','November','December']
37
+ # monthNamesShort: ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec']
38
+ # dayNames: ['Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday']
39
+ # dayNamesShort: ['Sun','Mon','Tue','Wed','Thu','Fri','Sat']
40
+ # buttonText:
41
+ # prev: "<span class='fc-text-arrow'>prev..</span>"
42
+ # next: "<span class='fc-text-arrow'>next..</span>"
43
+ # prevYear: "<span class='fc-text-arrow'>&laquo;</span>"
44
+ # nextYear: "<span class='fc-text-arrow'>&raquo;</span>"
45
+ # today: 'today'
46
+ # month: 'month'
47
+ # week: 'week'
48
+ # day: 'day'
49
+
50
+ # theme: false
51
+ # buttonIcons:
52
+ # prev: 'circle-triangle-w'
53
+ # next: 'circle-triangle-e'
54
+ # selectable: true
55
+ # unselectAuto: true
56
+ # dropAccept: '*'
57
+ # handleWindowResize: true
@@ -0,0 +1,17 @@
1
+ config = File.exists?('config/fullcalendar.yml') ? YAML.load_file("config/fullcalendar.yml") || {} : {}
2
+ FullcalendarEngine::Configuration = {
3
+ 'editable' => true,
4
+ 'header' => {
5
+ left: 'prev,next today',
6
+ center: 'title',
7
+ right: 'month,agendaWeek,agendaDay'
8
+ },
9
+ 'defaultView' => 'agendaWeek',
10
+ 'height' => 500,
11
+ 'slotMinutes' => 15,
12
+ 'dragOpacity' => 0.5,
13
+ 'selectable' => true,
14
+ 'timeFormat' => "h:mm t{ - h:mm t}"
15
+ }
16
+ FullcalendarEngine::Configuration.merge!(config)
17
+ FullcalendarEngine::Configuration['events'] = "#{FullcalendarEngine::Configuration['mount_path']}/events/get_events"
@@ -0,0 +1 @@
1
+ RECURRING_EVENTS_UPTO = (Date.today.beginning_of_year + 5.years).to_time
data/config/routes.rb ADDED
@@ -0,0 +1,12 @@
1
+ FullcalendarEngine::Engine.routes.draw do
2
+ root :to => 'events#index'
3
+ resources :events do
4
+ collection do
5
+ get :get_events
6
+ end
7
+ member do
8
+ post :move
9
+ post :resize
10
+ end
11
+ end
12
+ end