event-calendar 2.3.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/CHANGELOG.rdoc +38 -0
- data/MIT-LICENSE +20 -0
- data/README.rdoc +274 -0
- data/Rakefile +37 -0
- data/VERSION +1 -0
- data/generators/event_calendar/USAGE +20 -0
- data/generators/event_calendar/event_calendar_generator.rb +50 -0
- data/generators/event_calendar/lib/insert_routes.rb +55 -0
- data/generators/event_calendar/templates/controller.rb.erb +12 -0
- data/generators/event_calendar/templates/helper.rb.erb +35 -0
- data/generators/event_calendar/templates/javascript.js +49 -0
- data/generators/event_calendar/templates/jq_javascript.js +35 -0
- data/generators/event_calendar/templates/migration.rb.erb +18 -0
- data/generators/event_calendar/templates/model.rb.erb +4 -0
- data/generators/event_calendar/templates/stylesheet.css +233 -0
- data/generators/event_calendar/templates/view.html.erb +6 -0
- data/init.rb +2 -0
- data/install.rb +1 -0
- data/lib/event_calendar.rb +189 -0
- data/lib/event_calendar/calendar_helper.rb +366 -0
- data/lib/event_calendar/railtie.rb +12 -0
- data/lib/generators/event_calendar/USAGE +20 -0
- data/lib/generators/event_calendar/event_calendar_generator.rb +92 -0
- data/lib/generators/event_calendar/templates/controller.rb.erb +12 -0
- data/lib/generators/event_calendar/templates/helper.rb.erb +35 -0
- data/lib/generators/event_calendar/templates/javascript.js +49 -0
- data/lib/generators/event_calendar/templates/jq_javascript.js +35 -0
- data/lib/generators/event_calendar/templates/migration.rb.erb +21 -0
- data/lib/generators/event_calendar/templates/model.rb.erb +3 -0
- data/lib/generators/event_calendar/templates/stylesheet.css +233 -0
- data/lib/generators/event_calendar/templates/view.html.erb +6 -0
- data/lib/tasks/event_calendar_tasks.rake +4 -0
- data/spec/event_calendar_spec.rb +78 -0
- data/spec/fixtures/models.rb +6 -0
- data/spec/spec.opts +3 -0
- data/spec/spec_helper.rb +30 -0
- data/uninstall.rb +1 -0
- metadata +105 -0
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'event_calendar'
|
2
|
+
require 'event_calendar/calendar_helper'
|
3
|
+
require 'rails'
|
4
|
+
|
5
|
+
module EventCalendar
|
6
|
+
class Railtie < Rails::Engine
|
7
|
+
initializer :after_initialize do
|
8
|
+
ActionController::Base.helper EventCalendar::CalendarHelper
|
9
|
+
ActiveRecord::Base.extend EventCalendar::ClassMethods
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
Example:
|
2
|
+
|
3
|
+
rails generate event_calendar --use-all-day --use-jquery
|
4
|
+
|
5
|
+
This will create:
|
6
|
+
|
7
|
+
# static files
|
8
|
+
public/stylesheets/event_calendar.css
|
9
|
+
public/javascripts/event_calendar.js
|
10
|
+
|
11
|
+
# Unless --static-only option is given
|
12
|
+
# MVC and supporting files (depending on model and view name)
|
13
|
+
app/models/event.rb
|
14
|
+
app/controllers/calendar_controller.rb
|
15
|
+
app/views/calendar
|
16
|
+
app/views/calendar/index.html.erb
|
17
|
+
app/helpers/calendar_helper.rb
|
18
|
+
db/migrate
|
19
|
+
db/migrate/XXXX_create_events.rb
|
20
|
+
route map.calendar
|
@@ -0,0 +1,92 @@
|
|
1
|
+
require 'rails/generators/migration'
|
2
|
+
|
3
|
+
class EventCalendarGenerator < Rails::Generators::Base
|
4
|
+
include Rails::Generators::Migration
|
5
|
+
|
6
|
+
source_root File.expand_path('../templates', __FILE__)
|
7
|
+
|
8
|
+
argument :model_name, :optional => true, :default => 'event'
|
9
|
+
argument :controller_name, :optional => true, :default => 'calendar'
|
10
|
+
|
11
|
+
class_option :static_only, :type => :boolean, :default => false, :desc => "Only generate stylesheets and scripts"
|
12
|
+
class_option :use_jquery, :type => :boolean, :default => false, :desc => "Use JQuery for scripting"
|
13
|
+
class_option :use_all_day, :type => :boolean, :default => false, :desc => "Add an additional 'all_day' attribute"
|
14
|
+
class_option :use_color, :type => :boolean, :default => false, :desc => "Add an additional 'color' attribute"
|
15
|
+
|
16
|
+
def do_it
|
17
|
+
say "Adding an all_day column", :yellow if options[:use_all_day]
|
18
|
+
say "Adding a color column", :yellow if options[:use_color]
|
19
|
+
|
20
|
+
if options[:use_jquery]
|
21
|
+
say "Using JQuery for scripting", :yellow
|
22
|
+
copy_file 'jq_javascript.js', "public/javascripts/event_calendar.js"
|
23
|
+
else
|
24
|
+
say "Using Prototype for scripting", :yellow
|
25
|
+
copy_file 'javascript.js', "public/javascripts/event_calendar.js"
|
26
|
+
end
|
27
|
+
|
28
|
+
copy_file "stylesheet.css", "public/stylesheets/event_calendar.css"
|
29
|
+
|
30
|
+
unless options.static_only?
|
31
|
+
template "model.rb.erb", "app/models/#{model_name}.rb"
|
32
|
+
template "controller.rb.erb", "app/controllers/#{controller_name}.rb"
|
33
|
+
empty_directory "app/views/#{view_name}"
|
34
|
+
template "view.html.erb", File.join("app/views/#{view_name}/index.html.erb")
|
35
|
+
template "helper.rb.erb", "app/helpers/#{helper_name}.rb"
|
36
|
+
migration_template "migration.rb.erb", "db/migrate/create_#{table_name}.rb"
|
37
|
+
route "match '/#{view_name}(/:year(/:month))' => '#{view_name}#index', :as => :#{named_route_name}, :constraints => {:year => /\\d{4}/, :month => /\\d{1,2}/}"
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
|
42
|
+
def model_class_name
|
43
|
+
@model_name.classify
|
44
|
+
end
|
45
|
+
|
46
|
+
def model_name
|
47
|
+
model_class_name.underscore
|
48
|
+
end
|
49
|
+
|
50
|
+
def view_name
|
51
|
+
@controller_name.underscore
|
52
|
+
end
|
53
|
+
|
54
|
+
def controller_class_name
|
55
|
+
"#{@controller_name}_controller".classify
|
56
|
+
end
|
57
|
+
|
58
|
+
def controller_name
|
59
|
+
controller_class_name.underscore
|
60
|
+
end
|
61
|
+
|
62
|
+
def helper_class_name
|
63
|
+
"#{@controller_name}_helper".classify
|
64
|
+
end
|
65
|
+
|
66
|
+
def helper_name
|
67
|
+
helper_class_name.underscore
|
68
|
+
end
|
69
|
+
|
70
|
+
def table_name
|
71
|
+
model_name.pluralize
|
72
|
+
end
|
73
|
+
|
74
|
+
def named_route_name
|
75
|
+
if view_name.include?("/")
|
76
|
+
view_name.split("/").join("_")
|
77
|
+
else
|
78
|
+
view_name
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
# FIXME: Should be proxied to ActiveRecord::Generators::Base
|
83
|
+
# Implement the required interface for Rails::Generators::Migration.
|
84
|
+
def self.next_migration_number(dirname) #:nodoc:
|
85
|
+
if ActiveRecord::Base.timestamped_migrations
|
86
|
+
Time.now.utc.strftime("%Y%m%d%H%M%S")
|
87
|
+
else
|
88
|
+
"%.3d" % (current_migration_number(dirname) + 1)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
class <%= controller_class_name %> < ApplicationController
|
2
|
+
|
3
|
+
def index
|
4
|
+
@month = (params[:month] || (Time.zone || Time).now.month).to_i
|
5
|
+
@year = (params[:year] || (Time.zone || Time).now.year).to_i
|
6
|
+
|
7
|
+
@shown_month = Date.civil(@year, @month)
|
8
|
+
|
9
|
+
@event_strips = <%= model_class_name %>.event_strips_for_month(@shown_month)
|
10
|
+
end
|
11
|
+
|
12
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module <%= helper_class_name %>
|
2
|
+
def month_link(month_date)
|
3
|
+
link_to(I18n.localize(month_date, :format => "%B"), {:month => month_date.month, :year => month_date.year})
|
4
|
+
end
|
5
|
+
|
6
|
+
# custom options for this calendar
|
7
|
+
def event_calendar_opts
|
8
|
+
{
|
9
|
+
:year => @year,
|
10
|
+
:month => @month,
|
11
|
+
:event_strips => @event_strips,
|
12
|
+
:month_name_text => I18n.localize(@shown_month, :format => "%B %Y"),
|
13
|
+
:previous_month_text => "<< " + month_link(@shown_month.prev_month),
|
14
|
+
:next_month_text => month_link(@shown_month.next_month) + " >>"<%- if options[:use_all_day] -%>,
|
15
|
+
:use_all_day => true
|
16
|
+
<%- end -%>
|
17
|
+
}
|
18
|
+
end
|
19
|
+
|
20
|
+
def event_calendar
|
21
|
+
# args is an argument hash containing :event, :day, and :options
|
22
|
+
calendar event_calendar_opts do |args|
|
23
|
+
<%- if options[:use_all_day] -%>
|
24
|
+
event, day = args[:event], args[:day]
|
25
|
+
html = %(<a href="/events/#{event.id}" title="#{h(event.name)}">)
|
26
|
+
html << display_event_time(event, day)
|
27
|
+
html << %(#{h(event.name)}</a>)
|
28
|
+
html
|
29
|
+
<%- else -%>
|
30
|
+
event = args[:event]
|
31
|
+
%(<a href="/events/#{event.id}" title="#{h(event.name)}">#{h(event.name)}</a>)
|
32
|
+
<%- end -%>
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
/*
|
2
|
+
* Smart event highlighting
|
3
|
+
* Handles for when events span rows, or don't have a background color
|
4
|
+
*/
|
5
|
+
Event.observe(window, "load", function() {
|
6
|
+
var highlight_color = "#2EAC6A";
|
7
|
+
|
8
|
+
// highlight events that have a background color
|
9
|
+
$$(".ec-event-bg").each(function(ele) {
|
10
|
+
ele.observe("mouseover", function(evt) {
|
11
|
+
event_id = ele.readAttribute("data-event-id");
|
12
|
+
$$(".ec-event-"+event_id).each(function(el) {
|
13
|
+
el.setStyle({ backgroundColor: highlight_color });
|
14
|
+
});
|
15
|
+
});
|
16
|
+
ele.observe("mouseout", function(evt) {
|
17
|
+
event_color = ele.readAttribute("data-color");
|
18
|
+
event_id = ele.readAttribute("data-event-id");
|
19
|
+
$$(".ec-event-"+event_id).each(function(el) {
|
20
|
+
el.setStyle({ backgroundColor: event_color });
|
21
|
+
});
|
22
|
+
});
|
23
|
+
});
|
24
|
+
|
25
|
+
// highlight events that don't have a background color
|
26
|
+
$$(".ec-event-no-bg").each(function(ele) {
|
27
|
+
ele.observe("mouseover", function(evt) {
|
28
|
+
ele.setStyle({ color: "white" });
|
29
|
+
ele.select("a").each(function(link) {
|
30
|
+
link.setStyle({ color: "white" });
|
31
|
+
});
|
32
|
+
ele.select(".ec-bullet").each(function(bullet) {
|
33
|
+
bullet.setStyle({ backgroundColor: "white" });
|
34
|
+
});
|
35
|
+
ele.setStyle({ backgroundColor: highlight_color });
|
36
|
+
});
|
37
|
+
ele.observe("mouseout", function(evt) {
|
38
|
+
event_color = ele.readAttribute("data-color");
|
39
|
+
ele.setStyle({ color: event_color });
|
40
|
+
ele.select("a").each(function(link) {
|
41
|
+
link.setStyle({ color: event_color });
|
42
|
+
});
|
43
|
+
ele.select(".ec-bullet").each(function(bullet) {
|
44
|
+
bullet.setStyle({ backgroundColor: event_color });
|
45
|
+
});
|
46
|
+
ele.setStyle({ backgroundColor: "transparent" });
|
47
|
+
});
|
48
|
+
});
|
49
|
+
});
|
@@ -0,0 +1,35 @@
|
|
1
|
+
/*
|
2
|
+
* Smart event highlighting
|
3
|
+
* Handles when events span rows, or don't have a background color
|
4
|
+
*/
|
5
|
+
$(document).ready(function() {
|
6
|
+
var highlight_color = "#2EAC6A";
|
7
|
+
|
8
|
+
// highlight events that have a background color
|
9
|
+
$(".ec-event-bg").live("mouseover", function() {
|
10
|
+
event_id = $(this).attr("data-event-id");
|
11
|
+
$(".ec-event-"+event_id).css("background-color", highlight_color);
|
12
|
+
});
|
13
|
+
$(".ec-event-bg").live("mouseout", function() {
|
14
|
+
event_id = $(this).attr("data-event-id");
|
15
|
+
event_color = $(this).attr("data-color");
|
16
|
+
$(".ec-event-"+event_id).css("background-color", event_color);
|
17
|
+
});
|
18
|
+
|
19
|
+
// highlight events that don't have a background color
|
20
|
+
$(".ec-event-no-bg").live("mouseover", function() {
|
21
|
+
ele = $(this);
|
22
|
+
ele.css("color", "white");
|
23
|
+
ele.find("a").css("color", "white");
|
24
|
+
ele.find(".ec-bullet").css("background-color", "white");
|
25
|
+
ele.css("background-color", highlight_color);
|
26
|
+
});
|
27
|
+
$(".ec-event-no-bg").live("mouseout", function() {
|
28
|
+
ele = $(this);
|
29
|
+
event_color = $(this).attr("data-color");
|
30
|
+
ele.css("color", event_color);
|
31
|
+
ele.find("a").css("color", event_color);
|
32
|
+
ele.find(".ec-bullet").css("background-color", event_color);
|
33
|
+
ele.css("background-color", "transparent");
|
34
|
+
});
|
35
|
+
});
|
@@ -0,0 +1,21 @@
|
|
1
|
+
class Create<%= table_name.camelize %> < ActiveRecord::Migration
|
2
|
+
def self.up
|
3
|
+
create_table :<%= table_name %> do |t|
|
4
|
+
t.string :name
|
5
|
+
t.datetime :start_at
|
6
|
+
t.datetime :end_at
|
7
|
+
<%- if options[:use_all_day] -%>
|
8
|
+
t.boolean :all_day, :default => false
|
9
|
+
<%- end -%>
|
10
|
+
<%- if options[:use_color] -%>
|
11
|
+
t.string :color
|
12
|
+
<%- end -%>
|
13
|
+
|
14
|
+
t.timestamps
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.down
|
19
|
+
drop_table :<%= table_name %>
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,233 @@
|
|
1
|
+
/*
|
2
|
+
Event Calendar stylesheet
|
3
|
+
|
4
|
+
Colors:
|
5
|
+
#d5d5d5 - border (gray)
|
6
|
+
#303030 - day names bg (gray)
|
7
|
+
#444 - number (gray)
|
8
|
+
#ecede2 - day header bg (light tan)
|
9
|
+
##d7d7ba - today header bg (tan)
|
10
|
+
#ffffdd - today bg light (yellow)
|
11
|
+
#777 - other month number (gray)
|
12
|
+
#efefef - other month day header (gray)
|
13
|
+
#2eac6a - hover (green)
|
14
|
+
*/
|
15
|
+
|
16
|
+
/* Outer most container */
|
17
|
+
.ec-calendar {
|
18
|
+
font-family: verdana, arial, helvetica, sans-serif;
|
19
|
+
font-size: 11px;
|
20
|
+
line-height: 14px;
|
21
|
+
margin: 0;
|
22
|
+
padding: 0;
|
23
|
+
border-bottom: 1px solid #d5d5d5;
|
24
|
+
}
|
25
|
+
|
26
|
+
/* Month name header & links */
|
27
|
+
.ec-calendar-header {
|
28
|
+
padding: 5px 0;
|
29
|
+
width: 100%;
|
30
|
+
table-layout: fixed;
|
31
|
+
}
|
32
|
+
|
33
|
+
.ec-month-name {
|
34
|
+
font-size: 16px;
|
35
|
+
font-weight: bold;
|
36
|
+
}
|
37
|
+
|
38
|
+
.ec-month-nav {
|
39
|
+
|
40
|
+
}
|
41
|
+
|
42
|
+
/* Containers */
|
43
|
+
.ec-body {
|
44
|
+
position: relative;
|
45
|
+
border-right: 1px solid #303030;
|
46
|
+
white-space: nowrap;
|
47
|
+
}
|
48
|
+
|
49
|
+
/* Day names */
|
50
|
+
.ec-day-names {
|
51
|
+
position: absolute;
|
52
|
+
top: 0;
|
53
|
+
left: 0;
|
54
|
+
width: 100%;
|
55
|
+
table-layout: fixed;
|
56
|
+
padding: 2px 0;
|
57
|
+
background: #303030;
|
58
|
+
color: white;
|
59
|
+
}
|
60
|
+
|
61
|
+
.ec-day-name {
|
62
|
+
font-weight: normal;
|
63
|
+
}
|
64
|
+
|
65
|
+
/* Rows container and Row */
|
66
|
+
.ec-rows {
|
67
|
+
position: absolute;
|
68
|
+
left: 0;
|
69
|
+
bottom: 0;
|
70
|
+
width: 100%;
|
71
|
+
background: white;
|
72
|
+
overflow: hidden;
|
73
|
+
border-right: 1px solid #d5d5d5;
|
74
|
+
}
|
75
|
+
|
76
|
+
.ec-row {
|
77
|
+
position: absolute;
|
78
|
+
left: 0;
|
79
|
+
width: 100%;
|
80
|
+
overflow: hidden;
|
81
|
+
}
|
82
|
+
|
83
|
+
/* Background */
|
84
|
+
.ec-row-bg {
|
85
|
+
position: absolute;
|
86
|
+
top: 0;
|
87
|
+
left: 0;
|
88
|
+
height: 100%;
|
89
|
+
width: 100%;
|
90
|
+
table-layout: fixed;
|
91
|
+
}
|
92
|
+
|
93
|
+
.ec-day-bg {
|
94
|
+
border-left: 1px solid #d5d5d5;
|
95
|
+
}
|
96
|
+
|
97
|
+
.ec-today-bg {
|
98
|
+
background-color: #ffffdd;
|
99
|
+
}
|
100
|
+
|
101
|
+
.ec-row-table {
|
102
|
+
position: relative;
|
103
|
+
width: 100%;
|
104
|
+
table-layout: fixed;
|
105
|
+
}
|
106
|
+
|
107
|
+
/* Day header */
|
108
|
+
.ec-day-header {
|
109
|
+
color: #444;
|
110
|
+
text-align: right;
|
111
|
+
padding: 0 5px;
|
112
|
+
line-height: 16px;
|
113
|
+
border-top: 1px solid #d5d5d5;
|
114
|
+
border-left: 1px solid #d5d5d5;
|
115
|
+
border-bottom: 1px dotted #bbbbbb;
|
116
|
+
background-color: #ecede2;
|
117
|
+
overflow: hidden;
|
118
|
+
}
|
119
|
+
|
120
|
+
a.ec-day-link {
|
121
|
+
color: #444;
|
122
|
+
}
|
123
|
+
|
124
|
+
.ec-today-header {
|
125
|
+
background-color: #d7d7ba;
|
126
|
+
}
|
127
|
+
|
128
|
+
.ec-weekend-day-header {
|
129
|
+
|
130
|
+
}
|
131
|
+
|
132
|
+
.ec-other-month-header {
|
133
|
+
background-color: #efefef;
|
134
|
+
color: #777;
|
135
|
+
}
|
136
|
+
|
137
|
+
|
138
|
+
/* Event cell and container */
|
139
|
+
.ec-event-cell {
|
140
|
+
cursor: pointer;
|
141
|
+
vertical-align: top;
|
142
|
+
padding-right: 1px;
|
143
|
+
padding-left: 2px;
|
144
|
+
}
|
145
|
+
|
146
|
+
.ec-event-cell a {
|
147
|
+
text-decoration: none;
|
148
|
+
display: block;
|
149
|
+
width: 100%;
|
150
|
+
height: 100%;
|
151
|
+
}
|
152
|
+
|
153
|
+
.ec-no-event-cell {
|
154
|
+
cursor: default;
|
155
|
+
}
|
156
|
+
|
157
|
+
.ec-event {
|
158
|
+
color: white;
|
159
|
+
padding-right: 1px;
|
160
|
+
padding-left: 11px;
|
161
|
+
-webkit-border-radius: 3px;
|
162
|
+
-khtml-border-radius: 3px;
|
163
|
+
-moz-border-radius: 3px;
|
164
|
+
overflow: hidden;
|
165
|
+
white-space: nowrap;
|
166
|
+
}
|
167
|
+
|
168
|
+
.ec-event :hover {
|
169
|
+
/* doesn't look as good as js highlighting */
|
170
|
+
/* background-color: #2eac6a; */
|
171
|
+
}
|
172
|
+
|
173
|
+
.ec-event-bg a {
|
174
|
+
color: white;
|
175
|
+
}
|
176
|
+
|
177
|
+
/* used to distinguish non-all_day events */
|
178
|
+
.ec-event-no-bg {
|
179
|
+
position: relative;
|
180
|
+
/* padding-left: 5px; */
|
181
|
+
}
|
182
|
+
|
183
|
+
.ec-event-no-bg a {
|
184
|
+
/* isn't implemented in all browsers */
|
185
|
+
color: inherit;
|
186
|
+
}
|
187
|
+
|
188
|
+
.ec-event-time {
|
189
|
+
font-size: 85%;
|
190
|
+
font-weight: bold;
|
191
|
+
padding-right: 3px;
|
192
|
+
}
|
193
|
+
|
194
|
+
|
195
|
+
/* Left and right arrows */
|
196
|
+
/* Doesn't work in IE6, use bg images instead */
|
197
|
+
.ec-left-arrow, .ec-right-arrow {
|
198
|
+
position: relative;
|
199
|
+
top: 3px;
|
200
|
+
width: 0;
|
201
|
+
height: 0;
|
202
|
+
font-size: 0;
|
203
|
+
line-height: 0;
|
204
|
+
margin-bottom: -8px;
|
205
|
+
border-top: 4px solid transparent;
|
206
|
+
border-bottom: 4px solid transparent;
|
207
|
+
}
|
208
|
+
|
209
|
+
.ec-left-arrow {
|
210
|
+
margin-left: -7px;
|
211
|
+
margin-right: auto;
|
212
|
+
border-right: 4px solid white;
|
213
|
+
}
|
214
|
+
|
215
|
+
.ec-right-arrow {
|
216
|
+
margin-left: auto;
|
217
|
+
margin-right: 3px;
|
218
|
+
border-left: 4px solid white;
|
219
|
+
}
|
220
|
+
|
221
|
+
/* remove this to not have a bullet */
|
222
|
+
/* don't look as good in ie */
|
223
|
+
.ec-bullet {
|
224
|
+
position: absolute;
|
225
|
+
top: 7px;
|
226
|
+
width: 4px;
|
227
|
+
height: 4px;
|
228
|
+
margin-left: -7px;
|
229
|
+
margin-right: auto;
|
230
|
+
-webkit-border-radius: 2px;
|
231
|
+
-khtml-border-radius: 2px;
|
232
|
+
-moz-border-radius: 2px;
|
233
|
+
}
|