Calendario de Eventos ASP + jQuery
Abri um tópico http://forum.imasters.com.br/topic/525142-redigitar-em-asp/ e não obtive sucesso, mesmo não entendendo nada de PHP, resolvi arriscar e cheguei ao resultado esperado.
Vou postar abaixo (uma maneira de contribuir com o fórum)
Os arquivos Js, tem os comentários em português eu coloquei para facilitar na hora de ver o que cada ação fazia.
Outra dica: como usei isso em projeto já existente, coloquei o calendário dentro de iframe para não afetar o css do que já estava pronto
usei 10 arquivos:
calendar.asp
cursos-lista-detalhes-aulas-cad.asp
reset.css
<link rel='stylesheet' type='text/css' href='http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/themes/start/jquery-ui.css' />
jquery.weekcalendar.css
calendar.css
<script type='text/javascript' src='[http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js'>](http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js%27)
<script type='text/javascript' src='[http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/jquery-ui.min.js'>](http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/jquery-ui.min.js%27)
jquery.weekcalendar.js
calendar.js
calendar.asp
<%
Function FormataData(Data)
If Data <> "" Then FormataData = DatePart("yyyy", Data) & "-" & Right("0" & DatePart("m", Data),2) & "-" & Right("0" & DatePart("d", Data),2)
End Function
%>
<%
IdCurso = Request("IdReg")
%>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head>
<link rel='stylesheet' type='text/css' href='css/calendar/reset.css' />
<link rel='stylesheet' type='text/css' href='[http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/themes/start/jquery-ui.css'](http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/themes/start/jquery-ui.css) />
<link rel='stylesheet' type='text/css' href='css/calendar/jquery.weekcalendar.css' />
<link rel='stylesheet' type='text/css' href='css/calendar/calendar.css' />
<script type='text/javascript' src='http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js'></script>
<script type='text/javascript' src='http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/jquery-ui.min.js'></script>
<script type='text/javascript' src='js/calendar/jquery.weekcalendar.js'></script>
<script type='text/javascript' src='js/calendar/calendar.js'></script>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /></head>
<body>
<div style="width:90%; margin-left:30px;">
<div id='calendar'></div>
<div id="event_edit_container">
<form>
<input type="hidden" />
<ul>
<li>
<span>Data: </span><span class="date_holder"></span>
</li>
<li>
<label for="end">Id Curso: </label><input type="text" name="idcurso" value="<%=IdCurso%>" />
</li>
<li>
<label for="start">Horário Inicial: </label><select name="start"><option value="">Selecione...</option></select>
</li>
<li>
<label for="end">Horário Final: </label><select name="end"><option value="">Selecione...</option></select>
</li>
<li>
<label for="title">Título: </label><input type="text" name="title" />
</li>
<li>
<label for="title">Ch: </label><input type="text" name="ch" />
</li>
<li>
<label for="body">Observação: </label><textarea name="body"></textarea>
</li>
</ul>
</form>
</div>
</div>
<%
set RSLerDadosAula = server.createobject("adodb.recordset")
SQLLerDadosAula = "SELECT * FROM cursos_aulas where IdCurso = '" & IdCurso & "' "
RSLerDadosAula.open SQLLerDadosAula, objConn
%>
<script>
function getEventData() {
var year = new Date().getFullYear();
var month = new Date().getMonth();
//alert(month);
var day = new Date().getDate();
return {
events : [
// EVENTOS CADASTRADOS ATUAIS
// --- MES tem que ser menos (1)
<%
if RSLerDadosAula.eof then
%>
<%
else
%>
<%
while not RSLerDadosAula.eof
%>
<%
IdAula = RSLerDadosAula("id")
DataAula = RSLerDadosAula("DataAula")
AnoData = Year(DataAula)
MesData = month(DataAula)
MesData = MesData - 1
DiaData = Day(DataAula)
HoraInicial = RSLerDadosAula("HoraInicial")
HoraInicialI = Mid(HoraInicial,1,2)
HoraInicialF = Mid(HoraInicial,4,2)
HoraFinal = RSLerDadosAula("HoraFinal")
HoraFinalI = Mid(HoraFinal,1,2)
HoraFinalF = Mid(HoraFinal,4,2)
ChAula = RSLerDadosAula("ChAula")
NomeAula = RSLerDadosAula("NomeAula")
DescricaoAula = RSLerDadosAula("DescricaoAula")
%>
<%
response.write "{"
response.write """id"":" & IdAula & ","
response.write """start"": new Date(" & AnoData & ", " & MesData & ", " & DiaData & ", " & HoraInicialI & ", " & HoraInicialF & "),"
response.write """end"": new Date(" & AnoData & ", " & MesData & ", " & DiaData & ", " & HoraFinalI & ", " & HoraFinalF & "),"
response.write """title"":""" & NomeAula & ""","
response.write """body"":""" & DescricaoAula & ""","
response.write """ch"":""" & ChAula & ""","
response.write """idcurso"":""" & IdCurso & """"
response.write "},"
%>
<%
RSLerDadosAula.MoveNext : Wend
%>
<%
end if
%>
// EVENTOS CADASTRADOS ATUAIS
]
};
}
</script>
</body>
</html>
cursos-lista-detalhes-aulas-cad.asp
<%
Function FormataData(Data)
If Data <> "" Then FormataData = DatePart("yyyy", Data) & "-" & Right("0" & DatePart("m", Data),2) & "-" & Right("0" & DatePart("d", Data),2)
End Function
%>
<%
IdCurso = Request("IdCurso")
NomeAula = Request("TituloEvento")
HoraInicial = Request("HoraInicial")
HoraFinal = Request("HoraFinal")
DataAula = FormataData(Request("DataEvento"))
DescricaoAula = Request("DescricaoEvento")
ChAula = Request("Ch")
%>
<%
set RSLerDados = server.createobject("adodb.recordset")
SQLLerDados = "SELECT * FROM cursos_aulas where IdCurso = '" & IdCurso & "' and DataAula = '" & DataAula & "' and HoraInicial = '" & HoraInicial & "' and HoraFinal = '" & HoraFinal & "' "
RSLerDados.open SQLLerDados, objConn
if RSLerDados.eof then
SQLLerDadosUm = "insert into cursos_aulas (IdCurso,NomeAula,HoraInicial,HoraFinal,DataAula,DescricaoAula,ChAula) values ('"&IdCurso&"','"&NomeAula&"','"&HoraInicial&"','"&HoraFinal&"','"&DataAula&"','"&DescricaoAula&"','"&ChAula&"')"
Set RSLerDadosUm=Server.CreateObject("ADODB.Recordset")
RSLerDadosUm.Open SQLLerDadosUm, objConn
Set RSLerDadosUm = Nothing
else
IdReg = RSLerDados("Id")
Set RSLerDadosUm=Server.CreateObject("ADODB.Recordset")
SQLLerDadosUm = "Update cursos_aulas set NomeAula='"&NomeAula&"',HoraInicial='"&HoraInicial&"',HoraFinal='"&HoraFinal&"',DataAula='"&DataAula&"',DescricaoAula='"&DescricaoAula&"',ChAula='"&ChAula&"' where id = " & idreg
RSLerDadosUm.Open SQLLerDadosUm, objConn
end if
%>
reset.css
@charset "utf-8";
/*
Copyright (c) 2008, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.net/yui/license.txt
version: 2.5.1
*/
html {
color: #000;
background: #FFF;
}
body, div, dl, dt, dd, ul, ol, li, h1, h2, h3, h4, h5, h6, pre, code, form, fieldset, legend, input, textarea, p, blockquote, th, td {
margin: 0;
padding: 0;
}
table {
border-collapse: collapse;
border-spacing: 0;
}
fieldset, img {
border: 0;
}
address, caption, cite, code, dfn, em, strong, th, var {
font-style: normal;
font-weight: normal;
}
li {
list-style: none;
}
caption, th {
text-align: left;
}
h1, h2, h3, h4, h5, h6 {
font-size: 100%;
font-weight: normal;
}
q:before, q:after {
content: '';
}
abbr, acronym {
border: 0;
font-variant: normal;
}
sup {
vertical-align: text-top;
}
sub {
vertical-align: text-bottom;
}
input, textarea, select {
font-family: inherit;
font-size: inherit;
font-weight: inherit;
}
input, textarea, select {
* font-size:
100%;
}
legend {
color: #000;
}
jquery.weekcalendar.css
@charset "utf-8";
.wc-container {
font-size: 14px;
font-family: arial, helvetica;
}
.wc-nav {
padding: 1em;
text-align: right;
}
.wc-nav button {
margin: 0 0.5em;
}
.wc-container table {
border-collapse: collapse;
border-spacing: 0;
}.wc-container table td {
margin: 0;
padding: 0;
}
.wc-header {
background: #eee;
border-top: 1px solid #aaa;
border-bottom: 1px solid #aaa;
width: 100%;
}
.wc-header .wc-time-column-header {
width: 6%;
}
.wc-header .wc-scrollbar-shim {
width: 16px;
}
.wc-header .wc-day-column-header {
text-align: center;
padding: 0.4em;
}.wc-header td {
background-color: #eee;
}
.wc-grid-timeslot-header {
width: 6%;
background: #eee;
}
.wc-scrollable-grid {
overflow: auto;
overflow-x: hidden !important;
overflow-y: auto !important;
position: relative;
background-color: #fff;
width: 100%;
}
table.wc-time-slots {
width: 100%;
table-layout: fixed;
cursor: default;
}
.wc-day-column {
width: 13.5%;
border-left: 1px solid #ddd;
overflow: visible;
vertical-align: top;
}
.wc-day-column-inner {
width: 100%;
position:relative;
}
.wc-time-slot-wrapper {
position:relative;
height: 1px;
top: 1px;
}
.wc-time-slots {
position: absolute;
width: 100%;
}
.wc-time-header-cell {
padding: 5px;
height: 80px; /* reference height */
}
.wc-time-slot {
border-bottom: 1px dotted #ddd;
}
.wc-hour-header {
text-align: right;
}
.wc-hour-end, .wc-hour-header {
border-bottom: 1px solid #ccc;
color: #555;
}
.wc-business-hours {
background-color: #E6EEF1;
border-bottom: 1px solid #ccc;
color: #333;
font-size: 1.4em;
}
.wc-business-hours .wc-am-pm {
font-size: 0.6em;
}
.wc-day-header-cell {
text-align: center;
vertical-align: middle;
padding: 5px;
}
.wc-time-slot-header .wc-header-cell {
text-align: right;
padding-right: 10px;
}
.wc-header .wc-today {
font-weight: bold;
}
.wc-time-slots .wc-today {
/background-color: #ffffcc; /
}
.wc-cal-event {
background-color: #68a1e5;
filter:alpha(opacity=80);
-moz-opacity:0.8;
-khtml-opacity: 0.8;
opacity: 0.8;
position: absolute;
text-align: center;
overflow: hidden;
cursor: pointer;
color: #fff;
width: 100%;
display: none;
}
.wc-cal-event div {
padding: 0 5px;
}
.wc-cal-event .wc-time {
background-color: #2b72d0;
border: 1px solid #1b62c0;
color: #fff;
padding: 0;
font-weight: bold;
}
.wc-container .ui-draggable .wc-time {
cursor: move;
}
.wc-cal-event .wc-title {
position: relative;
}
.wc-container .ui-resizable-s {
height: 10px;
bottom: -8px;
}
.wc-container .ui-draggable-dragging {
z-index: 1000;
}
calendar.css
@charset "utf-8";
body {
font-family: "Lucida Grande", Helvetica, Arial, Verdana, sans-serif;
font-size: 83.33%;
}
h1 {
padding: 0.5em;
font-size: 1.6em;
}
h2 {
margin: 0.5em 0;
font-size: 1.4em;
}
p {
margin: 0.5em;
}
.ui-widget {
font-size: 1em;
}
#event_edit_container, #about {
display: none;
}
#about_button_container {
position: absolute;
top: 1em;
right: 1em;
padding: 0.5em 2em;
background: #ddf;
border: 1px solid #bbd;
width: 10em;
text-align: center;
}
.wc-header td {
background: url(images/header-bg.png) repeat-x;
}
label {
display: block;
margin-top: 1em;
margin-bottom: 0.5em;
}
form ul {
padding: 0.3em;
}
select, input[type='text'], textarea {
width: 250px;
padding: 3px;
}
input[type='text'] {
width: 245px;
}
ul.formatted,ol.formatted {
display: block;
margin: 1em 0.5em;
}
ul.formatted li,ol.formatted li {
margin: 5px 30px;
display: auto;
}
ul.formatted li {
list-style-type: disc;
}
ol.formatted li {
list-style-type: decimal;
}
jquery.weekcalendar.js
/*
* jQuery.weekCalendar v1.2.2
* http://www.redredred.com.au/
*
* Requires:
* - jquery.weekcalendar.css
* - jquery 1.3.x
* - jquery-ui 1.7.x (widget, drag, drop, resize)
*
* Copyright (c) 2009 Rob Monie
* Dual licensed under the MIT and GPL licenses:
* http://www.opensource.org/licenses/mit-license.php
* http://www.gnu.org/licenses/gpl.html
*
* If you're after a monthly calendar plugin, check out http://arshaw.com/fullcalendar/
*/
(function($) {
$.widget("ui.weekCalendar", {
/***********************
* Initialise calendar *
***********************/
_init : function() {
var self = this;
self._computeOptions();
self._setupEventDelegation();
self._renderCalendar();
self._loadCalEvents();
self._resizeCalendar();
self._scrollToHour(self.options.date.getHours());
$(window).unbind("resize.weekcalendar");
$(window).bind("resize.weekcalendar", function() {
self._resizeCalendar();
});
},
/********************
* public functions *
********************/
/*
* Refresh the events for the currently displayed week.
*/
refresh : function() {
this._clearCalendar();
this._loadCalEvents(this.element.data("startDate")); //reload with existing week
},
/*
* Clear all events currently loaded into the calendar
*/
clear : function() {
this._clearCalendar();
},
/*
* Go to this week
*/
today : function() {
this._clearCalendar();
this._loadCalEvents(new Date());
},
/*
* Go to the previous week relative to the currently displayed week
*/
prevWeek : function() {
//minus more than 1 day to be sure we're in previous week - account for daylight savings or other anomolies
var newDate = new Date(this.element.data("startDate").getTime() - (MILLIS_IN_WEEK / 6));
this._clearCalendar();
this._loadCalEvents(newDate);
},
/*
* Go to the next week relative to the currently displayed week
*/
nextWeek : function() {
//add 8 days to be sure of being in prev week - allows for daylight savings or other anomolies
var newDate = new Date(this.element.data("startDate").getTime() + MILLIS_IN_WEEK + (MILLIS_IN_WEEK / 7));
this._clearCalendar();
this._loadCalEvents(newDate);
},
/*
* Reload the calendar to whatever week the date passed in falls on.
*/
gotoWeek : function(date) {
this._clearCalendar();
this._loadCalEvents(date);
},
/*
* Remove an event based on it's id
*/
removeEvent : function(eventId) {
var self = this;
self.element.find(".wc-cal-event").each(function() {
if ($(this).data("calEvent").id === eventId) {
$(this).remove();
return false;
}
});
//
//
//
// -------------------- COLOCAR ROTINA PARA REMOVER EVENTO DA BASE DE DADOS ------------------------
// eventId é o ID do evento
//
//
//
//this could be more efficient rather than running on all days regardless...
self.element.find(".wc-day-column-inner").each(function() {
self._adjustOverlappingEvents($(this));
});
},
/*
* Removes any events that have been added but not yet saved (have no id).
* This is useful to call after adding a freshly saved new event.
*/
removeUnsavedEvents : function() {
var self = this;
self.element.find(".wc-new-cal-event").each(function() {
$(this).remove();
});
//
//
//
// -------------------- QUANDO CLICA PARA ADD UM EVENTO E CLICA EM CANCELAR ------------------------
// quando o evento ainda não tem ID
//
//
//
//this could be more efficient rather than running on all days regardless...
self.element.find(".wc-day-column-inner").each(function() {
self._adjustOverlappingEvents($(this));
});
},
/*
* update an event in the calendar. If the event exists it refreshes
* it's rendering. If it's a new event that does not exist in the calendar
* it will be added.
*/
updateEvent : function (calEvent) {
this._updateEventInCalendar(calEvent);
//
//
//
// -------------------- QUANDO CLICA EM SALVAR NO EDITAR DE UM EVENTO ------------------------
// MAS NÃO TEM ID
//
//
//
//alert(calEvent);
},
/*
* Returns an array of timeslot start and end times based on
* the configured grid of the calendar. Returns in both date and
* formatted time based on the 'timeFormat' config option.
*/
getTimeslotTimes : function(date) {
var options = this.options;
var firstHourDisplayed = options.businessHours.limitDisplay ? options.businessHours.start : 0;
var startDate = new Date(date.getFullYear(), date.getMonth(), date.getDate(), firstHourDisplayed);
var times = []
var startMillis = startDate.getTime();
for (var i = 0; i < options.timeslotsPerDay; i++) {
var endMillis = startMillis + options.millisPerTimeslot;
times[i] = {
start: new Date(startMillis),
startFormatted: this._formatDate(new Date(startMillis), options.timeFormat),
end: new Date(endMillis),
endFormatted: this._formatDate(new Date(endMillis), options.timeFormat)
};
startMillis = endMillis;
}
return times;
},
formatDate : function(date, format) {
if (format) {
return this._formatDate(date, format);
} else {
return this._formatDate(date, this.options.dateFormat);
}
},
formatTime : function(date, format) {
if (format) {
return this._formatDate(date, format);
} else {
return this._formatDate(date, this.options.timeFormat);
}
},
getData : function(key) {
return this._getData(key);
},
/*********************
* private functions *
*********************/
// compute dynamic options based on other config values
_computeOptions : function() {
var options = this.options;
if (options.businessHours.limitDisplay) {
options.timeslotsPerDay = options.timeslotsPerHour * (options.businessHours.end - options.businessHours.start);
options.millisToDisplay = (options.businessHours.end - options.businessHours.start) * 60 * 60 * 1000;
options.millisPerTimeslot = options.millisToDisplay / options.timeslotsPerDay;
} else {
options.timeslotsPerDay = options.timeslotsPerHour * 24;
options.millisToDisplay = MILLIS_IN_DAY;
options.millisPerTimeslot = MILLIS_IN_DAY / options.timeslotsPerDay;
}
},
/*
* Resize the calendar scrollable height based on the provided function in options.
*/
_resizeCalendar : function () {
var options = this.options;
if (options && $.isFunction(options.height)) {
var calendarHeight = options.height(this.element);
var headerHeight = this.element.find(".wc-header").outerHeight();
var navHeight = this.element.find(".wc-nav").outerHeight();
this.element.find(".wc-scrollable-grid").height(calendarHeight - navHeight - headerHeight);
}
},
/*
* configure calendar interaction events that are able to use event
* delegation for greater efficiency
*/
_setupEventDelegation : function() {
var self = this;
var options = this.options;
this.element.click(function(event) {
var $target = $(event.target);
if ($target.data("preventClick")) {
return;
}
if ($target.hasClass("wc-cal-event")) {
options.eventClick($target.data("calEvent"), $target, event);
} else if ($target.parent().hasClass("wc-cal-event")) {
options.eventClick($target.parent().data("calEvent"), $target.parent(), event);
}
}).mouseover(function(event) {
var $target = $(event.target);
if (self._isDraggingOrResizing($target)) {
return;
}
if ($target.hasClass("wc-cal-event")) {
options.eventMouseover($target.data("calEvent"), $target, event);
}
}).mouseout(function(event) {
var $target = $(event.target);
if (self._isDraggingOrResizing($target)) {
return;
}
if ($target.hasClass("wc-cal-event")) {
if ($target.data("sizing")) return;
options.eventMouseout($target.data("calEvent"), $target, event);
}
});
},
/*
* check if a ui draggable or resizable is currently being dragged or resized
*/
_isDraggingOrResizing : function ($target) {
return $target.hasClass("ui-draggable-dragging") || $target.hasClass("ui-resizable-resizing");
},
/*
* Render the main calendar layout
*/
_renderCalendar : function() {
var $calendarContainer, calendarNavHtml, calendarHeaderHtml, calendarBodyHtml, $weekDayColumns;
var self = this;
var options = this.options;
$calendarContainer = $("<div class=\"wc-container\">").appendTo(self.element);
if (options.buttons) {
calendarNavHtml = "<div class=\"wc-nav\">\
<button class=\"wc-today\">" + options.buttonText.today + "</button>\
<button class=\"wc-prev\">" + options.buttonText.lastWeek + "</button>\
<button class=\"wc-next\">" + options.buttonText.nextWeek + "</button>\
</div>";
$(calendarNavHtml).appendTo($calendarContainer);
$calendarContainer.find(".wc-nav .wc-today").click(function() {
self.element.weekCalendar("today");
return false;
});
$calendarContainer.find(".wc-nav .wc-prev").click(function() {
self.element.weekCalendar("prevWeek");
return false;
});
$calendarContainer.find(".wc-nav .wc-next").click(function() {
self.element.weekCalendar("nextWeek");
return false;
});
}
//render calendar header
calendarHeaderHtml = "<table class=\"wc-header\"><tbody><tr><td class=\"wc-time-column-header\"></td>";
for (var i = 1; i <= options.daysToShow; i++) {
calendarHeaderHtml += "<td class=\"wc-day-column-header wc-day-" + i + "\"></td>";
}
calendarHeaderHtml += "<td class=\"wc-scrollbar-shim\"></td></tr></tbody></table>";
//render calendar body
calendarBodyHtml = "<div class=\"wc-scrollable-grid\">\
<table class=\"wc-time-slots\">\
<tbody>\
<tr>\
<td class=\"wc-grid-timeslot-header\"></td>\
<td colspan=\"" + options.daysToShow + "\">\
<div class=\"wc-time-slot-wrapper\">\
<div class=\"wc-time-slots\">";
var start = options.businessHours.limitDisplay ? options.businessHours.start : 0;
var end = options.businessHours.limitDisplay ? options.businessHours.end : 24;
for (var i = start; i < end; i++) {
for (var j = 0; j < options.timeslotsPerHour - 1; j++) {
calendarBodyHtml += "<div class=\"wc-time-slot\"></div>";
}
calendarBodyHtml += "<div class=\"wc-time-slot wc-hour-end\"></div>";
}
calendarBodyHtml += "</div></div></td></tr><tr><td class=\"wc-grid-timeslot-header\">";
for (var i = start; i < end; i++) {
var bhClass = (options.businessHours.start <= i && options.businessHours.end > i) ? "wc-business-hours" : "";
calendarBodyHtml += "<div class=\"wc-hour-header " + bhClass + "\">"
if (options.use24Hour) {
calendarBodyHtml += "<div class=\"wc-time-header-cell\">" + self._24HourForIndex(i) + "</div>";
} else {
calendarBodyHtml += "<div class=\"wc-time-header-cell\">" + self._hourForIndex(i) + "<span class=\"wc-am-pm\">" + self._amOrPm(i) + "</span></div>";
}
calendarBodyHtml += "</div>";
}
calendarBodyHtml += "</td>";
for (var i = 1; i <= options.daysToShow; i++) {
calendarBodyHtml += "<td class=\"wc-day-column day-" + i + "\"><div class=\"wc-day-column-inner\"></div></td>"
}
calendarBodyHtml += "</tr></tbody></table></div>";
//append all calendar parts to container
$(calendarHeaderHtml + calendarBodyHtml).appendTo($calendarContainer);
$weekDayColumns = $calendarContainer.find(".wc-day-column-inner");
$weekDayColumns.each(function(i, val) {
$(this).height(options.timeslotHeight * options.timeslotsPerDay);
if (!options.readonly) {
self._addDroppableToWeekDay($(this));
self._setupEventCreationForWeekDay($(this));
}
});
$calendarContainer.find(".wc-time-slot").height(options.timeslotHeight - 1); //account for border
$calendarContainer.find(".wc-time-header-cell").css({
height : (options.timeslotHeight * options.timeslotsPerHour) - 11,
padding: 5
});
},
/*
* setup mouse events for capturing new events
*/
_setupEventCreationForWeekDay : function($weekDay) {
var self = this;
var options = this.options;
$weekDay.mousedown(function(event) {
var $target = $(event.target);
if ($target.hasClass("wc-day-column-inner")) {
var $newEvent = $("<div class=\"wc-cal-event wc-new-cal-event wc-new-cal-event-creating\"></div>");
$newEvent.css({lineHeight: (options.timeslotHeight - 2) + "px", fontSize: (options.timeslotHeight / 2) + "px"});
$target.append($newEvent);
var columnOffset = $target.offset().top;
var clickY = event.pageY - columnOffset;
var clickYRounded = (clickY - (clickY % options.timeslotHeight)) / options.timeslotHeight;
var topPosition = clickYRounded * options.timeslotHeight;
$newEvent.css({top: topPosition});
$target.bind("mousemove.newevent", function(event) {
$newEvent.show();
$newEvent.addClass("ui-resizable-resizing");
var height = Math.round(event.pageY - columnOffset - topPosition);
var remainder = height % options.timeslotHeight;
//snap to closest timeslot
if (remainder < (height / 2)) {
var useHeight = height - remainder;
$newEvent.css("height", useHeight < options.timeslotHeight ? options.timeslotHeight : useHeight);
} else {
$newEvent.css("height", height + (options.timeslotHeight - remainder));
}
}).mouseup(function() {
$target.unbind("mousemove.newevent");
$newEvent.addClass("ui-corner-all");
});
}
}).mouseup(function(event) {
var $target = $(event.target);
var $weekDay = $target.closest(".wc-day-column-inner");
var $newEvent = $weekDay.find(".wc-new-cal-event-creating");
if ($newEvent.length) {
//if even created from a single click only, default height
if (!$newEvent.hasClass("ui-resizable-resizing")) {
$newEvent.css({height: options.timeslotHeight * options.defaultEventLength}).show();
}
var top = parseInt($newEvent.css("top"));
var eventDuration = self._getEventDurationFromPositionedEventElement($weekDay, $newEvent, top);
$newEvent.remove();
var newCalEvent = {start: eventDuration.start, end: eventDuration.end, title: options.newEventText};
var $renderedCalEvent = self._renderEvent(newCalEvent, $weekDay);
if (!options.allowCalEventOverlap) {
self._adjustForEventCollisions($weekDay, $renderedCalEvent, newCalEvent, newCalEvent);
self._positionEvent($weekDay, $renderedCalEvent);
} else {
self._adjustOverlappingEvents($weekDay);
}
options.eventNew(eventDuration, $renderedCalEvent);
}
});
},
/*
* load calendar events for the week based on the date provided
*/
_loadCalEvents : function(dateWithinWeek) {
var date, weekStartDate, endDate, $weekDayColumns;
var self = this;
var options = this.options;
date = dateWithinWeek || options.date;
weekStartDate = self._dateFirstDayOfWeek(date);
weekEndDate = self._dateLastMilliOfWeek(date);
options.calendarBeforeLoad(self.element);
self.element.data("startDate", weekStartDate);
self.element.data("endDate", weekEndDate);
$weekDayColumns = self.element.find(".wc-day-column-inner");
self._updateDayColumnHeader($weekDayColumns);
//load events by chosen means
if (typeof options.data == 'string') {
if (options.loading) options.loading(true);
var jsonOptions = {};
jsonOptions[options.startParam || 'start'] = Math.round(weekStartDate.getTime() / 1000);
jsonOptions[options.endParam || 'end'] = Math.round(weekEndDate.getTime() / 1000);
$.getJSON(options.data, jsonOptions, function(data) {
self._renderEvents(data, $weekDayColumns);
if (options.loading) options.loading(false);
});
}
else if ($.isFunction(options.data)) {
options.data(weekStartDate, weekEndDate,
function(data) {
self._renderEvents(data, $weekDayColumns);
});
}
else if (options.data) {
self._renderEvents(options.data, $weekDayColumns);
}
self._disableTextSelect($weekDayColumns);
},
/*
* update the display of each day column header based on the calendar week
*/
_updateDayColumnHeader : function ($weekDayColumns) {
var self = this;
var options = this.options;
var currentDay = self._cloneDate(self.element.data("startDate"));
self.element.find(".wc-header td.wc-day-column-header").each(function(i, val) {
var dayName = options.useShortDayNames ? options.shortDays[currentDay.getDay()] : options.longDays[currentDay.getDay()];
$(this).html(dayName + "<br/>" + self._formatDate(currentDay, options.dateFormat));
if (self._isToday(currentDay)) {
$(this).addClass("wc-today");
} else {
$(this).removeClass("wc-today");
}
currentDay = self._addDays(currentDay, 1);
});
currentDay = self._dateFirstDayOfWeek(self._cloneDate(self.element.data("startDate")));
$weekDayColumns.each(function(i, val) {
$(this).data("startDate", self._cloneDate(currentDay));
$(this).data("endDate", new Date(currentDay.getTime() + (MILLIS_IN_DAY)));
if (self._isToday(currentDay)) {
$(this).parent().addClass("wc-today");
} else {
$(this).parent().removeClass("wc-today");
}
currentDay = self._addDays(currentDay, 1);
});
},
/*
* Render the events into the calendar
*/
_renderEvents : function (events, $weekDayColumns) {
var self = this;
var options = this.options;
var eventsToRender;
if ($.isArray(events)) {
eventsToRender = self._cleanEvents(events);
} else if (events.events) {
eventsToRender = self._cleanEvents(events.events);
}
if (events.options) {
var updateLayout = false;
//update options
$.each(events.options, function(key, value) {
if (value !== options[key]) {
options[key] = value;
updateLayout = true;
}
});
self._computeOptions();
if (updateLayout) {
self.element.empty();
self._renderCalendar();
$weekDayColumns = self.element.find(".wc-time-slots .wc-day-column-inner");
self._updateDayColumnHeader($weekDayColumns);
self._resizeCalendar();
}
}
$.each(eventsToRender, function(i, calEvent) {
var $weekDay = self._findWeekDayForEvent(calEvent, $weekDayColumns);
if ($weekDay) {
self._renderEvent(calEvent, $weekDay);
}
});
$weekDayColumns.each(function() {
self._adjustOverlappingEvents($(this));
});
options.calendarAfterLoad(self.element);
if (!eventsToRender.length) {
options.noEvents();
}
},
/*
* Render a specific event into the day provided. Assumes correct
* day for calEvent date
*/
_renderEvent: function (calEvent, $weekDay) {
var self = this;
var options = this.options;
if (calEvent.start.getTime() > calEvent.end.getTime()) {
return; // can't render a negative height
}
var eventClass, eventHtml, $calEvent, $modifiedEvent;
eventClass = calEvent.id ? "wc-cal-event" : "wc-cal-event wc-new-cal-event";
eventHtml = "<div class=\"" + eventClass + " ui-corner-all\">\
<div class=\"wc-time ui-corner-all\"></div>\
<div class=\"wc-title\"></div></div>";
$calEvent = $(eventHtml);
$modifiedEvent = options.eventRender(calEvent, $calEvent);
$calEvent = $modifiedEvent ? $modifiedEvent.appendTo($weekDay) : $calEvent.appendTo($weekDay);
$calEvent.css({lineHeight: (options.timeslotHeight - 2) + "px", fontSize: (options.timeslotHeight / 2) + "px"});
self._refreshEventDetails(calEvent, $calEvent);
self._positionEvent($weekDay, $calEvent);
$calEvent.show();
if (!options.readonly && options.resizable(calEvent, $calEvent)) {
self._addResizableToCalEvent(calEvent, $calEvent, $weekDay)
}
if (!options.readonly && options.draggable(calEvent, $calEvent)) {
self._addDraggableToCalEvent(calEvent, $calEvent);
}
options.eventAfterRender(calEvent, $calEvent);
return $calEvent;
},
_adjustOverlappingEvents : function($weekDay) {
var self = this;
if (self.options.allowCalEventOverlap) {
var groupsList = self._groupOverlappingEventElements($weekDay);
$.each(groupsList, function() {
var curGroups = this;
$.each(curGroups, function(groupIndex) {
var curGroup = this;
// do we want events to be displayed as overlapping
if (self.options.overlapEventsSeparate) {
var newWidth = 100 / curGroups.length;
var newLeft = groupIndex * newWidth;
} else {
// TODO what happens when the group has more than 10 elements
var newWidth = 100 - ( (curGroups.length - 1) * 10 );
var newLeft = groupIndex * 10;
}
$.each(curGroup, function() {
// bring mouseovered event to the front
if (!self.options.overlapEventsSeparate) {
$(this).bind("mouseover.z-index", function() {
var $elem = $(this);
$.each(curGroup, function() {
$(this).css({"z-index": "1"});
});
$elem.css({"z-index": "3"});
});
}
$(this).css({width: newWidth + "%", left:newLeft + "%", right: 0});
});
});
});
}
},
/*
* Find groups of overlapping events
*/
_groupOverlappingEventElements : function($weekDay) {
var $events = $weekDay.find(".wc-cal-event:visible");
var sortedEvents = $events.sort(function(a, b) {
return $(a).data("calEvent").start.getTime() - $(b).data("calEvent").start.getTime();
});
var lastEndTime = new Date(0, 0, 0);
var groups = [];
var curGroups = [];
var $curEvent;
$.each(sortedEvents, function() {
$curEvent = $(this);
//checks, if the current group list is not empty, if the overlapping is finished
if (curGroups.length > 0) {
if (lastEndTime.getTime() <= $curEvent.data("calEvent").start.getTime()) {
//finishes the current group list by adding it to the resulting list of groups and cleans it
groups.push(curGroups);
curGroups = [];
}
}
//finds the first group to fill with the event
for (var groupIndex = 0; groupIndex < curGroups.length; groupIndex++) {
if (curGroups[groupIndex].length > 0) {
//checks if the event starts after the end of the last event of the group
if (curGroups[groupIndex][curGroups [groupIndex].length - 1].data("calEvent").end.getTime() <= $curEvent.data("calEvent").start.getTime()) {
curGroups[groupIndex].push($curEvent);
if (lastEndTime.getTime() < $curEvent.data("calEvent").end.getTime()) {
lastEndTime = $curEvent.data("calEvent").end;
}
return;
}
}
}
//if not found, creates a new group
curGroups.push([$curEvent]);
if (lastEndTime.getTime() < $curEvent.data("calEvent").end.getTime()) {
lastEndTime = $curEvent.data("calEvent").end;
}
});
//adds the last groups in result
if (curGroups.length > 0) {
groups.push(curGroups);
}
return groups;
},
/*
* find the weekday in the current calendar that the calEvent falls within
*/
_findWeekDayForEvent : function(calEvent, $weekDayColumns) {
var $weekDay;
$weekDayColumns.each(function() {
if ($(this).data("startDate").getTime() <= calEvent.start.getTime() && $(this).data("endDate").getTime() >= calEvent.end.getTime()) {
$weekDay = $(this);
return false;
}
});
return $weekDay;
},
/*
* update the events rendering in the calendar. Add if does not yet exist.
*/
_updateEventInCalendar : function (calEvent) {
var self = this;
var options = this.options;
self._cleanEvent(calEvent);
if (calEvent.id) {
self.element.find(".wc-cal-event").each(function() {
if ($(this).data("calEvent").id === calEvent.id || $(this).hasClass("wc-new-cal-event")) {
$(this).remove();
return false;
}
});
}
var $weekDay = self._findWeekDayForEvent(calEvent, self.element.find(".wc-time-slots .wc-day-column-inner"));
if ($weekDay) {
var $calEvent = self._renderEvent(calEvent, $weekDay);
self._adjustForEventCollisions($weekDay, $calEvent, calEvent, calEvent);
self._refreshEventDetails(calEvent, $calEvent);
self._positionEvent($weekDay, $calEvent);
self._adjustOverlappingEvents($weekDay);
//
//
//
// -------------------- AO CLICAR EM SALVAR DEPOIS DE DIGITAR O EVENTO ------------------------
//
//
//
//
//var teste = self.element.find("wc-day-column-inner").html;
//alert(teste);
}
},
/*
* Position the event element within the weekday based on it's start / end dates.
*/
_positionEvent : function($weekDay, $calEvent) {
var options = this.options;
var calEvent = $calEvent.data("calEvent");
var pxPerMillis = $weekDay.height() / options.millisToDisplay;
var firstHourDisplayed = options.businessHours.limitDisplay ? options.businessHours.start : 0;
var startMillis = calEvent.start.getTime() - new Date(calEvent.start.getFullYear(), calEvent.start.getMonth(), calEvent.start.getDate(), firstHourDisplayed).getTime();
var eventMillis = calEvent.end.getTime() - calEvent.start.getTime();
var pxTop = pxPerMillis * startMillis;
var pxHeight = pxPerMillis * eventMillis;
$calEvent.css({top: pxTop, height: pxHeight});
},
/*
* Determine the actual start and end times of a calevent based on it's
* relative position within the weekday column and the starting hour of the
* displayed calendar.
*/
_getEventDurationFromPositionedEventElement : function($weekDay, $calEvent, top) {
var options = this.options;
var startOffsetMillis = options.businessHours.limitDisplay ? options.businessHours.start * 60 * 60 * 1000 : 0;
var start = new Date($weekDay.data("startDate").getTime() + startOffsetMillis + Math.round(top / options.timeslotHeight) * options.millisPerTimeslot);
var end = new Date(start.getTime() + ($calEvent.height() / options.timeslotHeight) * options.millisPerTimeslot);
return {start: start, end: end};
},
/*
* If the calendar does not allow event overlap, adjust the start or end date if necessary to
* avoid overlapping of events. Typically, shortens the resized / dropped event to it's max possible
* duration based on the overlap. If no satisfactory adjustment can be made, the event is reverted to
* it's original location.
*/
_adjustForEventCollisions : function($weekDay, $calEvent, newCalEvent, oldCalEvent, maintainEventDuration) {
var options = this.options;
if (options.allowCalEventOverlap) {
return;
}
var adjustedStart, adjustedEnd;
var self = this;
$weekDay.find(".wc-cal-event").not($calEvent).each(function() {
var currentCalEvent = $(this).data("calEvent");
//has been dropped onto existing event overlapping the end time
if (newCalEvent.start.getTime() < currentCalEvent.end.getTime()
&& newCalEvent.end.getTime() >= currentCalEvent.end.getTime()) {
adjustedStart = currentCalEvent.end;
}
//has been dropped onto existing event overlapping the start time
if (newCalEvent.end.getTime() > currentCalEvent.start.getTime()
&& newCalEvent.start.getTime() <= currentCalEvent.start.getTime()) {
adjustedEnd = currentCalEvent.start;
}
//has been dropped inside existing event with same or larger duration
if (! oldCalEvent.resizable || (newCalEvent.end.getTime() <= currentCalEvent.end.getTime()
&& newCalEvent.start.getTime() >= currentCalEvent.start.getTime())) {
adjustedStart = oldCalEvent.start;
adjustedEnd = oldCalEvent.end;
return false;
}
});
//alert('Start: '+adjustedStart.start+' End: '+adjustedEnd.end);
newCalEvent.start = adjustedStart || newCalEvent.start;
if (adjustedStart && maintainEventDuration) {
newCalEvent.end = new Date(adjustedStart.getTime() + (oldCalEvent.end.getTime() - oldCalEvent.start.getTime()));
self._adjustForEventCollisions($weekDay, $calEvent, newCalEvent, oldCalEvent);
} else {
newCalEvent.end = adjustedEnd || newCalEvent.end;
}
//reset if new cal event has been forced to zero size
if (newCalEvent.start.getTime() >= newCalEvent.end.getTime()) {
newCalEvent.start = oldCalEvent.start;
newCalEvent.end = oldCalEvent.end;
}
$calEvent.data("calEvent", newCalEvent);
//alert('Start: '+adjustedStart.start+' End: '+adjustedEnd.end);
},
/*
* Add draggable capabilities to an event
*/
_addDraggableToCalEvent : function(calEvent, $calEvent) {
var self = this;
var options = this.options;
var $weekDay = self._findWeekDayForEvent(calEvent, self.element.find(".wc-time-slots .wc-day-column-inner"));
$calEvent.draggable({
handle : ".wc-time",
containment: ".wc-scrollable-grid",
revert: 'valid',
opacity: 0.5,
grid : [$calEvent.outerWidth() + 1, options.timeslotHeight ],
start : function(event, ui) {
var $calEvent = ui.draggable;
options.eventDrag(calEvent, $calEvent);
}
});
},
/*
* Add droppable capabilites to weekdays to allow dropping of calEvents only
*/
_addDroppableToWeekDay : function($weekDay) {
var self = this;
var options = this.options;
$weekDay.droppable({
accept: ".wc-cal-event",
drop: function(event, ui) {
var $calEvent = ui.draggable;
var top = Math.round(parseInt(ui.position.top));
var eventDuration = self._getEventDurationFromPositionedEventElement($weekDay, $calEvent, top);
var calEvent = $calEvent.data("calEvent");
var newCalEvent = $.extend(true, {start: eventDuration.start, end: eventDuration.end}, calEvent);
self._adjustForEventCollisions($weekDay, $calEvent, newCalEvent, calEvent, true);
var $weekDayColumns = self.element.find(".wc-day-column-inner");
var $newEvent = self._renderEvent(newCalEvent, self._findWeekDayForEvent(newCalEvent, $weekDayColumns));
$calEvent.hide();
//alert('Start: '+eventDuration.start+' End: '+eventDuration.end);
//trigger drop callback
options.eventDrop(newCalEvent, calEvent, $newEvent);
$calEvent.data("preventClick", true);
var $weekDayOld = self._findWeekDayForEvent($calEvent.data("calEvent"), self.element.find(".wc-time-slots .wc-day-column-inner"));
if ($weekDayOld.data("startDate") != $weekDay.data("startDate")) {
self._adjustOverlappingEvents($weekDayOld);
}
self._adjustOverlappingEvents($weekDay);
setTimeout(function() {
$calEvent.remove();
}, 1000);
}
});
},
/*
* Add resizable capabilities to a calEvent
*/
_addResizableToCalEvent : function(calEvent, $calEvent, $weekDay) {
var self = this;
var options = this.options;
$calEvent.resizable({
grid: options.timeslotHeight,
containment : $weekDay,
handles: "s",
minHeight: options.timeslotHeight,
stop :function(event, ui) {
var $calEvent = ui.element;
var newEnd = new Date($calEvent.data("calEvent").start.getTime() + ($calEvent.height() / options.timeslotHeight) * options.millisPerTimeslot);
var newCalEvent = $.extend(true, {start: calEvent.start, end: newEnd}, calEvent);
self._adjustForEventCollisions($weekDay, $calEvent, newCalEvent, calEvent);
self._refreshEventDetails(newCalEvent, $calEvent);
self._positionEvent($weekDay, $calEvent);
self._adjustOverlappingEvents($weekDay);
//trigger resize callback
options.eventResize(newCalEvent, calEvent, $calEvent);
$calEvent.data("preventClick", true);
setTimeout(function() {
$calEvent.removeData("preventClick");
}, 500);
}
});
},
/*
* Refresh the displayed details of a calEvent in the calendar
*/
_refreshEventDetails : function(calEvent, $calEvent) {
var self = this;
var options = this.options;
$calEvent.find(".wc-time").html(self._formatDate(calEvent.start, options.timeFormat) + options.timeSeparator + self._formatDate(calEvent.end, options.timeFormat));
$calEvent.find(".wc-title").html(calEvent.title);
$calEvent.data("calEvent", calEvent);
},
/*
* Clear all cal events from the calendar
*/
_clearCalendar : function() {
this.element.find(".wc-day-column-inner div").remove();
},
/*
* Scroll the calendar to a specific hour
*/
_scrollToHour : function(hour) {
var self = this;
var options = this.options;
var $scrollable = this.element.find(".wc-scrollable-grid");
var slot = hour;
if (self.options.businessHours.limitDisplay) {
if (hour <= self.options.businessHours.start) {
slot = 0;
} else if (hour > self.options.businessHours.end) {
slot = self.options.businessHours.end -
self.options.businessHours.start - 1;
} else {
slot = hour - self.options.businessHours.start;
}
}
var $target = this.element.find(".wc-grid-timeslot-header .wc-hour-header:eq(" + slot + ")");
$scrollable.animate({scrollTop: 0}, 0, function() {
var targetOffset = $target.offset().top;
var scroll = targetOffset - $scrollable.offset().top - $target.outerHeight();
$scrollable.animate({scrollTop: scroll}, options.scrollToHourMillis);
});
},
/*
* find the hour (12 hour day) for a given hour index
*/
_hourForIndex : function(index) {
if (index === 0) { //midnight
return 12;
} else if (index < 13) { //am
return index;
} else { //pm
return index - 12;
}
},
_24HourForIndex : function(index) {
if (index === 0) { //midnight
return "00:00";
} else if (index < 10) {
return "0" + index + ":00";
} else {
return index + ":00";
}
},
_amOrPm : function (hourOfDay) {
return hourOfDay < 12 ? "AM" : "PM";
},
_isToday : function(date) {
var clonedDate = this._cloneDate(date);
this._clearTime(clonedDate);
var today = new Date();
this._clearTime(today);
return today.getTime() === clonedDate.getTime();
},
/*
* Clean events to ensure correct format
*/
_cleanEvents : function(events) {
var self = this;
$.each(events, function(i, event) {
self._cleanEvent(event);
});
//alert(start + ' ' + end);
return events;
},
/*
* Clean specific event
*/
_cleanEvent : function (event) {
if (event.date) {
event.start = event.date;
}
event.start = this._cleanDate(event.start);
event.end = this._cleanDate(event.end);
if (!event.end) {
event.end = this._addDays(this._cloneDate(event.start), 1);
}
},
/*
* Disable text selection of the elements in different browsers
*/
_disableTextSelect : function($elements) {
$elements.each(function() {
if ($.browser.mozilla) {//Firefox
$(this).css('MozUserSelect', 'none');
} else if ($.browser.msie) {//IE
$(this).bind('selectstart', function() {
return false;
});
} else {//Opera, etc.
$(this).mousedown(function() {
return false;
});
}
});
},
/*
* returns the date on the first millisecond of the week
*/
_dateFirstDayOfWeek : function(date) {
var self = this;
var midnightCurrentDate = new Date(date.getFullYear(), date.getMonth(), date.getDate());
var millisToSubtract = self._getAdjustedDayIndex(midnightCurrentDate) * 86400000;
return new Date(midnightCurrentDate.getTime() - millisToSubtract);
},
/*
* returns the date on the first millisecond of the last day of the week
*/
_dateLastDayOfWeek : function(date) {
var self = this;
var midnightCurrentDate = new Date(date.getFullYear(), date.getMonth(), date.getDate());
var millisToAdd = (6 - self._getAdjustedDayIndex(midnightCurrentDate)) * MILLIS_IN_DAY;
return new Date(midnightCurrentDate.getTime() + millisToAdd);
},
/*
* gets the index of the current day adjusted based on options
*/
_getAdjustedDayIndex : function(date) {
var midnightCurrentDate = new Date(date.getFullYear(), date.getMonth(), date.getDate());
var currentDayOfStandardWeek = midnightCurrentDate.getDay();
var days = [0,1,2,3,4,5,6];
this._rotate(days, this.options.firstDayOfWeek);
return days[currentDayOfStandardWeek];
},
/*
* returns the date on the last millisecond of the week
*/
_dateLastMilliOfWeek : function(date) {
var lastDayOfWeek = this._dateLastDayOfWeek(date);
return new Date(lastDayOfWeek.getTime() + (MILLIS_IN_DAY));
},
/*
* Clear the time components of a date leaving the date
* of the first milli of day
*/
_clearTime : function(d) {
d.setHours(0);
d.setMinutes(0);
d.setSeconds(0);
d.setMilliseconds(0);
return d;
},
/*
* add specific number of days to date
*/
_addDays : function(d, n, keepTime) {
d.setDate(d.getDate() + n);
if (keepTime) {
return d;
}
return this._clearTime(d);
},
/*
* Rotate an array by specified number of places.
*/
_rotate : function(a /*array*/, p /* integer, positive integer rotate to the right, negative to the left... */) {
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)) {
for (i = l; i > p; x = a[--i],a[i] = a[i - p],a[i - p] = x);
}
return a;
},
_cloneDate : function(d) {
return new Date(d.getTime());
},
/*
* return a date for different representations
*/
_cleanDate : function(d) {
if (typeof d == 'string') {
return $.weekCalendar.parseISO8601(d, true) || Date.parse(d) || new Date(parseInt(d));
}
if (typeof d == 'number') {
return new Date(d);
}
return d;
},
/*
* date formatting is adapted from
* [http://jacwright.com/projects/javascript/date_format](http://jacwright.com/projects/javascript/date_format)
*/
_formatDate : function(date, format) {
var options = this.options;
var returnStr = '';
for (var i = 0; i < format.length; i++) {
var curChar = format.charAt(i);
if ($.isFunction(this._replaceChars[curChar])) {
returnStr += this._replaceChars[curChar](date, options);
} else {
returnStr += curChar;
}
}
return returnStr;
},
_replaceChars : {
// Day
d: function(date) {
return (date.getDate() < 10 ? '0' : '') + date.getDate();
},
D: function(date, options) {
return options.shortDays[date.getDay()];
},
j: function(date) {
return date.getDate();
},
l: function(date, options) {
return options.longDays[date.getDay()];
},
N: function(date) {
return date.getDay() + 1;
},
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')));
},
w: function(date) {
return date.getDay();
},
z: function(date) {
return "Not Yet Supported";
},
// Week
W: function(date) {
return "Not Yet Supported";
},
// Month
F: function(date, options) {
return options.longMonths[date.getMonth()];
},
m: function(date) {
return (date.getMonth() < 9 ? '0' : '') + (date.getMonth() + 1);
},
M: function(date, options) {
return options.shortMonths[date.getMonth()];
},
n: function(date) {
return date.getMonth() + 1;
},
t: function(date) {
return "Not Yet Supported";
},
// Year
L: function(date) {
return "Not Yet Supported";
},
o: function(date) {
return "Not Supported";
},
Y: function(date) {
return date.getFullYear();
},
y: function(date) {
return ('' + date.getFullYear()).substr(2);
},
// Time
a: function(date) {
return date.getHours() < 12 ? 'am' : 'pm';
},
A: function(date) {
return date.getHours() < 12 ? 'AM' : 'PM';
},
B: function(date) {
return "Not Yet Supported";
},
g: function(date) {
return date.getHours() % 12 || 12;
},
G: function(date) {
return date.getHours();
},
h: function(date) {
return ((date.getHours() % 12 || 12) < 10 ? '0' : '') + (date.getHours() % 12 || 12);
},
H: function(date) {
return (date.getHours() < 10 ? '0' : '') + date.getHours();
},
i: function(date) {
return (date.getMinutes() < 10 ? '0' : '') + date.getMinutes();
},
s: function(date) {
return (date.getSeconds() < 10 ? '0' : '') + date.getSeconds();
},
// Timezone
e: function(date) {
return "Not Yet Supported";
},
I: function(date) {
return "Not Supported";
},
O: function(date) {
return (date.getTimezoneOffset() < 0 ? '-' : '+') + (date.getTimezoneOffset() / 60 < 10 ? '0' : '') + (date.getTimezoneOffset() / 60) + '00';
},
T: function(date) {
return "Not Yet Supported";
},
Z: function(date) {
return date.getTimezoneOffset() * 60;
},
// Full Date/Time
c: function(date) {
return "Not Yet Supported";
},
r: function(date) {
return date.toString();
},
U: function(date) {
return date.getTime() / 1000;
}
}
});
$.extend($.ui.weekCalendar, {
version: '1.2.2-pre',
getter: ['getTimeslotTimes', 'getData', 'formatDate', 'formatTime'],
defaults: {
date: new Date(),
timeFormat : "H:i",
dateFormat : "d M, Y",
use24Hour : true,
daysToShow : 7,
firstDayOfWeek : 0, // 0 = Sunday, 1 = Monday, 2 = Tuesday, ... , 6 = Saturday
useShortDayNames: false, // Nome pequeno do dia
timeSeparator : " até ",
startParam : "Inicio",
endParam : "Fim",
businessHours : {start: 8, end: 24, limitDisplay : false},
newEventText : "Novo Evento",
timeslotHeight: 18,
defaultEventLength : 2,
timeslotsPerHour : 2,
buttons : true,
buttonText : {
today : "Hoje",
lastWeek : " < ",
nextWeek : " > "
},
scrollToHourMillis : 500,
allowCalEventOverlap : false,
overlapEventsSeparate: false,
readonly: false, // permite arrastar
draggable : function(calEvent, element) {
return true;
},
resizable : function(calEvent, element) {
return true;
},
eventClick : function() {
},
eventRender : function(calEvent, element) {
return element;
},
eventAfterRender : function(calEvent, element) {
return element;
},
eventDrag : function(calEvent, element) {
},
eventDrop : function(calEvent, element) {
},
eventResize : function(calEvent, element) {
},
eventNew : function(calEvent, element) {
},
eventMouseover : function(calEvent, $event) {
},
eventMouseout : function(calEvent, $event) {
},
calendarBeforeLoad : function(calendar) {
},
calendarAfterLoad : function(calendar) {
},
noEvents : function() {
},
shortMonths : ['Jan', 'Fev', 'Mar', 'Abr', 'Mai', 'Jun', 'Jul', 'Ago', 'Set', 'Out', 'Nov', 'Dez'],
longMonths : ['Janeiro', 'Fevereiro', 'Março', 'Abril', 'Maio', 'Junho', 'Julho', 'Agosto', 'Setembro', 'Outubro', 'Novembro', 'Dezembro'],
shortDays : ['Dom', 'Seg', 'Ter', 'Qua', 'Qui', 'Sex', 'Sab'],
longDays : ['Domingo', 'Segunda', 'Terça', 'Quarta', 'Quinta', 'Sexta', 'Sabado']
}
});
var MILLIS_IN_DAY = 86400000;
var MILLIS_IN_WEEK = MILLIS_IN_DAY * 7;
$.weekCalendar = function() {
return {
parseISO8601 : function(s, ignoreTimezone) {
// derived from [http://delete.me.uk/2005/03/iso8601.html](http://delete.me.uk/2005/03/iso8601.html)
var regexp = "([0-9]{4})(-([0-9]{2})(-([0-9]{2})" +
"(T([0-9]{2}):([0-9]{2})(:([0-9]{2})(\.([0-9]+))?)?" +
"(Z|(([-+])([0-9]{2}):([0-9]{2})))?)?)?)?";
var d = s.match(new RegExp(regexp));
if (!d) return null;
var offset = 0;
var date = new Date(d[1], 0, 1);
if (d[3]) {
date.setMonth(d[3] - 1);
}
if (d[5]) {
date.setDate(d[5]);
}
if (d[7]) {
date.setHours(d[7]);
}
if (d[8]) {
date.setMinutes(d[8]);
}
if (d[10]) {
date.setSeconds(d[10]);
}
if (d[12]) {
date.setMilliseconds(Number("0." + d[12]) * 1000);
}
if (!ignoreTimezone) {
if (d[14]) {
offset = (Number(d[16]) * 60) + Number(d[17]);
offset *= ((d[15] == '-') ? 1 : -1);
}
offset -= date.getTimezoneOffset();
}
return new Date(Number(date) + (offset * 60 * 1000));
}
};
}();
})(jQuery);
calendar.js
function ajaxInit() {
var req;
try {
req = new ActiveXObject("Microsoft.XMLHTTP");
} catch(e) {
try {
req = new ActiveXObject("Msxml2.XMLHTTP");
} catch(ex) {
try {
req = new XMLHttpRequest();
} catch(exc) {
alert("Esse browser não suporta Ajax");
req = null;
}
}
}
return req;
}
$(document).ready(function() {
var $calendar = $('#calendar');
var id = 10;
$calendar.weekCalendar({
timeslotsPerHour : 2,
allowCalEventOverlap : true,
overlapEventsSeparate: true,
firstDayOfWeek : 1,
businessHours :{start: 8, end: 24, limitDisplay: true },
daysToShow : 7,
height : function($calendar) {
return $(window).height() - $("h1").outerHeight() - 1;
},
eventRender : function(calEvent, $event) {
if (calEvent.end.getTime() < new Date().getTime()) {
$event.css("backgroundColor", "#aaa");
$event.find(".wc-time").css({
"backgroundColor" : "#999",
"border" : "1px solid #888"
});
}
},
draggable : function(calEvent, $event) {
return calEvent.readOnly != true;
},
resizable : function(calEvent, $event) {
return calEvent.readOnly != true;
},
eventNew : function(calEvent, $event) {
var $dialogContent = $("#event_edit_container");
resetForm($dialogContent);
var startField = $dialogContent.find("select[name='start']").val(calEvent.start);
var endField = $dialogContent.find("select[name='end']").val(calEvent.end);
var titleField = $dialogContent.find("input[name='title']");
var chField = $dialogContent.find("input[name='ch']");
var idcursoField = $dialogContent.find("input[name='idcurso']");
var bodyField = $dialogContent.find("textarea[name='body']");
//
//
//
// -------------------- AO CLICAR NO CAMPO PARA DIGITAR NOVO EVENTO ------------------------
//
//
//
//
$dialogContent.dialog({
modal: true,
title: "Cadastrar Novo Evento",
close: function() {
$dialogContent.dialog("destroy");
$dialogContent.hide();
$('#calendar').weekCalendar("removeUnsavedEvents");
},
buttons: {
save : function() {
calEvent.id = id;
id++;
// ------------------------------ PEGA OS DADOS DO EVENTO ---------------------------------
DataInicioEvento = new Date(startField.val());
DiaEvento = DataInicioEvento.getDate();
if (DiaEvento.toString().length == 1)
DiaEvento = "0"+DiaEvento;
MesEvento = DataInicioEvento.getMonth()+1;
if (MesEvento.toString().length == 1)
MesEvento = "0"+MesEvento;
AnoEvento = DataInicioEvento.getFullYear();
DataEventoAtual = DiaEvento+"/"+MesEvento+"/"+AnoEvento;
HoraEventoInicio = DataInicioEvento.getHours();
if (HoraEventoInicio.toString().length == 1)
HoraEventoInicio = "0"+HoraEventoInicio
MinutoEventoInicio = DataInicioEvento.getMinutes();
if (MinutoEventoInicio.toString().length == 1)
MinutoEventoInicio = MinutoEventoInicio+"0"
HoraInicial = HoraEventoInicio + ':' + MinutoEventoInicio
DataFimEvento = new Date(endField.val());
HoraEventoFim = DataFimEvento.getHours();
if (HoraEventoFim.toString().length == 1)
HoraEventoFim = "0"+HoraEventoFim
MinutoEventoFim = DataFimEvento.getMinutes();
if (MinutoEventoFim.toString().length == 1)
MinutoEventoFim = MinutoEventoFim+"0"
HoraFinal = HoraEventoFim + ':' + MinutoEventoFim
TituloEvento = titleField.val();
ChEvento = chField.val();
IdCurso = idcursoField.val();
DescricaoEvento = bodyField.val();
//alert('Data Evento: ' + DataEventoAtual + ' Hora Inicial: ' + HoraInicial + ' Hora Final: ' + HoraFinal + '\n' + 'Titulo: ' + TituloEvento + '\n' + 'Descrição Evento: ' + DescricaoEvento);
//IdCurso = document.getElementById('IdCurso').value;
//alert('IdCurso: ' + IdCurso);
ajax = ajaxInit();
ajax.open("GET", "cursos-lista-detalhes-aulas-cad.asp?IdCurso="+IdCurso+"&DataEvento="+DataEventoAtual+"&HoraInicial="+HoraInicial+"&HoraFinal="+HoraFinal+"&TituloEvento="+TituloEvento+"&DescricaoEvento="+DescricaoEvento+"&Ch="+ChEvento,true);
ajax.onreadystatechange=function() {
if (ajax.readyState==4){
}
}
ajax.setRequestHeader("Pragma", "no-cache");
ajax.send(null);
// ------------------------------ PEGA OS DADOS DO EVENTO ---------------------------------
calEvent.start = new Date(startField.val());
calEvent.end = new Date(endField.val());
calEvent.title = titleField.val();
calEvent.ch = chField.val();
calEvent.idcurso = idcursoField.val();
calEvent.body = bodyField.val();
$calendar.weekCalendar("removeUnsavedEvents"); // pega a função que cancela o evento que ainda não tem ID
$calendar.weekCalendar("updateEvent", calEvent);
$dialogContent.dialog("close");
},
cancel : function() {
$dialogContent.dialog("close");
}
}
}).show();
$dialogContent.find(".date_holder").text($calendar.weekCalendar("formatDate", calEvent.start));
setupStartAndEndTimeFields(startField, endField, calEvent, $calendar.weekCalendar("getTimeslotTimes", calEvent.start));
},
eventDrop : function(calEvent, $event) {
},
eventResize : function(calEvent, $event) {
},
eventClick : function(calEvent, $event) {
if (calEvent.readOnly) {
return;
}
var $dialogContent = $("#event_edit_container");
resetForm($dialogContent);
var startField = $dialogContent.find("select[name='start']").val(calEvent.start);
var endField = $dialogContent.find("select[name='end']").val(calEvent.end);
var titleField = $dialogContent.find("input[name='title']").val(calEvent.title);
var chField = $dialogContent.find("input[name='ch']").val(calEvent.ch);
var idcursoField = $dialogContent.find("input[name='idcurso']").val(calEvent.idcurso);
var bodyField = $dialogContent.find("textarea[name='body']");
bodyField.val(calEvent.body);
// ---- AO CLICAR NO CAMPO PARA EDITAR EVENTO ------
$dialogContent.dialog({
modal: true,
title: "Editar - " + calEvent.title,
close: function() {
$dialogContent.dialog("destroy");
$dialogContent.hide();
$('#calendar').weekCalendar("removeUnsavedEvents");
},
buttons: {
save : function() {
// ------------------------------ PEGA OS DADOS DO EVENTO ---------------------------------
DataInicioEvento = new Date(startField.val());
DiaEvento = DataInicioEvento.getDate();
if (DiaEvento.toString().length == 1)
DiaEvento = "0"+DiaEvento;
MesEvento = DataInicioEvento.getMonth()+1;
if (MesEvento.toString().length == 1)
MesEvento = "0"+MesEvento;
AnoEvento = DataInicioEvento.getFullYear();
DataEventoAtual = DiaEvento+"/"+MesEvento+"/"+AnoEvento;
HoraEventoInicio = DataInicioEvento.getHours();
if (HoraEventoInicio.toString().length == 1)
HoraEventoInicio = "0"+HoraEventoInicio
MinutoEventoInicio = DataInicioEvento.getMinutes();
if (MinutoEventoInicio.toString().length == 1)
MinutoEventoInicio = MinutoEventoInicio+"0"
HoraInicial = HoraEventoInicio + ':' + MinutoEventoInicio
DataFimEvento = new Date(endField.val());
HoraEventoFim = DataFimEvento.getHours();
if (HoraEventoFim.toString().length == 1)
HoraEventoFim = "0"+HoraEventoFim
MinutoEventoFim = DataFimEvento.getMinutes();
if (MinutoEventoFim.toString().length == 1)
MinutoEventoFim = MinutoEventoFim+"0"
HoraFinal = HoraEventoFim + ':' + MinutoEventoFim
TituloEvento = titleField.val();
ChEvento = chField.val();
DescricaoEvento = bodyField.val();
IdCurso = idcursoField.val();
//alert('Data Evento: ' + DataEventoAtual + ' Hora Inicial: ' + HoraInicial + ' Hora Final: ' + HoraFinal + '\n' + 'Titulo: ' + TituloEvento + '\n' + 'Descrição Evento: ' + DescricaoEvento);
//IdCurso = document.getElementById('IdCurso').value;
ajax = ajaxInit();
ajax.open("GET", "cursos-lista-detalhes-aulas-cad.asp?IdCurso="+IdCurso+"&DataEvento="+DataEventoAtual+"&HoraInicial="+HoraInicial+"&HoraFinal="+HoraFinal+"&TituloEvento="+TituloEvento+"&DescricaoEvento="+DescricaoEvento+"&Ch="+ChEvento,true);
ajax.onreadystatechange=function() {
if (ajax.readyState==4){
}
}
ajax.setRequestHeader("Pragma", "no-cache");
ajax.send(null);
// ------------------------------ PEGA OS DADOS DO EVENTO ---------------------------------
calEvent.start = new Date(startField.val());
calEvent.end = new Date(endField.val());
calEvent.title = titleField.val();
calEvent.ch = chField.val();
calEvent.idcurso = idcursoField.val();
calEvent.body = bodyField.val();
$calendar.weekCalendar("updateEvent", calEvent);
$dialogContent.dialog("close");
},
"delete" : function() {
$calendar.weekCalendar("removeEvent", calEvent.id);
$dialogContent.dialog("close");
},
cancel : function() {
$dialogContent.dialog("close");
}
}
}).show();
var startField = $dialogContent.find("select[name='start']").val(calEvent.start);
var endField = $dialogContent.find("select[name='end']").val(calEvent.end);
$dialogContent.find(".date_holder").text($calendar.weekCalendar("formatDate", calEvent.start));
setupStartAndEndTimeFields(startField, endField, calEvent, $calendar.weekCalendar("getTimeslotTimes", calEvent.start));
$(window).resize().resize(); //fixes a bug in modal overlay size ??
//alert('teste '+startField);
},
eventMouseover : function(calEvent, $event) {
},
eventMouseout : function(calEvent, $event) {
},
noEvents : function() {
},
data : function(start, end, callback) {
callback(getEventData());
}
});
//alert('teste '+startField);
function resetForm($dialogContent) {
$dialogContent.find("input").val("");
$dialogContent.find("textarea").val("");
}
/*
* Sets up the start and end time fields in the calendar event
* form for editing based on the calendar event being edited
*/
function setupStartAndEndTimeFields($startTimeField, $endTimeField, calEvent, timeslotTimes) {
for (var i = 0; i < timeslotTimes.length; i++) {
var startTime = timeslotTimes[i].start;
var endTime = timeslotTimes[i].end;
var startSelected = "";
if (startTime.getTime() === calEvent.start.getTime()) {
startSelected = "selected=\"selected\"";
}
var endSelected = "";
if (endTime.getTime() === calEvent.end.getTime()) {
endSelected = "selected=\"selected\"";
}
$startTimeField.append("<option value=\"" + startTime + "\" " + startSelected + ">" + timeslotTimes[i].startFormatted + "</option>");
$endTimeField.append("<option value=\"" + endTime + "\" " + endSelected + ">" + timeslotTimes[i].endFormatted + "</option>");
}
$endTimeOptions = $endTimeField.find("option");
$startTimeField.trigger("change");
}
var $endTimeField = $("select[name='end']");
var $endTimeOptions = $endTimeField.find("option");
//reduces the end time options to be only after the start time options.
$("select[name='start']").change(function() {
var startTime = $(this).find(":selected").val();
var currentEndTime = $endTimeField.find("option:selected").val();
$endTimeField.html(
$endTimeOptions.filter(function() {
return startTime < $(this).val();
})
);
var endTimeSelected = false;
$endTimeField.find("option").each(function() {
if ($(this).val() === currentEndTime) {
$(this).attr("selected", "selected");
endTimeSelected = true;
return false;
}
});
if (!endTimeSelected) {
//automatically select an end date 2 slots away.
$endTimeField.find("option:eq(1)").attr("selected", "selected");
}
});
var $about = $("#about");
$("#about_button").click(function() {
$about.dialog({
title: "About this calendar demo",
width: 600,
close: function() {
$about.dialog("destroy");
$about.hide();
},
buttons: {
close : function() {
$about.dialog("close");
}
}
}).show();
});
});
Abs,
Discussão (6)
Carregando comentários...