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'></script>
<script type='text/javascript' src='http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/jquery-ui.min.js'></script>
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' /> <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 */ _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', '---', 'Sab'], longDays : ['Domingo', 'Segunda', 'Terça', 'Quarta', 'Quinta', '---ta', '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 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,