Pracując z pakietem SharePoint, wykorzystywanym przez duża grupę ludzi, każdy wcześniej czy później spotka się z problemem kolorowania kalendarza. Możemy chcieć pokolorować go zgodnie z kategoriami wydarzeń, ich priorytetem czy osobą, która to wydarzenie utworzyła. Powiedzmy sobie szczerze: każdy lubi kolory 🙂 Jedno spojrzenie na kolory w kalendarzu sprawi, że znajdziemy poszukiwaną informację. Tego samego nie można powiedzieć o jednokolorowym, nudnym kalendarzu:
Porównanie kalendarza jednobarwnego z kolorowym
Oczywiście, istnieje możliwość stworzenia kilku kalendarzy w różnych kolorach i nałożenia ich na siebie. Jednak ta opcja nie nadaje się do zastosowania we wszystkich przypadkach i jest ograniczona do dziesięciu kalendarzy na jednym widoku.
Chciałbym Wam zaproponować ciekawsze i równie proste rozwiązanie.
Kolorowanie kalendarza – opis rozwiązania
Przygotowałem kalendarz urlopowy, w którym każda osoba ma przyporządkowany własny kolor. Wykorzystałem do tego dodatkową listę, która przechowuje konfigurację nazwisko – kolor. W widoku kalendarza użyłem edytora skryptów do wprowadzenia skryptu JavaScript. Użytkownik tworzący wydarzenie musi podać w tytule tylko swoje imię i nazwisko, a skrypt zrobi za niego resztę. Przedstawię krok po kroku, jak tego dokonać. Do dzieła!
Lista konfiguracyjna
Pierwszą czynnością, jaką należy wykonać, jest dodanie nowej listy niestandardowej. Wchodzimy w zawartość interesującej nas witryny i „intuicyjnie” wybieramy Dodaj aplikację, a następnie pozycję nazwaną Lista niestandardowa:
Wprowadzamy nazwę naszej listy. Będzie ona użyta w skrypcie kalendarza.
Na nowo stworzonej liście tworzymy interesujące nas kolumny. Opis jak ukryć kolumnę z tytułem znajdziesz w moim wcześniejszym poście.
Lista jest już gotowa. Jak widać, kolumna z kolorami nie jest przyjemna dla użytkownika. Jeśli nie jesteś osobą, która spędziła całe życie na pisaniu stylów CSS, to ciężko wywnioskować, jaki kolor został wybrany. Poprawmy to trochę. Po pierwsze, musimy utworzyć plik z JavaScriptem. Nazwijmy go ColumnColoringScript.js i umieśćmy w nim następujący skrypt:
SP.SOD.executeFunc("clienttemplates.js", "SPClientTemplates", function() {
SPClientTemplates.TemplateManager.RegisterTemplateOverrides( {
OnPostRender: function(ctx) {
var rows = ctx.ListData.Row;
for (var i = 0; i < rows.length; i++) {
var color = rows[i]["Kolor"];
var rowId = GenerateIIDForListItem(ctx, rows[i]);
var row = document.getElementById(rowId);
$('.ms-vb2:contains(' + color + ')').css('color', color);
}
}
});
});
Plik wrzucamy na naszą stronę i dodajemy do naszej listy. Jak to zrobić?
- Otwieramy listę.
- Wybieramy opcję Edytuj stronę, a następnie Edytuj WebPart.
- Na samym dole, w zakładce Różne, w polu Łącze JS wpisujemy odpowiedni token do naszego pliku (więcej o ścieżkach i tokenach możesz dowiedzieć się ze strony Microsoftu).
W moim przypadku ścieżka wyglądała tak:
~site/SiteAssets/ColumnColoringScript.js
Oto efekt, o jaki nam chodziło. Oczywiście, wystarczy lekka modyfikacja skryptu, aby uzyskać inny efekt – w zależności od upodobań.
Oto przykłady, które można wykorzystać we własnych rozwiązaniach.
Wystarczy tylko podmienić linijkę $(’.ms-vb2:contains(’ + color + ’)’).css(’color’, color):
row.style.backgroundColor = color;
$(’.ms-vb2:contains(’ + color + ’)’).css(’backgroundColor’, color);
Kalendarz
Wreszcie przechodzimy do kalendarza. W tej chwili sprawa jest prosta: na stronie z kalendarzem musimy dodać dodatkowy WebPart. W kategorii Multimedia i zawartość odnajdujemy Edytor skryptu. Potem klikamy Edytuj wstawkę i wklejamy kod. Po zatwierdzeniu możemy przeładować stronę i cieszyć się kolorowym kalendarzem.
<img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" data-wp-preserve="%3Cstyle%3E%0A.ms-acal-item%7Bdisplay%3Anone%3B%7D%3Cbr%20%2F%3E%0A%3C%2Fstyle%3E" data-mce-resize="false" data-mce-placeholder="1" class="mce-object" width="20" height="20" alt="<style>" title="<style>" />
<img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" data-wp-preserve="%3Cscript%20type%3D%22text%2Fjavascript%22%20src%3D%22http%3A%2F%2Fajax.googleapis.com%2Fajax%2Flibs%2Fjquery%2F1.9.1%2Fjquery.min.js%22%3E%3C%2Fscript%3E" data-mce-resize="false" data-mce-placeholder="1" class="mce-object" width="20" height="20" alt="<script>" title="<script>" />
<img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" data-wp-preserve="%3Cscript%20type%3D%22text%2Fjavascript%22%3E%3C%2Fp%3E%0A%3Cp%3Efunction%20WaitForCalendarToLoad()%20%7B%3Cbr%20%2F%3E%0ASP.UI.ApplicationPages.SummaryCalendarView.prototype.renderGrids%20%3D%3Cbr%20%2F%3E%0Afunction%20SP_UI_ApplicationPages_SummaryCalendarView%24renderGrids(%24p0)%20%7B%3Cbr%20%2F%3E%0Avar%20%24v_0%20%3D%20new%20Sys.StringBuilder()%3B%3Cbr%20%2F%3E%0Avar%20%24v_1%20%3D%20%24p0.length%3B%20for%20(var%20%24v_2%20%3D%200%3B%20%24v_2%20%3C%20%24v_1%3B%20%24v_2%2B%2B)%20%7B%0Athis.%247V_2(%24v_2%2C%20%24p0%5B%24v_2%5D)%3B%0A%7D%0Afor%20(var%20%24v_3%20%3D%200%3B%20%24v_3%20%3C%20%24v_1%3B%20%24v_3%2B%2B)%20%7B%0A%24v_0.append('%0A%0A%0A%3Cdiv%3E')%3B%3Cbr%20%2F%3E%0Athis.%24I_2.%247Q_1(%24v_0%2C%20%24p0%5B%24v_3%5D%2C%20%24v_3)%3B%3Cbr%20%2F%3E%0A%24v_0.append(this.emptY_DIV)%3B%3Cbr%20%2F%3E%0A%24v_0.append('%3C%2Fdiv%3E%0A%3Cp%3E')%3B%3Cbr%20%2F%3E%0A%7D%3Cbr%20%2F%3E%0Athis.setInnerHtml(%24v_0.toString())%3B%3Cbr%20%2F%3E%0AgetColoursConfig()%3B%3Cbr%20%2F%3E%0A%7D%3C%2Fp%3E%0A%3Cp%3ESP.UI.ApplicationPages.CalendarStateHandler.prototype.onItemsSucceed%20%3D%20function%20(%24p0%2C%20%24p1)%20%7B%3Cbr%20%2F%3E%0Aif%20(this.%24K_1.%248G_0())%20%7B%3Cbr%20%2F%3E%0Athis.%2428_1()%3B%3Cbr%20%2F%3E%0Areturn%3B%3Cbr%20%2F%3E%0A%7D%3Cbr%20%2F%3E%0Athis.%2441_1%20%3D%20false%3B%3Cbr%20%2F%3E%0Aif%20(this.%243G_1)%20%7B%3Cbr%20%2F%3E%0Athis.%24D_1.%244T_1()%3B%3Cbr%20%2F%3E%0Athis.%243G_1%20%3D%20false%3B%3Cbr%20%2F%3E%0A%7D%3Cbr%20%2F%3E%0Aif%20(SP.UI.ApplicationPages.SU.%242(this.%2439_1%5Bthis.%24j_1%5D))%20%7B%3Cbr%20%2F%3E%0Athis.%2439_1%5Bthis.%24j_1%5D%20%3D%20%5B%5D%3B%3Cbr%20%2F%3E%0A%7D%3Cbr%20%2F%3E%0AArray.addRange(this.%2439_1%5Bthis.%24j_1%5D%2C%20%24p0)%3B%3Cbr%20%2F%3E%0Athis.%24D_1.%247S_1(this.%24j_1%2C%20this.%24v_1%2C%20%24p1%2C%20this.%2439_1%5Bthis.%24j_1%5D)%3B%3Cbr%20%2F%3E%0Athis.%24j_1%2B%2B%3B%3Cbr%20%2F%3E%0Athis.%241h_1()%3B%3Cbr%20%2F%3E%0AgetColoursConfig()%3B%3Cbr%20%2F%3E%0A%7D%3Cbr%20%2F%3E%0A%7D%3C%2Fp%3E%0A%3Cp%3Efunction%20getColoursConfig()%20%7B%3Cbr%20%2F%3E%0Avar%20siteUrl%20%3D%20'%2Fsites%2Fteamsiites%2Fpsd%2Fworkspace%2Fsharepoint'%3B%3C%2Fp%3E%0A%3Cp%3Evar%20clientContext%20%3D%20new%20SP.ClientContext(siteUrl)%3B%3Cbr%20%2F%3E%0Avar%20oList%20%3D%20clientContext.get_web().get_lists().getByTitle('Konfiguracja%20kalendarza%20urlop%C3%B3w')%3B%3C%2Fp%3E%0A%3Cp%3Evar%20camlQuery%20%3D%20new%20SP.CamlQuery()%3B%3Cbr%20%2F%3E%0AcamlQuery.set_viewXml('%3CView%3E%3C%2FView%3E')%3B%3Cbr%20%2F%3E%0Athis.collListItem%20%3D%20oList.getItems(camlQuery)%3B%3C%2Fp%3E%0A%3Cp%3EclientContext.load(collListItem)%3B%3C%2Fp%3E%0A%3Cp%3EclientContext.executeQueryAsync(%3Cbr%20%2F%3E%0AFunction.createDelegate(this%2C%20this.onQuerySucceeded)%2C%3Cbr%20%2F%3E%0AFunction.createDelegate(this%2C%20this.onQueryFailed)%3Cbr%20%2F%3E%0A)%3B%3Cbr%20%2F%3E%0A%7D%3C%2Fp%3E%0A%3Cp%3Efunction%20onQuerySucceeded(sender%2C%20args)%20%7B%3C%2Fp%3E%0A%3Cp%3Evar%20listItemEnumerator%20%3D%20collListItem.getEnumerator()%3B%3C%2Fp%3E%0A%3Cp%3Ewhile%20(listItemEnumerator.moveNext())%20%7B%3Cbr%20%2F%3E%0Avar%20oListItem%20%3D%20listItemEnumerator.get_current()%3B%3Cbr%20%2F%3E%0Avar%20name%20%3D%20oListItem.get_item('Osoba').get_lookupValue()%3B%3Cbr%20%2F%3E%0Avar%20colour%20%3D%20oListItem.get_item('Kolor')%3B%3C%2Fp%3E%0A%3Cp%3E%24('a%3Acontains('%20%2B%20name%20%2B%20')').closest('.ms-acal-item').css('background-color'%2C%20colour)%3B%3Cbr%20%2F%3E%0A%7D%3Cbr%20%2F%3E%0A%24('.ms-acal-item').css('display'%2C%20'block')%3B%3Cbr%20%2F%3E%0A%7D%3C%2Fp%3E%0A%3Cp%3Efunction%20onQueryFailed(sender%2C%20args)%20%7B%3Cbr%20%2F%3E%0A%24('.ms-acal-item').css('display'%2C%20'block')%3B%3Cbr%20%2F%3E%0Aalert('B%C5%82%C4%85d%20pobierania%20listy%20konfiguracyjnej%20kolor%C3%B3w%20kalendarza.%20'%20%2B%20args.get_message()%20%2B%20'%5Cn'%20%2B%20args.get_stackTrace())%3B%3Cbr%20%2F%3E%0A%7D%3C%2Fp%3E%0A%3Cp%3Efunction%20ShowCalendarRibbon%20()%3Cbr%20%2F%3E%0A%7B%3Cbr%20%2F%3E%0AsetTimeout(%20function()%7B%3Cbr%20%2F%3E%0Avar%20defaultWP%20%3D%20document.getElementById(%20%22MSOZoneCell_WebPartWPQ2%22)%3B%3Cbr%20%2F%3E%0AWpClick(%20%7B%20target%3AdefaultWP%2CsrcElement%3AdefaultWP%7D)%3B%3Cbr%20%2F%3E%0ASP.Ribbon.WebPartComponent.%243.deselectWebPartAndZone%20%3D%20function()%20%7B%20%7D%3B%3Cbr%20%2F%3E%0A%7D%2C100)%3B%3Cbr%20%2F%3E%0A%7D%3C%2Fp%3E%0A%3Cp%3ELoadSodByKey(%22SP.UI.ApplicationPages.Calendar.js%22%2C%20function%20()%20%7B%3Cbr%20%2F%3E%0AWaitForCalendarToLoad()%3B%3Cbr%20%2F%3E%0A%7D)%3B%3C%2Fp%3E%0A%3Cp%3E%24(document).ready(function()%7B%3Cbr%20%2F%3E%0AExecuteOrDelayUntilScriptLoaded(ShowCalendarRibbon%2C%20%22sp.ribbon.js%22%20)%3B%3Cbr%20%2F%3E%0A%7D)%3B%3C%2Fp%3E%0A%3Cp%3E%3C%2Fscript%3E" data-mce-resize="false" data-mce-placeholder="1" class="mce-object" width="20" height="20" alt="<script>" title="<script>" />
Personalizacja skryptu
Oczywiście, nie każdy jest zainteresowany kalendarzem urlopowym lub nie posiada takiej samej listy albo struktury katalogów. To nie problem. Skonfigurujemy każdą rzecz po kolei.
Opis skryptu
Skrypt składa się z kilku części, które możemy wyróżnić:
- Na początku ukrywane są wydarzenia. Istnieje tu problem natury estetycznej, gdyż kalendarz wyświetla się z domyślnymi kolorami, a skrypt z ułamkiem sekundy opóźnienia nakłada kolory. Jeśli nie ukryjemy wydarzeń, przeskok kolorów będzie widoczny.
- Funkcja WaitForCalendarToLoad nadpisuje domyślne zdarzenia kalendarza. Usunięcie tej funkcji spowoduje, że kolory w kalendarzu nie nałożą się przy zmianie widoku czy kolejnych miesięcy. Oczekuje ona również na załadowanie się kalendarza przed nałożeniem kolorów.
- Funkcja getColoursConfig pobiera konfigurację kalendarza z listy wykorzystując SharePoint Client Object Model. Kwerenda wykonywana jest asynchronicznie, a od jej powodzenia zależy wywołanie jednej z kolejnych metod.
- Funkcja onQuerySucceeded jest wywoływana, gdy uda się pobrać listę konfiguracyjną. Tutaj zawiera się cała magia. Przeglądana jest lista konfiguracyjna i odpowiednie kolory nakładane są na wydarzenia zapisanych osób. Po udanym kolorowaniu wydarzenia te są wyświetlane.
- Funkcja onQueryFailed uruchamia się przy niepowodzeniu kwerendy. Wyświetla wydarzenia z domyślnymi kolorami i finalizuje swoje działanie komunikatem o błędzie.
- Funkcja ShowCalendarRibbon jest opcjonalna. Dodając WebPart Edytor Skryptów sprawiamy, że na stronie znajdują się co najmniej dwa WebParty. W takim wypadku SharePoint nie wybiera żadnego z nich jako domyślny, przez co nie widzimy wstążki z opcjami. Ta funkcja ustawia focus na nasz kalendarz.
Wybór listy
Po pierwsze, musimy podać ścieżkę do strony, na której znajduje się nasza lista. To z niej właśnie pobierzemy konfiguracje. Wystarczy podmienić URL:
var siteUrl = '/sites/teamsiites/psd/workspace/sharepoint';
Oczywiście, na naszej stronie może znajdować się więcej niż jedna lista. Nazwę naszej precyzujemy parę linijek niżej:
var oList = clientContext.get_web().get_lists().getByTitle('Konfiguracja kalendarza urlopów');
Wybór kolumn
Ostatnią rzeczą, która może wymagać konfiguracji, jest wybór kolumn z listy:
</pre>
var name = oListItem.get_item('Osoba').get_lookupValue();
var colour = oListItem.get_item('Kolor');
<pre>
Wprowadzamy tutaj nazwę kolumny, po której przeszukujemy listę i kolumny, z której pobieramy kolor. U mnie były to kolumny Osoba i Kolor. W tym właśnie miejscu, w funkcji onQuerySucceeded można dokonywać własnych zmian. Liczba możliwości jest wręcz nieograniczona. Kolumnę Kolor możemy przykładowo zastąpić kolumną z kategorią, a funkcję w skrypcie – na sztywno wpisanymi wartościami kolorów.
Podsumowanie
Powyżej przedstawiłem jeden ze sposobów pokolorowania kalendarza, wykorzystując do tego listę konfiguracyjną. Jak widać, nie jest to trudne, a przeglądany kalendarz jest przyjemny dla oka. Jedyną rzeczą, która może budzić wątpliwości, jest sposób wprowadzenia koloru. Miałem do dyspozycji niestandardowe narzędzie w postaci Color Pickera, które znacznie ułatwia wypełnianie listy konfiguracyjnej.
Ten wpis może świetnie posłużyć jako punkt zaczepienia przy wypracowaniu własnego rozwiązania. Wystarczy podstawowa znajomość JavaScript, aby zmodyfikować funkcję kolorującą. Możemy utworzyć system priorytetów, kategorii czy kolorowania na podstawie pozostałych do wydarzenia dni. Jeśli chcesz zagłębić się w temat, zapraszam do zapoznania się z udostępnionymi poniżej stronami.
Powiązane artykuły
Wspomniane w artykule omówienie tokenów i URLów:
https://msdn.microsoft.com/en-us/library/office/ms431831.aspx
Pobieranie (i nie tylko) elementów z SharePoint’owej listy przy pomocy JavaScript:
https://msdn.microsoft.com/en-us/library/office/hh185007(v=office.14).aspx
Kolorowanie kalendarza po kategorii. Ciekawy wpis na blogu o podobnej tematyce:
http://blog.metrostarsystems.com/2014/07/16/sharepoint-2013-any-color-coded-calendar-step-by-step/
Opis jak wykorzystać workflow do wyświetlenia niestandardowego tytułu wydarzenia:
http://blog.incworx.com/blog/sharepoint-administrators-blog/a-simple-guide-to-show-more-information-on-a-calendar-event
Dziękuję za zainteresowanie artykułem! Mam nadzieję, że Twój kalendarz nabierze nowych kolorów.
Ciekawe rozwiązanie. Dla osób, które preferują rozwiązania konsultanckie – analogiczny efekt można osiągnąć za pomocą Nakładek tzw. Overlays. Ograniczeniem takiego rozwiązania jest konieczność skorzystania z listy gotowych kolorów oraz limit nakładek na widok (max 9).
A co w przypadku shp 2010?