kosmas58-compass-jquery-plugin 0.2.0.3 → 0.2.2.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.
- data/README.textile +18 -2
- data/lib/jquery/calendar.rb +5 -0
- data/lib/jquery/dynatree.rb +5 -0
- data/lib/jquery/jqgrid.rb +1 -1
- data/lib/jquery/rubygems.rake +1 -1
- data/lib/jquery/secret_sauce/helpers/ui_grid_helper.rb +3 -2
- data/lib/jquery/version.rb +2 -2
- data/templates/calendar/config/initializers/calendar.rb +3 -0
- data/templates/calendar/jquery.calendar.js +2047 -0
- data/templates/calendar/jquery.calendar.min.js +11 -0
- data/templates/calendar/jquery.ui/calendar.sass +288 -0
- data/templates/calendar/manifest.rb +7 -0
- data/templates/dynatree/config/initializers/dynatree.rb +3 -0
- data/templates/dynatree/manifest.rb +1 -0
- data/templates/jqgrid/config/initializers/jqgrid.rb +1 -1
- data/templates/jqgrid/jquery.jqGrid.js +26 -21
- data/templates/jqgrid/jquery.jqGrid.min.js +1 -1
- data/templates/secret_sauce/app/views/ui/_ui_grid_for_without_block.js.haml +136 -0
- data/templates/secret_sauce/manifest.rb +1 -1
- metadata +18 -4
- data/templates/secret_sauce/app/views/ui/_ui_grid_for_without_block.html.erb +0 -139
data/README.textile
CHANGED
@@ -61,7 +61,6 @@ To use the localized stylesheets and javacripts include:
|
|
61
61
|
|
62
62
|
<pre>
|
63
63
|
= stylesheet_link_tag 'compiled/jquery.ui/jqGrid.css', :media => 'screen, projection'
|
64
|
-
= stylesheet_link_tag 'fix_blueprint_jqgrid.css', :media => 'screen, projection'
|
65
64
|
= jqgrid_javascripts I18n.locale</pre>
|
66
65
|
|
67
66
|
jqGrid now uses the jQuery UI Themes. jqGrid has been included as a subproject. You do not need to check it out unless you want to use a different version.
|
@@ -80,9 +79,24 @@ To use the localized stylesheets and javacripts include:
|
|
80
79
|
|
81
80
|
<pre>
|
82
81
|
= stylesheet_link_tag 'compiled/jquery.ui/secret_sauce.css', :media => 'screen, projection'
|
83
|
-
= stylesheet_link_tag 'fix_blueprint_jqgrid.css', :media => 'screen, projection'
|
84
82
|
= javascript_include_tag :secret_sauce</pre>
|
85
83
|
|
84
|
+
h3. Calendar
|
85
|
+
|
86
|
+
Use compass to install the calendar javascript library into your project.
|
87
|
+
|
88
|
+
<pre>compass -f jquery -p calendar <project name></pre>
|
89
|
+
|
90
|
+
You will find all the stylesheets in easy-to-read Sass format.
|
91
|
+
|
92
|
+
<pre>stylesheets/jquery.ui</pre>
|
93
|
+
|
94
|
+
To use the (localized) stylesheets and javacripts include:
|
95
|
+
|
96
|
+
<pre>
|
97
|
+
= stylesheet_link_tag 'compiled/jquery.ui/calendar.css', :media => 'screen, projection'
|
98
|
+
= javascript_include_tag :calendar</pre>
|
99
|
+
|
86
100
|
h2. Thanks to the Contributors:
|
87
101
|
|
88
102
|
h3. Rails
|
@@ -101,3 +115,5 @@ h3. jQuery Plugins included
|
|
101
115
|
* John Reisig et. al. for <b>"jQuery Form Plugin":http://malsup.com/jquery/form//</b>
|
102
116
|
* Martin Wendt for <b>"jQuery Dynatree Plugin":http://www.wwwendt.de</b>
|
103
117
|
* Tony Tomov for <b>"jQuery Grid Plugin":http://www.trirand.com/blog/</b>
|
118
|
+
* Rob Monie for <b>"jQuery.weekCalendar":http://www.redredred.com.au/</b>
|
119
|
+
* Kyle LeNeau for <b>"jMonthCalendar":http://www.bytecyclist.com/projects/jmonthcalendar</b>
|
data/lib/jquery/jqgrid.rb
CHANGED
data/lib/jquery/rubygems.rake
CHANGED
@@ -8,7 +8,7 @@ spec = Gem::Specification.new do |s|
|
|
8
8
|
s.description = s.summary
|
9
9
|
#s.executables = ["jqgrid", "jquery-ui"]
|
10
10
|
s.files = %w[MIT-LICENSE Rakefile README.textile] + Dir["lib/**/*"] + Dir["templates/**/*"]
|
11
|
-
s.add_dependency("chriseppstein-compass", [">= 0.8.
|
11
|
+
s.add_dependency("chriseppstein-compass", [">= 0.8.16"])
|
12
12
|
end
|
13
13
|
|
14
14
|
Rake::GemPackageTask.new(spec) do |package|
|
@@ -210,8 +210,9 @@ module SecretSauce
|
|
210
210
|
:edit => false,
|
211
211
|
:add => false,
|
212
212
|
:del => false
|
213
|
-
}.merge(options[:nav]))
|
214
|
-
render
|
213
|
+
}.merge(options[:nav]))
|
214
|
+
#render(:partial => 'ui/ui_grid_for_without_block', :locals => {:options => mapped_options, :name => name_or_array, :nav => options[:nav], :actions => options[:actions]})
|
215
|
+
render(:file => 'ui/_ui_grid_for_without_block.js.haml', :locals => {:options => mapped_options, :name => name_or_array, :nav => options[:nav], :actions => options[:actions]})
|
215
216
|
end
|
216
217
|
end
|
217
218
|
end
|
data/lib/jquery/version.rb
CHANGED
@@ -0,0 +1,2047 @@
|
|
1
|
+
/*
|
2
|
+
* jQuery.weekCalendar v1.2.1
|
3
|
+
* http://www.redredred.com.au/
|
4
|
+
*
|
5
|
+
* Requires:
|
6
|
+
* - jquery.weekcalendar.css
|
7
|
+
* - jquery 1.3.x
|
8
|
+
* - jquery-ui 1.7.x (widget, drag, drop, resize)
|
9
|
+
*
|
10
|
+
* Copyright (c) 2009 Rob Monie
|
11
|
+
* Dual licensed under the MIT and GPL licenses:
|
12
|
+
* http://www.opensource.org/licenses/mit-license.php
|
13
|
+
* http://www.gnu.org/licenses/gpl.html
|
14
|
+
*
|
15
|
+
* If you're after a monthly calendar plugin, check out http://arshaw.com/fullcalendar/
|
16
|
+
*/
|
17
|
+
|
18
|
+
(function($) {
|
19
|
+
|
20
|
+
$.widget("ui.weekCalendar", {
|
21
|
+
|
22
|
+
/***********************
|
23
|
+
* Initialise calendar *
|
24
|
+
***********************/
|
25
|
+
_init : function() {
|
26
|
+
var self = this;
|
27
|
+
self._computeOptions();
|
28
|
+
self._setupEventDelegation();
|
29
|
+
self._renderCalendar();
|
30
|
+
self._loadCalEvents();
|
31
|
+
self._resizeCalendar();
|
32
|
+
//setTimeout(function() {
|
33
|
+
self._scrollToHour(self.options.date.getHours());
|
34
|
+
//}, 500);
|
35
|
+
|
36
|
+
$(window).unbind("resize.weekcalendar");
|
37
|
+
$(window).bind("resize.weekcalendar", function(){
|
38
|
+
self._resizeCalendar();
|
39
|
+
});
|
40
|
+
|
41
|
+
},
|
42
|
+
|
43
|
+
/********************
|
44
|
+
* public functions *
|
45
|
+
********************/
|
46
|
+
/*
|
47
|
+
* Refresh the events for the currently displayed week.
|
48
|
+
*/
|
49
|
+
refresh : function() {
|
50
|
+
this._clearCalendar();
|
51
|
+
this._loadCalEvents(this.element.data("startDate")); //reload with existing week
|
52
|
+
},
|
53
|
+
|
54
|
+
/*
|
55
|
+
* Clear all events currently loaded into the calendar
|
56
|
+
*/
|
57
|
+
clear : function() {
|
58
|
+
this._clearCalendar();
|
59
|
+
},
|
60
|
+
|
61
|
+
/*
|
62
|
+
* Go to this week
|
63
|
+
*/
|
64
|
+
today : function() {
|
65
|
+
this._clearCalendar();
|
66
|
+
this._loadCalEvents(new Date());
|
67
|
+
},
|
68
|
+
|
69
|
+
/*
|
70
|
+
* Go to the previous week relative to the currently displayed week
|
71
|
+
*/
|
72
|
+
prevWeek : function() {
|
73
|
+
//minus more than 1 day to be sure we're in previous week - account for daylight savings or other anomolies
|
74
|
+
var newDate = new Date(this.element.data("startDate").getTime() - (MILLIS_IN_WEEK / 6));
|
75
|
+
this._clearCalendar();
|
76
|
+
this._loadCalEvents(newDate);
|
77
|
+
},
|
78
|
+
|
79
|
+
/*
|
80
|
+
* Go to the next week relative to the currently displayed week
|
81
|
+
*/
|
82
|
+
nextWeek : function() {
|
83
|
+
//add 8 days to be sure of being in prev week - allows for daylight savings or other anomolies
|
84
|
+
var newDate = new Date(this.element.data("startDate").getTime() + MILLIS_IN_WEEK + (MILLIS_IN_WEEK / 7));
|
85
|
+
this._clearCalendar();
|
86
|
+
this._loadCalEvents(newDate);
|
87
|
+
},
|
88
|
+
|
89
|
+
/*
|
90
|
+
* Reload the calendar to whatever week the date passed in falls on.
|
91
|
+
*/
|
92
|
+
gotoWeek : function(date) {
|
93
|
+
this._clearCalendar();
|
94
|
+
this._loadCalEvents(date);
|
95
|
+
},
|
96
|
+
|
97
|
+
/*
|
98
|
+
* Remove an event based on it's id
|
99
|
+
*/
|
100
|
+
removeEvent : function(eventId) {
|
101
|
+
this.element.find(".cal-event").each(function(){
|
102
|
+
if($(this).data("calEvent").id === eventId) {
|
103
|
+
$(this).fadeOut(function(){
|
104
|
+
$(this).remove();
|
105
|
+
});
|
106
|
+
return false;
|
107
|
+
}
|
108
|
+
});
|
109
|
+
},
|
110
|
+
|
111
|
+
/*
|
112
|
+
* Removes any events that have been added but not yet saved (have no id).
|
113
|
+
* This is useful to call after adding a freshly saved new event.
|
114
|
+
*/
|
115
|
+
removeUnsavedEvents : function() {
|
116
|
+
this.element.find(".new-cal-event").fadeOut(function(){
|
117
|
+
$(this).remove();
|
118
|
+
});
|
119
|
+
},
|
120
|
+
|
121
|
+
/*
|
122
|
+
* update an event in the calendar. If the event exists it refreshes
|
123
|
+
* it's rendering. If it's a new event that does not exist in the calendar
|
124
|
+
* it will be added.
|
125
|
+
*/
|
126
|
+
updateEvent : function (calEvent) {
|
127
|
+
this._updateEventInCalendar(calEvent);
|
128
|
+
},
|
129
|
+
|
130
|
+
/*
|
131
|
+
* Returns an array of timeslot start and end times based on
|
132
|
+
* the configured grid of the calendar. Returns in both date and
|
133
|
+
* formatted time based on the 'timeFormat' config option.
|
134
|
+
*/
|
135
|
+
getTimeslotTimes : function(date) {
|
136
|
+
var options = this.options;
|
137
|
+
var firstHourDisplayed = options.businessHours.limitDisplay ? options.businessHours.start : 0;
|
138
|
+
var startDate = new Date(date.getFullYear(), date.getMonth(), date.getDate(), firstHourDisplayed);
|
139
|
+
|
140
|
+
var times = []
|
141
|
+
var startMillis = startDate.getTime();
|
142
|
+
for(var i=0; i < options.timeslotsPerDay; i++) {
|
143
|
+
var endMillis = startMillis + options.millisPerTimeslot;
|
144
|
+
times[i] = {
|
145
|
+
start: new Date(startMillis),
|
146
|
+
startFormatted: this._formatDate(new Date(startMillis), options.timeFormat),
|
147
|
+
end: new Date(endMillis),
|
148
|
+
endFormatted: this._formatDate(new Date(endMillis), options.timeFormat)
|
149
|
+
};
|
150
|
+
startMillis = endMillis;
|
151
|
+
}
|
152
|
+
return times;
|
153
|
+
},
|
154
|
+
|
155
|
+
formatDate : function(date, format) {
|
156
|
+
if(format) {
|
157
|
+
return this._formatDate(date, format);
|
158
|
+
} else {
|
159
|
+
return this._formatDate(date, this.options.dateFormat);
|
160
|
+
}
|
161
|
+
},
|
162
|
+
|
163
|
+
formatTime : function(date, format) {
|
164
|
+
if(format) {
|
165
|
+
return this._formatDate(date, format);
|
166
|
+
} else {
|
167
|
+
return this._formatDate(date, this.options.timeFormat);
|
168
|
+
}
|
169
|
+
},
|
170
|
+
|
171
|
+
getData : function(key) {
|
172
|
+
return this._getData(key);
|
173
|
+
},
|
174
|
+
|
175
|
+
/*********************
|
176
|
+
* private functions *
|
177
|
+
*********************/
|
178
|
+
// compute dynamic options based on other config values
|
179
|
+
_computeOptions : function() {
|
180
|
+
|
181
|
+
var options = this.options;
|
182
|
+
|
183
|
+
if(options.businessHours.limitDisplay) {
|
184
|
+
options.timeslotsPerDay = options.timeslotsPerHour * (options.businessHours.end - options.businessHours.start);
|
185
|
+
options.millisToDisplay = (options.businessHours.end - options.businessHours.start) * 60 * 60 * 1000;
|
186
|
+
options.millisPerTimeslot = options.millisToDisplay / options.timeslotsPerDay;
|
187
|
+
} else {
|
188
|
+
options.timeslotsPerDay = options.timeslotsPerHour * 24;
|
189
|
+
options.millisToDisplay = MILLIS_IN_DAY;
|
190
|
+
options.millisPerTimeslot = MILLIS_IN_DAY / options.timeslotsPerDay;
|
191
|
+
}
|
192
|
+
},
|
193
|
+
|
194
|
+
/*
|
195
|
+
* Resize the calendar scrollable height based on the provided function in options.
|
196
|
+
*/
|
197
|
+
_resizeCalendar : function () {
|
198
|
+
|
199
|
+
var options = this.options;
|
200
|
+
if(options && $.isFunction(options.height)) {
|
201
|
+
var calendarHeight = options.height(this.element);
|
202
|
+
var headerHeight = this.element.find(".week-calendar-header").outerHeight();
|
203
|
+
var navHeight = this.element.find(".calendar-nav").outerHeight();
|
204
|
+
this.element.find(".calendar-scrollable-grid").height(calendarHeight - navHeight - headerHeight);
|
205
|
+
}
|
206
|
+
},
|
207
|
+
|
208
|
+
/*
|
209
|
+
* configure calendar interaction events that are able to use event
|
210
|
+
* delegation for greater efficiency
|
211
|
+
*/
|
212
|
+
_setupEventDelegation : function() {
|
213
|
+
var self = this;
|
214
|
+
var options = this.options;
|
215
|
+
this.element.click(function(event) {
|
216
|
+
var $target = $(event.target);
|
217
|
+
if($target.data("preventClick")) {
|
218
|
+
return;
|
219
|
+
}
|
220
|
+
if($target.hasClass("cal-event")) {
|
221
|
+
options.eventClick($target.data("calEvent"), $target, event);
|
222
|
+
} else if($target.parent().hasClass("cal-event")) {
|
223
|
+
options.eventClick($target.parent().data("calEvent"), $target.parent(), event);
|
224
|
+
}
|
225
|
+
}).mouseover(function(event){
|
226
|
+
var $target = $(event.target);
|
227
|
+
|
228
|
+
if(self._isDraggingOrResizing($target)) {
|
229
|
+
return;
|
230
|
+
}
|
231
|
+
|
232
|
+
if($target.hasClass("cal-event") ) {
|
233
|
+
options.eventMouseover($target.data("calEvent"), $target, event);
|
234
|
+
}
|
235
|
+
}).mouseout(function(event){
|
236
|
+
var $target = $(event.target);
|
237
|
+
if(self._isDraggingOrResizing($target)) {
|
238
|
+
return;
|
239
|
+
}
|
240
|
+
if($target.hasClass("cal-event")) {
|
241
|
+
if($target.data("sizing")) return;
|
242
|
+
options.eventMouseout($target.data("calEvent"), $target, event);
|
243
|
+
|
244
|
+
}
|
245
|
+
});
|
246
|
+
},
|
247
|
+
|
248
|
+
/*
|
249
|
+
* check if a ui draggable or resizable is currently being dragged or resized
|
250
|
+
*/
|
251
|
+
_isDraggingOrResizing : function ($target) {
|
252
|
+
return $target.hasClass("ui-draggable-dragging") || $target.hasClass("ui-resizable-resizing");
|
253
|
+
},
|
254
|
+
|
255
|
+
/*
|
256
|
+
* Render the main calendar layout
|
257
|
+
*/
|
258
|
+
_renderCalendar : function() {
|
259
|
+
|
260
|
+
var $calendarContainer, calendarNavHtml, calendarHeaderHtml, calendarBodyHtml, $weekDayColumns;
|
261
|
+
var self = this;
|
262
|
+
var options = this.options;
|
263
|
+
|
264
|
+
$calendarContainer = $("<div class=\"week-calendar\">").appendTo(self.element);
|
265
|
+
|
266
|
+
if(options.buttons) {
|
267
|
+
calendarNavHtml = "<div class=\"calendar-nav\">\
|
268
|
+
<button class=\"today\">" + options.buttonText.today + "</button>\
|
269
|
+
<button class=\"prev\">" + options.buttonText.lastWeek + "</button>\
|
270
|
+
<button class=\"next\">" + options.buttonText.nextWeek + "</button>\
|
271
|
+
</div>";
|
272
|
+
|
273
|
+
$(calendarNavHtml).appendTo($calendarContainer);
|
274
|
+
|
275
|
+
$calendarContainer.find(".calendar-nav .today").click(function(){
|
276
|
+
self.element.weekCalendar("today");
|
277
|
+
return false;
|
278
|
+
});
|
279
|
+
|
280
|
+
$calendarContainer.find(".calendar-nav .prev").click(function(){
|
281
|
+
self.element.weekCalendar("prevWeek");
|
282
|
+
return false;
|
283
|
+
});
|
284
|
+
|
285
|
+
$calendarContainer.find(".calendar-nav .next").click(function(){
|
286
|
+
self.element.weekCalendar("nextWeek");
|
287
|
+
return false;
|
288
|
+
});
|
289
|
+
|
290
|
+
}
|
291
|
+
|
292
|
+
//render calendar header
|
293
|
+
calendarHeaderHtml = "<table class=\"week-calendar-header\"><tbody><tr><td class=\"time-column-header\"></td>";
|
294
|
+
for(var i=1 ; i<=7; i++) {
|
295
|
+
calendarHeaderHtml += "<td class=\"day-column-header day-" + i + "\"></td>";
|
296
|
+
}
|
297
|
+
calendarHeaderHtml += "<td class=\"scrollbar-shim\"></td></tr></tbody></table>";
|
298
|
+
|
299
|
+
//render calendar body
|
300
|
+
calendarBodyHtml = "<div class=\"calendar-scrollable-grid\">\
|
301
|
+
<table class=\"week-calendar-time-slots\">\
|
302
|
+
<tbody>\
|
303
|
+
<tr>\
|
304
|
+
<td class=\"grid-timeslot-header\"></td>\
|
305
|
+
<td colspan=\"7\">\
|
306
|
+
<div class=\"time-slot-wrapper\">\
|
307
|
+
<div class=\"time-slots\">";
|
308
|
+
|
309
|
+
var start = options.businessHours.limitDisplay ? options.businessHours.start : 0;
|
310
|
+
var end = options.businessHours.limitDisplay ? options.businessHours.end : 24;
|
311
|
+
|
312
|
+
for(var i = start ; i < end; i++) {
|
313
|
+
for(var j=0;j<options.timeslotsPerHour - 1; j++) {
|
314
|
+
calendarBodyHtml += "<div class=\"time-slot\"></div>";
|
315
|
+
}
|
316
|
+
calendarBodyHtml += "<div class=\"time-slot hour-end\"></div>";
|
317
|
+
}
|
318
|
+
|
319
|
+
calendarBodyHtml += "</div></div></td></tr><tr><td class=\"grid-timeslot-header\">";
|
320
|
+
|
321
|
+
for(var i = start ; i < end; i++) {
|
322
|
+
|
323
|
+
var bhClass = (options.businessHours.start <= i && options.businessHours.end > i) ? "business-hours" : "";
|
324
|
+
calendarBodyHtml += "<div class=\"hour-header " + bhClass + "\">"
|
325
|
+
if(options.use24Hour) {
|
326
|
+
calendarBodyHtml += "<div class=\"time-header-cell\">" + self._24HourForIndex(i) + "</div>";
|
327
|
+
} else {
|
328
|
+
calendarBodyHtml += "<div class=\"time-header-cell\">" + self._hourForIndex(i) + "<span class=\"am-pm\">" + self._amOrPm(i) + "</span></div>";
|
329
|
+
}
|
330
|
+
calendarBodyHtml += "</div>";
|
331
|
+
}
|
332
|
+
|
333
|
+
calendarBodyHtml += "</td>";
|
334
|
+
|
335
|
+
for(var i=1 ; i<=7; i++) {
|
336
|
+
calendarBodyHtml += "<td class=\"day-column day-" + i + "\"><div class=\"day-column-inner\"></div></td>"
|
337
|
+
}
|
338
|
+
|
339
|
+
calendarBodyHtml += "</tr></tbody></table></div>";
|
340
|
+
|
341
|
+
//append all calendar parts to container
|
342
|
+
$(calendarHeaderHtml + calendarBodyHtml).appendTo($calendarContainer);
|
343
|
+
|
344
|
+
$weekDayColumns = $calendarContainer.find(".day-column-inner");
|
345
|
+
$weekDayColumns.each(function(i, val) {
|
346
|
+
$(this).height(options.timeslotHeight * options.timeslotsPerDay);
|
347
|
+
if(!options.readonly) {
|
348
|
+
self._addDroppableToWeekDay($(this));
|
349
|
+
self._setupEventCreationForWeekDay($(this));
|
350
|
+
}
|
351
|
+
});
|
352
|
+
|
353
|
+
$calendarContainer.find(".time-slot").height(options.timeslotHeight -1); //account for border
|
354
|
+
|
355
|
+
$calendarContainer.find(".time-header-cell").css({
|
356
|
+
height : (options.timeslotHeight * options.timeslotsPerHour) - 11,
|
357
|
+
padding: 5
|
358
|
+
});
|
359
|
+
|
360
|
+
|
361
|
+
|
362
|
+
},
|
363
|
+
|
364
|
+
/*
|
365
|
+
* setup mouse events for capturing new events
|
366
|
+
*/
|
367
|
+
_setupEventCreationForWeekDay : function($weekDay) {
|
368
|
+
var self = this;
|
369
|
+
var options = this.options;
|
370
|
+
$weekDay.mousedown(function(event) {
|
371
|
+
var $target = $(event.target);
|
372
|
+
if($target.hasClass("day-column-inner")) {
|
373
|
+
|
374
|
+
var $newEvent = $("<div class=\"cal-event new-cal-event new-cal-event-creating\"></div>");
|
375
|
+
|
376
|
+
$newEvent.css({lineHeight: (options.timeslotHeight - 2) + "px", fontSize: (options.timeslotHeight / 2) + "px"});
|
377
|
+
$target.append($newEvent);
|
378
|
+
|
379
|
+
var columnOffset = $target.offset().top;
|
380
|
+
var clickY = event.pageY - columnOffset;
|
381
|
+
var clickYRounded = (clickY - (clickY % options.timeslotHeight)) / options.timeslotHeight;
|
382
|
+
var topPosition = clickYRounded * options.timeslotHeight;
|
383
|
+
$newEvent.css({top: topPosition});
|
384
|
+
|
385
|
+
$target.bind("mousemove.newevent", function(event){
|
386
|
+
$newEvent.show();
|
387
|
+
$newEvent.addClass("ui-resizable-resizing");
|
388
|
+
var height = Math.round(event.pageY - columnOffset - topPosition);
|
389
|
+
var remainder = height % options.timeslotHeight;
|
390
|
+
//snap to closest timeslot
|
391
|
+
if(remainder < (height / 2)) {
|
392
|
+
var useHeight = height - remainder;
|
393
|
+
$newEvent.css("height", useHeight < options.timeslotHeight ? options.timeslotHeight : useHeight);
|
394
|
+
} else {
|
395
|
+
$newEvent.css("height", height + (options.timeslotHeight - remainder));
|
396
|
+
}
|
397
|
+
}).mouseup(function(){
|
398
|
+
$target.unbind("mousemove.newevent");
|
399
|
+
$newEvent.addClass("ui-corner-all");
|
400
|
+
});
|
401
|
+
}
|
402
|
+
|
403
|
+
}).mouseup(function(event) {
|
404
|
+
var $target = $(event.target);
|
405
|
+
|
406
|
+
var $weekDay = $target.closest(".day-column-inner");
|
407
|
+
var $newEvent = $weekDay.find(".new-cal-event-creating");
|
408
|
+
|
409
|
+
if($newEvent.length) {
|
410
|
+
//if even created from a single click only, default height
|
411
|
+
if(!$newEvent.hasClass("ui-resizable-resizing")) {
|
412
|
+
$newEvent.css({height: options.timeslotHeight * options.defaultEventLength}).show();
|
413
|
+
}
|
414
|
+
var top = parseInt($newEvent.css("top"));
|
415
|
+
var eventDuration = self._getEventDurationFromPositionedEventElement($weekDay, $newEvent, top);
|
416
|
+
|
417
|
+
$newEvent.remove();
|
418
|
+
var newCalEvent = {start: eventDuration.start, end: eventDuration.end, title: options.newEventText};
|
419
|
+
var $renderedCalEvent = self._renderEvent(newCalEvent, $weekDay);
|
420
|
+
|
421
|
+
if(!options.allowCalEventOverlap) {
|
422
|
+
self._adjustForEventCollisions($weekDay, $renderedCalEvent, newCalEvent, newCalEvent);
|
423
|
+
self._positionEvent($weekDay, $renderedCalEvent);
|
424
|
+
} else {
|
425
|
+
self._adjustOverlappingEvents($weekDay);
|
426
|
+
}
|
427
|
+
|
428
|
+
options.eventNew(eventDuration, $renderedCalEvent);
|
429
|
+
}
|
430
|
+
});
|
431
|
+
},
|
432
|
+
|
433
|
+
/*
|
434
|
+
* load calendar events for the week based on the date provided
|
435
|
+
*/
|
436
|
+
_loadCalEvents : function(dateWithinWeek) {
|
437
|
+
|
438
|
+
var date, weekStartDate, endDate, $weekDayColumns;
|
439
|
+
var self = this;
|
440
|
+
var options = this.options;
|
441
|
+
date = dateWithinWeek || options.date;
|
442
|
+
weekStartDate = self._dateFirstDayOfWeek(date);
|
443
|
+
weekEndDate = self._dateLastMilliOfWeek(date);
|
444
|
+
|
445
|
+
options.calendarBeforeLoad(self.element);
|
446
|
+
|
447
|
+
self.element.data("startDate", weekStartDate);
|
448
|
+
self.element.data("endDate", weekEndDate);
|
449
|
+
|
450
|
+
$weekDayColumns = self.element.find(".day-column-inner");
|
451
|
+
|
452
|
+
self._updateDayColumnHeader($weekDayColumns);
|
453
|
+
|
454
|
+
//load events by chosen means
|
455
|
+
if (typeof options.data == 'string') {
|
456
|
+
if (options.loading) options.loading(true);
|
457
|
+
var jsonOptions = {};
|
458
|
+
jsonOptions[options.startParam || 'start'] = Math.round(weekStartDate.getTime() / 1000);
|
459
|
+
jsonOptions[options.endParam || 'end'] = Math.round(weekEndDate.getTime() / 1000);
|
460
|
+
$.getJSON(options.data, jsonOptions, function(data) {
|
461
|
+
self._renderEvents(data, $weekDayColumns);
|
462
|
+
if (options.loading) options.loading(false);
|
463
|
+
});
|
464
|
+
}
|
465
|
+
else if ($.isFunction(options.data)) {
|
466
|
+
options.data(weekStartDate, weekEndDate,
|
467
|
+
function(data) {
|
468
|
+
self._renderEvents(data, $weekDayColumns);
|
469
|
+
});
|
470
|
+
}
|
471
|
+
else if (options.data) {
|
472
|
+
self._renderEvents(options.data, $weekDayColumns);
|
473
|
+
}
|
474
|
+
|
475
|
+
self._disableTextSelect($weekDayColumns);
|
476
|
+
|
477
|
+
|
478
|
+
},
|
479
|
+
|
480
|
+
/*
|
481
|
+
* update the display of each day column header based on the calendar week
|
482
|
+
*/
|
483
|
+
_updateDayColumnHeader : function ($weekDayColumns) {
|
484
|
+
var self = this;
|
485
|
+
var options = this.options;
|
486
|
+
var currentDay = self._cloneDate(self.element.data("startDate"));
|
487
|
+
|
488
|
+
self.element.find(".week-calendar-header td.day-column-header").each(function(i, val) {
|
489
|
+
|
490
|
+
var dayName = options.useShortDayNames ? options.shortDays[currentDay.getDay()] : options.longDays[currentDay.getDay()];
|
491
|
+
|
492
|
+
$(this).html(dayName + "<br/>" + self._formatDate(currentDay, options.dateFormat));
|
493
|
+
if(self._isToday(currentDay)) {
|
494
|
+
$(this).addClass("today");
|
495
|
+
} else {
|
496
|
+
$(this).removeClass("today");
|
497
|
+
}
|
498
|
+
currentDay = self._addDays(currentDay, 1);
|
499
|
+
|
500
|
+
});
|
501
|
+
|
502
|
+
currentDay = self._dateFirstDayOfWeek(self._cloneDate(self.element.data("startDate")));
|
503
|
+
|
504
|
+
$weekDayColumns.each(function(i, val) {
|
505
|
+
|
506
|
+
$(this).data("startDate", self._cloneDate(currentDay));
|
507
|
+
$(this).data("endDate", new Date(currentDay.getTime() + (MILLIS_IN_DAY - 1)));
|
508
|
+
if(self._isToday(currentDay)) {
|
509
|
+
$(this).parent().addClass("today");
|
510
|
+
} else {
|
511
|
+
$(this).parent().removeClass("today");
|
512
|
+
}
|
513
|
+
|
514
|
+
currentDay = self._addDays(currentDay, 1);
|
515
|
+
});
|
516
|
+
|
517
|
+
},
|
518
|
+
|
519
|
+
/*
|
520
|
+
* Render the events into the calendar
|
521
|
+
*/
|
522
|
+
_renderEvents : function (events, $weekDayColumns) {
|
523
|
+
var self = this;
|
524
|
+
var options = this.options;
|
525
|
+
var eventsToRender;
|
526
|
+
|
527
|
+
if($.isArray(events)) {
|
528
|
+
eventsToRender = self._cleanEvents(events);
|
529
|
+
} else if(events.events) {
|
530
|
+
eventsToRender = self._cleanEvents(events.events);
|
531
|
+
}
|
532
|
+
if(events.options) {
|
533
|
+
|
534
|
+
var updateLayout = false;
|
535
|
+
//update options
|
536
|
+
$.each(events.options, function(key, value){
|
537
|
+
if(value !== options[key]) {
|
538
|
+
options[key] = value;
|
539
|
+
updateLayout = true;
|
540
|
+
}
|
541
|
+
});
|
542
|
+
|
543
|
+
self._computeOptions();
|
544
|
+
|
545
|
+
if(updateLayout) {
|
546
|
+
self.element.empty();
|
547
|
+
self._renderCalendar();
|
548
|
+
$weekDayColumns = self.element.find(".week-calendar-time-slots .day-column-inner");
|
549
|
+
self._updateDayColumnHeader($weekDayColumns);
|
550
|
+
self._resizeCalendar();
|
551
|
+
}
|
552
|
+
|
553
|
+
}
|
554
|
+
|
555
|
+
|
556
|
+
$.each(eventsToRender, function(i, calEvent){
|
557
|
+
|
558
|
+
var $weekDay = self._findWeekDayForEvent(calEvent, $weekDayColumns);
|
559
|
+
|
560
|
+
if($weekDay) {
|
561
|
+
self._renderEvent(calEvent, $weekDay);
|
562
|
+
}
|
563
|
+
});
|
564
|
+
|
565
|
+
$weekDayColumns.each(function(){
|
566
|
+
self._adjustOverlappingEvents($(this));
|
567
|
+
});
|
568
|
+
|
569
|
+
options.calendarAfterLoad(self.element);
|
570
|
+
|
571
|
+
if(!eventsToRender.length) {
|
572
|
+
options.noEvents();
|
573
|
+
}
|
574
|
+
|
575
|
+
},
|
576
|
+
|
577
|
+
/*
|
578
|
+
* Render a specific event into the day provided. Assumes correct
|
579
|
+
* day for calEvent date
|
580
|
+
*/
|
581
|
+
_renderEvent: function (calEvent, $weekDay) {
|
582
|
+
var self = this;
|
583
|
+
var options = this.options;
|
584
|
+
if(calEvent.start.getTime() > calEvent.end.getTime()) {
|
585
|
+
return; // can't render a negative height
|
586
|
+
}
|
587
|
+
|
588
|
+
var eventClass, eventHtml, $calEvent, $modifiedEvent;
|
589
|
+
|
590
|
+
eventClass = calEvent.id ? "cal-event" : "cal-event new-cal-event";
|
591
|
+
eventHtml = "<div class=\"" + eventClass + " ui-corner-all\">\
|
592
|
+
<div class=\"time ui-corner-all\"></div>\
|
593
|
+
<div class=\"title\"></div></div>";
|
594
|
+
|
595
|
+
$calEvent = $(eventHtml);
|
596
|
+
$modifiedEvent = options.eventRender(calEvent, $calEvent);
|
597
|
+
$calEvent = $modifiedEvent ? $modifiedEvent.appendTo($weekDay) : $calEvent.appendTo($weekDay);
|
598
|
+
$calEvent.css({lineHeight: (options.timeslotHeight - 2) + "px", fontSize: (options.timeslotHeight / 2) + "px"});
|
599
|
+
|
600
|
+
self._refreshEventDetails(calEvent, $calEvent);
|
601
|
+
self._positionEvent($weekDay, $calEvent);
|
602
|
+
$calEvent.show();
|
603
|
+
|
604
|
+
if(!options.readonly && options.resizable(calEvent, $calEvent)) {
|
605
|
+
self._addResizableToCalEvent(calEvent, $calEvent, $weekDay)
|
606
|
+
}
|
607
|
+
if(!options.readonly && options.draggable(calEvent, $calEvent)) {
|
608
|
+
self._addDraggableToCalEvent(calEvent, $calEvent);
|
609
|
+
}
|
610
|
+
|
611
|
+
options.eventAfterRender(calEvent, $calEvent);
|
612
|
+
|
613
|
+
return $calEvent;
|
614
|
+
|
615
|
+
},
|
616
|
+
|
617
|
+
/*
|
618
|
+
* If overlapping is allowed, check for overlapping events and format
|
619
|
+
* for greater readability
|
620
|
+
*/
|
621
|
+
_adjustOverlappingEvents : function($weekDay) {
|
622
|
+
var self = this;
|
623
|
+
if(self.options.allowCalEventOverlap) {
|
624
|
+
var groups = self._groupOverlappingEventElements($weekDay);
|
625
|
+
|
626
|
+
$.each(groups, function(){
|
627
|
+
var groupAmount = this.length;
|
628
|
+
var curGroup = this;
|
629
|
+
// do we want events to be displayed as overlapping
|
630
|
+
if (self.options.overlapEventsSeparate){
|
631
|
+
var newWidth = 100/groupAmount;
|
632
|
+
var newLeftAdd = newWidth;
|
633
|
+
} else {
|
634
|
+
// TODO what happens when the group has more than 10 elements
|
635
|
+
var newWidth = (100 - (groupAmount*10));
|
636
|
+
var newLeftAdd = (100 - newWidth) / (groupAmount-1);
|
637
|
+
}
|
638
|
+
$.each(this, function(i){
|
639
|
+
var newLeft = (i * newLeftAdd);
|
640
|
+
// bring mouseovered event to the front
|
641
|
+
if(!self.options.overlapEventsSeparate){
|
642
|
+
$(this).bind("mouseover.z-index",function(){
|
643
|
+
var $elem = $(this);
|
644
|
+
$.each(curGroup, function() {
|
645
|
+
$(this).css({"z-index": "1"});
|
646
|
+
});
|
647
|
+
$elem.css({"z-index": "3"});
|
648
|
+
});
|
649
|
+
}
|
650
|
+
$(this).css({width: newWidth+"%", left: newLeft+"%", right: 0});
|
651
|
+
});
|
652
|
+
});
|
653
|
+
}
|
654
|
+
},
|
655
|
+
|
656
|
+
|
657
|
+
/*
|
658
|
+
* Find groups of overlapping events
|
659
|
+
*/
|
660
|
+
_groupOverlappingEventElements : function($weekDay) {
|
661
|
+
var self = this;
|
662
|
+
var $events = $weekDay.find(".cal-event");
|
663
|
+
var sortedEvents = $events.sort(function(a, b){
|
664
|
+
return $(a).data("calEvent").start.getTime() - $(b).data("calEvent").start.getTime();
|
665
|
+
});
|
666
|
+
|
667
|
+
var $lastEvent;
|
668
|
+
var groups = [];
|
669
|
+
var currentGroup = [];
|
670
|
+
var $curEvent;
|
671
|
+
var currentGroupStartTime = 0;
|
672
|
+
var currentGroupEndTime = 0;
|
673
|
+
var lastGroupEndTime = 0;
|
674
|
+
$.each(sortedEvents, function(){
|
675
|
+
|
676
|
+
$curEvent = $(this);
|
677
|
+
currentGroupStartTime = $curEvent.data("calEvent").start.getTime();
|
678
|
+
currentGroupEndTime = $curEvent.data("calEvent").end.getTime();
|
679
|
+
$curEvent.css({width: "100%", left: "0%", right: "", "z-index": "1"});
|
680
|
+
$curEvent.unbind("mouseover.z-index");
|
681
|
+
// if current start time is lower than current endtime time than either this event is earlier than the group, or already within the group
|
682
|
+
if ($curEvent.data("calEvent").start.getTime() < lastGroupEndTime) {
|
683
|
+
return;
|
684
|
+
}
|
685
|
+
// loop through all current weekday events to check if they belong to the same group
|
686
|
+
$.each(sortedEvents, function() {
|
687
|
+
// check for same element and possibility to even be in the same group note: somehow ($curEvent == $(this) doens't work
|
688
|
+
if ($curEvent.data("calEvent").id == $(this).data("calEvent").id ||
|
689
|
+
currentGroupStartTime > $(this).data("calEvent").start.getTime()+1 ||
|
690
|
+
currentGroupEndTime < $(this).data("calEvent").start.getTime()+1) {
|
691
|
+
return;
|
692
|
+
}
|
693
|
+
//set new endtime of the group
|
694
|
+
if ($(this).data("calEvent").end.getTime() > currentGroupEndTime) {
|
695
|
+
currentGroupEndTime = $(this).data("calEvent").end.getTime();
|
696
|
+
}
|
697
|
+
// ain't we adding the same element
|
698
|
+
if ($.inArray($(this), currentGroup) == -1) {
|
699
|
+
currentGroup.push($(this));
|
700
|
+
}
|
701
|
+
// ain't we adding the same element
|
702
|
+
if ($.inArray($curEvent, currentGroup) == -1) {
|
703
|
+
currentGroup.push($curEvent);
|
704
|
+
}
|
705
|
+
});
|
706
|
+
if(currentGroup.length) {
|
707
|
+
currentGroup.sort(function(a,b){
|
708
|
+
if ($(a).data("calEvent").start.getTime() > $(b).data("calEvent").start.getTime()) {
|
709
|
+
return 1;
|
710
|
+
} else if ($(a).data("calEvent").start.getTime() < $(b).data("calEvent").start.getTime()) {
|
711
|
+
return -1;
|
712
|
+
} else {
|
713
|
+
return ($(a).data("calEvent").end.getTime() - $(a).data("calEvent").start.getTime())
|
714
|
+
- ($(b).data("calEvent").end.getTime() - $(b).data("calEvent").start.getTime());
|
715
|
+
}
|
716
|
+
});
|
717
|
+
groups.push(currentGroup);
|
718
|
+
currentGroup = [];
|
719
|
+
lastGroupEndTime = currentGroupEndTime;
|
720
|
+
}
|
721
|
+
|
722
|
+
});
|
723
|
+
|
724
|
+
return groups;
|
725
|
+
|
726
|
+
},
|
727
|
+
/*
|
728
|
+
* Check if two groups containt the same events. It assumes the groups are sorted NOTE: might be obsolete
|
729
|
+
*/
|
730
|
+
_compareGroups: function(thisGroup, thatGroup){
|
731
|
+
if (thisGroup.length != thatGroup.length) {
|
732
|
+
return false;
|
733
|
+
}
|
734
|
+
|
735
|
+
for (var i = 0; i < thisGroup.length; i++) {
|
736
|
+
if (thisGroup[i].data("calEvent").id != thatGroup[i].data("calEvent").id) {
|
737
|
+
return false;
|
738
|
+
}
|
739
|
+
}
|
740
|
+
|
741
|
+
return true;
|
742
|
+
},
|
743
|
+
|
744
|
+
|
745
|
+
|
746
|
+
/*
|
747
|
+
* find the weekday in the current calendar that the calEvent falls within
|
748
|
+
*/
|
749
|
+
_findWeekDayForEvent : function(calEvent, $weekDayColumns) {
|
750
|
+
|
751
|
+
var $weekDay;
|
752
|
+
$weekDayColumns.each(function(){
|
753
|
+
if($(this).data("startDate").getTime() <= calEvent.start.getTime() && $(this).data("endDate").getTime() >= calEvent.end.getTime()) {
|
754
|
+
$weekDay = $(this);
|
755
|
+
return false;
|
756
|
+
}
|
757
|
+
});
|
758
|
+
return $weekDay;
|
759
|
+
},
|
760
|
+
|
761
|
+
/*
|
762
|
+
* update the events rendering in the calendar. Add if does not yet exist.
|
763
|
+
*/
|
764
|
+
_updateEventInCalendar : function (calEvent) {
|
765
|
+
var self = this;
|
766
|
+
var options = this.options;
|
767
|
+
self._cleanEvent(calEvent);
|
768
|
+
|
769
|
+
if(calEvent.id) {
|
770
|
+
self.element.find(".cal-event").each(function(){
|
771
|
+
if($(this).data("calEvent").id === calEvent.id || $(this).hasClass("new-cal-event")) {
|
772
|
+
$(this).remove();
|
773
|
+
return false;
|
774
|
+
}
|
775
|
+
});
|
776
|
+
}
|
777
|
+
|
778
|
+
var $weekDay = self._findWeekDayForEvent(calEvent, self.element.find(".week-calendar-time-slots .day-column-inner"));
|
779
|
+
if($weekDay) {
|
780
|
+
self._renderEvent(calEvent, $weekDay);
|
781
|
+
self._adjustOverlappingEvents($weekDay);
|
782
|
+
}
|
783
|
+
},
|
784
|
+
|
785
|
+
/*
|
786
|
+
* Position the event element within the weekday based on it's start / end dates.
|
787
|
+
*/
|
788
|
+
_positionEvent : function($weekDay, $calEvent) {
|
789
|
+
var options = this.options;
|
790
|
+
var calEvent = $calEvent.data("calEvent");
|
791
|
+
var pxPerMillis = $weekDay.height() / options.millisToDisplay;
|
792
|
+
var firstHourDisplayed = options.businessHours.limitDisplay ? options.businessHours.start : 0;
|
793
|
+
var startMillis = calEvent.start.getTime() - new Date(calEvent.start.getFullYear(), calEvent.start.getMonth(), calEvent.start.getDate(), firstHourDisplayed).getTime();
|
794
|
+
var eventMillis = calEvent.end.getTime() - calEvent.start.getTime();
|
795
|
+
var pxTop = pxPerMillis * startMillis;
|
796
|
+
var pxHeight = pxPerMillis * eventMillis;
|
797
|
+
$calEvent.css({top: pxTop, height: pxHeight});
|
798
|
+
},
|
799
|
+
|
800
|
+
/*
|
801
|
+
* Determine the actual start and end times of a calevent based on it's
|
802
|
+
* relative position within the weekday column and the starting hour of the
|
803
|
+
* displayed calendar.
|
804
|
+
*/
|
805
|
+
_getEventDurationFromPositionedEventElement : function($weekDay, $calEvent, top) {
|
806
|
+
var options = this.options;
|
807
|
+
var startOffsetMillis = options.businessHours.limitDisplay ? options.businessHours.start * 60 *60 * 1000 : 0;
|
808
|
+
var start = new Date($weekDay.data("startDate").getTime() + startOffsetMillis + Math.round(top / options.timeslotHeight) * options.millisPerTimeslot);
|
809
|
+
var end = new Date(start.getTime() + ($calEvent.height() / options.timeslotHeight) * options.millisPerTimeslot);
|
810
|
+
return {start: start, end: end};
|
811
|
+
},
|
812
|
+
|
813
|
+
/*
|
814
|
+
* If the calendar does not allow event overlap, adjust the start or end date if necessary to
|
815
|
+
* avoid overlapping of events. Typically, shortens the resized / dropped event to it's max possible
|
816
|
+
* duration based on the overlap. If no satisfactory adjustment can be made, the event is reverted to
|
817
|
+
* it's original location.
|
818
|
+
*/
|
819
|
+
_adjustForEventCollisions : function($weekDay, $calEvent, newCalEvent, oldCalEvent, maintainEventDuration) {
|
820
|
+
var options = this.options;
|
821
|
+
|
822
|
+
if(options.allowCalEventOverlap) {
|
823
|
+
return;
|
824
|
+
}
|
825
|
+
var adjustedStart, adjustedEnd;
|
826
|
+
var self = this;
|
827
|
+
|
828
|
+
$weekDay.find(".cal-event").not($calEvent).each(function(){
|
829
|
+
var currentCalEvent = $(this).data("calEvent");
|
830
|
+
|
831
|
+
//has been dropped onto existing event overlapping the end time
|
832
|
+
if(newCalEvent.start.getTime() < currentCalEvent.end.getTime()
|
833
|
+
&& newCalEvent.end.getTime() >= currentCalEvent.end.getTime()) {
|
834
|
+
|
835
|
+
adjustedStart = currentCalEvent.end;
|
836
|
+
}
|
837
|
+
|
838
|
+
|
839
|
+
//has been dropped onto existing event overlapping the start time
|
840
|
+
if(newCalEvent.end.getTime() > currentCalEvent.start.getTime()
|
841
|
+
&& newCalEvent.start.getTime() <= currentCalEvent.start.getTime()) {
|
842
|
+
|
843
|
+
adjustedEnd = currentCalEvent.start;
|
844
|
+
}
|
845
|
+
//has been dropped inside existing event with same or larger duration
|
846
|
+
if(newCalEvent.end.getTime() <= currentCalEvent.end.getTime()
|
847
|
+
&& newCalEvent.start.getTime() >= currentCalEvent.start.getTime()) {
|
848
|
+
|
849
|
+
adjustedStart = oldCalEvent.start;
|
850
|
+
adjustedEnd = oldCalEvent.end;
|
851
|
+
return false;
|
852
|
+
}
|
853
|
+
|
854
|
+
});
|
855
|
+
|
856
|
+
|
857
|
+
newCalEvent.start = adjustedStart || newCalEvent.start;
|
858
|
+
|
859
|
+
if(adjustedStart && maintainEventDuration) {
|
860
|
+
newCalEvent.end = new Date(adjustedStart.getTime() + (oldCalEvent.end.getTime() - oldCalEvent.start.getTime()));
|
861
|
+
self._adjustForEventCollisions($weekDay, $calEvent, newCalEvent, oldCalEvent);
|
862
|
+
} else {
|
863
|
+
newCalEvent.end = adjustedEnd || newCalEvent.end;
|
864
|
+
}
|
865
|
+
|
866
|
+
|
867
|
+
|
868
|
+
//reset if new cal event has been forced to zero size
|
869
|
+
if(newCalEvent.start.getTime() >= newCalEvent.end.getTime()) {
|
870
|
+
newCalEvent.start = oldCalEvent.start;
|
871
|
+
newCalEvent.end = oldCalEvent.end;
|
872
|
+
}
|
873
|
+
|
874
|
+
$calEvent.data("calEvent", newCalEvent);
|
875
|
+
},
|
876
|
+
|
877
|
+
/*
|
878
|
+
* Add draggable capabilities to an event
|
879
|
+
*/
|
880
|
+
_addDraggableToCalEvent : function(calEvent, $calEvent) {
|
881
|
+
var self = this;
|
882
|
+
var options = this.options;
|
883
|
+
var $weekDay = self._findWeekDayForEvent(calEvent, self.element.find(".week-calendar-time-slots .day-column-inner"));
|
884
|
+
$calEvent.draggable({
|
885
|
+
handle : ".time",
|
886
|
+
containment: ".calendar-scrollable-grid",
|
887
|
+
revert: 'valid',
|
888
|
+
opacity: 0.5,
|
889
|
+
grid : [$calEvent.outerWidth() + 1, options.timeslotHeight ],
|
890
|
+
start : function(event, ui) {
|
891
|
+
var $calEvent = ui.draggable;
|
892
|
+
options.eventDrag(calEvent, $calEvent);
|
893
|
+
}
|
894
|
+
});
|
895
|
+
|
896
|
+
},
|
897
|
+
|
898
|
+
/*
|
899
|
+
* Add droppable capabilites to weekdays to allow dropping of calEvents only
|
900
|
+
*/
|
901
|
+
_addDroppableToWeekDay : function($weekDay) {
|
902
|
+
var self = this;
|
903
|
+
var options = this.options;
|
904
|
+
$weekDay.droppable({
|
905
|
+
accept: ".cal-event",
|
906
|
+
drop: function(event, ui) {
|
907
|
+
var $calEvent = ui.draggable;
|
908
|
+
var top = Math.round(parseInt(ui.position.top));
|
909
|
+
var eventDuration = self._getEventDurationFromPositionedEventElement($weekDay, $calEvent, top);
|
910
|
+
var calEvent = $calEvent.data("calEvent");
|
911
|
+
var newCalEvent = $.extend(true, {start: eventDuration.start, end: eventDuration.end}, calEvent);
|
912
|
+
self._adjustForEventCollisions($weekDay, $calEvent, newCalEvent, calEvent, true);
|
913
|
+
var $weekDayColumns = self.element.find(".day-column-inner");
|
914
|
+
var $newEvent = self._renderEvent(newCalEvent, self._findWeekDayForEvent(newCalEvent, $weekDayColumns));
|
915
|
+
$calEvent.hide();
|
916
|
+
|
917
|
+
//trigger drop callback
|
918
|
+
options.eventDrop(newCalEvent, calEvent, $newEvent);
|
919
|
+
$calEvent.data("preventClick", true);
|
920
|
+
setTimeout(function(){
|
921
|
+
var $weekDayOld = self._findWeekDayForEvent($calEvent.data("calEvent"), self.element.find(".week-calendar-time-slots .day-column-inner"));
|
922
|
+
$calEvent.remove();
|
923
|
+
if ($weekDayOld.data("startDate") != $weekDay.data("startDate")) {
|
924
|
+
self._adjustOverlappingEvents($weekDayOld);
|
925
|
+
}
|
926
|
+
self._adjustOverlappingEvents($weekDay);
|
927
|
+
}, 500);
|
928
|
+
|
929
|
+
}
|
930
|
+
});
|
931
|
+
},
|
932
|
+
|
933
|
+
/*
|
934
|
+
* Add resizable capabilities to a calEvent
|
935
|
+
*/
|
936
|
+
_addResizableToCalEvent : function(calEvent, $calEvent, $weekDay) {
|
937
|
+
var self = this;
|
938
|
+
var options = this.options;
|
939
|
+
$calEvent.resizable({
|
940
|
+
grid: options.timeslotHeight,
|
941
|
+
containment : $weekDay,
|
942
|
+
handles: "s",
|
943
|
+
minHeight: options.timeslotHeight,
|
944
|
+
stop :function(event, ui){
|
945
|
+
var $calEvent = ui.element;
|
946
|
+
var newEnd = new Date($calEvent.data("calEvent").start.getTime() + ($calEvent.height() / options.timeslotHeight) * options.millisPerTimeslot);
|
947
|
+
var newCalEvent = $.extend(true, {start: calEvent.start, end: newEnd}, calEvent);
|
948
|
+
self._adjustForEventCollisions($weekDay, $calEvent, newCalEvent, calEvent);
|
949
|
+
|
950
|
+
self._refreshEventDetails(newCalEvent, $calEvent);
|
951
|
+
self._positionEvent($weekDay, $calEvent);
|
952
|
+
|
953
|
+
//trigger resize callback
|
954
|
+
options.eventResize(newCalEvent, calEvent, $calEvent);
|
955
|
+
$calEvent.data("preventClick", true);
|
956
|
+
setTimeout(function(){
|
957
|
+
$calEvent.removeData("preventClick");
|
958
|
+
}, 500);
|
959
|
+
}
|
960
|
+
});
|
961
|
+
},
|
962
|
+
|
963
|
+
/*
|
964
|
+
* Refresh the displayed details of a calEvent in the calendar
|
965
|
+
*/
|
966
|
+
_refreshEventDetails : function(calEvent, $calEvent) {
|
967
|
+
var self = this;
|
968
|
+
var options = this.options;
|
969
|
+
$calEvent.find(".time").text(self._formatDate(calEvent.start, options.timeFormat) + options.timeSeparator + self._formatDate(calEvent.end, options.timeFormat));
|
970
|
+
$calEvent.find(".title").text(calEvent.title);
|
971
|
+
$calEvent.data("calEvent", calEvent);
|
972
|
+
},
|
973
|
+
|
974
|
+
/*
|
975
|
+
* Clear all cal events from the calendar
|
976
|
+
*/
|
977
|
+
_clearCalendar : function() {
|
978
|
+
this.element.find(".day-column-inner div").remove();
|
979
|
+
},
|
980
|
+
|
981
|
+
/*
|
982
|
+
* Scroll the calendar to a specific hour
|
983
|
+
*/
|
984
|
+
_scrollToHour : function(hour) {
|
985
|
+
var self = this;
|
986
|
+
var options = this.options;
|
987
|
+
var $scrollable = this.element.find(".calendar-scrollable-grid");
|
988
|
+
var slot = hour;
|
989
|
+
if(self.options.businessHours.limitDisplay) {
|
990
|
+
if(hour < self.options.businessHours.start) {
|
991
|
+
slot = 0;
|
992
|
+
} else if(hour > self.options.businessHours.end) {
|
993
|
+
slot = self.options.businessHours.end - self.options.businessHours.start - 1;
|
994
|
+
}
|
995
|
+
}
|
996
|
+
|
997
|
+
var $target = this.element.find(".grid-timeslot-header .hour-header:eq(" + slot + ")");
|
998
|
+
|
999
|
+
$scrollable.animate({scrollTop: 0}, 0, function(){
|
1000
|
+
var targetOffset = $target.offset().top;
|
1001
|
+
var scroll = targetOffset - $scrollable.offset().top - $target.outerHeight();
|
1002
|
+
$scrollable.animate({scrollTop: scroll}, options.scrollToHourMillis);
|
1003
|
+
});
|
1004
|
+
},
|
1005
|
+
|
1006
|
+
/*
|
1007
|
+
* find the hour (12 hour day) for a given hour index
|
1008
|
+
*/
|
1009
|
+
_hourForIndex : function(index) {
|
1010
|
+
if(index === 0 ) { //midnight
|
1011
|
+
return 12;
|
1012
|
+
} else if(index < 13) { //am
|
1013
|
+
return index;
|
1014
|
+
} else { //pm
|
1015
|
+
return index - 12;
|
1016
|
+
}
|
1017
|
+
},
|
1018
|
+
|
1019
|
+
_24HourForIndex : function(index) {
|
1020
|
+
if(index === 0 ) { //midnight
|
1021
|
+
return "00:00";
|
1022
|
+
} else if(index < 10) {
|
1023
|
+
return "0"+index+":00";
|
1024
|
+
} else {
|
1025
|
+
return index+":00";
|
1026
|
+
}
|
1027
|
+
},
|
1028
|
+
|
1029
|
+
_amOrPm : function (hourOfDay) {
|
1030
|
+
return hourOfDay < 12 ? "AM" : "PM";
|
1031
|
+
},
|
1032
|
+
|
1033
|
+
_isToday : function(date) {
|
1034
|
+
var clonedDate = this._cloneDate(date);
|
1035
|
+
this._clearTime(clonedDate);
|
1036
|
+
var today = new Date();
|
1037
|
+
this._clearTime(today);
|
1038
|
+
return today.getTime() === clonedDate.getTime();
|
1039
|
+
},
|
1040
|
+
|
1041
|
+
/*
|
1042
|
+
* Clean events to ensure correct format
|
1043
|
+
*/
|
1044
|
+
_cleanEvents : function(events) {
|
1045
|
+
var self = this;
|
1046
|
+
$.each(events, function(i, event) {
|
1047
|
+
self._cleanEvent(event);
|
1048
|
+
});
|
1049
|
+
return events;
|
1050
|
+
},
|
1051
|
+
|
1052
|
+
/*
|
1053
|
+
* Clean specific event
|
1054
|
+
*/
|
1055
|
+
_cleanEvent : function (event) {
|
1056
|
+
if (event.date) {
|
1057
|
+
event.start = event.date;
|
1058
|
+
}
|
1059
|
+
event.start = this._cleanDate(event.start);
|
1060
|
+
event.end = this._cleanDate(event.end);
|
1061
|
+
if (!event.end) {
|
1062
|
+
event.end = this._addDays(this._cloneDate(event.start), 1);
|
1063
|
+
}
|
1064
|
+
},
|
1065
|
+
|
1066
|
+
/*
|
1067
|
+
* Disable text selection of the elements in different browsers
|
1068
|
+
*/
|
1069
|
+
_disableTextSelect : function($elements) {
|
1070
|
+
$elements.each(function(){
|
1071
|
+
if($.browser.mozilla){//Firefox
|
1072
|
+
$(this).css('MozUserSelect','none');
|
1073
|
+
}else if($.browser.msie){//IE
|
1074
|
+
$(this).bind('selectstart',function(){return false;});
|
1075
|
+
}else{//Opera, etc.
|
1076
|
+
$(this).mousedown(function(){return false;});
|
1077
|
+
}
|
1078
|
+
});
|
1079
|
+
},
|
1080
|
+
|
1081
|
+
/*
|
1082
|
+
* returns the date on the first millisecond of the week
|
1083
|
+
*/
|
1084
|
+
_dateFirstDayOfWeek : function(date) {
|
1085
|
+
var self = this;
|
1086
|
+
var midnightCurrentDate = new Date(date.getFullYear(), date.getMonth(), date.getDate());
|
1087
|
+
var millisToSubtract = self._getAdjustedDayIndex(midnightCurrentDate) * 86400000;
|
1088
|
+
return new Date(midnightCurrentDate.getTime() - millisToSubtract);
|
1089
|
+
|
1090
|
+
},
|
1091
|
+
|
1092
|
+
/*
|
1093
|
+
* returns the date on the first millisecond of the last day of the week
|
1094
|
+
*/
|
1095
|
+
_dateLastDayOfWeek : function(date) {
|
1096
|
+
var self = this;
|
1097
|
+
var midnightCurrentDate = new Date(date.getFullYear(), date.getMonth(), date.getDate());
|
1098
|
+
var millisToAdd = (6 - self._getAdjustedDayIndex(midnightCurrentDate)) * MILLIS_IN_DAY;
|
1099
|
+
return new Date(midnightCurrentDate.getTime() + millisToAdd);
|
1100
|
+
},
|
1101
|
+
|
1102
|
+
/*
|
1103
|
+
* gets the index of the current day adjusted based on options
|
1104
|
+
*/
|
1105
|
+
_getAdjustedDayIndex : function(date) {
|
1106
|
+
|
1107
|
+
var midnightCurrentDate = new Date(date.getFullYear(), date.getMonth(), date.getDate());
|
1108
|
+
var currentDayOfStandardWeek = midnightCurrentDate.getDay();
|
1109
|
+
var days = [0,1,2,3,4,5,6];
|
1110
|
+
this._rotate(days, this.options.firstDayOfWeek);
|
1111
|
+
return days[currentDayOfStandardWeek];
|
1112
|
+
},
|
1113
|
+
|
1114
|
+
/*
|
1115
|
+
* returns the date on the last millisecond of the week
|
1116
|
+
*/
|
1117
|
+
_dateLastMilliOfWeek : function(date) {
|
1118
|
+
var lastDayOfWeek = this._dateLastDayOfWeek(date);
|
1119
|
+
return new Date(lastDayOfWeek.getTime() + (MILLIS_IN_DAY - 1));
|
1120
|
+
|
1121
|
+
},
|
1122
|
+
|
1123
|
+
/*
|
1124
|
+
* Clear the time components of a date leaving the date
|
1125
|
+
* of the first milli of day
|
1126
|
+
*/
|
1127
|
+
_clearTime : function(d) {
|
1128
|
+
d.setHours(0);
|
1129
|
+
d.setMinutes(0);
|
1130
|
+
d.setSeconds(0);
|
1131
|
+
d.setMilliseconds(0);
|
1132
|
+
return d;
|
1133
|
+
},
|
1134
|
+
|
1135
|
+
/*
|
1136
|
+
* add specific number of days to date
|
1137
|
+
*/
|
1138
|
+
_addDays : function(d, n, keepTime) {
|
1139
|
+
d.setDate(d.getDate() + n);
|
1140
|
+
if (keepTime) {
|
1141
|
+
return d;
|
1142
|
+
}
|
1143
|
+
return this._clearTime(d);
|
1144
|
+
},
|
1145
|
+
|
1146
|
+
/*
|
1147
|
+
* Rotate an array by specified number of places.
|
1148
|
+
*/
|
1149
|
+
_rotate : function(a /*array*/, p /* integer, positive integer rotate to the right, negative to the left... */){
|
1150
|
+
for(var l = a.length, p = (Math.abs(p) >= l && (p %= l), p < 0 && (p += l), p), i, x; p; p = (Math.ceil(l / p) - 1) * p - l + (l = p)) {
|
1151
|
+
for(i = l; i > p; x = a[--i], a[i] = a[i - p], a[i - p] = x);
|
1152
|
+
}
|
1153
|
+
return a;
|
1154
|
+
},
|
1155
|
+
|
1156
|
+
_cloneDate : function(d) {
|
1157
|
+
return new Date(+d);
|
1158
|
+
},
|
1159
|
+
|
1160
|
+
/*
|
1161
|
+
* return a date for different representations
|
1162
|
+
*/
|
1163
|
+
_cleanDate : function(d) {
|
1164
|
+
if (typeof d == 'string') {
|
1165
|
+
return $.weekCalendar.parseISO8601(d, true) || Date.parse(d) || new Date(parseInt(d));
|
1166
|
+
}
|
1167
|
+
if (typeof d == 'number') {
|
1168
|
+
return new Date(d);
|
1169
|
+
}
|
1170
|
+
return d;
|
1171
|
+
},
|
1172
|
+
|
1173
|
+
/*
|
1174
|
+
* date formatting is adapted from
|
1175
|
+
* http://jacwright.com/projects/javascript/date_format
|
1176
|
+
*/
|
1177
|
+
_formatDate : function(date, format) {
|
1178
|
+
var options = this.options;
|
1179
|
+
var returnStr = '';
|
1180
|
+
for (var i = 0; i < format.length; i++) {
|
1181
|
+
var curChar = format.charAt(i);
|
1182
|
+
if ($.isFunction(this._replaceChars[curChar])) {
|
1183
|
+
returnStr += this._replaceChars[curChar](date, options);
|
1184
|
+
} else {
|
1185
|
+
returnStr += curChar;
|
1186
|
+
}
|
1187
|
+
}
|
1188
|
+
return returnStr;
|
1189
|
+
},
|
1190
|
+
|
1191
|
+
_replaceChars : {
|
1192
|
+
|
1193
|
+
// Day
|
1194
|
+
d: function(date) { return (date.getDate() < 10 ? '0' : '') + date.getDate(); },
|
1195
|
+
D: function(date, options) { return options.shortDays[date.getDay()]; },
|
1196
|
+
j: function(date) { return date.getDate(); },
|
1197
|
+
l: function(date, options) { return options.longDays[date.getDay()]; },
|
1198
|
+
N: function(date) { return date.getDay() + 1; },
|
1199
|
+
S: function(date) { return (date.getDate() % 10 == 1 && date.getDate() != 11 ? 'st' : (date.getDate() % 10 == 2 && date.getDate() != 12 ? 'nd' : (date.getDate() % 10 == 3 && date.getDate() != 13 ? 'rd' : 'th'))); },
|
1200
|
+
w: function(date) { return date.getDay(); },
|
1201
|
+
z: function(date) { return "Not Yet Supported"; },
|
1202
|
+
// Week
|
1203
|
+
W: function(date) { return "Not Yet Supported"; },
|
1204
|
+
// Month
|
1205
|
+
F: function(date, options) { return options.longMonths[date.getMonth()]; },
|
1206
|
+
m: function(date) { return (date.getMonth() < 9 ? '0' : '') + (date.getMonth() + 1); },
|
1207
|
+
M: function(date, options) { return options.shortMonths[date.getMonth()]; },
|
1208
|
+
n: function(date) { return date.getMonth() + 1; },
|
1209
|
+
t: function(date) { return "Not Yet Supported"; },
|
1210
|
+
// Year
|
1211
|
+
L: function(date) { return "Not Yet Supported"; },
|
1212
|
+
o: function(date) { return "Not Supported"; },
|
1213
|
+
Y: function(date) { return date.getFullYear(); },
|
1214
|
+
y: function(date) { return ('' + date.getFullYear()).substr(2); },
|
1215
|
+
// Time
|
1216
|
+
a: function(date) { return date.getHours() < 12 ? 'am' : 'pm'; },
|
1217
|
+
A: function(date) { return date.getHours() < 12 ? 'AM' : 'PM'; },
|
1218
|
+
B: function(date) { return "Not Yet Supported"; },
|
1219
|
+
g: function(date) { return date.getHours() % 12 || 12; },
|
1220
|
+
G: function(date) { return date.getHours(); },
|
1221
|
+
h: function(date) { return ((date.getHours() % 12 || 12) < 10 ? '0' : '') + (date.getHours() % 12 || 12); },
|
1222
|
+
H: function(date) { return (date.getHours() < 10 ? '0' : '') + date.getHours(); },
|
1223
|
+
i: function(date) { return (date.getMinutes() < 10 ? '0' : '') + date.getMinutes(); },
|
1224
|
+
s: function(date) { return (date.getSeconds() < 10 ? '0' : '') + date.getSeconds(); },
|
1225
|
+
// Timezone
|
1226
|
+
e: function(date) { return "Not Yet Supported"; },
|
1227
|
+
I: function(date) { return "Not Supported"; },
|
1228
|
+
O: function(date) { return (date.getTimezoneOffset() < 0 ? '-' : '+') + (date.getTimezoneOffset() / 60 < 10 ? '0' : '') + (date.getTimezoneOffset() / 60) + '00'; },
|
1229
|
+
T: function(date) { return "Not Yet Supported"; },
|
1230
|
+
Z: function(date) { return date.getTimezoneOffset() * 60; },
|
1231
|
+
// Full Date/Time
|
1232
|
+
c: function(date) { return "Not Yet Supported"; },
|
1233
|
+
r: function(date) { return date.toString(); },
|
1234
|
+
U: function(date) { return date.getTime() / 1000; }
|
1235
|
+
}
|
1236
|
+
|
1237
|
+
});
|
1238
|
+
|
1239
|
+
$.extend($.ui.weekCalendar, {
|
1240
|
+
version: '1.2.1',
|
1241
|
+
getter: ['getTimeslotTimes', 'getData', 'formatDate', 'formatTime'],
|
1242
|
+
defaults: {
|
1243
|
+
date: new Date(),
|
1244
|
+
timeFormat : "h:i a",
|
1245
|
+
dateFormat : "M d, Y",
|
1246
|
+
use24Hour : false,
|
1247
|
+
firstDayOfWeek : 0, // 0 = Sunday, 1 = Monday, 2 = Tuesday, ... , 6 = Saturday
|
1248
|
+
useShortDayNames: false,
|
1249
|
+
timeSeparator : " to ",
|
1250
|
+
startParam : "start",
|
1251
|
+
endParam : "end",
|
1252
|
+
businessHours : {start: 8, end: 18, limitDisplay : false},
|
1253
|
+
newEventText : "New Event",
|
1254
|
+
timeslotHeight: 20,
|
1255
|
+
defaultEventLength : 2,
|
1256
|
+
timeslotsPerHour : 4,
|
1257
|
+
buttons : true,
|
1258
|
+
buttonText : {
|
1259
|
+
today : "today",
|
1260
|
+
lastWeek : " < ",
|
1261
|
+
nextWeek : " > "
|
1262
|
+
},
|
1263
|
+
scrollToHourMillis : 500,
|
1264
|
+
allowCalEventOverlap : false,
|
1265
|
+
overlapEventsSeparate: false,
|
1266
|
+
readonly: false,
|
1267
|
+
draggable : function(calEvent, element) { return true;},
|
1268
|
+
resizable : function(calEvent, element) { return true;},
|
1269
|
+
eventClick : function(){},
|
1270
|
+
eventRender : function(calEvent, element) { return element;},
|
1271
|
+
eventAfterRender : function(calEvent, element) { return element;},
|
1272
|
+
eventDrag : function(calEvent, element) {},
|
1273
|
+
eventDrop : function(calEvent, element){},
|
1274
|
+
eventResize : function(calEvent, element){},
|
1275
|
+
eventNew : function(calEvent, element) {},
|
1276
|
+
eventMouseover : function(calEvent, $event) {},
|
1277
|
+
eventMouseout : function(calEvent, $event) {},
|
1278
|
+
calendarBeforeLoad : function(calendar) {},
|
1279
|
+
calendarAfterLoad : function(calendar) {},
|
1280
|
+
noEvents : function() {},
|
1281
|
+
shortMonths : ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
|
1282
|
+
longMonths : ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],
|
1283
|
+
shortDays : ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'],
|
1284
|
+
longDays : ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday']
|
1285
|
+
}
|
1286
|
+
});
|
1287
|
+
|
1288
|
+
var MILLIS_IN_DAY = 86400000;
|
1289
|
+
var MILLIS_IN_WEEK = MILLIS_IN_DAY * 7;
|
1290
|
+
|
1291
|
+
$.weekCalendar = function() {
|
1292
|
+
return {
|
1293
|
+
parseISO8601 : function(s, ignoreTimezone) {
|
1294
|
+
|
1295
|
+
// derived from http://delete.me.uk/2005/03/iso8601.html
|
1296
|
+
var regexp = "([0-9]{4})(-([0-9]{2})(-([0-9]{2})" +
|
1297
|
+
"(T([0-9]{2}):([0-9]{2})(:([0-9]{2})(\.([0-9]+))?)?" +
|
1298
|
+
"(Z|(([-+])([0-9]{2}):([0-9]{2})))?)?)?)?";
|
1299
|
+
var d = s.match(new RegExp(regexp));
|
1300
|
+
if (!d) return null;
|
1301
|
+
var offset = 0;
|
1302
|
+
var date = new Date(d[1], 0, 1);
|
1303
|
+
if (d[3]) { date.setMonth(d[3] - 1); }
|
1304
|
+
if (d[5]) { date.setDate(d[5]); }
|
1305
|
+
if (d[7]) { date.setHours(d[7]); }
|
1306
|
+
if (d[8]) { date.setMinutes(d[8]); }
|
1307
|
+
if (d[10]) { date.setSeconds(d[10]); }
|
1308
|
+
if (d[12]) { date.setMilliseconds(Number("0." + d[12]) * 1000); }
|
1309
|
+
if (!ignoreTimezone) {
|
1310
|
+
if (d[14]) {
|
1311
|
+
offset = (Number(d[16]) * 60) + Number(d[17]);
|
1312
|
+
offset *= ((d[15] == '-') ? 1 : -1);
|
1313
|
+
}
|
1314
|
+
offset -= date.getTimezoneOffset();
|
1315
|
+
}
|
1316
|
+
return new Date(Number(date) + (offset * 60 * 1000));
|
1317
|
+
}
|
1318
|
+
};
|
1319
|
+
}();
|
1320
|
+
|
1321
|
+
|
1322
|
+
})(jQuery);
|
1323
|
+
|
1324
|
+
|
1325
|
+
/*!
|
1326
|
+
* Title: jMonthCalendar 1.3.2-beta2
|
1327
|
+
* Dependencies: jQuery 1.3.0 +
|
1328
|
+
* Author: Kyle LeNeau
|
1329
|
+
* Email: kyle.leneau@gmail.com
|
1330
|
+
* Project Hompage: http://www.bytecyclist.com/projects/jmonthcalendar
|
1331
|
+
* Source: http://code.google.com/p/jmonthcalendar
|
1332
|
+
*
|
1333
|
+
*/
|
1334
|
+
(function($) {
|
1335
|
+
var _boxes = [];
|
1336
|
+
var _eventObj = {};
|
1337
|
+
|
1338
|
+
var _workingDate = null;
|
1339
|
+
var _daysInMonth = 0;
|
1340
|
+
var _firstOfMonth = null;
|
1341
|
+
var _lastOfMonth = null;
|
1342
|
+
var _gridOffset = 0;
|
1343
|
+
var _totalDates = 0;
|
1344
|
+
var _gridRows = 0;
|
1345
|
+
var _totalBoxes = 0;
|
1346
|
+
var _dateRange = { startDate: null, endDate: null };
|
1347
|
+
|
1348
|
+
|
1349
|
+
var cEvents = [];
|
1350
|
+
var def = {
|
1351
|
+
containerId: "#jMonthCalendar",
|
1352
|
+
headerHeight: 50,
|
1353
|
+
firstDayOfWeek: 0,
|
1354
|
+
calendarStartDate:new Date(),
|
1355
|
+
dragableEvents: true,
|
1356
|
+
dragHoverClass: 'DateBoxOver',
|
1357
|
+
navLinks: {
|
1358
|
+
enableToday: true,
|
1359
|
+
enableNextYear: true,
|
1360
|
+
enablePrevYear: true,
|
1361
|
+
p:'‹ Prev',
|
1362
|
+
n:'Next ›',
|
1363
|
+
t:'Today',
|
1364
|
+
showMore: 'Show More'
|
1365
|
+
},
|
1366
|
+
onMonthChanging: function() {},
|
1367
|
+
onMonthChanged: function() {},
|
1368
|
+
onEventLinkClick: function() {},
|
1369
|
+
onEventBlockClick: function() {},
|
1370
|
+
onEventBlockOver: function() {},
|
1371
|
+
onEventBlockOut: function() {},
|
1372
|
+
onDayLinkClick: function() {},
|
1373
|
+
onDayCellClick: function() {},
|
1374
|
+
onDayCellDblClick: function() {},
|
1375
|
+
onEventDropped: function() {},
|
1376
|
+
onShowMoreClick: function() {}
|
1377
|
+
};
|
1378
|
+
|
1379
|
+
$.jMonthCalendar = $.J = function() {};
|
1380
|
+
|
1381
|
+
var _getJSONDate = function(dateStr) {
|
1382
|
+
//check conditions for different types of accepted dates
|
1383
|
+
var tDt, k;
|
1384
|
+
if (typeof dateStr == "string") {
|
1385
|
+
|
1386
|
+
// "2008-12-28T00:00:00.0000000"
|
1387
|
+
var isoRegPlus = /^([0-9]{4})-([0-9]{2})-([0-9]{2})T([0-9]{2}):([0-9]{2}):([0-9]{2}).([0-9]{7})$/;
|
1388
|
+
|
1389
|
+
// "2008-12-28T00:00:00"
|
1390
|
+
var isoReg = /^([0-9]{4})-([0-9]{2})-([0-9]{2})T([0-9]{2}):([0-9]{2}):([0-9]{2})$/;
|
1391
|
+
|
1392
|
+
//"2008-12-28"
|
1393
|
+
var yyyyMMdd = /^([0-9]{4})-([0-9]{2})-([0-9]{2})$/;
|
1394
|
+
|
1395
|
+
// "new Date(2009, 1, 1)"
|
1396
|
+
// "new Date(1230444000000)
|
1397
|
+
var newReg = /^new/;
|
1398
|
+
|
1399
|
+
// "\/Date(1234418400000-0600)\/"
|
1400
|
+
var stdReg = /^\\\/Date\(([0-9]{13})-([0-9]{4})\)\\\/$/;
|
1401
|
+
|
1402
|
+
if (k = dateStr.match(isoRegPlus)) {
|
1403
|
+
return new Date(k[1],k[2]-1,k[3],k[4],k[5],k[6]);
|
1404
|
+
} else if (k = dateStr.match(isoReg)) {
|
1405
|
+
return new Date(k[1],k[2]-1,k[3],k[4],k[5],k[6]);
|
1406
|
+
} else if (k = dateStr.match(yyyyMMdd)) {
|
1407
|
+
return new Date(k[1],k[2]-1,k[3]);
|
1408
|
+
}
|
1409
|
+
|
1410
|
+
if (k = dateStr.match(stdReg)) {
|
1411
|
+
return new Date(k[1]);
|
1412
|
+
}
|
1413
|
+
|
1414
|
+
if (k = dateStr.match(newReg)) {
|
1415
|
+
return eval('(' + dateStr + ')');
|
1416
|
+
}
|
1417
|
+
|
1418
|
+
return tDt;
|
1419
|
+
}
|
1420
|
+
};
|
1421
|
+
|
1422
|
+
//This function will clean the JSON array, primaryly the dates and put the correct ones in the object. Intended to alwasy be called on event functions.
|
1423
|
+
var _filterEventCollection = function() {
|
1424
|
+
if (cEvents && cEvents.length > 0) {
|
1425
|
+
var multi = [];
|
1426
|
+
var single = [];
|
1427
|
+
|
1428
|
+
//Update and parse all the dates
|
1429
|
+
$.each(cEvents, function(){
|
1430
|
+
var ev = this;
|
1431
|
+
//Date Parse the JSON to create a new Date to work with here
|
1432
|
+
if(ev.StartDateTime) {
|
1433
|
+
if (typeof ev.StartDateTime == 'object' && ev.StartDateTime.getDate) { this.StartDateTime = ev.StartDateTime; }
|
1434
|
+
if (typeof ev.StartDateTime == 'string' && ev.StartDateTime.split) { this.StartDateTime = _getJSONDate(ev.StartDateTime); }
|
1435
|
+
} else if(ev.Date) { // DEPRECATED
|
1436
|
+
if (typeof ev.Date == 'object' && ev.Date.getDate) { this.StartDateTime = ev.Date; }
|
1437
|
+
if (typeof ev.Date == 'string' && ev.Date.split) { this.StartDateTime = _getJSONDate(ev.Date); }
|
1438
|
+
} else {
|
1439
|
+
return; //no start date, or legacy date. no event.
|
1440
|
+
}
|
1441
|
+
|
1442
|
+
if(ev.EndDateTime) {
|
1443
|
+
if (typeof ev.EndDateTime == 'object' && ev.EndDateTime.getDate) { this.EndDateTime = ev.EndDateTime; }
|
1444
|
+
if (typeof ev.EndDateTime == 'string' && ev.EndDateTime.split) { this.EndDateTime = _getJSONDate(ev.EndDateTime); }
|
1445
|
+
} else {
|
1446
|
+
this.EndDateTime = this.StartDateTime.clone();
|
1447
|
+
}
|
1448
|
+
|
1449
|
+
if (this.StartDateTime.clone().clearTime().compareTo(this.EndDateTime.clone().clearTime()) == 0) {
|
1450
|
+
single.push(this);
|
1451
|
+
} else if (this.StartDateTime.clone().clearTime().compareTo(this.EndDateTime.clone().clearTime()) == -1) {
|
1452
|
+
multi.push(this);
|
1453
|
+
}
|
1454
|
+
});
|
1455
|
+
|
1456
|
+
multi.sort(_eventSort);
|
1457
|
+
single.sort(_eventSort);
|
1458
|
+
cEvents = [];
|
1459
|
+
$.merge(cEvents, multi);
|
1460
|
+
$.merge(cEvents, single);
|
1461
|
+
}
|
1462
|
+
};
|
1463
|
+
|
1464
|
+
var _eventSort = function(a, b) {
|
1465
|
+
return a.StartDateTime.compareTo(b.StartDateTime);
|
1466
|
+
};
|
1467
|
+
|
1468
|
+
var _clearBoxes = function() {
|
1469
|
+
_clearBoxEvents();
|
1470
|
+
_boxes = [];
|
1471
|
+
};
|
1472
|
+
|
1473
|
+
var _clearBoxEvents = function() {
|
1474
|
+
for (var i = 0; i < _boxes.length; i++) {
|
1475
|
+
_boxes[i].clear();
|
1476
|
+
}
|
1477
|
+
_eventObj = {};
|
1478
|
+
};
|
1479
|
+
|
1480
|
+
var _initDates = function(dateIn) {
|
1481
|
+
var today = def.calendarStartDate;
|
1482
|
+
if(dateIn == undefined) {
|
1483
|
+
_workingDate = new Date(today.getFullYear(), today.getMonth(), 1);
|
1484
|
+
} else {
|
1485
|
+
_workingDate = dateIn;
|
1486
|
+
_workingDate.setDate(1);
|
1487
|
+
}
|
1488
|
+
|
1489
|
+
_daysInMonth = _workingDate.getDaysInMonth();
|
1490
|
+
_firstOfMonth = _workingDate.clone().moveToFirstDayOfMonth();
|
1491
|
+
_lastOfMonth = _workingDate.clone().moveToLastDayOfMonth();
|
1492
|
+
_gridOffset = _firstOfMonth.getDay() - def.firstDayOfWeek;
|
1493
|
+
_totalDates = _gridOffset + _daysInMonth;
|
1494
|
+
_gridRows = Math.ceil(_totalDates / 7);
|
1495
|
+
_totalBoxes = _gridRows * 7;
|
1496
|
+
|
1497
|
+
_dateRange.startDate = _firstOfMonth.clone().addDays((-1) * _gridOffset);
|
1498
|
+
_dateRange.endDate = _lastOfMonth.clone().addDays(_totalBoxes - (_daysInMonth + _gridOffset));
|
1499
|
+
};
|
1500
|
+
|
1501
|
+
var _initHeaders = function() {
|
1502
|
+
// Create Previous Month link for later
|
1503
|
+
var prevMonth = _workingDate.clone().addMonths(-1);
|
1504
|
+
var prevMLink = $('<div class="MonthNavPrev"><a class="link-prev">'+ def.navLinks.p +'</a></div>').click(function() {
|
1505
|
+
$.J.ChangeMonth(prevMonth);
|
1506
|
+
return false;
|
1507
|
+
});
|
1508
|
+
|
1509
|
+
//Create Next Month link for later
|
1510
|
+
var nextMonth = _workingDate.clone().addMonths(1);
|
1511
|
+
var nextMLink = $('<div class="MonthNavNext"><a class="link-next">'+ def.navLinks.n +'</a></div>').click(function() {
|
1512
|
+
$.J.ChangeMonth(nextMonth);
|
1513
|
+
return false;
|
1514
|
+
});
|
1515
|
+
|
1516
|
+
//Create Previous Year link for later
|
1517
|
+
var prevYear = _workingDate.clone().addYears(-1);
|
1518
|
+
var prevYLink;
|
1519
|
+
if(def.navLinks.enablePrevYear) {
|
1520
|
+
prevYLink = $('<div class="YearNavPrev"><a>'+ prevYear.getFullYear() +'</a></div>').click(function() {
|
1521
|
+
$.J.ChangeMonth(prevYear);
|
1522
|
+
return false;
|
1523
|
+
});
|
1524
|
+
}
|
1525
|
+
|
1526
|
+
//Create Next Year link for later
|
1527
|
+
var nextYear = _workingDate.clone().addYears(1);
|
1528
|
+
var nextYLink;
|
1529
|
+
if(def.navLinks.enableNextYear) {
|
1530
|
+
nextYLink = $('<div class="YearNavNext"><a>'+ nextYear.getFullYear() +'</a></div>').click(function() {
|
1531
|
+
$.J.ChangeMonth(nextYear);
|
1532
|
+
return false;
|
1533
|
+
});
|
1534
|
+
}
|
1535
|
+
|
1536
|
+
var todayLink;
|
1537
|
+
if(def.navLinks.enableToday) {
|
1538
|
+
//Create Today link for later
|
1539
|
+
todayLink = $('<div class="TodayLink"><a class="link-today">'+ def.navLinks.t +'</a></div>').click(function() {
|
1540
|
+
$.J.ChangeMonth(new Date());
|
1541
|
+
return false;
|
1542
|
+
});
|
1543
|
+
}
|
1544
|
+
|
1545
|
+
//Build up the Header first, Navigation
|
1546
|
+
var navRow = $('<tr><td colspan="7"><div class="FormHeader MonthNavigation"></div></td></tr>');
|
1547
|
+
var navHead = $('.MonthNavigation', navRow);
|
1548
|
+
|
1549
|
+
navHead.append(prevMLink, nextMLink);
|
1550
|
+
if(def.navLinks.enableToday) { navHead.append(todayLink); }
|
1551
|
+
|
1552
|
+
navHead.append($('<div class="MonthName"></div>').append(Date.CultureInfo.monthNames[_workingDate.getMonth()] + " " + _workingDate.getFullYear()));
|
1553
|
+
|
1554
|
+
if(def.navLinks.enablePrevYear) { navHead.append(prevYLink); }
|
1555
|
+
if(def.navLinks.enableNextYear) { navHead.append(nextYLink); }
|
1556
|
+
|
1557
|
+
|
1558
|
+
// Days
|
1559
|
+
var headRow = $("<tr></tr>");
|
1560
|
+
for (var i = def.firstDayOfWeek; i < def.firstDayOfWeek+7; i++) {
|
1561
|
+
var weekday = i % 7;
|
1562
|
+
var wordday = Date.CultureInfo.dayNames[weekday];
|
1563
|
+
headRow.append('<th title="' + wordday + '" class="DateHeader' + (weekday == 0 || weekday == 6 ? ' Weekend' : '') + '"><span>' + wordday + '</span></th>');
|
1564
|
+
}
|
1565
|
+
|
1566
|
+
headRow = $("<thead id=\"CalendarHead\"></thead>").css({ "height" : def.headerHeight + "px" }).append(headRow);
|
1567
|
+
headRow = headRow.prepend(navRow);
|
1568
|
+
return headRow;
|
1569
|
+
};
|
1570
|
+
|
1571
|
+
|
1572
|
+
|
1573
|
+
$.J.DrawCalendar = function(dateIn){
|
1574
|
+
var now = new Date();
|
1575
|
+
now.clearTime();
|
1576
|
+
|
1577
|
+
var today = def.calendarStartDate;
|
1578
|
+
|
1579
|
+
_clearBoxes();
|
1580
|
+
|
1581
|
+
_initDates(dateIn);
|
1582
|
+
var headerRow = _initHeaders();
|
1583
|
+
|
1584
|
+
//properties
|
1585
|
+
var isCurrentMonth = (_workingDate.getMonth() == today.getMonth() && _workingDate.getFullYear() == today.getFullYear());
|
1586
|
+
var containerHeight = $(def.containerId).outerHeight();
|
1587
|
+
var rowHeight = (containerHeight - def.headerHeight) / _gridRows;
|
1588
|
+
var row = null;
|
1589
|
+
|
1590
|
+
//Build up the Body
|
1591
|
+
var tBody = $('<tbody id="CalendarBody"></tbody>');
|
1592
|
+
|
1593
|
+
for (var i = 0; i < _totalBoxes; i++) {
|
1594
|
+
var currentDate = _dateRange.startDate.clone().addDays(i);
|
1595
|
+
if (i % 7 == 0 || i == 0) {
|
1596
|
+
row = $("<tr></tr>");
|
1597
|
+
row.css({ "height" : rowHeight + "px" });
|
1598
|
+
tBody.append(row);
|
1599
|
+
}
|
1600
|
+
|
1601
|
+
var weekday = (def.firstDayOfWeek + i) % 7;
|
1602
|
+
var atts = {'class':"DateBox" + (weekday == 0 || weekday == 6 ? ' Weekend ' : ''),
|
1603
|
+
'date':currentDate.toString("M/d/yyyy")
|
1604
|
+
};
|
1605
|
+
|
1606
|
+
//dates outside of month range.
|
1607
|
+
if (currentDate.compareTo(_firstOfMonth) == -1 || currentDate.compareTo(_lastOfMonth) == 1) {
|
1608
|
+
atts['class'] += ' Inactive';
|
1609
|
+
}
|
1610
|
+
|
1611
|
+
//check to see if current date rendering is today
|
1612
|
+
if (currentDate.compareTo(now) == 0) {
|
1613
|
+
atts['class'] += ' Today';
|
1614
|
+
}
|
1615
|
+
|
1616
|
+
//DateBox Events
|
1617
|
+
var dateLink = $('<div class="DateLabel"><a>' + currentDate.getDate() + '</a></div>');
|
1618
|
+
dateLink.bind('click', { Date: currentDate.clone() }, def.onDayLinkClick);
|
1619
|
+
|
1620
|
+
var dateBox = $("<td></td>").attr(atts).append(dateLink);
|
1621
|
+
dateBox.bind('dblclick', { Date: currentDate.clone() }, def.onDayCellDblClick);
|
1622
|
+
dateBox.bind('click', { Date: currentDate.clone() }, def.onDayCellClick);
|
1623
|
+
|
1624
|
+
if (def.dragableEvents) {
|
1625
|
+
dateBox.droppable({
|
1626
|
+
hoverClass: def.dragHoverClass,
|
1627
|
+
tolerance: 'pointer',
|
1628
|
+
drop: function(ev, ui) {
|
1629
|
+
var eventId = ui.draggable.attr("eventid")
|
1630
|
+
var newDate = new Date($(this).attr("date")).clearTime();
|
1631
|
+
|
1632
|
+
var event;
|
1633
|
+
$.each(cEvents, function() {
|
1634
|
+
if (this.EventID == eventId) {
|
1635
|
+
var days = new TimeSpan(newDate - this.StartDateTime).days;
|
1636
|
+
|
1637
|
+
this.StartDateTime.addDays(days);
|
1638
|
+
this.EndDateTime.addDays(days);
|
1639
|
+
|
1640
|
+
event = this;
|
1641
|
+
}
|
1642
|
+
});
|
1643
|
+
|
1644
|
+
$.J.ClearEventsOnCalendar();
|
1645
|
+
_drawEventsOnCalendar();
|
1646
|
+
|
1647
|
+
def.onEventDropped.call(this, event, newDate);
|
1648
|
+
}
|
1649
|
+
});
|
1650
|
+
}
|
1651
|
+
|
1652
|
+
_boxes.push(new CalendarBox(i, currentDate, dateBox, dateLink));
|
1653
|
+
row.append(dateBox);
|
1654
|
+
}
|
1655
|
+
tBody.append(row);
|
1656
|
+
|
1657
|
+
var a = $(def.containerId);
|
1658
|
+
var cal = $('<table class="MonthlyCalendar" cellpadding="0" tablespacing="0"></table>').append(headerRow, tBody);
|
1659
|
+
|
1660
|
+
a.hide();
|
1661
|
+
a.html(cal);
|
1662
|
+
a.fadeIn("normal");
|
1663
|
+
|
1664
|
+
_drawEventsOnCalendar();
|
1665
|
+
}
|
1666
|
+
|
1667
|
+
var _drawEventsOnCalendar = function() {
|
1668
|
+
//filter the JSON array for proper dates
|
1669
|
+
_filterEventCollection();
|
1670
|
+
_clearBoxEvents();
|
1671
|
+
|
1672
|
+
if (cEvents && cEvents.length > 0) {
|
1673
|
+
var container = $(def.containerId);
|
1674
|
+
|
1675
|
+
$.each(cEvents, function(){
|
1676
|
+
var ev = this;
|
1677
|
+
//alert("eventID: " + ev.EventID + ", start: " + ev.StartDateTime + ",end: " + ev.EndDateTime);
|
1678
|
+
|
1679
|
+
var tempStartDT = ev.StartDateTime.clone().clearTime();
|
1680
|
+
var tempEndDT = ev.EndDateTime.clone().clearTime();
|
1681
|
+
|
1682
|
+
var startI = new TimeSpan(tempStartDT - _dateRange.startDate).days;
|
1683
|
+
var endI = new TimeSpan(tempEndDT - _dateRange.startDate).days;
|
1684
|
+
//alert("start I: " + startI + " end I: " + endI);
|
1685
|
+
|
1686
|
+
var istart = (startI < 0) ? 0 : startI;
|
1687
|
+
var iend = (endI > _boxes.length - 1) ? _boxes.length - 1 : endI;
|
1688
|
+
//alert("istart: " + istart + " iend: " + iend);
|
1689
|
+
|
1690
|
+
|
1691
|
+
for (var i = istart; i <= iend; i++) {
|
1692
|
+
var b = _boxes[i];
|
1693
|
+
|
1694
|
+
var startBoxCompare = tempStartDT.compareTo(b.date);
|
1695
|
+
var endBoxCompare = tempEndDT.compareTo(b.date);
|
1696
|
+
|
1697
|
+
var continueEvent = ((i != 0 && startBoxCompare == -1 && endBoxCompare >= 0 && b.weekNumber != _boxes[i - 1].weekNumber) || (i == 0 && startBoxCompare == -1));
|
1698
|
+
var toManyEvents = (startBoxCompare == 0 || (i == 0 && startBoxCompare == -1) ||
|
1699
|
+
continueEvent || (startBoxCompare == -1 && endBoxCompare >= 0)) && b.vOffset >= (b.getCellBox().height() - b.getLabelHeight() - 32);
|
1700
|
+
|
1701
|
+
//alert("b.vOffset: " + b.vOffset + ", cell height: " + (b.getCellBox().height() - b.getLabelHeight() - 32));
|
1702
|
+
//alert(continueEvent);
|
1703
|
+
//alert(toManyEvents);
|
1704
|
+
|
1705
|
+
if (toManyEvents) {
|
1706
|
+
if (!b.isTooManySet) {
|
1707
|
+
var moreDiv = $('<div class="MoreEvents" id="ME_' + i + '">' + def.navLinks.showMore + '</div>');
|
1708
|
+
var pos = b.getCellPosition();
|
1709
|
+
var index = i;
|
1710
|
+
|
1711
|
+
moreDiv.css({
|
1712
|
+
"top" : (pos.top + (b.getCellBox().height() - b.getLabelHeight())),
|
1713
|
+
"left" : pos.left,
|
1714
|
+
"width" : (b.getLabelWidth() - 7),
|
1715
|
+
"position" : "absolute" });
|
1716
|
+
|
1717
|
+
moreDiv.click(function(e) { _showMoreClick(e, index); });
|
1718
|
+
|
1719
|
+
_eventObj[moreDiv.attr("id")] = moreDiv;
|
1720
|
+
b.isTooManySet = true;
|
1721
|
+
} //else update the +more to show??
|
1722
|
+
b.events.push(ev);
|
1723
|
+
} else if (startBoxCompare == 0 || (i == 0 && startBoxCompare == -1) || continueEvent) {
|
1724
|
+
var block = _buildEventBlock(ev, b.weekNumber);
|
1725
|
+
var pos = b.getCellPosition();
|
1726
|
+
|
1727
|
+
block.css({
|
1728
|
+
"top" : (pos.top + b.getLabelHeight() + b.vOffset),
|
1729
|
+
"left" : pos.left,
|
1730
|
+
"width" : (b.getLabelWidth() - 7),
|
1731
|
+
"position" : "absolute" });
|
1732
|
+
|
1733
|
+
b.vOffset += 19;
|
1734
|
+
|
1735
|
+
if (continueEvent) {
|
1736
|
+
block.prepend($('<span />').addClass("ui-icon").addClass("ui-icon-triangle-1-w"));
|
1737
|
+
|
1738
|
+
var e = _eventObj['Event_' + ev.EventID + '_' + (b.weekNumber - 1)];
|
1739
|
+
if (e) { e.prepend($('<span />').addClass("ui-icon").addClass("ui-icon-triangle-1-e")); }
|
1740
|
+
}
|
1741
|
+
|
1742
|
+
_eventObj[block.attr("id")] = block;
|
1743
|
+
|
1744
|
+
b.events.push(ev);
|
1745
|
+
} else if (startBoxCompare == -1 && endBoxCompare >= 0) {
|
1746
|
+
var e = _eventObj['Event_' + ev.EventID + '_' + b.weekNumber];
|
1747
|
+
if (e) {
|
1748
|
+
var w = e.css("width")
|
1749
|
+
e.css({ "width" : (parseInt(w) + b.getLabelWidth() + 1) });
|
1750
|
+
b.vOffset += 19;
|
1751
|
+
b.events.push(ev);
|
1752
|
+
}
|
1753
|
+
}
|
1754
|
+
|
1755
|
+
//end of month continue
|
1756
|
+
if (i == iend && endBoxCompare > 0) {
|
1757
|
+
var e = _eventObj['Event_' + ev.EventID + '_' + b.weekNumber];
|
1758
|
+
if (e) { e.prepend($('<span />').addClass("ui-icon").addClass("ui-icon-triangle-1-e")); }
|
1759
|
+
}
|
1760
|
+
}
|
1761
|
+
});
|
1762
|
+
|
1763
|
+
for (var o in _eventObj) {
|
1764
|
+
_eventObj[o].hide();
|
1765
|
+
container.append(_eventObj[o]);
|
1766
|
+
_eventObj[o].show();
|
1767
|
+
}
|
1768
|
+
}
|
1769
|
+
}
|
1770
|
+
|
1771
|
+
var _buildEventBlock = function(ev, weekNumber) {
|
1772
|
+
var block = $('<div class="Event" id="Event_' + ev.EventID + '_' + weekNumber + '" eventid="' + ev.EventID +'"></div>');
|
1773
|
+
|
1774
|
+
if(ev.CssClass) { block.addClass(ev.CssClass) }
|
1775
|
+
block.bind('click', { Event: ev }, def.onEventBlockClick);
|
1776
|
+
block.bind('mouseover', { Event: ev }, def.onEventBlockOver);
|
1777
|
+
block.bind('mouseout', { Event: ev }, def.onEventBlockOut);
|
1778
|
+
|
1779
|
+
if (def.dragableEvents) {
|
1780
|
+
_dragableEvent(ev, block, weekNumber);
|
1781
|
+
}
|
1782
|
+
|
1783
|
+
var link;
|
1784
|
+
if (ev.URL && ev.URL.length > 0) {
|
1785
|
+
link = $('<a href="' + ev.URL + '">' + ev.Title + '</a>');
|
1786
|
+
} else {
|
1787
|
+
link = $('<a>' + ev.Title + '</a>');
|
1788
|
+
}
|
1789
|
+
|
1790
|
+
link.bind('click', { Event: ev }, def.onEventLinkClick);
|
1791
|
+
block.append(link);
|
1792
|
+
return block;
|
1793
|
+
}
|
1794
|
+
|
1795
|
+
var _dragableEvent = function(event, block, weekNumber) {
|
1796
|
+
block.draggable({
|
1797
|
+
zIndex: 4,
|
1798
|
+
delay: 50,
|
1799
|
+
opacity: 0.5,
|
1800
|
+
revertDuration: 1000,
|
1801
|
+
cursorAt: { left: 5 },
|
1802
|
+
start: function(ev, ui) {
|
1803
|
+
//hide any additional event parts
|
1804
|
+
for (var i = 0; i <= _gridRows; i++) {
|
1805
|
+
if (i == weekNumber) {
|
1806
|
+
continue;
|
1807
|
+
}
|
1808
|
+
|
1809
|
+
var e = _eventObj['Event_' + event.EventID + '_' + i];
|
1810
|
+
if (e) { e.hide(); }
|
1811
|
+
}
|
1812
|
+
}
|
1813
|
+
});
|
1814
|
+
}
|
1815
|
+
|
1816
|
+
var _showMoreClick = function(e, boxIndex) {
|
1817
|
+
var box = _boxes[boxIndex];
|
1818
|
+
def.onShowMoreClick.call(this, box.events);
|
1819
|
+
e.stopPropagation();
|
1820
|
+
}
|
1821
|
+
|
1822
|
+
|
1823
|
+
$.J.ClearEventsOnCalendar = function() {
|
1824
|
+
_clearBoxEvents();
|
1825
|
+
$(".Event", $(def.containerId)).remove();
|
1826
|
+
$(".MoreEvents", $(def.containerId)).remove();
|
1827
|
+
}
|
1828
|
+
|
1829
|
+
$.J.AddEvents = function(eventCollection) {
|
1830
|
+
if(eventCollection) {
|
1831
|
+
if(eventCollection.length > 0) {
|
1832
|
+
$.merge(cEvents, eventCollection);
|
1833
|
+
} else {
|
1834
|
+
cEvents.push(eventCollection);
|
1835
|
+
}
|
1836
|
+
$.J.ClearEventsOnCalendar();
|
1837
|
+
_drawEventsOnCalendar();
|
1838
|
+
}
|
1839
|
+
}
|
1840
|
+
|
1841
|
+
$.J.ReplaceEventCollection = function(eventCollection) {
|
1842
|
+
if(eventCollection) {
|
1843
|
+
cEvents = [];
|
1844
|
+
cEvents = eventCollection;
|
1845
|
+
}
|
1846
|
+
|
1847
|
+
$.J.ClearEventsOnCalendar();
|
1848
|
+
_drawEventsOnCalendar();
|
1849
|
+
}
|
1850
|
+
|
1851
|
+
$.J.ChangeMonth = function(dateIn) {
|
1852
|
+
var returned = def.onMonthChanging.call(this, dateIn);
|
1853
|
+
if (!returned) {
|
1854
|
+
$.J.DrawCalendar(dateIn);
|
1855
|
+
def.onMonthChanged.call(this, dateIn);
|
1856
|
+
}
|
1857
|
+
}
|
1858
|
+
|
1859
|
+
$.J.Initialize = function(options, events) {
|
1860
|
+
var today = new Date();
|
1861
|
+
|
1862
|
+
options = $.extend(def, options);
|
1863
|
+
|
1864
|
+
if (events) {
|
1865
|
+
$.J.ClearEventsOnCalendar();
|
1866
|
+
cEvents = events;
|
1867
|
+
}
|
1868
|
+
|
1869
|
+
$.J.DrawCalendar();
|
1870
|
+
};
|
1871
|
+
|
1872
|
+
|
1873
|
+
function CalendarBox(id, boxDate, cell, label) {
|
1874
|
+
this.id = id;
|
1875
|
+
this.date = boxDate;
|
1876
|
+
this.cell = cell;
|
1877
|
+
this.label = label;
|
1878
|
+
this.weekNumber = Math.floor(id / 7);
|
1879
|
+
this.events= [];
|
1880
|
+
this.isTooManySet = false;
|
1881
|
+
this.vOffset = 0;
|
1882
|
+
|
1883
|
+
this.echo = function() {
|
1884
|
+
alert("Date: " + this.date + " WeekNumber: " + this.weekNumber + " ID: " + this.id);
|
1885
|
+
}
|
1886
|
+
|
1887
|
+
this.clear = function() {
|
1888
|
+
this.events = [];
|
1889
|
+
this.isTooManySet = false;
|
1890
|
+
this.vOffset = 0;
|
1891
|
+
}
|
1892
|
+
|
1893
|
+
this.getCellPosition = function() {
|
1894
|
+
if (this.cell) {
|
1895
|
+
return this.cell.position();
|
1896
|
+
}
|
1897
|
+
return;
|
1898
|
+
}
|
1899
|
+
|
1900
|
+
this.getCellBox = function() {
|
1901
|
+
if (this.cell) {
|
1902
|
+
return this.cell;
|
1903
|
+
}
|
1904
|
+
return;
|
1905
|
+
}
|
1906
|
+
|
1907
|
+
this.getLabelWidth = function() {
|
1908
|
+
if (this.label) {
|
1909
|
+
return this.label.innerWidth();
|
1910
|
+
}
|
1911
|
+
return;
|
1912
|
+
}
|
1913
|
+
|
1914
|
+
this.getLabelHeight = function() {
|
1915
|
+
if (this.label) {
|
1916
|
+
return this.label.height();
|
1917
|
+
}
|
1918
|
+
return;
|
1919
|
+
}
|
1920
|
+
|
1921
|
+
this.getDate = function() {
|
1922
|
+
return this.date;
|
1923
|
+
}
|
1924
|
+
}
|
1925
|
+
})(jQuery);/**
|
1926
|
+
* Version: 1.0 Alpha-1
|
1927
|
+
* Build Date: 13-Nov-2007
|
1928
|
+
* Copyright (c) 2006-2007, Coolite Inc. (http://www.coolite.com/). All rights reserved.
|
1929
|
+
* License: Licensed under The MIT License. See license.txt and http://www.datejs.com/license/.
|
1930
|
+
* Website: http://www.datejs.com/ or http://www.coolite.com/datejs/
|
1931
|
+
*/
|
1932
|
+
Date.CultureInfo={name:"en-US",englishName:"English (United States)",nativeName:"English (United States)",dayNames:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],abbreviatedDayNames:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],shortestDayNames:["Su","Mo","Tu","We","Th","Fr","Sa"],firstLetterDayNames:["S","M","T","W","T","F","S"],monthNames:["January","February","March","April","May","June","July","August","September","October","November","December"],abbreviatedMonthNames:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],amDesignator:"AM",pmDesignator:"PM",firstDayOfWeek:0,twoDigitYearMax:2029,dateElementOrder:"mdy",formatPatterns:{shortDate:"M/d/yyyy",longDate:"dddd, MMMM dd, yyyy",shortTime:"h:mm tt",longTime:"h:mm:ss tt",fullDateTime:"dddd, MMMM dd, yyyy h:mm:ss tt",sortableDateTime:"yyyy-MM-ddTHH:mm:ss",universalSortableDateTime:"yyyy-MM-dd HH:mm:ssZ",rfc1123:"ddd, dd MMM yyyy HH:mm:ss GMT",monthDay:"MMMM dd",yearMonth:"MMMM, yyyy"},regexPatterns:{jan:/^jan(uary)?/i,feb:/^feb(ruary)?/i,mar:/^mar(ch)?/i,apr:/^apr(il)?/i,may:/^may/i,jun:/^jun(e)?/i,jul:/^jul(y)?/i,aug:/^aug(ust)?/i,sep:/^sep(t(ember)?)?/i,oct:/^oct(ober)?/i,nov:/^nov(ember)?/i,dec:/^dec(ember)?/i,sun:/^su(n(day)?)?/i,mon:/^mo(n(day)?)?/i,tue:/^tu(e(s(day)?)?)?/i,wed:/^we(d(nesday)?)?/i,thu:/^th(u(r(s(day)?)?)?)?/i,fri:/^fr(i(day)?)?/i,sat:/^sa(t(urday)?)?/i,future:/^next/i,past:/^last|past|prev(ious)?/i,add:/^(\+|after|from)/i,subtract:/^(\-|before|ago)/i,yesterday:/^yesterday/i,today:/^t(oday)?/i,tomorrow:/^tomorrow/i,now:/^n(ow)?/i,millisecond:/^ms|milli(second)?s?/i,second:/^sec(ond)?s?/i,minute:/^min(ute)?s?/i,hour:/^h(ou)?rs?/i,week:/^w(ee)?k/i,month:/^m(o(nth)?s?)?/i,day:/^d(ays?)?/i,year:/^y((ea)?rs?)?/i,shortMeridian:/^(a|p)/i,longMeridian:/^(a\.?m?\.?|p\.?m?\.?)/i,timezone:/^((e(s|d)t|c(s|d)t|m(s|d)t|p(s|d)t)|((gmt)?\s*(\+|\-)\s*\d\d\d\d?)|gmt)/i,ordinalSuffix:/^\s*(st|nd|rd|th)/i,timeContext:/^\s*(\:|a|p)/i},abbreviatedTimeZoneStandard:{GMT:"-000",EST:"-0400",CST:"-0500",MST:"-0600",PST:"-0700"},abbreviatedTimeZoneDST:{GMT:"-000",EDT:"-0500",CDT:"-0600",MDT:"-0700",PDT:"-0800"}};
|
1933
|
+
Date.getMonthNumberFromName=function(name){var n=Date.CultureInfo.monthNames,m=Date.CultureInfo.abbreviatedMonthNames,s=name.toLowerCase();for(var i=0;i<n.length;i++){if(n[i].toLowerCase()==s||m[i].toLowerCase()==s){return i;}}
|
1934
|
+
return-1;};Date.getDayNumberFromName=function(name){var n=Date.CultureInfo.dayNames,m=Date.CultureInfo.abbreviatedDayNames,o=Date.CultureInfo.shortestDayNames,s=name.toLowerCase();for(var i=0;i<n.length;i++){if(n[i].toLowerCase()==s||m[i].toLowerCase()==s){return i;}}
|
1935
|
+
return-1;};Date.isLeapYear=function(year){return(((year%4===0)&&(year%100!==0))||(year%400===0));};Date.getDaysInMonth=function(year,month){return[31,(Date.isLeapYear(year)?29:28),31,30,31,30,31,31,30,31,30,31][month];};Date.getTimezoneOffset=function(s,dst){return(dst||false)?Date.CultureInfo.abbreviatedTimeZoneDST[s.toUpperCase()]:Date.CultureInfo.abbreviatedTimeZoneStandard[s.toUpperCase()];};Date.getTimezoneAbbreviation=function(offset,dst){var n=(dst||false)?Date.CultureInfo.abbreviatedTimeZoneDST:Date.CultureInfo.abbreviatedTimeZoneStandard,p;for(p in n){if(n[p]===offset){return p;}}
|
1936
|
+
return null;};Date.prototype.clone=function(){return new Date(this.getTime());};Date.prototype.compareTo=function(date){if(isNaN(this)){throw new Error(this);}
|
1937
|
+
if(date instanceof Date&&!isNaN(date)){return(this>date)?1:(this<date)?-1:0;}else{throw new TypeError(date);}};Date.prototype.equals=function(date){return(this.compareTo(date)===0);};Date.prototype.between=function(start,end){var t=this.getTime();return t>=start.getTime()&&t<=end.getTime();};Date.prototype.addMilliseconds=function(value){this.setMilliseconds(this.getMilliseconds()+value);return this;};Date.prototype.addSeconds=function(value){return this.addMilliseconds(value*1000);};Date.prototype.addMinutes=function(value){return this.addMilliseconds(value*60000);};Date.prototype.addHours=function(value){return this.addMilliseconds(value*3600000);};Date.prototype.addDays=function(value){return this.addMilliseconds(value*86400000);};Date.prototype.addWeeks=function(value){return this.addMilliseconds(value*604800000);};Date.prototype.addMonths=function(value){var n=this.getDate();this.setDate(1);this.setMonth(this.getMonth()+value);this.setDate(Math.min(n,this.getDaysInMonth()));return this;};Date.prototype.addYears=function(value){return this.addMonths(value*12);};Date.prototype.add=function(config){if(typeof config=="number"){this._orient=config;return this;}
|
1938
|
+
var x=config;if(x.millisecond||x.milliseconds){this.addMilliseconds(x.millisecond||x.milliseconds);}
|
1939
|
+
if(x.second||x.seconds){this.addSeconds(x.second||x.seconds);}
|
1940
|
+
if(x.minute||x.minutes){this.addMinutes(x.minute||x.minutes);}
|
1941
|
+
if(x.hour||x.hours){this.addHours(x.hour||x.hours);}
|
1942
|
+
if(x.month||x.months){this.addMonths(x.month||x.months);}
|
1943
|
+
if(x.year||x.years){this.addYears(x.year||x.years);}
|
1944
|
+
if(x.day||x.days){this.addDays(x.day||x.days);}
|
1945
|
+
return this;};Date._validate=function(value,min,max,name){if(typeof value!="number"){throw new TypeError(value+" is not a Number.");}else if(value<min||value>max){throw new RangeError(value+" is not a valid value for "+name+".");}
|
1946
|
+
return true;};Date.validateMillisecond=function(n){return Date._validate(n,0,999,"milliseconds");};Date.validateSecond=function(n){return Date._validate(n,0,59,"seconds");};Date.validateMinute=function(n){return Date._validate(n,0,59,"minutes");};Date.validateHour=function(n){return Date._validate(n,0,23,"hours");};Date.validateDay=function(n,year,month){return Date._validate(n,1,Date.getDaysInMonth(year,month),"days");};Date.validateMonth=function(n){return Date._validate(n,0,11,"months");};Date.validateYear=function(n){return Date._validate(n,1,9999,"seconds");};Date.prototype.set=function(config){var x=config;if(!x.millisecond&&x.millisecond!==0){x.millisecond=-1;}
|
1947
|
+
if(!x.second&&x.second!==0){x.second=-1;}
|
1948
|
+
if(!x.minute&&x.minute!==0){x.minute=-1;}
|
1949
|
+
if(!x.hour&&x.hour!==0){x.hour=-1;}
|
1950
|
+
if(!x.day&&x.day!==0){x.day=-1;}
|
1951
|
+
if(!x.month&&x.month!==0){x.month=-1;}
|
1952
|
+
if(!x.year&&x.year!==0){x.year=-1;}
|
1953
|
+
if(x.millisecond!=-1&&Date.validateMillisecond(x.millisecond)){this.addMilliseconds(x.millisecond-this.getMilliseconds());}
|
1954
|
+
if(x.second!=-1&&Date.validateSecond(x.second)){this.addSeconds(x.second-this.getSeconds());}
|
1955
|
+
if(x.minute!=-1&&Date.validateMinute(x.minute)){this.addMinutes(x.minute-this.getMinutes());}
|
1956
|
+
if(x.hour!=-1&&Date.validateHour(x.hour)){this.addHours(x.hour-this.getHours());}
|
1957
|
+
if(x.month!==-1&&Date.validateMonth(x.month)){this.addMonths(x.month-this.getMonth());}
|
1958
|
+
if(x.year!=-1&&Date.validateYear(x.year)){this.addYears(x.year-this.getFullYear());}
|
1959
|
+
if(x.day!=-1&&Date.validateDay(x.day,this.getFullYear(),this.getMonth())){this.addDays(x.day-this.getDate());}
|
1960
|
+
if(x.timezone){this.setTimezone(x.timezone);}
|
1961
|
+
if(x.timezoneOffset){this.setTimezoneOffset(x.timezoneOffset);}
|
1962
|
+
return this;};Date.prototype.clearTime=function(){this.setHours(0);this.setMinutes(0);this.setSeconds(0);this.setMilliseconds(0);return this;};Date.prototype.isLeapYear=function(){var y=this.getFullYear();return(((y%4===0)&&(y%100!==0))||(y%400===0));};Date.prototype.isWeekday=function(){return!(this.is().sat()||this.is().sun());};Date.prototype.getDaysInMonth=function(){return Date.getDaysInMonth(this.getFullYear(),this.getMonth());};Date.prototype.moveToFirstDayOfMonth=function(){return this.set({day:1});};Date.prototype.moveToLastDayOfMonth=function(){return this.set({day:this.getDaysInMonth()});};Date.prototype.moveToDayOfWeek=function(day,orient){var diff=(day-this.getDay()+7*(orient||+1))%7;return this.addDays((diff===0)?diff+=7*(orient||+1):diff);};Date.prototype.moveToMonth=function(month,orient){var diff=(month-this.getMonth()+12*(orient||+1))%12;return this.addMonths((diff===0)?diff+=12*(orient||+1):diff);};Date.prototype.getDayOfYear=function(){return Math.floor((this-new Date(this.getFullYear(),0,1))/86400000);};Date.prototype.getWeekOfYear=function(firstDayOfWeek){var y=this.getFullYear(),m=this.getMonth(),d=this.getDate();var dow=firstDayOfWeek||Date.CultureInfo.firstDayOfWeek;var offset=7+1-new Date(y,0,1).getDay();if(offset==8){offset=1;}
|
1963
|
+
var daynum=((Date.UTC(y,m,d,0,0,0)-Date.UTC(y,0,1,0,0,0))/86400000)+1;var w=Math.floor((daynum-offset+7)/7);if(w===dow){y--;var prevOffset=7+1-new Date(y,0,1).getDay();if(prevOffset==2||prevOffset==8){w=53;}else{w=52;}}
|
1964
|
+
return w;};Date.prototype.isDST=function(){console.log('isDST');return this.toString().match(/(E|C|M|P)(S|D)T/)[2]=="D";};Date.prototype.getTimezone=function(){return Date.getTimezoneAbbreviation(this.getUTCOffset,this.isDST());};Date.prototype.setTimezoneOffset=function(s){var here=this.getTimezoneOffset(),there=Number(s)*-6/10;this.addMinutes(there-here);return this;};Date.prototype.setTimezone=function(s){return this.setTimezoneOffset(Date.getTimezoneOffset(s));};Date.prototype.getUTCOffset=function(){var n=this.getTimezoneOffset()*-10/6,r;if(n<0){r=(n-10000).toString();return r[0]+r.substr(2);}else{r=(n+10000).toString();return"+"+r.substr(1);}};Date.prototype.getDayName=function(abbrev){return abbrev?Date.CultureInfo.abbreviatedDayNames[this.getDay()]:Date.CultureInfo.dayNames[this.getDay()];};Date.prototype.getMonthName=function(abbrev){return abbrev?Date.CultureInfo.abbreviatedMonthNames[this.getMonth()]:Date.CultureInfo.monthNames[this.getMonth()];};Date.prototype._toString=Date.prototype.toString;Date.prototype.toString=function(format){var self=this;var p=function p(s){return(s.toString().length==1)?"0"+s:s;};return format?format.replace(/dd?d?d?|MM?M?M?|yy?y?y?|hh?|HH?|mm?|ss?|tt?|zz?z?/g,function(format){switch(format){case"hh":return p(self.getHours()<13?self.getHours():(self.getHours()-12));case"h":return self.getHours()<13?self.getHours():(self.getHours()-12);case"HH":return p(self.getHours());case"H":return self.getHours();case"mm":return p(self.getMinutes());case"m":return self.getMinutes();case"ss":return p(self.getSeconds());case"s":return self.getSeconds();case"yyyy":return self.getFullYear();case"yy":return self.getFullYear().toString().substring(2,4);case"dddd":return self.getDayName();case"ddd":return self.getDayName(true);case"dd":return p(self.getDate());case"d":return self.getDate().toString();case"MMMM":return self.getMonthName();case"MMM":return self.getMonthName(true);case"MM":return p((self.getMonth()+1));case"M":return self.getMonth()+1;case"t":return self.getHours()<12?Date.CultureInfo.amDesignator.substring(0,1):Date.CultureInfo.pmDesignator.substring(0,1);case"tt":return self.getHours()<12?Date.CultureInfo.amDesignator:Date.CultureInfo.pmDesignator;case"zzz":case"zz":case"z":return"";}}):this._toString();};
|
1965
|
+
Date.now=function(){return new Date();};Date.today=function(){return Date.now().clearTime();};Date.prototype._orient=+1;Date.prototype.next=function(){this._orient=+1;return this;};Date.prototype.last=Date.prototype.prev=Date.prototype.previous=function(){this._orient=-1;return this;};Date.prototype._is=false;Date.prototype.is=function(){this._is=true;return this;};Number.prototype._dateElement="day";Number.prototype.fromNow=function(){var c={};c[this._dateElement]=this;return Date.now().add(c);};Number.prototype.ago=function(){var c={};c[this._dateElement]=this*-1;return Date.now().add(c);};(function(){var $D=Date.prototype,$N=Number.prototype;var dx=("sunday monday tuesday wednesday thursday friday saturday").split(/\s/),mx=("january february march april may june july august september october november december").split(/\s/),px=("Millisecond Second Minute Hour Day Week Month Year").split(/\s/),de;var df=function(n){return function(){if(this._is){this._is=false;return this.getDay()==n;}
|
1966
|
+
return this.moveToDayOfWeek(n,this._orient);};};for(var i=0;i<dx.length;i++){$D[dx[i]]=$D[dx[i].substring(0,3)]=df(i);}
|
1967
|
+
var mf=function(n){return function(){if(this._is){this._is=false;return this.getMonth()===n;}
|
1968
|
+
return this.moveToMonth(n,this._orient);};};for(var j=0;j<mx.length;j++){$D[mx[j]]=$D[mx[j].substring(0,3)]=mf(j);}
|
1969
|
+
var ef=function(j){return function(){if(j.substring(j.length-1)!="s"){j+="s";}
|
1970
|
+
return this["add"+j](this._orient);};};var nf=function(n){return function(){this._dateElement=n;return this;};};for(var k=0;k<px.length;k++){de=px[k].toLowerCase();$D[de]=$D[de+"s"]=ef(px[k]);$N[de]=$N[de+"s"]=nf(de);}}());Date.prototype.toJSONString=function(){return this.toString("yyyy-MM-ddThh:mm:ssZ");};Date.prototype.toShortDateString=function(){return this.toString(Date.CultureInfo.formatPatterns.shortDatePattern);};Date.prototype.toLongDateString=function(){return this.toString(Date.CultureInfo.formatPatterns.longDatePattern);};Date.prototype.toShortTimeString=function(){return this.toString(Date.CultureInfo.formatPatterns.shortTimePattern);};Date.prototype.toLongTimeString=function(){return this.toString(Date.CultureInfo.formatPatterns.longTimePattern);};Date.prototype.getOrdinal=function(){switch(this.getDate()){case 1:case 21:case 31:return"st";case 2:case 22:return"nd";case 3:case 23:return"rd";default:return"th";}};
|
1971
|
+
(function(){Date.Parsing={Exception:function(s){this.message="Parse error at '"+s.substring(0,10)+" ...'";}};var $P=Date.Parsing;var _=$P.Operators={rtoken:function(r){return function(s){var mx=s.match(r);if(mx){return([mx[0],s.substring(mx[0].length)]);}else{throw new $P.Exception(s);}};},token:function(s){return function(s){return _.rtoken(new RegExp("^\s*"+s+"\s*"))(s);};},stoken:function(s){return _.rtoken(new RegExp("^"+s));},until:function(p){return function(s){var qx=[],rx=null;while(s.length){try{rx=p.call(this,s);}catch(e){qx.push(rx[0]);s=rx[1];continue;}
|
1972
|
+
break;}
|
1973
|
+
return[qx,s];};},many:function(p){return function(s){var rx=[],r=null;while(s.length){try{r=p.call(this,s);}catch(e){return[rx,s];}
|
1974
|
+
rx.push(r[0]);s=r[1];}
|
1975
|
+
return[rx,s];};},optional:function(p){return function(s){var r=null;try{r=p.call(this,s);}catch(e){return[null,s];}
|
1976
|
+
return[r[0],r[1]];};},not:function(p){return function(s){try{p.call(this,s);}catch(e){return[null,s];}
|
1977
|
+
throw new $P.Exception(s);};},ignore:function(p){return p?function(s){var r=null;r=p.call(this,s);return[null,r[1]];}:null;},product:function(){var px=arguments[0],qx=Array.prototype.slice.call(arguments,1),rx=[];for(var i=0;i<px.length;i++){rx.push(_.each(px[i],qx));}
|
1978
|
+
return rx;},cache:function(rule){var cache={},r=null;return function(s){try{r=cache[s]=(cache[s]||rule.call(this,s));}catch(e){r=cache[s]=e;}
|
1979
|
+
if(r instanceof $P.Exception){throw r;}else{return r;}};},any:function(){var px=arguments;return function(s){var r=null;for(var i=0;i<px.length;i++){if(px[i]==null){continue;}
|
1980
|
+
try{r=(px[i].call(this,s));}catch(e){r=null;}
|
1981
|
+
if(r){return r;}}
|
1982
|
+
throw new $P.Exception(s);};},each:function(){var px=arguments;return function(s){var rx=[],r=null;for(var i=0;i<px.length;i++){if(px[i]==null){continue;}
|
1983
|
+
try{r=(px[i].call(this,s));}catch(e){throw new $P.Exception(s);}
|
1984
|
+
rx.push(r[0]);s=r[1];}
|
1985
|
+
return[rx,s];};},all:function(){var px=arguments,_=_;return _.each(_.optional(px));},sequence:function(px,d,c){d=d||_.rtoken(/^\s*/);c=c||null;if(px.length==1){return px[0];}
|
1986
|
+
return function(s){var r=null,q=null;var rx=[];for(var i=0;i<px.length;i++){try{r=px[i].call(this,s);}catch(e){break;}
|
1987
|
+
rx.push(r[0]);try{q=d.call(this,r[1]);}catch(ex){q=null;break;}
|
1988
|
+
s=q[1];}
|
1989
|
+
if(!r){throw new $P.Exception(s);}
|
1990
|
+
if(q){throw new $P.Exception(q[1]);}
|
1991
|
+
if(c){try{r=c.call(this,r[1]);}catch(ey){throw new $P.Exception(r[1]);}}
|
1992
|
+
return[rx,(r?r[1]:s)];};},between:function(d1,p,d2){d2=d2||d1;var _fn=_.each(_.ignore(d1),p,_.ignore(d2));return function(s){var rx=_fn.call(this,s);return[[rx[0][0],r[0][2]],rx[1]];};},list:function(p,d,c){d=d||_.rtoken(/^\s*/);c=c||null;return(p instanceof Array?_.each(_.product(p.slice(0,-1),_.ignore(d)),p.slice(-1),_.ignore(c)):_.each(_.many(_.each(p,_.ignore(d))),px,_.ignore(c)));},set:function(px,d,c){d=d||_.rtoken(/^\s*/);c=c||null;return function(s){var r=null,p=null,q=null,rx=null,best=[[],s],last=false;for(var i=0;i<px.length;i++){q=null;p=null;r=null;last=(px.length==1);try{r=px[i].call(this,s);}catch(e){continue;}
|
1993
|
+
rx=[[r[0]],r[1]];if(r[1].length>0&&!last){try{q=d.call(this,r[1]);}catch(ex){last=true;}}else{last=true;}
|
1994
|
+
if(!last&&q[1].length===0){last=true;}
|
1995
|
+
if(!last){var qx=[];for(var j=0;j<px.length;j++){if(i!=j){qx.push(px[j]);}}
|
1996
|
+
p=_.set(qx,d).call(this,q[1]);if(p[0].length>0){rx[0]=rx[0].concat(p[0]);rx[1]=p[1];}}
|
1997
|
+
if(rx[1].length<best[1].length){best=rx;}
|
1998
|
+
if(best[1].length===0){break;}}
|
1999
|
+
if(best[0].length===0){return best;}
|
2000
|
+
if(c){try{q=c.call(this,best[1]);}catch(ey){throw new $P.Exception(best[1]);}
|
2001
|
+
best[1]=q[1];}
|
2002
|
+
return best;};},forward:function(gr,fname){return function(s){return gr[fname].call(this,s);};},replace:function(rule,repl){return function(s){var r=rule.call(this,s);return[repl,r[1]];};},process:function(rule,fn){return function(s){var r=rule.call(this,s);return[fn.call(this,r[0]),r[1]];};},min:function(min,rule){return function(s){var rx=rule.call(this,s);if(rx[0].length<min){throw new $P.Exception(s);}
|
2003
|
+
return rx;};}};var _generator=function(op){return function(){var args=null,rx=[];if(arguments.length>1){args=Array.prototype.slice.call(arguments);}else if(arguments[0]instanceof Array){args=arguments[0];}
|
2004
|
+
if(args){for(var i=0,px=args.shift();i<px.length;i++){args.unshift(px[i]);rx.push(op.apply(null,args));args.shift();return rx;}}else{return op.apply(null,arguments);}};};var gx="optional not ignore cache".split(/\s/);for(var i=0;i<gx.length;i++){_[gx[i]]=_generator(_[gx[i]]);}
|
2005
|
+
var _vector=function(op){return function(){if(arguments[0]instanceof Array){return op.apply(null,arguments[0]);}else{return op.apply(null,arguments);}};};var vx="each any all".split(/\s/);for(var j=0;j<vx.length;j++){_[vx[j]]=_vector(_[vx[j]]);}}());(function(){var flattenAndCompact=function(ax){var rx=[];for(var i=0;i<ax.length;i++){if(ax[i]instanceof Array){rx=rx.concat(flattenAndCompact(ax[i]));}else{if(ax[i]){rx.push(ax[i]);}}}
|
2006
|
+
return rx;};Date.Grammar={};Date.Translator={hour:function(s){return function(){this.hour=Number(s);};},minute:function(s){return function(){this.minute=Number(s);};},second:function(s){return function(){this.second=Number(s);};},meridian:function(s){return function(){this.meridian=s.slice(0,1).toLowerCase();};},timezone:function(s){return function(){var n=s.replace(/[^\d\+\-]/g,"");if(n.length){this.timezoneOffset=Number(n);}else{this.timezone=s.toLowerCase();}};},day:function(x){var s=x[0];return function(){this.day=Number(s.match(/\d+/)[0]);};},month:function(s){return function(){this.month=((s.length==3)?Date.getMonthNumberFromName(s):(Number(s)-1));};},year:function(s){return function(){var n=Number(s);this.year=((s.length>2)?n:(n+(((n+2000)<Date.CultureInfo.twoDigitYearMax)?2000:1900)));};},rday:function(s){return function(){switch(s){case"yesterday":this.days=-1;break;case"tomorrow":this.days=1;break;case"today":this.days=0;break;case"now":this.days=0;this.now=true;break;}};},finishExact:function(x){x=(x instanceof Array)?x:[x];var now=new Date();this.year=now.getFullYear();this.month=now.getMonth();this.day=1;this.hour=0;this.minute=0;this.second=0;for(var i=0;i<x.length;i++){if(x[i]){x[i].call(this);}}
|
2007
|
+
this.hour=(this.meridian=="p"&&this.hour<13)?this.hour+12:this.hour;if(this.day>Date.getDaysInMonth(this.year,this.month)){throw new RangeError(this.day+" is not a valid value for days.");}
|
2008
|
+
var r=new Date(this.year,this.month,this.day,this.hour,this.minute,this.second);if(this.timezone){r.set({timezone:this.timezone});}else if(this.timezoneOffset){r.set({timezoneOffset:this.timezoneOffset});}
|
2009
|
+
return r;},finish:function(x){x=(x instanceof Array)?flattenAndCompact(x):[x];if(x.length===0){return null;}
|
2010
|
+
for(var i=0;i<x.length;i++){if(typeof x[i]=="function"){x[i].call(this);}}
|
2011
|
+
if(this.now){return new Date();}
|
2012
|
+
var today=Date.today();var method=null;var expression=!!(this.days!=null||this.orient||this.operator);if(expression){var gap,mod,orient;orient=((this.orient=="past"||this.operator=="subtract")?-1:1);if(this.weekday){this.unit="day";gap=(Date.getDayNumberFromName(this.weekday)-today.getDay());mod=7;this.days=gap?((gap+(orient*mod))%mod):(orient*mod);}
|
2013
|
+
if(this.month){this.unit="month";gap=(this.month-today.getMonth());mod=12;this.months=gap?((gap+(orient*mod))%mod):(orient*mod);this.month=null;}
|
2014
|
+
if(!this.unit){this.unit="day";}
|
2015
|
+
if(this[this.unit+"s"]==null||this.operator!=null){if(!this.value){this.value=1;}
|
2016
|
+
if(this.unit=="week"){this.unit="day";this.value=this.value*7;}
|
2017
|
+
this[this.unit+"s"]=this.value*orient;}
|
2018
|
+
return today.add(this);}else{if(this.meridian&&this.hour){this.hour=(this.hour<13&&this.meridian=="p")?this.hour+12:this.hour;}
|
2019
|
+
if(this.weekday&&!this.day){this.day=(today.addDays((Date.getDayNumberFromName(this.weekday)-today.getDay()))).getDate();}
|
2020
|
+
if(this.month&&!this.day){this.day=1;}
|
2021
|
+
return today.set(this);}}};var _=Date.Parsing.Operators,g=Date.Grammar,t=Date.Translator,_fn;g.datePartDelimiter=_.rtoken(/^([\s\-\.\,\/\x27]+)/);g.timePartDelimiter=_.stoken(":");g.whiteSpace=_.rtoken(/^\s*/);g.generalDelimiter=_.rtoken(/^(([\s\,]|at|on)+)/);var _C={};g.ctoken=function(keys){var fn=_C[keys];if(!fn){var c=Date.CultureInfo.regexPatterns;var kx=keys.split(/\s+/),px=[];for(var i=0;i<kx.length;i++){px.push(_.replace(_.rtoken(c[kx[i]]),kx[i]));}
|
2022
|
+
fn=_C[keys]=_.any.apply(null,px);}
|
2023
|
+
return fn;};g.ctoken2=function(key){return _.rtoken(Date.CultureInfo.regexPatterns[key]);};g.h=_.cache(_.process(_.rtoken(/^(0[0-9]|1[0-2]|[1-9])/),t.hour));g.hh=_.cache(_.process(_.rtoken(/^(0[0-9]|1[0-2])/),t.hour));g.H=_.cache(_.process(_.rtoken(/^([0-1][0-9]|2[0-3]|[0-9])/),t.hour));g.HH=_.cache(_.process(_.rtoken(/^([0-1][0-9]|2[0-3])/),t.hour));g.m=_.cache(_.process(_.rtoken(/^([0-5][0-9]|[0-9])/),t.minute));g.mm=_.cache(_.process(_.rtoken(/^[0-5][0-9]/),t.minute));g.s=_.cache(_.process(_.rtoken(/^([0-5][0-9]|[0-9])/),t.second));g.ss=_.cache(_.process(_.rtoken(/^[0-5][0-9]/),t.second));g.hms=_.cache(_.sequence([g.H,g.mm,g.ss],g.timePartDelimiter));g.t=_.cache(_.process(g.ctoken2("shortMeridian"),t.meridian));g.tt=_.cache(_.process(g.ctoken2("longMeridian"),t.meridian));g.z=_.cache(_.process(_.rtoken(/^(\+|\-)?\s*\d\d\d\d?/),t.timezone));g.zz=_.cache(_.process(_.rtoken(/^(\+|\-)\s*\d\d\d\d/),t.timezone));g.zzz=_.cache(_.process(g.ctoken2("timezone"),t.timezone));g.timeSuffix=_.each(_.ignore(g.whiteSpace),_.set([g.tt,g.zzz]));g.time=_.each(_.optional(_.ignore(_.stoken("T"))),g.hms,g.timeSuffix);g.d=_.cache(_.process(_.each(_.rtoken(/^([0-2]\d|3[0-1]|\d)/),_.optional(g.ctoken2("ordinalSuffix"))),t.day));g.dd=_.cache(_.process(_.each(_.rtoken(/^([0-2]\d|3[0-1])/),_.optional(g.ctoken2("ordinalSuffix"))),t.day));g.ddd=g.dddd=_.cache(_.process(g.ctoken("sun mon tue wed thu fri sat"),function(s){return function(){this.weekday=s;};}));g.M=_.cache(_.process(_.rtoken(/^(1[0-2]|0\d|\d)/),t.month));g.MM=_.cache(_.process(_.rtoken(/^(1[0-2]|0\d)/),t.month));g.MMM=g.MMMM=_.cache(_.process(g.ctoken("jan feb mar apr may jun jul aug sep oct nov dec"),t.month));g.y=_.cache(_.process(_.rtoken(/^(\d\d?)/),t.year));g.yy=_.cache(_.process(_.rtoken(/^(\d\d)/),t.year));g.yyy=_.cache(_.process(_.rtoken(/^(\d\d?\d?\d?)/),t.year));g.yyyy=_.cache(_.process(_.rtoken(/^(\d\d\d\d)/),t.year));_fn=function(){return _.each(_.any.apply(null,arguments),_.not(g.ctoken2("timeContext")));};g.day=_fn(g.d,g.dd);g.month=_fn(g.M,g.MMM);g.year=_fn(g.yyyy,g.yy);g.orientation=_.process(g.ctoken("past future"),function(s){return function(){this.orient=s;};});g.operator=_.process(g.ctoken("add subtract"),function(s){return function(){this.operator=s;};});g.rday=_.process(g.ctoken("yesterday tomorrow today now"),t.rday);g.unit=_.process(g.ctoken("minute hour day week month year"),function(s){return function(){this.unit=s;};});g.value=_.process(_.rtoken(/^\d\d?(st|nd|rd|th)?/),function(s){return function(){this.value=s.replace(/\D/g,"");};});g.expression=_.set([g.rday,g.operator,g.value,g.unit,g.orientation,g.ddd,g.MMM]);_fn=function(){return _.set(arguments,g.datePartDelimiter);};g.mdy=_fn(g.ddd,g.month,g.day,g.year);g.ymd=_fn(g.ddd,g.year,g.month,g.day);g.dmy=_fn(g.ddd,g.day,g.month,g.year);g.date=function(s){return((g[Date.CultureInfo.dateElementOrder]||g.mdy).call(this,s));};g.format=_.process(_.many(_.any(_.process(_.rtoken(/^(dd?d?d?|MM?M?M?|yy?y?y?|hh?|HH?|mm?|ss?|tt?|zz?z?)/),function(fmt){if(g[fmt]){return g[fmt];}else{throw Date.Parsing.Exception(fmt);}}),_.process(_.rtoken(/^[^dMyhHmstz]+/),function(s){return _.ignore(_.stoken(s));}))),function(rules){return _.process(_.each.apply(null,rules),t.finishExact);});var _F={};var _get=function(f){return _F[f]=(_F[f]||g.format(f)[0]);};g.formats=function(fx){if(fx instanceof Array){var rx=[];for(var i=0;i<fx.length;i++){rx.push(_get(fx[i]));}
|
2024
|
+
return _.any.apply(null,rx);}else{return _get(fx);}};g._formats=g.formats(["yyyy-MM-ddTHH:mm:ss","ddd, MMM dd, yyyy H:mm:ss tt","ddd MMM d yyyy HH:mm:ss zzz","d"]);g._start=_.process(_.set([g.date,g.time,g.expression],g.generalDelimiter,g.whiteSpace),t.finish);g.start=function(s){try{var r=g._formats.call({},s);if(r[1].length===0){return r;}}catch(e){}
|
2025
|
+
return g._start.call({},s);};}());Date._parse=Date.parse;Date.parse=function(s){var r=null;if(!s){return null;}
|
2026
|
+
try{r=Date.Grammar.start.call({},s);}catch(e){return null;}
|
2027
|
+
return((r[1].length===0)?r[0]:null);};Date.getParseFunction=function(fx){var fn=Date.Grammar.formats(fx);return function(s){var r=null;try{r=fn.call({},s);}catch(e){return null;}
|
2028
|
+
return((r[1].length===0)?r[0]:null);};};Date.parseExact=function(s,fx){return Date.getParseFunction(fx)(s);};
|
2029
|
+
/**
|
2030
|
+
* Version: 1.0 Alpha-1
|
2031
|
+
* Build Date: 13-Nov-2007
|
2032
|
+
* Copyright (c) 2006-2007, Coolite Inc. (http://www.coolite.com/). All rights reserved.
|
2033
|
+
* License: Licensed under The MIT License. See license.txt and http://www.datejs.com/license/.
|
2034
|
+
* Website: http://www.datejs.com/ or http://www.coolite.com/datejs/
|
2035
|
+
*/
|
2036
|
+
TimeSpan=function(days,hours,minutes,seconds,milliseconds){this.days=0;this.hours=0;this.minutes=0;this.seconds=0;this.milliseconds=0;if(arguments.length==5){this.days=days;this.hours=hours;this.minutes=minutes;this.seconds=seconds;this.milliseconds=milliseconds;}
|
2037
|
+
else if(arguments.length==1&&typeof days=="number"){var orient=(days<0)?-1:+1;this.milliseconds=Math.abs(days);this.days=Math.floor(this.milliseconds/(24*60*60*1000))*orient;this.milliseconds=this.milliseconds%(24*60*60*1000);this.hours=Math.floor(this.milliseconds/(60*60*1000))*orient;this.milliseconds=this.milliseconds%(60*60*1000);this.minutes=Math.floor(this.milliseconds/(60*1000))*orient;this.milliseconds=this.milliseconds%(60*1000);this.seconds=Math.floor(this.milliseconds/1000)*orient;this.milliseconds=this.milliseconds%1000;this.milliseconds=this.milliseconds*orient;return this;}
|
2038
|
+
else{return null;}};TimeSpan.prototype.compare=function(timeSpan){var t1=new Date(1970,1,1,this.hours(),this.minutes(),this.seconds()),t2;if(timeSpan===null){t2=new Date(1970,1,1,0,0,0);}
|
2039
|
+
else{t2=new Date(1970,1,1,timeSpan.hours(),timeSpan.minutes(),timeSpan.seconds());}
|
2040
|
+
return(t1>t2)?1:(t1<t2)?-1:0;};TimeSpan.prototype.add=function(timeSpan){return(timeSpan===null)?this:this.addSeconds(timeSpan.getTotalMilliseconds()/1000);};TimeSpan.prototype.subtract=function(timeSpan){return(timeSpan===null)?this:this.addSeconds(-timeSpan.getTotalMilliseconds()/1000);};TimeSpan.prototype.addDays=function(n){return new TimeSpan(this.getTotalMilliseconds()+(n*24*60*60*1000));};TimeSpan.prototype.addHours=function(n){return new TimeSpan(this.getTotalMilliseconds()+(n*60*60*1000));};TimeSpan.prototype.addMinutes=function(n){return new TimeSpan(this.getTotalMilliseconds()+(n*60*1000));};TimeSpan.prototype.addSeconds=function(n){return new TimeSpan(this.getTotalMilliseconds()+(n*1000));};TimeSpan.prototype.addMilliseconds=function(n){return new TimeSpan(this.getTotalMilliseconds()+n);};TimeSpan.prototype.getTotalMilliseconds=function(){return(this.days()*(24*60*60*1000))+(this.hours()*(60*60*1000))+(this.minutes()*(60*1000))+(this.seconds()*(1000));};TimeSpan.prototype.get12HourHour=function(){return((h=this.hours()%12)?h:12);};TimeSpan.prototype.getDesignator=function(){return(this.hours()<12)?Date.CultureInfo.amDesignator:Date.CultureInfo.pmDesignator;};TimeSpan.prototype.toString=function(format){function _toString(){if(this.days()!==null&&this.days()>0){return this.days()+"."+this.hours()+":"+p(this.minutes())+":"+p(this.seconds());}
|
2041
|
+
else{return this.hours()+":"+p(this.minutes())+":"+p(this.seconds());}}
|
2042
|
+
function p(s){return(s.toString().length<2)?"0"+s:s;}
|
2043
|
+
var self=this;return format?format.replace(/d|dd|HH|H|hh|h|mm|m|ss|s|tt|t/g,function(format){switch(format){case"d":return self.days();case"dd":return p(self.days());case"H":return self.hours();case"HH":return p(self.hours());case"h":return self.get12HourHour();case"hh":return p(self.get12HourHour());case"m":return self.minutes();case"mm":return p(self.minutes());case"s":return self.seconds();case"ss":return p(self.seconds());case"t":return((this.hours()<12)?Date.CultureInfo.amDesignator:Date.CultureInfo.pmDesignator).substring(0,1);case"tt":return(this.hours()<12)?Date.CultureInfo.amDesignator:Date.CultureInfo.pmDesignator;}}):this._toString();};var TimePeriod=function(years,months,days,hours,minutes,seconds,milliseconds){this.years=0;this.months=0;this.days=0;this.hours=0;this.minutes=0;this.seconds=0;this.milliseconds=0;if(arguments.length==2&&arguments[0]instanceof Date&&arguments[1]instanceof Date){var date1=years.clone();var date2=months.clone();var temp=date1.clone();var orient=(date1>date2)?-1:+1;this.years=date2.getFullYear()-date1.getFullYear();temp.addYears(this.years);if(orient==+1){if(temp>date2){if(this.years!==0){this.years--;}}}else{if(temp<date2){if(this.years!==0){this.years++;}}}
|
2044
|
+
date1.addYears(this.years);if(orient==+1){while(date1<date2&&date1.clone().addDays(date1.getDaysInMonth())<date2){date1.addMonths(1);this.months++;}}
|
2045
|
+
else{while(date1>date2&&date1.clone().addDays(-date1.getDaysInMonth())>date2){date1.addMonths(-1);this.months--;}}
|
2046
|
+
var diff=date2-date1;if(diff!==0){var ts=new TimeSpan(diff);this.days=ts.days;this.hours=ts.hours;this.minutes=ts.minutes;this.seconds=ts.seconds;this.milliseconds=ts.milliseconds;}
|
2047
|
+
return this;}};
|