Kalendarz Google w jQuery cz. 1
JavaScript, SQL 25 stycznia 2010Chcąc stworzyć funkcjonalny kalendarz, należy popatrzeć jak robią to mistrzowie w dziedzinie użyteczności i ilości użytkowników korzystających z ich produktów – mianowicie Google. Mowa tutaj o w pełni funkcjonalnym i bardzo użytko-przyjaznym narzędziu jakim jest Kalendarz giganta z Mountain View. Mnie obecnie była potrzeba tylko funkcjonalność całego tygodnia. Zacząłem wertować stronice internetu i w końcu trafiłem na kilka pozycji które mnie zaciekawiły. Pierwszym było rozwiązanie proponowane przez dhtmlx a mianowicie – dhtmlxScheduler, jednak lekko przeraziło mnie API jak i sam ciężar tej aplikacji, nie chciałem jakiegoś monstrum tylko coś lekkiego. Po kliku chwilach znalazłem coś co okazało się naprawdę fajne, był to strzał w dziesiątkę. Znalazłem aplikacje napisaną w jQuery a mianowicie jQuery Week Calendar. Po krótszym przyglądnięciu się postanowiłem że to będzie to, rozbuduje dodam dynamiczną obsługę zdarzeń i będzie hulać. W pierwszej części tego poradnika pokaże podstawowe rzeczy związane z właśnie tą aplikacją.
Na stronie: http://www.redredred.com.au/projects/jquery-week-calendar/, mamy w pełni opisane API, więc w razie wątpliwości odsyłam właśnie do tej strony, są tam opisane wszystkie metody jakimi dysponuje ta biblioteka. Do prawidłowego posługiwania się ta biblioteką jest potrzeba podstawowa znajomość frameworka jQuery, jeśli jej nie posiadasz odsyłam do dokumentacji jQuery.
1. Wprowadzenie
Na samym początku musimy wyświetlić nasz kalendarz. Do poprawnego generowania kalendarza będa nam potrzebne m. in.:
- jQuery w wersji większej niż 1.3.2
- jQuery UI
- oczywiście plik z samą biblioteką kalendarza czyli jQuery Week Calendar
- dodatkowo możemy potrzebować plików ze stylami zarówno do UI jak i kalendarza UI CSS
Teraz w sekcji <head> dodajemy wszytstkie biblioteki:
| HTML | | copy code | | ? |
<link rel='stylesheet' type='text/css' href='http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/themes/smoothness/jquery-ui.css' /> |
<link rel='stylesheet' type='text/css' href='jquery.weekcalendar.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='jquery.weekcalendar.js'></script> |
W ciele naszego strony umieszczamy kontener:
| HTML | | copy code | | ? |
<div id='calendar'></div> |
to właśnie w nim będzie wyświetlany nasz kalendarz.
2. Generujemy kalendarz
„Serce” naszego kalendarza to ta jedna linijka $('#calendar').weekCalendar. To właśnie do tej funkcji będziemy dopisywać kolejne metody i personalizować nasz kalendarz. Standardowe uruchomienie:
| Javascript | | copy code | | ? |
| 01 | <script type='text/javascript'> |
| 02 | var year = new Date().getFullYear(); |
| 03 | var month = new Date().getMonth(); |
| 04 | var day = new Date().getDate(); |
| 05 | var eventData = { |
| 06 | events : [ |
| 07 | {"id":1, "start": new Date(year, month, day, 12), "end": new Date(year, month, day, 13, 35),"title":"Zdarzenie jeden"}, |
| 08 | {"id":2, "start": new Date(year, month, day, 14), "end": new Date(year, month, day, 14, 45),"title":"Kolokwium z algebry"}, |
| 09 | {"id":3, "start": new Date(year, month, day + 1, 18), "end": new Date(year, month, day + 1, 18, 45),"title":"Impreza u Kuby"}, |
| 10 | {"id":4, "start": new Date(year, month, day - 1, 8), "end": new Date(year, month, day - 1, 9, 30),"title":"Narty z kolegami"}, |
| 11 | {"id":5, "start": new Date(year, month, day + 1, 14), "end": new Date(year, month, day + 1, 15),"title":"Gramy w chinczyka"} |
| 12 | ] |
| 13 | }; |
| 14 | |
| 15 | $(document).ready(function() { |
| 16 | $('#calendar').weekCalendar({ |
| 17 | timeslotsPerHour : 2, |
| 18 | allowCalEventOverlap : true, |
| 19 | overlapEventsSeparate: true, |
| 20 | firstDayOfWeek : 1, |
| 21 | businessHours :{start: 8, end: 18, limitDisplay: true }, |
| 22 | daysToShow : 7, |
| 23 | longDays : ['Niedziela', 'Poniedziałek', 'Wtorek', 'Śoda', 'Czwartek', 'Piatek', 'Sobota'], |
| 24 | shortMonths : ['Sty', 'Luty', 'Marz', 'Kwie', 'Czerw', 'Lip', 'Sierp', 'Wrze', 'Paźdz', 'List', 'Gru'], |
| 25 | timeFormat : 'G:i', |
| 26 | timeSeparator: ' - ', |
| 27 | use24Hour: true, |
| 28 | height: function($calendar){ |
| 29 | return $(window).height() - $("h1").outerHeight(); |
| 30 | }, |
| 31 | eventRender : function(calEvent, $event) { |
| 32 | if(calEvent.end.getTime() < new Date().getTime()) { |
| 33 | $event.css("backgroundColor", "#aaa"); |
| 34 | $event.find(".time").css({"backgroundColor": "#999", "border":"1px solid #888"}); |
| 35 | } |
| 36 | }, |
| 37 | data:eventData |
| 38 | }); |
| 39 | }); |
| 40 | |
| 41 | </script> |
Oto wygenerowany kalendarz: kalendarz-1.
Teraz opiszmy co robimy dokładnie. W pierwszych 13 liniach definiujemy sobie jakieś przykładowe zdarzenia. To co dzieje się w funkcji weekCalendar, to już sprawa API, no i tego jak użyjemy odpowiednich funkcji.
Można się zgodzić że takie dodawanie nowych zdarzeń, poprzez wpisywanie ich w formacie JSON jest bardzo niewygodne i bardzo uciążliwe. Dobrym pomysłem będzie zintegrować cały kalendarz z bazą danych, podniesie to jego funkcjonalność i przydatność podczas implementacji różnego rodzaju aplikacjach.
Tworzymy sobie tabelkę w której będziemy trzymać nasze zdarzenia:
| MySQL | | copy code | | ? |
CREATE TABLE kalendarz ( |
id serial NOT NULL, |
start timestamp without time zone, |
koniec timestamp without time zone, |
title text, |
body text |
); |
W poszczególnych kolumnach będziemy trzymać kolejno ID danego zdarzenia, datę rozpoczęcia, datę zakończenia, nagłówek i treść danego zdarzenia.
Funkcja która odpowiedzialna jest za dodawanie nowego zdarzenia to eventNew:
| Javascript | | copy code | | ? |
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 bodyField = $dialogContent.find("textarea[name='body']"); |
$dialogContent.dialog({ |
modal: true, |
height: 260, |
width: 400, |
title: "Nowe zdarzenie", |
close: function() { |
$dialogContent.dialog("destroy"); |
$dialogContent.hide(); |
$('#calendar').weekCalendar("removeUnsavedEvents"); |
}, |
buttons: { |
Zamknij : function() { |
$dialogContent.dialog("close"); |
}, |
Dodaj : function() { |
calEvent.id = id; |
id++; |
calEvent.start = new Date(startField.val()); |
calEvent.end = new Date(endField.val()); |
calEvent.title = titleField.val(); |
calEvent.body = bodyField.val(); |
$calendar.weekCalendar("removeUnsavedEvents"); |
$calendar.weekCalendar("updateEvent", calEvent); |
$.ajax({ |
type : "GET", |
url: "kalendarz_do.php?co=save", |
data: ({start: new Date(startField.val())/1000, end: new Date(endField.val())/1000, title: titleField.val()}) |
}); |
$dialogContent.dialog("close"); |
} |
} |
}).show(); |
$dialogContent.find(".date_holder").text($calendar.weekCalendar("formatDate", calEvent.start)); |
setupStartAndEndTimeFields(startField, endField, calEvent, $calendar.weekCalendar("getTimeslotTimes", calEvent.start)); |
} |
Wywołujemy w niej kolejną bardzo przyjemną funkcjonalność jaką oferuje nam jQurey a mianowicie okienka. To właśnie w nim będziemy dodawać kolejne zdarzenia. Wszystkie dane wysyłane są za pomocą funkcji do obsługi AJAX’a dostarczonej przez twórców jQuery.
Teraz w naszym okienku powinny pojawić się select listy z możliwością wyboru godziny, ta sprawę załatwi za nasz funkcja setupStartAndEndTimeFields:
| Javascript | | copy code | | ? |
| 01 | function setupStartAndEndTimeFields($startTimeField, $endTimeField, calEvent, timeslotTimes) { |
| 02 | |
| 03 | for (var i = 0; i < timeslotTimes.length; i++) { |
| 04 | var startTime = timeslotTimes[i].start; |
| 05 | var endTime = timeslotTimes[i].end; |
| 06 | var startSelected = ""; |
| 07 | if (startTime.toGMTString() === calEvent.start.toGMTString()) { |
| 08 | startSelected = "selected=\"selected\""; |
| 09 | } |
| 10 | var endSelected = ""; |
| 11 | if (endTime.toGMTString() === calEvent.end.toGMTString()) { |
| 12 | endSelected = "selected=\"selected\""; |
| 13 | } |
| 14 | $startTimeField.append("<option value=\"" + startTime + "\" " + startSelected + ">" + timeslotTimes[i].startFormatted + "</option>"); |
| 15 | $endTimeField.append("<option value=\"" + endTime + "\" " + endSelected + ">" + timeslotTimes[i].endFormatted + "</option>"); |
| 16 | |
| 17 | } |
| 18 | $endTimeOptions = $endTimeField.find("option"); |
| 19 | $startTimeField.trigger("change"); |
| 20 | } |
| 21 | |
| 22 | var $endTimeField = $("select[name='end']"); |
| 23 | var $endTimeOptions = $endTimeField.find("option"); |
Teraz trzeba stworzyć kontener w którym będziemy trzymać nasz pola formularza:
| HTML | | copy code | | ? |
| 01 | <div id="event_edit_container" style="display: none;"> |
| 02 | <form action="" method="post" autocomplete="off" class="tabled"> |
| 03 | <input type="hidden" /> |
| 04 | <table> |
| 05 | <tr><td><span>Data: </span><span class="date_holder"></span></td></tr> |
| 06 | <tr><td>Start:</td><td><select name="start"><option value="">Wybierz godzine</option></select></td></tr> |
| 07 | |
| 08 | <tr><td>Koniec: </td><td><select name="end"><option value="">Wybierz godzine</option></select></td></tr> |
| 09 | <tr><td>Nagłówek:</td><td><input type="text" name="title" id="nr_rejestracyjny" /></td></tr> |
| 10 | <tr><td>Opis:</td><td><textarea name="body"></textarea></td></tr> |
| 11 | </table> |
| 12 | </form> |
| 13 | </div> |
Po ustawieniu wszystkich opcji kolejnym krokiem jest obsłużenie tych wszystkich danych po stronie serwera i zapisanie ich w bazie danych. U mnie za wszelkie operacje na tym kalendarzu odpowiada plik kalendarz_do.php jako pierwszy atrybut przekazuje akcje jaka ma być wykonana. W tym wypadku kalendarz_do.php?co=save
| PHP | | copy code | | ? |
| 1 | if ($_GET['co']=='save') |
| 2 | { |
| 3 | "INSERT INTO kalendarz (start, koniec, title, body) values ( |
| 4 | ('1970-01-01 00:00'::timestamp + interval '{$_GET['start']}')::timestamp at time zone 'GMT', |
| 5 | ('1970-01-01 00:00'::timestamp + interval '{$_GET['end']}')::timestamp at time zone 'GMT', |
| 6 | '{$_GET['title']}', '{$_GET['body']}')"); |
| 7 | } |
Jako że dane ze skryptu otrzymujemy w postaci integer jako liczba sekund, do bazy zapiszemy sobie w normalnej formie, aby można było cokolwiek z tego wiedzieć i móc używać w innych miejscach naszej aplikacji.
4. Odczytywanie zdarzeń z bazy danych
Mamy już obsłużone dodawanie nowych zdarzeń, czas aby jakoś pokazać użytkownikowi dane jakie dodał. Za wczytwanie odpowiada metoda:
| Javascript | | copy code | | ? |
data: 'kalendarz_do.php?co=get' |
Teraz podczas uruchamiania naszego kalendarza do pliku kalendarz_do.php zostaje przesłane rządanie aby „odpalić” pobieranie danych z bazy. Po stronie serwera wygląda to tak:
| PHP | | copy code | | ? |
| 01 | if ($_GET['action']=='get') |
| 02 | { |
| 03 | //łaczymy sie z baza |
| 04 | zapytanie("SELECT id, extract (epoch from start::timestamp) as start, extract (epoch from koniec::timestamp) as end, title, body FROM kalendarz"); |
| 05 | |
| 06 | for($i=0 ; $i<ilosc_rekordów_w_bazie ; $i++) |
| 07 | { |
| 08 | $id; //id naszego zdarzenia |
| 09 | $start; //start - data rozpoczęcia |
| 10 | $end; //koniec - data zakończenia |
| 11 | $title; //title - nagłówek zdarzenia |
| 12 | $body; //treść - treść zdarzenia |
| 13 | $tab[$i]['id'] = $id; |
| 14 | $tab[$i]['start'] = date('c', $start); |
| 15 | $tab[$i]['end'] = date('c', $end); |
| 16 | $tab[$i]['title'] = $title; |
| 17 | $tab[$i]['body'] = $body; |
| 18 | } |
| 19 | |
| 20 | echo json_encode($tab); |
| 21 | } |
Jako że wszystkie dane do JS podawane są w formacie JSON, musimy użyć funkcji PHP:json_encode, aby zakodować tablice właśnie na ten standard.
5. Epilog
Właśnie w ten sposób stworzyliśmy prosty sposób dodawania i wyświetlania dodanych zdarzeń w kalendarzu jQuery. W kolejnej części zajmiemy się edycją i usuwaniem zdarzeń.
Kolejna część: http://piotrooo.com/2010/01/kalendarz-google-w-jquery-cz-2/
26 stycznia 2010 at 15:52
świetna sprawa, na pewno się przyda, dzięki za tutorial !