Vijay J. - PHP i jQuery. Receptury

Spis treści Podziękowania 7 O autorze 9 O recenzentach 11 Wstęp 13 Rozdział 1. Obsługa zdarzeń w jQuery 17 Wprowadzenie 17 Wykonywanie funkcji w momen...

17 downloads 50 Views 8MB Size
'; } $('#container').html(str); } $('#size').change(function() { game.init($(this).val()); $('#log').html('Waiting for Player 1'); }); $('h2:last').click(function() { game.init($('#size').val()); $('#log').html('Waiting for Player 1'); $(this).hide('slow'); }); game.init(3); });

6. Gra jest już ukończona i możemy spróbować, jak działa. Uruchom zatem plik index.html w przeglądarce, a zobaczysz planszę do gry w kółko i krzyżyk o wielkości 3 pól.

7. Zacznij grę. Umieszczenie wskaźnika myszy nad polem spowoduje, że zabarwi się ono na żółto. Kliknięcie dowolnego pola umieści na nim kółko lub krzyżyk. Gdy jeden z graczy wygra grę, okno przeglądarki będzie wyglądało podobnie do poniższego:

172

Rozdział 6. • Efekty specjalne w formularzach

Jak to działa? Najpierw definiujemy globalny obiekt game. Posłuży on nam za przestrzeń nazw, w której będziemy przechowywać wszystkie zmienne i funkcje potrzebne do funkcjonowania naszej gry. Zaczynamy od funkcji init(), której trzeba przekazać liczbę określającą wielkość planszy. Ważna jest też zmienna player, której wartość określa gracza wykonującego ruch. Wartość 0 wskazuje na gracza numer 1, a wartość 1 na gracza numer 2. Zmienna marker definiuje rodzaj ikony, jaką należy umieścić w polu, zależnie od tego, który gracz wykonuje swój ruch. Krzyżyki przypisane są graczowi numer 1, a kółka graczowi numer 2. Kolejnym elementem jest funkcja createGrid(), która przygotowuje planszę do gry. Tworzy ona element div z wierszami i kolumnami, którym przypisuje klasy CSS definiujące ich wygląd. Jeżeli plansza ma wielkość 3, to znaczy, że będzie ona miała wysokość i szerokość trzech pól. Po przygotowaniu kodu HTML planszy zostaje on wstawiony do elementu div o identyfikatorze container. Każdej kolumnie na planszy przypisywane są też dwa dodatkowe atrybuty i oraz j, których wartości definiują indeks pola w tablicy. Zasada przypisywania wartości tym atrybutom została wyjaśniona na poniższym rysunku.

173

PHP i jQuery. Receptury

Zanim przejdziemy dalej, muszę wspomnieć jeszcze o dwóch klasach CSS: cross i round. Pierwsza z nich dodaje w tle elementu obrazek z krzyżykiem, natomiast druga dodaje do tła elementu obrazek z kółkiem. Nasz interfejs użytkownika jest już gotowy, a zatem możemy przygotować funkcje obsługi zdarzeń. W naszym przykładzie definiujemy dwie ważne funkcje. Pierwsza z nich wywoływana jest, gdy użytkownik umieszcza wskaźnik myszy nad polami planszy. W takiej sytuacji korzystamy z funkcji biblioteki jQuery hover(), poprzez którą zmieniamy kolor pola na żółty. Gdy tylko wskaźnik zostanie przesunięty poza pole, jego kolor znów staje się biały. Najważniejsza jest jednak funkcja obsługująca zdarzenie click wywoływane przez pola planszy. W przypadku kliknięcia pola najpierw sprawdzamy, czy nie została mu już przypisana klasa cross lub round. Jeżeli tak jest, to po prostu kończymy pracę, ponieważ gracz może wykonać ruch tylko na pustym polu. Jak już wspominałem, zmienna who określa, który gracz wykonuje właśnie ruch, a zmienna marker definiuje styl CSS nadawany wybranemu przez gracza polu. W kolejnym kroku sprawdzamy, który gracz wykonuje ruch, i przypisujemy wybranemu przez niego polu odpowiednią klasę. Po umieszczeniu w polu właściwego stylu CSS sprawdzamy, czy gracz zdołał wygrać tę potyczkę. Posługujemy się w tym celu funkcją checkForWin(). Jeżeli zwróci ona wartość true, to znaczy, że aktualny gracz wygrał i możemy odpiąć funkcje obsługi zdarzenia click od pól planszy. Oprócz tego nie możemy też zapomnieć o wyświetleniu wyniku i informacji o zakończeniu gry.

174

Rozdział 6. • Efekty specjalne w formularzach

Jeżeli jednak funkcja checkForWin() zwróci nam wartość false, to zmieniamy tylko aktywnego gracza przez odpowiednią modyfikację zmiennej player i wyświetlenie tej informacji na stronie. Funkcja checkForWin() szuka tylko trzech jednakowych klas CSS w jednej kolumnie, wierszu lub na przekątnej planszy. Wiersze i kolumny przeszukiwane są za pomocą prostych pętli for. Następnie przystępujemy do sprawdzania przekątnych i tutaj potrzebne są już dwie współpracujące pętle. Sama logika jest bardzo prosta. Jeżeli wszystkie elementy w wierszu, kolumnie lub na przekątnej mają tę samą klasę CSS, to aktualny gracz wygrywa. Funkcja zwraca zatem wartość true lub false. Definiujemy też dwie kolejne funkcje obsługi zdarzeń. Jedną dla listy rozwijanej, w której wywołujemy funkcję init(), zmieniając tym samym wielkość pola gry. Druga funkcja związana jest z przyciskiem Od nowa, który pojawia się na stronie po wygranej jednego z graczy. Proszę zauważyć, że przygotowany przez nas kod jest bardzo uogólniony. Przekazując liczbę funkcji init(), możemy przygotować sobie planszę o dowolnej wielkości.

I coś jeszcze Ćwiczenie: sprawdź, czy nie mamy remisu Gdy się chwilę zastanowić, stwierdzimy, że nasz przykład wyświetla przycisk Od nowa jedynie w przypadku wygranej jednego z graczy. Jeżeli jednak uzyskamy remis, to nie będziemy mieli możliwości ponownego rozpoczęcia gry. Rozwiązanie tego dylematu pozostawiam jako ćwiczenie dla Czytelnika. W ramach sprawdzania, czy nie mamy remisu, musimy tylko liczyć kliknięcia wykonane na planszy i porównać je z liczbą pól. Na przykład dla planszy o wymiarach 3×3 po dziewięciu kliknięciach nastąpi remis, chyba że wcześniej funkcja checkForWin() zwróci wartość true.

Informowanie użytkownika o przetwarzaniu żądania AJAX Ze względu na to, że aplikacje AJAX nie przeładowują całej strony, użytkownik może czuć się nieco zagubiony, w czasie gdy żądanie wysłane do serwera jest w trakcie przetwarzania.

175

PHP i jQuery. Receptury

Oznacza to, że użytkownik musi otrzymać jakąś informację, że nasza aplikacja nadal pracuje. Jest to bardzo ważny element, o którym nie można zapominać, tworząc nawet najprostsze aplikacje używające technologii AJAX. W tej recepturze dowiemy się, jak można poinformować użytkownika, że aktualnie przetwarzane jest żądanie AJAX.

Przygotowania W katalogu rozdzial6 utwórz nowy katalog o nazwie receptura2. Oprócz tego zajrzyj na stronę pod adresem http://ajaxload.info lub http://preloadres.net. Na tych stronach znajdziesz różne animowane obrazki oraz ikony z informacją o ładowaniu danych. Wybierz sobie jeden z tych obrazków i pobierz go, ponieważ będzie nam potrzebny przy tworzeniu tej receptury. Osobiście wykorzystałem poniższy obrazek pobrany ze strony http://ajaxload.info.

Jak to zrobić? 1. W katalogu receptura2 utwórz nowy plik i nazwij go index.html. 2. Przygotuj formularz, do którego użytkownik będzie mógł wprowadzić pewne informacje i wysłać je na serwer. Oprócz takiego formularza umieść na stronie znacznik img, którego atrybut src będzie wskazywał na wspomniany wcześniej obrazek. Na razie ukryj go jednak, wykorzystując odpowiedni styl CSS. Dodatkowo dopisz jeszcze pusty akapit, w którym będziemy wyświetlali odpowiedź przesłaną przez serwer. Informacja dla użytkownika
Proszę wypełnić formularz

176

Rozdział 6. • Efekty specjalne w formularzach

Nazwisko:
Adres:
Miasto:
Kraj:



177

PHP i jQuery. Receptury

3. Teraz przygotujmy kod korzystający z biblioteki jQuery, który będzie zbierał informacje z pól formularza i wysyłał je do skryptu process.php działającego po stronie serwera. Po otrzymaniu odpowiedzi ukryjemy formularz i wyświetlimy tylko dane przesłane przez serwer. Ten sam kod będzie się też zajmował wyświetlaniem wskaźnika postępu, w czasie gdy skrypt PHP będzie pracował na serwerze.

4. W katalogu receptura2 utwórz kolejny plik i nadaj mu nazwę process.php. Kod z tego pliku odeśle po prostu informacje otrzymane od przeglądarki, ale wcześniej opakuje je w odpowiednio sformatowany tekst. Aby zasymulować opóźnienia na serwerze, tak żeby w przeglądarce odpowiednio długo wyświetlany był pasek postępu, wywołujemy funkcję sleep(), która zatrzyma działanie skryptu na pięć sekund. '; $str.= 'Nazwisko - '. $_POST['name']; $str.= '
'; $str.= 'Adres - '. $_POST['address']; $str.= '
';

178

Rozdział 6. • Efekty specjalne w formularzach

$str.= 'Miasto - '. $_POST['city']; $str.= '
'; $str.= 'Kraj - '. $_POST['country']; echo $str; ?>

5. Możemy już wypróbować działanie naszego kodu. Uruchom w przeglądarce plik index.html, wypełnij formularz danymi i kliknij przycisk Zapisz. Na stronie pojawi się pasek postępu, który będzie widoczny przez pięć sekund, aż do otrzymania przez przeglądarkę odpowiedzi ze skryptu PHP. Gdy tylko odpowiedź zostanie odebrana, na stronie pojawią się wartości wpisane przez nas do formularza.

6. Poniższy obrazek prezentuje wygląd strony po otrzymaniu odpowiedzi od skryptu PHP.

179

PHP i jQuery. Receptury

Jak to działa? Do przycisku Zapisz przypięliśmy funkcję obsługi zdarzenia click, która jest uruchamiana przy każdym kliknięciu przycisku. Po uruchomieniu funkcja wyświetla obrazek o identyfikatorze loading, wywołując w tym celu funkcję biblioteki jQuery show(). Jednocześnie tekst na obrazku zmieniany jest na Proszę czekać…, a do pliku process.php wysyłane jest żądanie AJAX. Skrypt PHP po otrzymaniu wartości od przeglądarki najpierw czeka pięć sekund, a następnie podsyła do niej przygotowany tekst. W momencie otrzymania odpowiedzi od skryptu PHP biblioteka jQuery ukrywa pasek postępu oraz formularz, a tekst przesłany przez serwer wyświetla w specjalnym akapicie na stronie. W ten sposób użytkownik jest informowany, że system przetwarza wprowadzone informacje i należy poczekać na zakończenie tych prac.

I coś jeszcze Używanie tekstu zamiast obrazków Jeżeli nie chcesz używać obrazków jako sygnalizacji dla użytkownika, to możesz zamiast nich wprowadzić na stronę odpowiedni tekst.

Używanie nakładek, aby zablokować możliwość interakcji z formularzem W poprzednim przykładzie w czasie obsługi jednego żądania użytkownik może ponownie kliknąć przycisk Zapisz, a wtedy do serwera zostanie przesłane kolejne żądanie. Aby uniknąć takich sytuacji, możemy wyłączyć przycisk Zapisz albo utworzyć nakładkę (ang. overlay), która zakryje cały formularz do czasu otrzymania odpowiedzi z serwera. Będzie to bardzo dobitna informacja dla użytkownika, że w czasie przetwarzania wprowadzanych danych nie można korzystać z formularza.

Zobacz też Q Recepturę „Wysyłanie danych do PHP” z rozdziału 2.

180

Rozdział 6. • Efekty specjalne w formularzach

Tworzenie rozwijanych i zwijanych ramek (harmonijek) Harmonijki są dobrym przykładem gadżetu pozwalającego na wyświetlenie większej ilości informacji w ograniczonej przestrzeni w interaktywny i atrakcyjny sposób. W tej recepturze nauczymy się tworzyć proste harmonijki za pomocą biblioteki jQuery.

Przygotowania W katalogu rozdzial6 utwórz nowy katalog i nazwij go receptura3.

Jak to zrobić? 1. W katalogu receptura3 utwórz nowy plik o nazwie index.html. 2. W utworzonym pliku zdefiniuj kod HTML opisujący harmonijkę. Harmonijka składa się z elementów div zawierających treść, przy których znajdują się elementy h1 służące za nagłówek sekcji. Każdej sekcji nadaj jakiś tytuł i wpisz do niej dowolną treść. Oprócz tego w sekcji head strony zdefiniuj też style CSS nadające harmonijce ładny wygląd. Harmonijka

PHP: PHP Preprocessor Hipertekstu

PHP jest szeroko używanym, serwerowym

181

PHP i jQuery. Receptury

językiem skryptowym, który wykorzystywany jest do tworzenia dynamicznych aplikacji WWW. PHP jest bardzo popularnym językiem wśród programistów, dlatego wiele ważnych witryn powstało z wykorzystaniem tego języka.

jQuery - JavaScript typu pisz mniej, uzyskaj więcej

Za Wikipedią: lekka biblioteka programistyczna dla języka JavaScript, ułatwiająca korzystanie z JavaScript (w tym manipulację drzewem DOM) [...] Wszystkie efekty osiągnięte za pomocą jQuery można osiągnąć również bez jej użycia. Jednak kod okazuje się nieporównywalnie dłuższy i bardziej skomplikowany.

AJAX - Asynchronous JavaScript and XML

Ajax jest grupą technik tworzenia interaktywnych aplikacji dla sieci WWW działającą po stronie klienta (w przeglądarce). Technologii tej można użyć do asynchronicznego pobierania danych z serwera w tle. Obiekt XMLHttpRequest jest używany w przeglądarce do nawiązywania kontaktu z serwerem.

JSON - JavaScript Object Notation

JSON jest skrótem od JavaScript Object Notation, czyli notacji obiektów języka JavaScript. Opisuje on lekki i interaktywny format wymiany danych. Jest też określany jako odchudzona alternatywa dla języka XML. Jest to format tekstowy, niezależny od języka programowania, ale w języku JavaScript używany jest w sposób naturalny. Jest znacznie szybszy i mniej obciążający system niż XML. Głównym popularyzatorem tego formatu jest Douglas Crockford.

Ze względu na to, że format JSON jest naturalnym formatem danych języka JavaScript, może być łatwo używany w aplikacjach po stronie klienta. Znacznie łatwiej niż format XML.



182

Rozdział 6. • Efekty specjalne w formularzach

Przygotowaną stronę można podziwiać na poniższym rysunku.

3. Przed zamykającym znacznikiem body dołącz plik biblioteki jQuery i dopisz kod, który zmieni nasze znaczniki HTML w działającą harmonijkę.

4. Teraz nasza harmonijka jest już gotowa. Uruchom w przeglądarce plik index.html, a zobaczysz na stronie cztery sekcje harmonijki. Kliknięcie nagłówka sekcji spowoduje jego rozwinięcie i jednoczesne ukrycie pozostałych sekcji.

Jak to działa? Podany tu kod HTML składa się z głównego elementu div oraz znajdujących się w nim czterech kolejnych elementów div. Każdy z tych czterech elementów będzie jedną z sekcji harmonijki. Każda sekcja składa się natomiast z dwóch elementów: znacznika h1 oraz elementu div klasy container. Znacznik h1 służyć nam będzie jako nagłówek sekcji, a w elemencie div umieszczona zostanie treść tej sekcji. Style CSS sprawiają, że całość wygląda tak, jak pokazano na powyższym rysunku. W ten sposób uzyskujemy podstawową strukturę, którą zamienimy w harmonijkę za pomocą biblioteki jQuery. Teraz możemy już zająć się skryptem korzystającym z biblioteki jQuery. Na początek ukrywamy wszystkie elementy div klasy container, tak żeby widoczne były tylko nagłówki sekcji. Następnie dodajemy do nagłówka h1 funkcję obsługi zdarzenia click. Proszę

184

Rozdział 6. • Efekty specjalne w formularzach

zauważyć, że zdefiniowaliśmy tu styl CSS o nazwie active, który będzie przypisywany klikniętemu elementowi h1. Po kliknięciu nagłówka najpierw usuwamy klasę active ze wszystkich nagłówków harmonijki, a następnie przypisujemy ją klikniętemu elementowi h1, dzięki czemu tekst nagłówka zabarwia się na czerwono. Za pomocą selektora .container:visible wybieramy wszystkie widoczne aktualnie segmenty harmonijki i ukrywamy je, wywołując metodę slideUp(). Na zakończenie wybieramy jeszcze element div następujący po klikniętym elemencie h1 i wywołujemy na jego rzecz metodę toggleSlide(), tak żeby go pokazać lub ukryć. W ten sposób zrealizowaliśmy mechanizm harmonijki. Podsumowując, wykonaliśmy poniższe kroki: Q pobranie klikniętego elementu h1, Q usunięcie klasy active ze wszystkich elementów h1, Q dodanie klasy active do klikniętego elementu h1, Q ukrycie widocznych sekcji harmonijki, Q wyświetlenie elementu div klasy container znajdującego się za klikniętym elementem h1.

I coś jeszcze Używanie różnych znaczników w harmonijce Tworząc harmonijkę, nie musimy ściśle trzymać się z góry wyznaczonych znaczników. W naszym przykładzie zastosowaliśmy elementy h1 i div do oznaczania nagłówków i treści sekcji. Możemy jednak wykorzystać też listy wypunktowane, znaczniki łączy, a także dowolny inny znacznik i uzyskać dokładnie te same rezultaty. Trzeba tylko pamiętać o odpowiednim dopasowaniu kodu JavaScript oraz stylów CSS, ponieważ poszczególne znaczniki są inaczej wyświetlane przez przeglądarki. Jako ćwiczenie proponuję spróbować zaimplementować harmonijkę za pomocą znaczników ul i li.

Stopniowe ukrywanie elementu po jego zaktualizowaniu W nowoczesnych aplikacjach WWW, w których poszczególne elementy strony są aktualizowane bez przeładowywania całości, niezbędne jest poinformowanie użytkownika o zmianach, które zostały wprowadzone. Bez takich powiadomień użytkownik może nie zauważyć, że zawartość pewnej części strony się zmieniła.

185

PHP i jQuery. Receptury

Jednym z często stosowanych rozwiązań jest tutaj technika YFT, czyli Yellow Fade Technique (technika płowiejącej żółci). Ogólna idea jest tutaj bardzo prosta. W momencie wprowadzenia zmiany w danej części strony jej tło otrzymuje kolor żółty, który z czasem staje się coraz bledszy, aż w końcu tło wraca do koloru pierwotnego. W ten sposób zwracamy uwagę użytkownika na zaktualizowaną część strony. Mimo swojej prostoty technika ta doskonale się sprawdza w czasie tworzenia aplikacji AJAX. Podstawowa biblioteka jQuery nie udostępnia tego efektu, ale za to znajdziemy go w dodatkowej bibliotece jQuery UI. Chcąc wykorzystać ten efekt, musimy jednak dołączyć do naszej strony dodatkowe pliki effects.core.js oraz effects.highlight.js pochodzące z biblioteki jQuery UI. Z drugiej strony możemy też wykorzystać wtyczkę jQuery easing dostępną na stronie http://gsgd.co.uk/sandbox/jquery/easing/. W tej recepturze nauczymy się, jak stworzyć podobny efekt za pomocą zaledwie kilku wierszy kodu, bez konieczności dołączania dodatkowych plików.

Przygotowania W katalogu rozdzial6 utwórz nowy katalog o nazwie receptura4.

Jak to zrobić? 1. W katalogu receptura4 utwórz nowy plik o nazwie index.html. 2. Do utworzonego pliku wpisz kod HTML tworzący pole tekstowe i przycisk. Oprócz tego utwórz też element p, w którym prezentowany będzie efekt podświetlenia. Efekt specjalny



186

Rozdział 6. • Efekty specjalne w formularzach

3. Teraz dołącz plik biblioteki jQuery i napisz kod, który po kliknięciu przycisku pobierze wartość pola tekstowego i wpisze ją do elementu p. Następnie element ten powinien zostać wyróżniony za pomocą funkcji fade().

4. I to już wszystko. Możemy już podziwiać przygotowany przez siebie efekt. Uruchom plik index.html w przeglądarce i wpisz w polu tekstowym swoje imię. Teraz kliknij przycisk Pokaż, a poniżej pojawi się akapit z tekstem wpisanym do formularza. Początkowe żółte tło akapitu będzie powoli blakło, aż wróci do pierwotnej barwy.

187

PHP i jQuery. Receptury

Jak to działa? Idea jest taka: aby zmienić kolor elementu z żółtego na biały, musimy zacząć od nadania mu koloru żółtego, a następnie zmieniać wartości RGB tak, żeby powoli zmieniać ten kolor w biały. I tak właśnie tutaj postępujemy. Na początek wstawiamy w tło akapitu kolor RGB o wartości 255, 255, 100, a następnie zwiększamy tę ostatnią wartość o 10 aż do osiągnięcia koloru RGB 255, 255, 255, czyli białego. Aby rozłożyć proces modyfikowania koloru w czasie, wykorzystujemy funkcję języka JavaScript setInterval(), dzięki której zmiana koloru następuje do 100 milisekund. Najpierw deklarujemy zmienne base i interval. Następnie do zdarzenia click przycisku dołączamy funkcję YFT(), która pobiera wartość z pola tekstowego i wstawia ją do akapitu. Następnie wpisujemy do zmiennej base wartość 100 i wywołujemy funkcję setInterval(), która co 100 milisekund będzie wywoływać funkcję fade(). W ramach funkcji fade() sprawdzamy wartość, jaka aktualnie zapisana jest w zmiennej base. Jeżeli wartość ta przekroczy 255, to funkcja fade() nie będzie więcej wywoływana. Będzie to oznaczało, że kolor tła akapitu jest już biały. Jeżeli jednak wartość zmiennej base nadal jest mniejsza od 255, to modyfikujemy barwę akapitu zmienioną wartością RGB, przy czym składowe R i G nadal będą miały wartość 255, a wartość składowej B zostanie zwiększona o 10. Jak już wcześniej wspominałem, funkcja setInterval() będzie wywoływała funkcję fade(), aż wartość składowej B przekroczy 255.

Wyświetlanie pływającego okienka na żądanie Wyobraźmy sobie stronę, na której wypisana jest długa lista produktów, z której możemy wybrać kilka pozycji, a wtedy aktualizowana jest lista w osobnym kontenerze. Po dotarciu wreszcie do końca strony możemy już nie pamiętać, co właściwie wybraliśmy, a okienko z wybranymi pozycjami znajduje się przy górnej krawędzi strony. Czyż nie byłoby wspaniale, gdyby takie pomocnicze okienko przesuwało się tak, żeby było zawsze widoczne, niezależnie od tego, którą część strony aktualnie oglądamy? Innymi słowy, musimy przygotować pływające okienko, które będzie przemieszczało się wraz z przewijaniem widoku strony. W tej recepturze zajmiemy się zatem tworzeniem pływającego okienka, które automatycznie będzie przesuwało się w dół i w górę strony.

188

Rozdział 6. • Efekty specjalne w formularzach

Przygotowania W katalogu rozdzial6 utwórz nowy katalog i nazwij go receptura5.

Jak to zrobić? 1. W katalogu receptura5 utwórz nowy plik o nazwie index.html. 2. Chcąc zaprezentować pływający element div, musimy przygotować sobie naprawdę długą stronę. W tym celu tworzymy kilka elementów akapitu i każdemu z nich nadajemy wysokość 200 pikseli (używamy do tego stylów CSS). Następnie tworzymy element div, który zmienimy w pływające okienko, korzystając z funkcji biblioteki jQuery, i przypisujemy mu klasę CSS oraz identyfikator float. Definiując styl CSS dla tego elementu, nie możemy zapomnieć o przypisaniu właściwości position wartości absolute. To właśnie dzięki temu nasze okienko zostanie oderwane od pozostałych części strony. Pływające okienko

Bardzo ciekawy tekst

Bardzo ciekawy tekst

189

PHP i jQuery. Receptury

Bardzo ciekawy tekst

Bardzo ciekawy tekst

Bardzo ciekawy tekst

Bardzo ciekawy tekst

Bardzo ciekawy tekst

Bardzo ciekawy tekst

Pływające okienko


3. Mamy już przygotowany kod HTML strony, a zatem możemy przystąpić do zmiany elementu div w pływające okienko. Na początek musimy oczywiście dołączyć wspaniałą bibliotekę jQuery. Następnie skorzystamy z funkcji floatDiv(), która zmieni nasz element div w pływające okienko. Po zdefiniowaniu tej funkcji dodajemy funkcję obsługi do zdarzenia przewijania okna, która będzie wywoływana przy każdym przewinięciu strony w górę lub w dół. Na koniec wywołujemy funkcję floatDiv(), tak żeby zaraz po załadowaniu strony element div stał się pływającym okienkiem.

190

Rozdział 6. • Efekty specjalne w formularzach

4. Uruchom w przeglądarce plik index.html i przewiń stronę w dół i w górę za pomocą klawiatury lub myszy. Zobaczysz, że nasze pływające okienko cały czas znajduje się w prawym górnym rogu strony, niezależnie od tego, która jej część jest aktualnie wyświetlana.

Jak to działa? Za tworzenie pływającego okienka z elementu div odpowiadają dwie funkcje. Pierwsza z nich to funkcja $(document).scrollTop(), która zwraca nam liczbę całkowitą określającą liczbę pikseli do górnej krawędzi okna przeglądarki, do aktualnej pozycji paska przewijania. Druga funkcja to animate(), której używamy do tworzenia własnych animacji za pomocą biblioteki jQuery. Do obiektu okna przypięliśmy funkcję floatDiv(), która zajmie się obsługą zdarzenia scroll. Będzie ona wywoływana za każdym razem, gdy użytkownik przewinie stronę za pomocą myszy lub klawiatury. Wewnątrz funkcji floatDiv() pobieramy z obiektu dokumentu wartość scrollTop, dodajemy ją do zmiennej defaultOffset i zapisujemy wynik do zmiennej offsetTop. W zmiennej defaultOffset zapisaliśmy wcześniej wartość 50, co oznacza, że pływające okienko zawsze będzie miało odstęp 50 pikseli od górnej krawędzi okna przeglądarki. Do zdefiniowania wartości pozycji górnej krawędzi elementu div wykorzystujemy funkcję animate(). Proszę zauważyć, że funkcji podajemy też opcję duration z wartością 500, przez co cała animacja będzie trwała dokładnie 500 milisekund. Drugą opcją jest queue z przypisaną wartością false, dzięki czemu biblioteka jQuery nie będzie czekać na zakończenie poprzedniej animacji, aby rozpocząć nową.

191

PHP i jQuery. Receptury

Na koniec zaraz po załadowaniu dokumentu DOM wywołujemy jeszcze funkcję floatDiv(). Jest to konieczne, jeżeli chcemy, żeby nasze okienko było pływające już od momentu załadowania strony. Całość można wypróbować, przewijając stronę w górę i w dół, a następnie naciskając klawisz F5. Przygotowane przez nas okienko będzie zawsze zajmowało to samo miejsce na stronie, niezależnie od jej aktualnej pozycji.

I coś jeszcze Ważna informacja o funkcji animate() Za pomocą funkcji animate() można tworzyć animacje innych właściwości przyjmujących wartości liczbowe. Właściwości nieliczbowych, takich jak color lub background-color, nie można animować w ten sposób. Na przykład proszę spojrzeć na poniższy kod: $('#float').animate({backgroundColor: "#ffffcc"},{duration:500,queue:false});

Jest to właśnie przykład niewłaściwego wykorzystania funkcji animate(). Z drugiej jednak strony poniższy przykład będzie działał doskonale: $('#float').animate({width: 500},{duration:500,queue:false});

Aktualizowanie pozycji w koszyku na zakupy Spróbujemy tutaj przygotować prostą stronę z listą produktów uzupełnioną o informacje o cenie i liczbie wybranych sztuk. Użytkownik będzie mógł tutaj wybrać dowolną liczbę produktów i ta informacja zostanie przesłana do serwera. Skrypt działający na serwerze będzie wyliczał cenę zamówienia i wyświetlał ją od razu na stronie. Jest to działanie podobne do koszyka na zakupy dostępnego na wielu stronach WWW. Różnica polega na tym, że nie będziemy tutaj mieli przeładowywania strony, dzięki czemu użytkownik nie będzie musiał tak długo czekać na dane. Ta receptura będzie tylko prostym przykładem, który można dowolnie rozbudowywać, tak żeby dopasować go do własnych wymagań.

Przygotowania W katalogu rozdzial6 utwórz nowy katalog i nazwij go receptura6. Następnie w tym samym katalogu utwórz plik XML, w którym zapiszemy listę książek. Każda z nich będzie miała identyfikator, tytuł oraz cenę. Z tego pliku będziemy korzystać przy wyświetlaniu na stronie listy książek dostępnych dla użytkownika. Utworzony plik nazwij books.xml. 192

Rozdział 6. • Efekty specjalne w formularzach

Książka o PHP 35 Książka o jQuery 35 Książka o API Twittera 35 Podstawy Facebooka 35

Jak to zrobić? 1. W katalogu receptura6 utwórz plik o nazwie index.php. Kod z tego pliku będzie zapisywał pustą tablicę w sesji, którą wykorzystamy jako koszyk przechowujący informacje o wybranych książkach. Następnie zdefiniuj element div, który posłuży nam za koszyk. W kolejnym kroku wypisz listę książek wraz z ich cenami, odczytując dane z pliku XML za pomocą funkcji simplexml. Dla każdej książki wypisz jej tytuł, cenę, listę rozwijaną pozwalającą na wybranie liczby sztuk oraz przycisk do zapisania dokonanego wyboru. Oprócz tego przy każdej książce będziemy też potrzebować ukrytego pola, w którym zapisany będzie jej identyfikator. Koszyk sklepowy
Twój koszyk

Koszyk jest pusty

book as $book) { echo '
'; echo 'Tytuł - '. $book->name,'
'; echo 'Cena - '. $book->price,' PLN
'; ?> Liczba '; } ?>

W efekcie uzyskamy następujący wygląd strony:

194

Rozdział 6. • Efekty specjalne w formularzach

2. Teraz dołącz plik biblioteki jQuery i zapisz funkcję obsługującą kliknięcia przycisków Wybierz tę książkę. Kliknięcie takiego przycisku będzie wysyłało żądanie AJAX skierowane do pliku PHP o nazwie calculate.php. Żądanie to będzie przenosiło identyfikator wybranej książki oraz liczbę sztuk. W momencie odebrania odpowiedzi od skryptu PHP wstawimy ją do elementu o identyfikatorze cart.

3. Przejdźmy teraz na stronę serwera. Utwórz zatem nowy plik i nazwij go calculate.php. To właśnie tutaj obsługiwane będą żądania AJAX. Najpierw sprawdzamy, czy wybrana książka jest już zapisana w sesji. Jeżeli tak nie jest, to zapisujemy w sesji identyfikator 195

PHP i jQuery. Receptury

książki oraz liczbę sztuk wybranych przez użytkownika, a w przeciwnym wypadku aktualizujemy jedynie informację o liczbie sztuk. W ostatnim kroku tworzymy kod HTML z informacją o stanie koszyka. Wypisujemy tu wszystkie wybrane książki, liczbę sztuk, cenę, a na koniec podajemy jeszcze ogólną wartość książek. 0) { for($i=0; $i< count($booksInfo); $i++) { if($booksInfo[$i]['bookId'] == $_POST['bookId']) { $booksInfo[$i]['quantity'] = $_POST['quantity']; $bookFound = true; break; } } } if(!$bookFound) { $book = array('bookId' => $_POST['bookId'], 'quantity' => $_POST['quantity']); array_push($booksInfo, $book); } $_SESSION['cart'] = $booksInfo; $grossTotal = 0; $str=''; for($i=0; $i< count($booksInfo); $i++) { $aBook = $booksInfo[$i]; $bookName = getBookName($booksInfo[$i]['bookId']); $bookPrice = getPriceForBook($booksInfo[$i]['bookId']); $totalPrice = $bookPrice * $booksInfo[$i]['quantity']; $grossTotal+= $totalPrice; $str.= 'Tytuł - '.$bookName; $str.= '
'; $str.= ' Egzemplarzy - '.$booksInfo[$i]['quantity']; $str.= '
'; $str.= 'Cena - '.$bookPrice. ' PLN * ' .$booksInfo[$i]['quantity'].' = '.$totalPrice.' PLN'; $str.= '

'; } $str.= 'Suma zamówienia - '.$grossTotal.' PLN'; echo $str; function getBookName($id) { $objXML = simplexml_load_file('books.xml'); foreach($objXML->book as $book)

196

Rozdział 6. • Efekty specjalne w formularzach

{

if($book['id'] == $id) { return $book->name; }

} return false;

} function getPriceForBook($id) { $objXML = simplexml_load_file('books.xml'); foreach($objXML->book as $book) { if($book['id'] == $id) { return $book->price; } } return false; }

?>

4. I wszystko gotowe! Możemy już sprawdzić, jak działa nasz przykład. Uruchom w przeglądarce plik index.php. Zobaczysz listę dostępnych książek, a po prawej stronie okienko koszyka. Wybierz liczbę sztuk dowolnej książki i kliknij przycisk Wybierz tę książkę. Dane w okienku koszyka zostaną zaktualizowane. Spróbuj teraz wybrać wiele książek i zmieniać im liczbę sztuk. Koszyk powinien zawsze odzwierciedlać wszystkie dokonane przez nas wybory.

197

PHP i jQuery. Receptury

Jak to działa? Kod PHP w pliku index.php jest względnie prosty. Tworzymy w nim pustą tablicę $booksInfo i zapisujemy ją w sesji. To właśnie w tej tablicy będziemy przechowywać wybory dokonane przez użytkownika. Następnie za pomocą funkcji simplexml_load_file() ładujemy plik books.xml. Iterując po elementach book, tworzymy kod HTML, który wyświetla na stronie listę książek dostępnych w sklepie. Obok danych poszczególnych książek tworzymy też ukryte zmienne przechowujące ich identyfikatory, których będziemy potrzebować podczas przesyłania danych do serwera. Przyjrzyjmy się teraz kodowi korzystającemu z biblioteki jQuery. Po kliknięciu przycisku Wybierz tę książkę pobieramy wartość wybranej książki oraz jej ukryty identyfikator, wykorzystując do tego selektory jQuery. Zebrane dane wysyłamy następnie do pliku PHP o nazwie calculate.php za pośrednictwem żądania AJAX. Funkcja wywoływana po otrzymaniu odpowiedzi na to żądanie wstawia tylko przesłany tekst do elementu o identyfikatorze cart. Prawdziwe czary dzieją się jednak po stronie serwera, w pliku calculate.php. Na początek przyjrzyjmy się strukturze tablicy $booksInfo. Przechowujemy w niej identyfikatory książek wybranych przez użytkownika razem z informacją o liczbie sztuk. Sama tablica ma następującą strukturę: Array ( [0] => Array ( [bookId] => 1 [quantity] => 1 ) [1] => Array ( [bookId] => 3 [quantity] => 2 ) )

Kod w pliku calculate.php zaczyna się od wywołania funkcji session_start(), która inicjuje aktualną sesję w języku PHP. Następnie z uzyskanej sesji wydobywamy tablicę $booksInfo. Teraz sprawdzamy, czy wybrana przez użytkownika książka (jej identyfikator pobrany ze zmiennej $_POST['bookId']) jest już zapisana w tej tablicy. Jeżeli znajdziemy w niej identyfikator, to aktualizujemy tylko liczbę sztuk wartością otrzymaną w żądaniu AJAX ($_POST['quantity']). Jeżeli jednak książki jeszcze nie ma w tablicy $booksInfo, to tworzymy dla niej nową tablicę z danymi książki i wstawiamy jako kolejny element tablicy $booksInfo. W kolejnym kroku zapisujemy tablicę $booksInfo do aktualnej sesji.

198

Rozdział 6. • Efekty specjalne w formularzach

Teraz przystępujemy do obliczania ceny wszystkich książek wybranych przez użytkownika. W tym celu iterujemy po tablicy $booksInfo i pobieramy tytuł oraz cenę poszczególnych książek. Do pobierania tytułu książki przygotowaliśmy sobie specjalną funkcję o nazwie getBookName(), która przyjmuje w parametrze identyfikator książki i szuka go w pliku books.xml. Po znalezieniu właściwego węzła w strukturze XML funkcja zwraca ciąg znaków z tytułem książki. Podobnie działa funkcja getPriceForBook(), ale zwraca jednostkową cenę wybranej książki. Po uzyskaniu tych dwóch wartości tworzymy kod HTML wyświetlający tytuł każdej książki wraz z jej ceną. Na zakończenie podajemy jeszcze sumę zamówienia. Po obsłużeniu wszystkich książek zamówionych przez użytkownika odsyłamy przygotowany kod HTML do przeglądarki. Biblioteka jQuery po otrzymaniu odpowiedzi na wysłane wcześniej żądanie wstawia tekst do elementu o identyfikatorze cart. W tej recepturze stosujemy bardzo ważne rozwiązanie. Moglibyśmy przecież wykonywać wszystkie obliczenia po stronie klienta, używając do tego biblioteki jQuery, więc po co przesyłać na serwer dane każdego wyboru dokonanego przez użytkownika? Chodzi o to, że obliczenia wykonywane po stronie klienta można dowolnie zmanipulować, wprowadzając zmiany za pomocą takich narzędzi, jak Firebug. To dlatego całość obliczeń prowadziliśmy po stronie serwera, a w przeglądarce wyświetlaliśmy tylko ich wyniki. W takiej sytuacji użytkownik nie może wpływać na wykonywane kalkulacje, a serwer raczej nie powinien pomylić się podczas dodawania.

I coś jeszcze Usuwanie pozycji z koszyka Można jeszcze zmodyfikować naszą recepturę tak, żeby oprócz dodawania pozwalała ona również na usuwanie pozycji z koszyka. Wystarczy w tym celu umieścić łącze przy każdym z elementów znajdujących się w koszyku. Kliknięcie tego łącza uruchomi żądanie AJAX, które prześle identyfikator książki na serwer. Skrypt PHP będzie mógł wtedy wyszukać otrzymany identyfikator w aktualnej sesji i usunąć odpowiadającą mu pozycję w tablicy $booksInfo.

Zobacz też Q Recepturę „Ładowanie danych XML z plików oraz ciągów znaków za pomocą

SimpleXML” z rozdziału 3. Q Recepturę „Korzystanie z elementów i atrybutów za pomocą SimpleXML” z rozdziału 3.

199

PHP i jQuery. Receptury

200

7 Tworzenie menu nawigacyjnych W tym rozdziale zajmiemy się: Q tworzeniem prostych menu rozwijanych, Q tworzeniem menu zmieniających kolor tła po wskazaniu myszą, Q tworzeniem menu harmonijkowego, Q tworzeniem menu pływającego, Q tworzeniem interfejsu do nawigacji w kartach, Q dodawaniem nowych kart, Q tworzeniem kreatora za pomocą kart.

Wprowadzenie Menu stanowią podstawę każdej witryny WWW. Spróbujmy sobie wyobrazić stronę bez menu. Nawigacja na niej byłaby praktycznie niemożliwa. Witryna wyposażona w dobre łącza nawigacyjne staje się natomiast bardzo przyjazna dla użytkowników. Oznacza to, że dobre menu nawigacyjne są kluczem do zadowolenia użytkownika. W tym rozdziale przyjrzymy się kilku technikom pozwalającym nam na tworzenie różnego rodzaju menu. Zaczniemy od najprostszych menu rozwijanych, a potem przejdziemy do menu harmonijkowych oraz pływających.

PHP i jQuery. Receptury

Na zakończenie przygotujemy mechanizm nawigacji w kartach i zbadamy kilka metod implementacji kart.

Tworzenie prostych menu rozwijanych W tej recepturze przygotujemy proste menu rozwijane składające się z trzech pozycji. Umieszczenie wskaźnika myszy nad jedną z nich spowoduje wyświetlenie podmenu, a przesunięcie wskaźnika poza pozycję menu spowoduje ukrycie wyświetlonego wcześniej podmenu.

Przygotowania W katalogu rozdzial7 utwórz nowy katalog o nazwie receptura1. W nowym katalogu utwórz plik i nazwij go index.html.

Jak to zrobić? Zaczniemy od tworzenia struktury menu oraz dopasowanych do niego stylów CSS. Samo menu zostanie zbudowane z listy wypunktowanej, w której każda pozycja stanie się nagłówkiem menu. W elemencie listy umieścimy znacznik a, a w nim tekst pozycji menu. Obok znajdzie się kolejna lista wypunktowana, której elementy posłużą nam za pozycje podmenu. Każdy z tych elementów będzie zawierał łącze pozwalające na nawigowanie po stronie. 1. Podczas pisania kodu HTML musimy pamiętać też o tym, że całe menu musi być dostępne na stronie nawet wtedy, gdy wyłączymy obsługę języka JavaScript w przeglądarce. Poniższy kod definiuje omawianą przed momentem stronę: Menu jQuery

2. Teraz utwórz plik o nazwie style.css, który dołączaliśmy już do pliku index.html, i wpisz do niego poniższe style CSS. body { font-family:"Trebuchet MS",verdana; } ul { list-style:none; margin:0; padding:0; } li.menuHeader { border:1px solid #fff; float:left; padding:5px 10px; text-align:center; width:120px; } ul.menuItem { margin-top:5px; } .menuItem > li { padding:5px 10px;

203

PHP i jQuery. Receptury

} a { color:#fff; } .about{ background-color:#6D9931;} .products{ background-color:#D63333;} .tech{ background-color:#D49248;}

Zaprezentowany poniżej rysunek przedstawia aktualny wygląd naszej strony.

3. Przez zamykającym znacznikiem body dołącz plik biblioteki jQuery. Teraz ukryjemy elementy podmenu i przygotujemy funkcję obsługi zdarzenia, która zajmie się wyświetlaniem i ukrywaniem podmenu zależnie od pozycji wskaźnika myszy.

4. Zapisz plik i otwórz go w przeglądarce. Zobaczysz nagłówki trzech menu rozwijanych. Wskaż myszą dowolny z nich, a pojawi się powiązane z tym nagłówkiem podmenu. Przesunięcie wskaźnika myszy poza nagłówek spowoduje ponownie ukrycie podmenu.

204

Rozdział 7. • Tworzenie menu nawigacyjnych

Jak to działa? Zaczynamy od przygotowania kodu HTML tworzącego strukturę menu. Zastosowaliśmy tu listę wypunktowaną, która przechowuje wszystkie pozycje menu i podmenu. Każda pozycja menu ma przypisaną klasę menuHeader. W każdym z tych elementów znajduje się znacznik a przechowujący tekst pozycji. W rzeczywistych zastosowaniach przypiszemy jeszcze faktyczną wartość do atrybutu href, tak żeby pozycja menu odsyłała użytkownika do konkretnej strony. Zaraz za łączem umieszczamy kolejną listę wypunktowaną, w której umieścimy pozycje tego menu rozwijanego. W liście tej może znaleźć się wiele pozycji, a każda z nich musi być wyposażona w łącze nawigacyjne. Po załadowaniu dokumentu DOM biblioteka jQuery ukrywa wszystkie elementy klasy menuItem. Jak już wcześniej wyjaśniałem, elementy te reprezentują pozycje menu, które powinny zostać ukryte zaraz po załadowaniu strony. Oznacza to, że początkowo widoczne będą jedynie nagłówki menu. Następnie za pomocą funkcji hover() włączamy animację menu. Jak dowiedzieliśmy się we wcześniejszych recepturach, funkcja hover() przyjmuje w parametrach dwie funkcje, które wykonywane są, w momencie gdy wskaźnik myszy znajdzie się nad elementem i gdy wskaźnik zostanie przesunięty poza ten element. W pierwszej funkcji wybieramy element ul znajdujący się w bieżącej pozycji listy i wywołujemy na jego rzecz metodę slideDown(), która wyświetla menu rozwijane. Podobnie druga funkcja wywołuje tylko metodę slideUp() ukrywającą menu po przesunięciu myszy.

I coś jeszcze Otwieranie menu kliknięciem Możemy też przygotować menu, które będzie się otwierało dopiero po kliknięciu. Poniższy kod otworzy menu rozwijane i jednocześnie ukryje wszystkie aktualnie otwarte inne menu.

205

PHP i jQuery. Receptury

$(".menuHeader > a").click(function(){ $('.menuItem:visible').slideToggle(); $('ul', $(this).parent()).slideToggle(); });

Zobacz też Q Recepturę „Tworzenie menu zmieniającego kolor tła po wskazaniu myszą”. Q Recepturę „Tworzenie menu harmonijkowego”.

Tworzenie menu zmieniającego kolor tła po wskazaniu myszą W tej recepturze nauczymy się tworzyć menu podświetlające pozycję wskazywaną przez mysz. Pozostałe pozycje zostaną przyciemnione, tak że na pierwszy plan wybijać się będzie pozycja wskazana myszą.

Przygotowania W katalogu rozdzial7 utwórz nowy katalog o nazwie receptura2. Oprócz tego w nowym katalogu utwórz też plik o nazwie index.html. Przygotuj trzy obrazki, które wykorzystamy jako tło dla naszych menu. Każdy z tych obrazków powinien mieć wielkość 120×41 pikseli.

206

Rozdział 7. • Tworzenie menu nawigacyjnych

Jak to zrobić? 1. Na początek przygotuj strukturę HTML tworzącą menu. Wpisz kod listy wypunktowanej z trzema elementami. Każdemu z elementów przypisz klasę menuHeader, z której później będzie korzystać biblioteka jQuery. Kolejna nazwa klasy będzie służyła nam do dodawania obrazka tła. W każdym elemencie li umieść łącze i wpisz do atrybutu href adres strony docelowej. Menu jQuery

2. Teraz utwórz nowy plik o nazwie style.css, w którym zdefiniuj podane niżej style: body{ font-family:"Trebuchet MS",verdana; } ul { list-style:none; margin:0; padding:0; } li.menuHeader { border:1px solid #fff; cursor:pointer; float:left; padding:5px 10px; text-align:center;

207

PHP i jQuery. Receptury

width:120px; } a{ color:#fff;} .about{ background-image:url(1_1.png);} .products{ background-image:url(1_2.png);} .tech{ background-image:url(1_3.png);}

3. Dołącz plik biblioteki jQuery. Następnie ustal przezroczystość wszystkich pozycji menu na 0.5, tak żeby po załadowaniu strony wyglądały na przyciemnione. Do każdego nagłówka menu podłącz funkcję obsługującą zdarzenie hover, która będzie podświetlała pozycję wskazaną myszą przez użytkownika. Gdy tylko wskaźnik myszy zostanie usunięty znad nagłówka menu, powinniśmy przywrócić jego początkowy stan.

4. Uruchom w przeglądarce plik index.html, a zobaczysz trzy wyblakłe pozycje menu. Wskaż jedną z nich myszą, a zostanie ona powoli podświetlona. Dodatkowo tekst tej pozycji staje się pogrubiony i pisany wielkimi literami. Na poniższym rysunku zobaczyć można wygląd menu z jedną pozycją wskazaną myszą.

208

Rozdział 7. • Tworzenie menu nawigacyjnych

Jak to działa? Na początek ustalamy przezroczystość wszystkich pozycji menu na wartość 0.5 za pomocą wyrażenia $("li.menuHeader").css("opacity", "0.5"). W ten sposób pozycje te będą wyglądały na przyciemnione. Ponownie będziemy tu wykorzystywać funkcję hover(), która wywoływana jest w momencie umieszczenia wskaźnika myszy nad elementem strony. Pierwsza przekazana jej funkcja (obsługuje zdarzenie wskazania pozycji menu) wywołuje funkcję animate(), aby powoli zmienić wartość przezroczystości elementu na 1. W drugim parametrze funkcji animate() podaliśmy wartość slow, a w trzecim funkcję wywoływaną po zakończeniu animacji. Funkcja ta wyszukuje pierwszy podelement aktualnej pozycji menu, nadaje jej właściwości CSS font-weight oraz text-transform, przez co tekst pozycji staje się pogrubiony i pisany wielkimi literami.

Zobacz też Q Recepturę „Tworzenie prostych menu rozwijanych”. Q Recepturę „Tworzenie menu harmonijkowego”.

Tworzenie menu harmonijkowego Harmonijek można też użyć jako menu. W końcu zawartość każdej sekcji harmonijki może być wykorzystana w dowolny sposób. W tej recepturze zajmiemy się tworzeniem prostej harmonijki, której użyjemy jako menu naszej strony. Nagłówki będą rozwijały sekcje z treścią, a w niej znajdzie się troszkę tekstu oraz łącze Czytaj więcej. Kliknięcie tego łącza spowoduje przesłanie żądania do pliku PHP, który odeśle tekst do wyświetlenia na stronie.

209

PHP i jQuery. Receptury

Takie rozwiązanie może przydawać się w sytuacji, gdy początkowo chcemy wyświetlić tylko podsumowanie (na przykład danych produktu), a pełną informację podawać tylko na żądanie. Jeżeli użytkownik zostanie zainteresowany tekstem podsumowania, to będzie mógł kliknąć łącze i przeczytać pozostałe informacje. W ten sposób zaoszczędzimy wiele miejsca na stronie, które można wykorzystać w inny sposób.

Przygotowania W katalogu rozdzial7 utwórz nowy katalog o nazwie receptura3.

Jak to zrobić? 1. W katalogu receptura3 utwórz nowy plik o nazwie index.html. Wpisz do niego kod HTML tworzący stronę z trzema sekcjami. Na górze znajdzie się nagłówek z nazwą strony. Poniżej strona zostanie podzielona na dwie części, które nazwiemy lewym i prawym panelem. W lewym panelu umieścimy kod tworzący harmonijkę. Znaczników h1 użyjemy tu jako nagłówków, a pod nimi umieszczać będziemy znaczniki div klasy containter, w których umieścimy treść oraz łącze pozwalające na pobranie z serwera danych odpowiednich dla danej sekcji harmonijki. W prawym panelu umieścimy tekst przesłany z serwera. W sekcji head kodu strony można też umieść kilka stylów CSS definiujących wygląd całej strony. Menu harmonijkowe

210

Rozdział 7. • Tworzenie menu nawigacyjnych

Moja wspaniała strona

PHP

PHP jest szeroko używanym, serwerowym językiem skryptowym... Czytaj więcej

jQuery

Za Wikipedią: lekka biblioteka programistyczna dla języka JavaScript... Czytaj więcej

AJAX

Ajax jest grupą technik tworzenia interaktywnych aplikacji dla sieci WWW... Czytaj więcej

JSON

JSON jest skrótem od JavaScript Object Notation, czyli notacji obiektów języka JavaScript... Czytaj więcej

Z lewego menu wybierz hasło, o którym chcesz uzyskać więcej informacji.



211

PHP i jQuery. Receptury

Tak przygotowana strona powinna wyglądać podobnie do poniższego rysunku:

2. Strona z poprzedniego rysunku nie korzysta jeszcze ze skryptów JavaScript i biblioteki jQuery. Dołącz zatem plik biblioteki jQuery, nie zapominając o podaniu właściwej ścieżki. Musimy teraz zrobić dwie rzeczy. Po pierwsze przygotować kod dla lewego panelu, który zmieni go w harmonijkę, a po drugie obsłużyć kliknięcia łącza Czytaj więcej, czyli pobierać odpowiednie dane z serwera. W tym celu musimy napisać dwie funkcje obsługi zdarzeń. Pierwsza z nich będzie wywoływana przy kliknięciu nagłówków harmonijki, a druga przy kliknięciu łącza Czytaj więcej. W tym drugim przypadku wywoływana będzie funkcja getData(), która wyśle żądanie do serwerowego skryptu data.php. Poprzez bibliotekę jQuery wyślemy też informację o tym, które z łączy zostało kliknięte.

3. Aby obsłużyć żądania AJAX przesyłane przez naszą stronę, utwórz w tym samym katalogu plik o nazwie data.php. W tym pliku umieścimy kod, który będzie odsyłał tekst odpowiedzi zależny od wartości otrzymanej w ramach żądania GET.
213

PHP i jQuery. Receptury

echo 'JSON jest skrótem od JavaScript Object Notation, czyli notacji obiektów języka JavaScript. i Opisuje on lekk i interaktywny format wymiany danych. Jest też określany jako odchudzona alternatywa dla języka XML. Jest to format tekstowy, niezależny od języka programowania, ale w języku JavaScript używany jest w sposób naturalny. Jest znacznie szybszy i mniej obciążający system niż XML. Głównym popularyzatorem tego formatu jest Douglas Crockford.'; break; } ?>

4. Po zakończeniu tych prac uruchom w przeglądarce plik index.html i kliknij jeden z nagłówków harmonijki. Zostanie ona rozwinięta, a wszystkie pozostałe sekcje zostaną ukryte. W lewym panelu zobaczysz wtedy krótkie podsumowanie oraz łącze. Kliknij je, a biblioteka jQuery załaduje odpowiednie dane z pliku data.php. Jeżeli klikniesz łącze Czytaj więcej w sekcji AJAX, to w prawym panelu powinien pojawić się tekst pokazany na poniższym rysunku.

Jak to działa? Elementy div, którym przypisano klasę container, reprezentują części harmonijki, w których przechowywane są dane. Po załadowaniu dokumentu ukrywamy te części strony za pomocą wyrażenia $('container').hide(), dzięki czemu widoczne są tylko nagłówki harmonijki. W kolejnym kroku wszystkim elementom h1 harmonijki przypisujemy funkcję obsługującą zdarzenie

214

Rozdział 7. • Tworzenie menu nawigacyjnych

click. Kliknięcie nagłówka h1 powoduje usunięcie najpierw klasy active ze wszystkich nagłów-

ków harmonijki. Potem ukrywane są wszystkie widoczne aktualnie sekcje, a następnie dodajemy klasę active do klikniętego nagłówka i rozwijamy następujący po nim element div. W ten sposób na stronie pojawia się podsumowanie zagadnienia wybranego przez użytkownika, a nasze zadanie związane z obsługą lewego panelu jest ukończone. Teraz musimy jeszcze aktywować łącza Czytaj więcej. W związku z tym dodajemy funkcję nasłuchującą zdarzeń pochodzących z elementu div klasy container. Proszę zauważyć, że atrybut href każdego łącza ma w tekście zapytania zapisany parametr page, którego wartość jest różna w każdej sekcji harmonijki. Kliknięcie łącza wywołuje funkcję getData(), która pobiera wartość atrybutu href z klikniętego łącza, a następnie wysyła na ten adres żądanie AJAX za pośrednictwem metody get(). Żądanie to jest odbierane przez serwerowy skrypt data.php, który analizuje otrzymaną zmienną page (pobiera ją z tablicy $_GET). Na podstawie tej wartości instrukcja switch wybiera tekst, który

ma zostać odesłany do klienta. W przeglądarce biblioteka jQuery po otrzymaniu odpowiedzi umieszcza tekst w prawym panelu, czyli w elemencie div i identyfikatorze rightPanel. Nie można zapomnieć o tym, żeby w funkcji getData() zwrócić wartość false. W przeciwnym wypadku przeglądarka otworzy po prostu stronę wskazywaną przez łącze Czytaj więcej.

I coś jeszcze Harmonijka biblioteki jQuery UI Więcej funkcji i szersze możliwości harmonijki można uzyskać, stosując implementację z biblioteki jQuery UI. Jest ona dostępna na stronie biblioteki pod adresem http://jqueryui.com/demos/ accordion/.

Zobacz też Q Recepturę „Tworzenie rozwijanych i zwijanych ramek (harmonijek)” z rozdziału 6. Q Recepturę „Pobieranie danych z PHP za pomocą jQuery” z rozdziału 2.

215

PHP i jQuery. Receptury

Tworzenie menu pływającego W poprzednim rozdziale „Efekty specjalne w formularzach” nauczyliśmy się tworzyć pływające okienko, które zmienia swoją pozycję podczas przewijania strony w górę i w dół, tak żeby zawsze znajdować się w widocznej części. Z tego efektu możemy też skorzystać do tworzenia menu, które będzie ułatwiało użytkownikom pracę na długich stronach. Zazwyczaj, gdy użytkownik przewinie stronę za daleko w dół, będzie musiał przewinąć ją na samą górę, żeby dostać się do menu. Możemy zatem umieścić menu wewnątrz pływającego okienka, tak żeby było ono dostępne dla użytkownika niezależnie od tego, w której części strony się on znajduje. W tej recepturze wyjaśnię metody tworzenia takiego menu. Kliknięcie pozycji menu spowoduje wyświetlenie związanego z nim podmenu. Takie menu będą mogły mieć kilka poziomów zagnieżdżania.

Przygotowania W katalogu rozdzial7 utwórz nowy katalog i nazwij go receptura4.

Jak to zrobić? 1. W katalogu receptura4 utwórz nowy plik o nazwie index.html. 2. Menu będziemy tu tworzyć w taki sposób, żeby możliwe było zdefiniowanie dowolnej liczby zagnieżdżonych podmenu bez konieczności wprowadzania zmian w kodzie JavaScript. Z tego powodu kod HTML musi być przygotowany tak, żeby mechanizmy biblioteki jQuery mogły być stosowane na dowolnym poziomie podmenu. 3. W pierwszej kolejności utwórz na stronie długi akapit, tak żebyśmy mogli podziwiać efekt pływającego menu. Następnie utwórz element div, który stanie się naszym pływającym okienkiem. W elemencie tym znajdzie się też kod tworzący strukturę menu. Do tego celu wykorzystamy listę wypunktowaną, której elementy będą pozycjami menu. W każdym elemencie listy znajdzie się element span, a za nim kolejna lista wypunktowana, która będzie spełniać rolę podmenu. Wszystkie elementy span otrzymają klasę CSS menu, a wszystkie listy wypunktowane tworzące podmenu otrzymają klasę menuItem. Na zakończenie w elementach ostatniej listy w hierarchii można umieścić łącza kierujące nas do innych stron. Taką strukturę można zagnieżdżać dowolną liczbę razy. W naszym przykładzie przygotujemy menu o głębokości trzech poziomów. Style CSS niezbędne do odpowiedniego zaprezentowania wszystkich elementów menu zostaną umieszczone w sekcji head.

216

Rozdział 7. • Tworzenie menu nawigacyjnych

Menu pływające

217

PHP i jQuery. Receptury

Ten akapit ma wysokość 1000 pikseli i tworzy naprawdę długą stronę



218

Rozdział 7. • Tworzenie menu nawigacyjnych

Wyniki naszej pracy możemy podziwiać na poniższym rysunku.

4. Na razie nie ukryliśmy żadnych podmenu, dlatego takie rozwiązanie będzie działało dobrze nawet przy wyłączonej obsłudze języka JavaScript. Dodajmy teraz trochę magii biblioteki jQuery, aby nieco ożywić naszą stronę. Przed zamykającym znacznikiem body dołącz plik biblioteki. W pierwszym kroku dodaj metodę nasłuchującą zdarzeń przewijania okna. Będzie ona pozycjonowała okienko pływające w zależności od aktualnej pozycji strony. Następnie ukryj wszystkie podmenu i dodaj funkcję obsługującą zdarzenie click do elementów klasy menuItem.

5. I to już wszystko! Zapisz kod i uruchom plik index.html w przeglądarce. Zobaczysz długą stronę, którą można przewijać za pomocą suwaka. Po prawej stronie widoczne będzie okienko zawierające dwie pozycje menu. Za pomocą myszy lub klawiatury przewiń stronę w górę i w dół, a okienko z menu powinno przesuwać się razem ze stroną. Kliknij teraz dowolną z pozycji menu, a zostaną one rozwinięte, ukazując podmenu. Spróbuj otworzyć drugą pozycję: Pozycja menu2. Ukrywa się pod nią system trójpoziomowego menu. Na poniższym rysunku widoczne jest to właśnie menu z rozwiniętymi wszystkimi trzema poziomami.

Jak to działa? Zaczniemy od pływającego okienka. Funkcja floatDiv() wywoływana jest zaraz po załadowaniu strony albo po przewinięciu jej przez użytkownika. Funkcja pobiera pozycję suwaka liczoną od górnej krawędzi strony, wywołując metodę biblioteki jQuery $(document).scrollTop(), a następnie wywołuje metodę animate() i z jej pomocą, przez 250 milisekund, ustala wartość właściwości top naszego pływającego okienka. Funkcja ta wywoływana jest też po załadowaniu strony, tak żeby od samego początku ustalić właściwą pozycję okienka.

220

Rozdział 7. • Tworzenie menu nawigacyjnych

Po zakończeniu pracy funkcji floatDiv() pobieramy wszystkie elementy klasy menuItem i ukrywamy je. Nie zrobiliśmy tego w stylach CSS, ponieważ w przypadku wyłączenia obsługi języka JavaScript w przeglądarce użytkownik nie miałby możliwości skorzystania z wszystkich elementów menu. Wtedy nawigacja po stronie stałaby się koszmarem. Wyświetlenie podmenu w wyniku kliknięcia pozycji menu wymagało zastosowania funkcji nasłuchującej zdarzeń pochodzących z elementów span klasy menu. Gdy taki element zostanie kliknięty, pobieramy następujący po nim element ul (zawiera podmenu), wywołując metodę next(), i za pomocą funkcji slideToggle() przełączamy jej widoczność na ekranie. Dzięki zastosowaniu funkcji slideToggle() kolejne kliknięcia tej samej pozycji menu będą powodowały wyświetlenie lub ukrycie podmenu. W przeciwieństwie do funkcji show() lub hide() wpływa ona na wysokość elementu, tworząc efekt jego zwijania lub rozwijania. Przyjmuje ona parametry zbliżone do parametrów funkcji show() i hide(), dlatego można jej przekazać wartości slow, normal lub fast albo bezpośrednio podać liczbę milisekund trwania efektu.

Zobacz też Q Recepturę „Wyświetlanie pływającego okienka na żądanie” z rozdziału 6.

Tworzenie interfejsu do nawigacji w kartach Karty są bardzo użytecznym narzędziem pozwalającym zmieścić więcej treści na niewielkiej przestrzeni. W tej i kolejnych recepturach przyjrzymy się kilku technikom pozwalającym na tworzenie kart i wyświetlanie w nich danych.

Przygotowania W katalogu rozdzial7 utwórz nowy katalog i nazwij go receptura5.

Jak to zrobić? 1. W katalogu receptura5 utwórz plik o nazwie index.html. W tym samym katalogu utwórz jeszcze jeden plik i nazwij go tabs.css. Ten drugi będzie przechowywał style CSS elementów tworzących karty.

221

PHP i jQuery. Receptury

2. Otwórz plik index.html w edytorze i w sekcji head kodu HTML wpisz przede wszystkim referencję pliku tabs.css. Teraz przygotuj strukturę kart. Nagłówkami kart będą pozycje listy wypunktowanej, przy czym każda pozycja będzie nagłówkiem jednej karty. Zaraz za nią umieść element div, w którym znajdą się treści z poszczególnych kart umieszczone w osobnych elementach div. Pierwszej pozycji listy (nagłówkowi karty) przyporządkowany będzie pierwszy element div z treścią, druga pozycja listy zostanie związana z drugim elementem div itd. Oba elementy główne (listę i element div z treściami) umieść jeszcze w nadrzędnym elemencie div. Karty
  • Karta 1
  • Karta 2
  • Karta 3

Karta 1

Treść dla karty 1

Karta 2

Treść dla karty 2

Karta 3

Treść dla karty 3


3. Otwórz plik tabs.css w edytorze i zdefiniuj w nim właściwości CSS dla poszczególnych elementów strony. W tym przykładzie zastosujemy tylko bardzo ograniczoną stylizację, ale nic nie stoi na przeszkodzie, żeby dodać do kart obrazki lub zmienić ich kolory, uatrakcyjniając całą kompozycję. body { font-family:"Trebuchet MS",verdana;

222

Rozdział 7. • Tworzenie menu nawigacyjnych

margin: 50 auto; width:800px; } h3 { margin:0;padding:0; } ul { float: left; list-style: none; margin: 0pt; padding: 0pt; width:600px; } li { border-left:1px solid #000; border-right:1px solid #000; cursor:pointer; float:left; padding:5px; text-align:center; width:100px; } .tabContainer { border:1px solid #000; float:left; width:600px; } .tabContent { border-top:1px solid #000; float:left; height:100px; padding:5px; text-align:justify; width:590px; } .active { background-color:#6AA63B; color:white; }

223

PHP i jQuery. Receptury

Efekt naszych prac powinien być podobny do przedstawionego na poniższym rysunku:

4. Dołącz teraz plik biblioteki jQuery, stosując przy tym właściwą ścieżkę. Możemy już dopisać kod JavaScript, który zamieni nasze struktury w prawdziwe karty. Pierwszej karcie chcemy od razu nadać wygląd karty aktywnej, dlatego musimy zdefiniować funkcję showHideTabs(), która będzie wywoływana po kliknięciu nagłówka karty. Funkcja ta sprawi, że kliknięta karta stanie się aktywna i na ekranie pojawi się związana z nią treść.

5. Cały kod jest już gotowy. Uruchom plik index.html w przeglądarce. Zobaczysz trzy dostępne karty, ale tylko pierwsza z nich będzie oznaczona jako aktywna i tylko treść tej karty będzie widoczna na ekranie. Kliknięcie nagłówka innej karty spowoduje jednak, że to ona stanie się aktywna i zmieni się widoczna w przeglądarce treść. 224

Rozdział 7. • Tworzenie menu nawigacyjnych

Jak to działa? Logika działania kart nie jest szczególnie skomplikowana. Treść wszystkich kart przechowywana jest w elementach div klasy tabContent. Użyte w skrypcie wywołanie $('.tabContent:gt(0)').hide() ukrywa wszystkie elementy o indeksie większym od zera. Oznacza to, że początkowo widoczny będzie tylko pierwszy element div klasy tabContent. W kolejnym wierszu wyrażenie $('.tabHeader > li:eq(0)').addClass('active') dodaje klasę active do pierwszego elementu listy, dzięki czemu zostaje on wyróżniony. Następnie podłączamy do elementów listy funkcję obsługującą zdarzenie click. Kliknięcie powoduje wywołanie funkcji showHideTabs(), która zajmuje się przełączeniem aktywnej karty. Teraz zajmijmy się samą funkcją showHideTabs(). W pierwszej kolejności pobiera wszystkie elementy listy i usuwa z nich klasę active, wywołując w tym celu funkcję removeClass(). Następnie wywołuje funkcję addClass(), aby dodać klasę active do klikniętego elementu. W ten sposób wyróżniony zostaje kliknięty nagłówek karty. Pozostaje jeszcze wyświetlenie jej treści. Pobieramy zatem indeks klikniętego elementu listy, wywołując funkcję index(), która zwraca pozycję elementu w kolekcji, zaczynając numerację od zera. Następnie ukrywamy widoczny element div, wyszukując go za pomocą selektora :visible. Na zakończenie wyświetlamy jeszcze element div, którego indeks jest równy indeksowi klikniętego elementu listy. Jeżeli kliknięty zostanie drugi element listy, to jego indeks będzie równy 1. W związku z tym wywołanie $('.tabContent:eq('+index+')').show() pobierze element div o indeksie równym 1 i wyświetli go na ekranie.

Dodawanie nowych kart W tej recepturze przygotujemy nowe elementy uzupełniające poprzednią, w której nauczyliśmy się tworzyć karty. Tym razem zajmiemy się metodami dodawania nowych kart do zestawu już istniejących. Oczywiście możliwe będzie też określenie nazwy oraz treści nowych kart.

225

PHP i jQuery. Receptury

Przygotowania W katalogu rozdzial7 utwórz nowy katalog o nazwie receptura6.

Jak to zrobić? 1. W katalogu receptura6 utwórz nowy plik i nazwij go index.html. W tym samym katalogu utwórz dodatkowy plik o nazwie tabs.css. 2. Otwórz plik tabs.css w edytorze i wprowadź do niego poniższe właściwości elementów strony. Tym razem w pliku zapisanych będzie więcej właściwości niż w poprzedniej recepturze, ponieważ potrzebne nam będą też elementy umożliwiające wprowadzanie nazwy i treści nowej karty. body{ font-family:"Trebuchet MS",verdana;} ul { float: left; margin: 0pt; padding: 0pt; list-style: none; width:600px; } li { border-left:1px solid #000; border-right:1px solid #000; cursor:pointer; float:left; padding:5px; text-align:center; width:100px; } .tabContainer { border:1px solid #000; float:left; width:600px; } .tabContent { border-top:1px solid #000; float:left; height:200px; padding:5px; text-align:justify; width:590px; }

226

Rozdział 7. • Tworzenie menu nawigacyjnych

.newTabHolder { float:left; width:300px; } .active { background-color:DarkBlue; color:white; } .hide { display:none; } #error{ color:#ff0000;} .remove{float: right;font-weight:bold;color:#ff0000;} h4{ margin:0px;padding:0px; } label{float: left; width: 100px;} input,textarea{ width:185px;}

3. Przygotujemy teraz kod HTML tworzący karty. Wykorzystamy tutaj dokładnie tę samą strukturę, której użyliśmy w poprzedniej recepturze. Najpierw jednak wstawimy na stronę małe i duże pole tekstowe oraz jeden przycisk. Nazwę karty będziemy wprowadzać w małym polu tekstowym, a jej treść w dużym. Z kolei przyciskiem dodamy nową kartę po uprzednim wpisaniu jej danych. Otwórz zatem plik index.html w edytorze i wpisz do niego odwołanie do pliku tabs.css, a następnie uzupełnij kodem HTML przedstawionym poniżej: Karty

Dodaj nową kartę


  • Karta 1
  • Karta 2
  • Karta 3


227

PHP i jQuery. Receptury

Karta 1

Treść karty 1

Karta 2

Treść karty 2

Karta 3

Treść karty 3


Teraz nasza strona powinna wyglądać tak jak na poniższym rysunku:

228

Rozdział 7. • Tworzenie menu nawigacyjnych

4. Na początek dołącz plik biblioteki jQuery, nie zapominając o podaniu właściwej ścieżki. Oprócz aktywowania pierwszej karty i ukrycia wszystkich pozostałych napiszemy jeszcze funkcję addTab(), która będzie pobierała nazwę oraz treść karty i na ich podstawie dodawała nową kartę do już istniejących. Z poprzedniej receptury przejmiemy funkcje związane z przełączaniem aktywnej karty. W tym celu wykorzystamy funkcję showHideTabs(), która przełącza klikniętą kartę w stan aktywny i wyświetla przypisaną jej treść.

5. Zapisz plik index.html i uruchom go w przeglądarce. Po lewej stronie zobaczysz małe i duże pole tekstowe oraz przycisk. Po prawej stronie widoczne będą natomiast trzy karty, a pierwsza z nich będzie już aktywna. Wprowadź tekst do elementów z lewej strony okna i kliknij przycisk Dodaj nową kartę. Zostanie wtedy utworzona nowa karta, która pojawi się zaraz za już istniejącymi.

229

PHP i jQuery. Receptury

Jak to działa? Na początek muszę przypomnieć (choć mówiłem już o tym w poprzedniej recepturze), że funkcja showHideTabs() podłączana jest jako funkcja obsługi zdarzenia click nagłówków kart. W tej recepturze dodajemy nowe karty do już istniejących, a zatem chcielibyśmy, żeby zdarzenie click było obsługiwane również w nowych kartach. Oznacza to, że zamiast po prostu przyłączyć funkcję do zdarzenia click, wykorzystamy funkcję live(), która wiąże funkcję ze zdarzeniami w elementach tworzonych również później. Wróćmy teraz do dodawania nowej karty. Po kliknięciu przycisku Dodaj nową kartę wywoływana jest funkcja addTab(). Sprawdza ona, czy w polach tekstowych został wprowadzony jakiś tekst. Jeżeli którekolwiek z pól tekstowych nie zostało wypełnione, to wyświetlany jest komunikat o błędzie. Karta może zostać dodana jedynie w przypadku, gdy oba pola są wypełnione. Najpierw usuwana jest zawartość elementu span, w którym mógłby znajdować się komunikat o błędzie. W kolejnym wierszu tworzymy element listy z wpisaną nazwą karty (pobraną z małego pola tekstowego) i dodajemy go do listy wypunktowanej. Podobnie tworzymy też element div i wpisujemy do niego treść karty pobraną z dużego pola tekstowego, a następnie wstawiamy go do elementu div klasy contents. Wstawianemu elementowi div przypisujemy jeszcze klasę hide, przez co zostaje on ukryty i nie wpływa na aktualny wygląd strony. Dopiero kliknięcie nagłówka nowej karty spowoduje wyświetlenie jej zawartości.

I coś jeszcze Domyślne wyświetlanie nowej karty W podanym kodzie tworzona jest nowa karta, ale nie jest ona domyślnie ustawiana jako aktywna. Nic nie stoi jednak na przeszkodzie temu, żeby od razu wyświetlać nowo utworzoną kartę. W funkcji addTab() dodaj poniższe wiersze kodu na zakończenie bloku if.

230

Rozdział 7. • Tworzenie menu nawigacyjnych

$('#tabHeader > li').removeClass('active'); $('#tabHeader > li:last').addClass('active'); $('.tabContent:visible').hide(); $('.tabContent:last').show();

Ze względu na to, że nowa karta dodawana jest jako ostatnia, pierwsze dwa wiersze usuwają klasę active z nagłówków kart, a następnie dodają ją do ostatniej karty. Kolejne dwa wiersze ukrywają najpierw wszystkie elementy div klasy content, a potem wyświetlają ostatni z nich. Oznacza to, że widoczna będzie tylko ostatnio dodana karta.

Zobacz też Q Recepturę „Tworzenie interfejsu do nawigacji w kartach”. Q Recepturę „Dodawanie zdarzeń do elementów, które zostaną utworzone później”

z rozdziału 1.

Tworzenie kreatora za pomocą kart W tej recepturze dowiemy się, jak można przygotować kreatora, który będzie krok po kroku prowadził użytkownika strony.

Przygotowania W katalogu rozdzial7 utwórz nowy katalog o nazwie receptura7, a następnie utwórz w nim plik i nazwij go index.html.

Jak to zrobić? 1. Podobnie jak to było w poprzedniej recepturze, zaczniemy od przygotowania struktury kart, wykorzystując do tego elementy listy wypunktowanej jako nagłówki oraz elementy div klasy tabContent jako kontenery na treść. Nie zapomnij o dodaniu stylów CSS w sekcji head strony. Karty
  • Nazwisko
  • Wybór
  • Potwierdzenie

Proszę, podaj swoje nazwisko

Proszę, wybierz produkt

Wybierz liczbę sztuk

Potwierdzenie



233

PHP i jQuery. Receptury

Na każdej karcie znajduje się kilka dodatkowych elementów. Na pierwszej zobaczymy pole tekstowe oraz przycisk Dalej, który pozwoli nam przejść do następnej karty. Na drugiej karcie umieściliśmy dwie listy rozwijane oraz przyciski Wróć i Dalej, za pomocą których można przejść do poprzedniej lub następnej karty. Trzeciej i ostatniej karcie przypisaliśmy dodatkowo klasę last, a jej element div otrzymał identyfikator order. Umieściliśmy na niej przycisk Wróć. Ogólny wygląd strony można zobaczyć na poniższym rysunku.

2. Teraz dołącz plik biblioteki jQuery i przygotuj funkcje obsługujące kliknięcia przycisków Wróć i Dalej. Dla uproszczenia nie będziemy reagować na kliknięcia nagłówków kart, przez co użytkownik nie będzie mógł przejść bezpośrednio do wybranej karty. Funkcje obsługujące przyciski muszą najpierw pobrać indeks

234

Rozdział 7. • Tworzenie menu nawigacyjnych

aktualnej karty, a następnie wywołać funkcję showHideTabs(), która zajmie się przełączeniem kart zgodnie z podaną jej w parametrze wartością. Oprócz tego sprawdzi też, czy aktywowana została ostatnia karta. W takiej sytuacji biblioteka jQuery zbierze dane wprowadzone przez użytkownika na poprzednich kartach i wyświetli podsumowanie na ostatniej.

3. Zapisz plik i otwórz go w przeglądarce. Zobaczysz wtedy trzy znane nam już karty. Wprowadź dane do formularza na pierwszej karcie i kliknij przycisk Dalej. Na drugiej karcie wybierz produkt i liczbę sztuk, a następnie kliknij przycisk Dalej. Na ostatniej karcie zobaczymy tylko komunikat potwierdzający dokonany wcześniej wybór.

Jak to działa? Najpierw ukrywamy wszystkie karty z wyjątkiem pierwszej i dodajemy do niej klasę active. Następnie dołączamy funkcję obsługującą zdarzenie click przycisków Wróć i Dalej. Po kliknięciu przycisku wywołujemy funkcję getCurrentTabIndes(), pobieramy za jej pomocą indeks nadrzędnego elementu div i zapisujemy go w zmiennej currentTabIndex. W kolejnym kroku sprawdzamy klasę klikniętego przycisku. Jeżeli jest to klasa prev, to znaczy, że użytkownik chce przejść do poprzedniej karty, a zatem zmniejszamy wartość zmiennej currentTabIndex i przekazujemy ją do funkcji showHideTabs(). Podobnie, jeżeli kliknięty został przycisk klasy next, to do funkcji showHideTabs() przekazujemy powiększoną uprzednio wartość zmiennej currentTabIndex. Funkcja showHideTabs() najpierw usuwa klasę active z elementów listy, a następnie szuka elementu o indeksie równym wartości przekazanej jej w parametrze i jemu przypisuje klasę active. W kolejnym kroku ukrywany jest aktualnie widoczny element div klasy tabContent, a wyświetlany jest ten o pasującym numerze indeksu.

236

Rozdział 7. • Tworzenie menu nawigacyjnych

Na zakończenie funkcja sprawdza jeszcze, czy nie została aktywowana ostatnia karta, szukając w niej klasy last. Jeżeli to rzeczywiście jest ostatnia karta, wywoływana jest funkcja display ´SelectedValues(). Funkcja displaySelectedValues() pobiera tekst wprowadzony do pola tekstowego userName oraz wartości wybrane z list rozwijanych product i quantity, a następnie przygotowuje na ich podstawie sformatowany komunikat, który umieszczany jest w elemencie div o identyfikatorze order.

Zobacz też Q Recepturę „Tworzenie interfejsu do nawigacji w kartach”. Q Recepturę „Dodawanie nowych kart”.

237

PHP i jQuery. Receptury

238

8 Wiązanie danych w PHP i jQuery W tym rozdziale zajmiemy się: Q pobieraniem danych z bazy i wyświetlaniem ich w formie tabeli, Q zbieraniem danych z formularza i zapisywaniem ich w bazie (formularz rejestracyjny), Q wypełnianiem powiązanych ze sobą list rozwijanych, Q sprawdzaniem w bazie danych dostępności nazwy użytkownika, Q podziałem dużych ilości danych na strony, Q dodawaniem funkcji podpowiedzi do pól tekstowych, Q tworzeniem chmury znaczników.

Wprowadzenie W tym rozdziale znajdą się receptury, w których po stronie serwera będziemy korzystać z bazy danych oraz języka PHP. Baza danych jest nieodzownym elementem niemal każdej dynamicznej aplikacji WWW. Język PHP udostępnia wiele funkcji ułatwiających pracę z bazami danych. W połączeniu z językiem PHP najczęściej używanym rodzajem bazy danych jest MySQL. W tym rozdziale będziemy korzystać ze specjalnej wersji rozszerzenia MySQL o nazwie MySQLi, gdzie literka i oznacza improved, czyli usprawniony. Wprowadza ona wiele poprawek w stosunku do standardowego rozszerzenia MySQL, przy czym najważniejszą zmianą jest obsługa obiektowego interfejsu obok dotychczasowego interfejsu proceduralnego. Wśród innych funkcji można wymienić obsługę transakcji, instrukcje wbudowane i inne.

PHP i jQuery. Receptury

Więcej informacji na temat rozszerzenia MySQLi można znaleźć na stronach języka PHP pod adresem http://www.php.net/manual/pl/book.mysqli.php. Rozszerzenie MySQLi dostępne jest tylko dla PHP od wersji 5.0 i nowszych. Upewnij się zatem, że korzystasz z właściwej wersji. Jeżeli korzystamy z wersji PHP 5.0 lub nowszej, to musimy osobno skonfigurować rozszerzenie MySQL jako domyślne dla języka PHP, ponieważ jego obsługa w tych wersjach interpretera został zarzucona.

Czyszczenie danych przed ich użyciem W recepturach prezentowanych w tej książce bezpośrednio korzystamy z danych wprowadzonych przez użytkownika, pobierając je z tablic $_GET lub $_POST. W przykładach takie postępowanie jest do zaakceptowania, jednak w praktycznych zastosowaniach dane wprowadzane przez użytkownika muszą zostać odpowiednio oczyszczone, zanim zostaną na nich wykonane jakiekolwiek inne operacje. Tylko w ten sposób można zabezpieczyć swoją aplikację przed złośliwymi działaniami. Poniżej przedstawiam adresy, pod którymi można znaleźć więcej informacji na temat zabezpieczenia danych i ogólnego bezpieczeństwa aplikacji. Konsorcjum PHP Security: http://phpsec.org. Podręcznik języka PHP: http://www.php.net/manual/pl/security.php.

Pobieranie danych z bazy i wyświetlanie ich w formie tabeli Zaczynamy prostą recepturą, w której będziemy pobierać dane z tabeli i wyświetlać je na stronie. Użytkownik zobaczy na stronie listę rozwijaną, z której będzie mógł wybrać język programowania. Wybranie języka spowoduje pobranie z bazy listy funkcji razem z ich opisami.

Przygotowania W katalogu rozdzial8 utwórz nowy katalog o nazwie receptura1. Teraz za pomocą narzędzia phpMyAdmin utwórz bazę danych exampleDB, a w niej tabelę o nazwie language. Wykorzystaj do tego poniższe zapytanie: CREATE TABLE `language` ( `id` int(3) NOT NULL auto_increment, `languageName` varchar(50) NOT NULL, PRIMARY KEY (`id`) );

240

Rozdział 8. • Wiązanie danych w PHP i jQuery

Teraz wstaw do nowej tabeli dwa wiersze, wpisując w kolumnie languageName nazwy PHP i jQuery. Utwórz też kolejną tabelę o nazwie functions, do której będziemy wpisywać nazwy funkcji z opisami oraz odnośnikiem do języka programowania. CREATE TABLE `functions` ( `id` int(3) NOT NULL auto_increment, `languageId` int(11) NOT NULL, `functionName` varchar(64) NOT NULL, `summary` varchar(128) NOT NULL, `example` text NOT NULL, PRIMARY KEY (`id`) );

W polu languageID znajdzie się identyfikator języka zapisany wcześniej w tabeli language. Wstaw teraz do tabeli functions kilka wierszy, opisując w nich funkcje znane z języka PHP i biblioteki jQuery. Oto widok tej tabeli po wprowadzeniu do niej danych:

Jak to zrobić? 1. W katalogu receptura1 utwórz nowy plik i nazwij go index.php. Za pomocą metod klasy MySQLi wybierz dane z tabeli language i wprowadź je do listy rozwijanej. Oprócz tego utwórz element p, w którym będą wyświetlane funkcje wybranego języka.

241

PHP i jQuery. Receptury

query($query)) { if ($result->num_rows > 0) { ?>

Wybierz język

close(); } else { echo 'Błąd w zapytaniu: $query. '.$mysqli->error; } } $mysqli->close(); ?>

242

Rozdział 8. • Wiązanie danych w PHP i jQuery

2. Teraz dodaj referencję pliku jQuery i dopisz funkcję obsługującą zmianę wartości wybranej z listy rozwijanej. Funkcja ta powinna wysyłać żądanie AJAX do pliku PHP o nazwie results.php, który pobierze z bazy dane wskazanego języka i prześle do przeglądarki, gdzie zostaną one umieszczone w elemencie p.

3. Utwórz kolejny plik i nazwij go result.php. Zapisany w nim skrypt będzie łączył się z bazą danych exampleDB i pobierał z niej dane związane ze wskazanym językiem. Następnie utworzy kod HTML i umieści w nim wyniki zapytania, po czym odeśle je do przeglądarki, tak żeby biblioteka jQuery mogła wstawić otrzymany tekst do elementu p. query($query)) { if ($result->num_rows > 0) { $resultStr.='
    '; while($row = $result->fetch_assoc()) { $resultStr.= '
  • '.$row['functionName']. ´'- '.$row['summary']; $resultStr.= '
    '.$row['example'].'
    '; $resultStr.= '
  • '; } $resultStr.= '
'; } else

243

PHP i jQuery. Receptury

{ $resultStr = 'Nothing found'; } } echo $resultStr; ?>

4. Uruchom teraz w przeglądarce plik index.php, a zobaczysz listę rozwijaną pozwalającą na wybranie języka. Dostępne są w niej dwie pozycje: PHP i jQuery. Wybierz jedną z tych opcji, a poniżej pojawi się lista funkcji wraz z krótkim objaśnieniem.

Jak to działa? Na początku tworzymy nowy obiekt klasy MySQLi, wywołując jej konstruktor. Przekazujemy mu nazwę hosta, nazwę użytkownika bazy danych, hasło oraz nazwę samej bazy. Następnie sprawdzamy, czy podczas nawiązywania połączenia z bazą danych nie wystąpiły żadne błędy. Jeżeli nie udało się nawiązać połączenia, to wyświetlamy komunikat o błędzie i kończymy działanie skryptu.

244

Rozdział 8. • Wiązanie danych w PHP i jQuery

Następnie wywołujemy metodę query obiektu mysqli, aby pobrać z bazy wszystkie informacje o dostępnych językach. Jeżeli zapytanie zakończy się sukcesem, to zapisujemy wynik jego pracy w zmiennej $result. W zmiennej tej znajdzie się obiekt klasy MySQLi_Result, która udostępnia kilka metod pobierania danych z obiektu. W naszym przykładzie skorzystaliśmy z metody fetch_assoc(), która pobiera wiersze danych w postaci tablicy asocjatywnej. Następnie w pętli while iterujemy po kolejnych wierszach danych z obiektu $result. Na tym etapie tworzymy listę rozwijaną o identyfikatorze selectLanguage, którą wypełniamy wartościami pola languageName, a wartość pola ID wstawiamy jako wartość danej opcji. W kodzie biblioteki jQuery dołączamy do przygotowanej wcześniej listy rozwijanej funkcję obsługującą zdarzenie change. Pobiera ona wartość wybranej opcji i przesyła ją jako parametr żądania AJAX kierowanego do pliku resutls.php. Skrypt z pliku results.php łączy się najpierw z bazą danych exampleDB, a następnie tworzy zapytania pobierające z bazy informacje o konkretnym języku. Biblioteka jQuery przesłała identyfikator języka w ramach żądania AJAX i teraz informacja ta zostanie wykorzystana w budowanym zapytaniu. Podobnie jak to było w pliku index.php, pobieramy wyniki zapytania i zapisujemy je w zmiennej $result. Teraz możemy już iterować po wynikach zapytania i na ich podstawie przygotować listę wypunktowaną i wpisać ją do zmiennej $resultStr. Każda pozycja listy będzie składała się z nazwy funkcji, krótkiego opisu oraz przykładu użycia. W przypadku wystąpienia jakiegokolwiek błędu do zmiennej $resultStr zapisywany jest odpowiedni komunikat. Na zakończenie odsyłamy zawartość zmiennej $resultStr do przeglądarki, gdzie biblioteka jQuery wstawi otrzymany tekst do elementu p o identyfikatorze result.

I coś jeszcze Czym jest konstruktor W programowaniu obiektowym konstruktor jest metodą, która jest wywoływana podczas tworzenia nowego obiektu danej klasy. Konstruktor zawsze nosi nazwę identyczną z nazwą klasy. $mysqli = new mysqli('localhost', 'root', '', 'exampleDB');

Powyższy wiersz kodu tworzy nowy obiekt klasy mysqli, której konstruktor przyjmuje cztery parametry. Trzeba tu pamiętać o jednej rzeczy. W języku PHP 5 i nowszych wersjach konstruktor definiowany jest wyrażeniem __construct(), podczas gdy w starszych wersjach interpretera konstruktor miał po prostu nazwę identyczną z nazwą klasy. Więcej informacji na temat konstruktorów w języku PHP można znaleźć na stronach PHP pod adresem http://www.php.net/manual/pl/language. oop5.decon.php.

245

PHP i jQuery. Receptury

Zbieranie danych z formularza i zapisywanie ich w bazie Wykorzystamy tu te same tabele, których użyliśmy w poprzedniej recepturze, i na tej podstawie przygotujemy formularz, w którym użytkownik będzie mógł wybrać język, wprowadzić nazwę funkcji, krótki opis i przykład zastosowania. Wszystkie te informacje zapiszemy potem w tabeli functions i powiążemy z wybranym językiem.

Przygotowania W katalogu rozdzial8 utwórz nowy katalog i nazwij go receptura2.

Jak to zrobić? 1. W katalogu receptura2 utwórz plik o nazwie index.php. Wpisz do niego kod formularza z czterema polami. Pierwszym będzie lista rozwijana, której wartości pobierz z tabeli language naszej bazy danych. Następnie utwórz dwa pola tekstowe, opisując je Nazwa funkcji i Opis. Na koniec wstaw jeszcze pole typu textarea, w którym podawany będzie przykład użycia funkcji. Nie zapomnij o przypisaniu wszystkim polom klasy CSS required.

246

Rozdział 8. • Wiązanie danych w PHP i jQuery

2. Przed zamykającym znacznikiem body dołącz plik jquery.js, a następnie wpisz funkcję obsługującą zdarzenie submit formularza. Funkcja ta przeprowadzi prostą kontrolę formularza, sprawdzając wartości wprowadzone do wszystkich pól. Jeżeli jakiekolwiek pole nie będzie wypełnione, to pojawi się komunikat o błędzie. Jeżeli jednak nie wystąpią żadne błędy, to formularz zostanie przesłany na serwer.

3. Po przesłaniu danych z formularza skrypt PHP pobierze wartości poszczególnych pól z globalnej tablicy $_POST i przypisze je do osobnych zmiennych, uprzednio oczyszczając ich zawartość. Następnie uruchamiane jest zapytanie INSERT, które wstawi otrzymane wartości do bazy danych. Przy okazji wyświetlony zostanie odpowiedni komunikat, zależnie od tego, czy operacja zapisu danych się powiodła czy też nie. Poniżej przedstawiam pełny kod pliku index.php.

247

PHP i jQuery. Receptury

real_escape_string($_POST['language']); $functionName = $mysqli->real_escape_string($_POST['functionName']); $summary = $mysqli->real_escape_string($_POST['summary']); $example = $mysqli->real_escape_string($_POST['example']); $query = 'INSERT INTO functions (languageId ,functionName ´,summary ,example) VALUES ('.$language.', "'.$functionName.'", "'.$summary.'","'.$example.'")'; if ($mysqli->query($query)) { echo 'Dane zostały zapisane.'; } else { echo 'Wystąpił błąd podczas zapisywania danych.'; } } $query = 'SELECT * FROM language'; if ($result = $mysqli->query($query)) { if ($result->num_rows > 0) { ?>
Dodaj nową funkcję



248

Rozdział 8. • Wiązanie danych w PHP i jQuery

close(); } else { echo 'Błąd w zapytaniu: $query. '.$mysqli->error; } $mysqli->close(); ?>

4. Teraz uruchom w przeglądarce nasz plik i wprowadź do formularza jakieś dane. Po kliknięciu przycisku Zapisz informacje teksty wprowadzone w formularzu zostaną zapisane do tabeli functions. Na stronie pojawi się też komunikat Dane zostały zapisane. Próba przesłania formularza bez wypełnienia wszystkich pól będzie skutkowała tylko pojawieniem się komunikatu o błędzie.

Jak to działa? Na początek łączymy się z bazą danych, wywołując konstruktor klasy mysqli. Następnie instrukcją if sprawdzamy, czy formularz został już przesłany czy też strona jest wyświetlona po raz pierwszy.

249

PHP i jQuery. Receptury

Następna sekcja kodu wykonywana jest tylko w przypadku otrzymania danych z formularza. Przyjrzymy się jej w dalszej części tego punktu. if(isset($_POST['save'])) { }

Niezależnie od podanego wyżej warunku pobieramy dane z tabeli language, uruchamiając zapytanie SELECT, i w ten sposób otrzymujemy listę języków obsługiwanych przez bazę danych. Wszystkie te języki wraz z ich identyfikatorami wpisujemy do listy rozwijanej. Oprócz tego w formularzu umieszczamy dwa pola tekstowe i jeden element typu textarea. Po przesłaniu na serwer wypełnionego formularza skrypt PHP pobiera wartości z tablicy $_POST i oczyszcza je za pomocą metody real_escape_string() dostępnej w klasie mysqli. Funkcja ta przygotowuje dane otrzymane przez użytkownika do dalszych operacji na bazie. W związku z tym wstawiamy te wartości (identyfikator języka, nazwa funkcji, jej opis i przykład użycia) do zapytania INSERT. Wywołana metoda query() zwróci wartość true, jeżeli uda się zapisać dane do tabeli, albo wartość false, jeżeli podczas zapisywania wystąpi jakiś błąd. Na zakończenie na podstawie wartości otrzymanej od tej metody wyświetlany jest jeszcze stosowny komunikat.

I coś jeszcze Funkcja real_escape_string() Funkcja real_escape_string() używana jest do zamaskowania znaków specjalnych, które mogłyby znaleźć się w ciągu znaków. Jeżeli w treści zapytania SQL znajdą się niezamaskowane znaki specjalne, to całe zapytanie może zakończyć się błędem. Z tego powodu przy korzystaniu z bazy danych zawsze należy korzystać z tej funkcji. Trzeba tu też nadmienić, że działanie tej funkcji wymaga aktywnego połączenia z bazą danych.

Wartości zwracane przez metodę mysqli->query() W przypadku zapytań typu SELECT, SHOW i podobnych metoda ta zwraca obiekt klasy MySQLi_ ´Result. W przypadku zapytań typu INSERT, UPDATE i DELETE zwraca jedynie wartość true lub false.

Zobacz też Q Recepturę „Szukanie pustych pól za pomocą biblioteki jQuery” z rozdziału 5.

250

Rozdział 8. • Wiązanie danych w PHP i jQuery

Wypełnianie powiązanych ze sobą list rozwijanych W tej recepturze postaramy się rozwiązać dość powszechny problem, występujący w wielu aplikacjach WWW. Chodzi o filtrowanie zawartości listy rozwijanej zgodnie z wyborem dokonanym na innej liście rozwijanej. Przygotujemy tutaj przykład, w którym użytkownik będzie mógł skorzystać z trzech list rozwijanych: w jednej znajdą się nazwy państw, w drugiej nazwy regionów, a w ostatniej nazwy miast. Wybranie kraju spowoduje wpisanie do drugiej listy nazw regionów, a wybranie jednego z regionów wypełni trzecią listę nazwami miast. Na zakończenie wybranie miasta spowoduje wyświetlenie krótkiej informacji na jego temat. Najważniejsze w tym wszystkim jest to, że nie będziemy w związku z tym przeładowywać strony, ale wykorzystamy żądania AJAX, aby w tle filtrować zawartość list. Dzięki temu doznania użytkownika poprawią się w stosunku do klasycznych rozwiązań z każdorazowym przeładowaniem całej strony po wykonaniu wyboru.

Przygotowania W katalogu rozdzial8 utwórz nowy katalog i nazwij go receptura3. Oprócz tego utwórz w bazie danych cztery nowe tabele. Ponownie skorzystaj z narzędzia phpMyAdmin i uruchom w nim podane niżej zapytania. Q Tabela Country CREATE TABLE `country` ( `id` int(11) NOT NULL auto_increment, `countryName` varchar(64) NOT NULL, PRIMARY KEY (`id`) ); INSERT INTO `country` (`id`, `countryName`) VALUES (1, 'Indie') Q Tabela States CREATE TABLE `states` ( `id` int(11) NOT NULL auto_increment, `countryId` int(11) NOT NULL, `stateName` varchar(64) NOT NULL, PRIMARY KEY (`id`) ); INSERT INTO `states` (`id`, `countryId`, `stateName`) VALUES (1, 1, 'U.P.'), (2, 1, 'Uttarakhand');

251

PHP i jQuery. Receptury

Q Tabela Towns CREATE TABLE `towns` ( `id` int(11) NOT NULL auto_increment, `stateId` int(11) NOT NULL, `townName` varchar(64) NOT NULL, PRIMARY KEY (`id`) ); INSERT INTO `towns` (`id`, `stateId`, `townName`) VALUES (1, 1, 'Lucknow'), (2, 1, 'Bareilly'), (3, 2, 'Pithoragarh'), (4, 2, 'Dehradun'), (5, 2, 'Nainital'); Q Tabela Towninfo CREATE TABLE `towninfo` ( `id` int(11) NOT NULL auto_increment, `townId` int(11) NOT NULL, `description` text NOT NULL, PRIMARY KEY (`id`) ); INSERT INTO `towninfo` (`id`, `townId`, `description`) VALUES (1, 3, 'Pithoragarh jest pięknym miastem położonym w regionie Kumaon. Średnia ´wysokość nad poziomem morza wynosi w tym mieście 1,514 metrów (4,967 stóp).'), (2, 4, 'Dehradun, nazywane jest też Doon, jest stolicą regionu Uttarakhand. ´Położone jest w odległości 250 kilometrów od stolicy państwa - Delhi.\r\nGłównymi ´produktami wytwarzanymi w tym mieście jest ryż i lychee.'), (3, 1, 'Lucknow jest stolicą regionu U.P. lub Uttar Pradesh.\r\nW Lucknow ´znajduje się pierwszy azjatycki bank DNA.\r\nNazywane jest też Miastem ´Nawabs, Złotym miastem wschodu albo Konstantynopolem Indii.');

Jak to zrobić? 1. W katalogu receptura3 utwórz nowy plik o nazwie index.html. Wpisz do niego kod HTML tworzący trzy listy rozwijane, w których znajdą się nazwy państw, regionów i miast, a także element p, w którym wypisywane będą informacje na temat wybranego miasta. W sekcji head strony dopisz też kilka stylów CSS zmieniających wygląd tych elementów. Wszystkie wartości dostępne na listach rozwijanych zostaną wprowadzone za pomocą żądań AJAX.

252

Rozdział 8. • Wiązanie danych w PHP i jQuery

  • Państwo
  • Region
  • Miasto



253

PHP i jQuery. Receptury

2. Przed zamykającym znacznikiem body dołącz plik biblioteki jQuery. Wpisz też funkcję getList(), która będzie wywoływana przy każdej zmianie wartości wybranej z listy rozwijanej. W zależności tego, z której listy wybrano nową pozycję, adres URL żądania zostanie uzupełniony o dwa parametry: find i id. Na zakończenie wysyłamy żądanie AJAX pod zbudowany wcześniej adres URL i odbieramy przesłane przez serwer wyniki. Funkcja getList() zostanie też wywołana zaraz po załadowaniu dokumentu, tak żeby już od samego początku dostępne były wartości na liście Państwo.

3. Żądanie AJAX zostanie przesłane do pliku results.php. Przygotuj zatem nowy plik o takiej właśnie nazwie. Skrypt znajdujący się w tym pliku musi najpierw połączyć się z bazą danych i zależnie od wartości parametrów find i id odczytać z niej dane z odpowiedniej tabeli. Na podstawie informacji uzyskanych z bazy danych tworzony jest kod HTML, który następnie odsyłany jest do przeglądarki, gdzie biblioteka jQuery może wstawić go w odpowiednie miejsce. query($query)) { $result = $mysqli->query($query); if($find == 'information') { if($result->num_rows > 0) { $row = $result->fetch_array(); echo $row[1]; } else { echo 'No Information found'; } } else { ?>

255

PHP i jQuery. Receptury

fetch_array()) { ?>

4. Uruchom plik index.html w przeglądarce. Zobaczysz, że na liście rozwijanej Państwo znajdują się już wartości, natomiast pozostałe listy są nadal puste. Wybierz z listy Państwo jedną z wartości, a lista Region zostanie wypełniona odpowiednimi opcjami. Po wybraniu regionu również ostatnia lista zostanie wypełniona nazwami miast. Na koniec wybierz jeszcze jedno z dostępnych miast, a żądanie AJAX pobierze z bazy danych krótki opis tego miasta i wyświetli go w elemencie p.

Jak to działa? Kod HTML z pliku index.html jest wyjątkowo prosty. Utworzyliśmy w nim trzy listy rozwijane oraz element typu p. Każdy z tych elementów otrzymał swój identyfikator: countryList, stateList, townList oraz information. W kodzie JavaScript dodaliśmy metodę nasłuchującą zdarzeń change we wszystkich znajdujących się na stronie listach rozwijanych, która w przypadku wybrania wartości w którejkolwiek z list wywołuje funkcję getList(). Funkcja ta definiuje dwie zmienne: url i target. Następnie pobiera identyfikator listy oraz wartość elementu wybranego z tej listy, a potem za pomocą instrukcji switch tworzy cztery ścieżki wykonywane zależnie od wartości pobranego wcześniej identyfikatora. Jeżeli wybrana została wartość z listy o identyfikatorze countryList, to w parametrze find adresu URL wstawiana jest wartość states oraz wartość wybrana z listy. Podobnie w przypadku wybrania wartości z listy stateList parametr find adresu URL otrzymuje wartość towns, a w przypadku listy

256

Rozdział 8. • Wiązanie danych w PHP i jQuery

townList — wartość information, ponieważ tym razem chcemy uzyskać opis wybranej miejscowości. W domyślnym przypadku parametr find otrzymuje wartość country, przez co z bazy danych pobierane będą wszystkie zdefiniowane w niej państwa, a następnie ich nazwy zostaną wpisane do pierwszej listy rozwijanej. Oprócz określenia adresu URL definiujemy również parametr target opisujący element, do którego skierowane zostaną dane.

Po zakończeniu instrukcji switch żądanie AJAX wysyłane jest za pomocą biblioteki jQuery do skryptu PHP results.php. Odpowiedź otrzymana od tego skryptu zostanie następnie wstawiona do elementu określonego parametrem target. Przyjrzyjmy się teraz skryptowi zapisanemu w pliku results.php. Na początku tworzy on połączenie z bazą danych exampleDB, a następnie pobiera z globalnej tablicy $_GET wartość klucza find. W kolejnym kroku instrukcja switch sprawdza wartość zmiennej $find i na tej podstawie uruchamia właściwe zapytanie. Jeżeli zmienna $find ma wartość states, to tworzone jest zapytanie korzystające ze zmiennej $countryID. W przypadku wartości information pobierane są dane z tabeli information dotyczące miasta o podanym identyfikatorze. Po pobraniu tych wartości z bazy danych pętla while iteruje po całej kolekcji wierszy tabeli i na podstawie ich zawartości tworzy kod HTML, który odsyłany jest do przeglądarki, gdzie biblioteka jQuery wstawia go do elementu wskazywanego przez parametr target.

Sprawdzanie w bazie danych dostępności nazwy użytkownika Przygotujemy tutaj przykładowy formularz rejestracyjny, który będzie szukał nazwy wprowadzonej przez użytkownika wśród wszystkich nazw zapisanych już w bazie danych. Jeżeli wprowadzona nazwa zostanie znaleziona, to użytkownik zostanie o tym poinformowany.

Przygotowania W katalogu rozdzial8 utwórz nowy katalog i nazwij go receptura4. Otwórz narzędzie phpMyAdmin i utwórz nową tabelę o nazwie users i strukturze podanej poniżej: CREATE TABLE `users` ( `id` int(11) NOT NULL AUTO_INCREMENT, `username` varchar(32) NOT NULL, `password` varchar(32) NOT NULL, PRIMARY KEY (`id`) ); INSERT INTO `users` (`id`, `username`, `password`) VALUES

257

PHP i jQuery. Receptury

(1, 'holmes', 'sherlockholmes'), (2, 'watson', 'johnwatson'), (3, 'sati', 'pranay'), (4, 'mantu', 'ajayjoshi'), (5, 'sahji', 'brijsah'), (6, 'vijay', 'vijayjoshi'), (7, 'brij', 'brijsah'), (8, 'arjun', 'samant'), (9, 'jyotsna', 'sonawane'), (12, 'ravindra', 'pokharia'), (13, 'prakash', 'joshi'), (14, 'sahji2', 'aloklal'), (15, 'basant', 'bhandari')

Jak to zrobić? 1. W katalogu receptura4 utwórz nowy plik i nazwij go index.html. Wpisz do niego kod HTML tworzący pola tekstowe dla nazwy użytkownika i hasła. Obok pola nazwy użytkownika dodaj łącze, po którego kliknięciu sprawdzana będzie dostępność danej nazwy. Jeszcze jeden element umieszczony zaraz za łączem będzie sygnalizował, czy wybrana nazwa jest dostępna. Sprawdzanie nazwy użytkownika
Formularz rejestracyjny

Sprawdź



258

Rozdział 8. • Wiązanie danych w PHP i jQuery



2. Teraz dołącz plik biblioteki jQuery. Napisz też funkcję obsługującą kliknięcia elementu o identyfikatorze check. Będzie ona wysyłała żądanie AJAX do skryptu PHP zapisanego w pliku check.php, który z kolei zwracać będzie wartość true lub false zależnie od tego, czy dana nazwa użytkownika jest jeszcze wolna czy może jest już zajęta. Kolejna funkcja obsługi zdarzeń powinna zostać związana ze zdarzeniem submit wywoływanym z formularza. Pozwoli ona na przesłanie danych na serwer dopiero po wybraniu przez użytkownika dostępnej nazwy.

3. W tym samym katalogu utwórz kolejny plik i nazwij go check.php. Zapisz do niego skrypt sprawdzający wartość przekazaną mu przez bibliotekę jQuery, który przeszuka tabelę users i zwróci wartość true lub false. query($selectQuery); if($result) { if ($result->num_rows > 0) { echo false; } else { echo true;

260

Rozdział 8. • Wiązanie danych w PHP i jQuery

} } else { echo false; } ?>

4. Uruchom w przeglądarce plik index.php i wprowadź w formularzu nazwę użytkownika, która jest już zapisana w bazie danych, a następnie kliknij łącze Sprawdź. Zobaczysz komunikat, że ta nazwa użytkownika jest już zajęta. Wprowadź teraz dowolną nazwę użytkownika, której jeszcze nie ma w bazie, a pojawi się komunikat, że ta nazwa jest jeszcze wolna. Próba przesłania formularza bez uprzedniego sprawdzenia dostępności wybranej nazwy użytkownika również spowoduje wyświetlenie komunikatu z prośbą o kontrolę tej nazwy.

Jak to działa? Kliknięcie łącza Sprawdź uruchamia żądanie AJAX, które kierowane jest do pliku check.php. Po stronie serwera skrypt szuka otrzymanej nazwy użytkownika w tabeli users. Jeżeli w tabeli znajduje się niezerowa liczba wierszy z taką nazwą, to możemy mieć pewność, że nazwa ta jest już w użyciu i dlatego zwracana jest wartość false. W przeciwnym przypadku zwracana jest wartość true. Po stronie klienta funkcja wywoływana w przypadku poprawnej obsługi żądania sprawdza wartość odesłaną przez skrypt PHP i wyświetla odpowiedni komunikat. Dodatkowo zmienna checked używana jest do blokowania możliwości przesłania formularza, jeżeli wcześniej nie została sprawdzona dostępność wprowadzonej nazwy użytkownika. Tylko w przypadku gdy nazwa ta jest dostępna, zmiennej przypisywana jest wartość true, co pozwala na przesłanie formularza na serwer.

261

PHP i jQuery. Receptury

I coś jeszcze Alternatywna metoda implementacji W tej recepturze sprawdzaliśmy dostępność nazwy użytkownika po kliknięciu łącza. To samo zachowanie można jednak zaimplementować w ramach zdarzenia onkeydown pochodzącego z pola tekstowego. Wprowadzenie tej zmiany pozostawiam jako ćwiczenie dla Czytelnika.

Podział dużych ilości danych na strony Długie listy lub teksty dobrze jest podzielić na mniejsze strony i pozwolić na nawigowanie między nimi za pomocą przycisków typu Wstecz i Dalej oraz numerów kolejnych stron. W tej recepturze zajmiemy się długą listą elementów HTML i podzielimy ją na kilka stron, przy czym na każdej z nich znajdzie się z góry określona liczba tych elementów. Pozwolimy też użytkownikowi na natychmiastowe przejście do dowolnej strony przez wybranie jej z listy rozwijanej.

Przygotowania W katalogu rozdzial8 utwórz nowy katalog i nazwij go receptura5. Za pomocą narzędzia phpMyAdmin utwórz nową tabelę movies, nadając jej następującą strukturę. CREATE TABLE IF NOT EXISTS `movies` ( `id` int(11) NOT NULL AUTO_INCREMENT, `movieName` varchar(64) NOT NULL, PRIMARY KEY (`id`) );

Będziemy potrzebować też długiej listy tytułów filmowych, którą będziemy mogli podzielić na strony. Uzupełnij zatem utworzoną tabelę, wprowadzając do niej tytuły za pomocą narzędzia phpMyAdmin. W ramach tego przykładu wprowadziłem już do niej tytuły 100 filmów. Możesz zatem skorzystać z dołączonego do tej książki pliku movies.sql, który zapisze dane filmów do tabeli. Wszystkie te tytuły zostały pobrane ze strony http://www.thebest100lists.com/best100movies/.

Jak to zrobić? 1. W katalogu receptura5 utwórz plik o nazwie index.php. Nawiąż w nim połączenie z bazą danych i załaduj wszystkie tytuły filmów z tabeli movies, a następnie przygotuj na tej podstawie listę wypunktowaną. Dodatkowo utwórz element div o identyfikatorze

262

Rozdział 8. • Wiązanie danych w PHP i jQuery

navigation, w której znajdą się przyciski podziału listy na strony. Nie można też zapomnieć o zdefiniowaniu w sekcji head strony stylów CSS, które poprawią jej wygląd. 100 najlepszych filmów

100 najlepszych filmów według internautów

http://www.thebest100lists.com/best100movies/
    connect_errno) { die('Błąd połączenia: ' . $mysqli->connect_errno); } $query = 'SELECT movieName FROM movies'; if ($mysqli->query($query)) { $result = $mysqli->query($query); if($result->num_rows > 0) { while($row = $result->fetch_array()) { echo '
  • '.$row[0].'
  • '; } } else { echo 'Brak danych'; } } else

    263

    PHP i jQuery. Receptury

    { echo 'Błąd zapytania'; } ?>

 



2. Na powyższym rysunku można zobaczyć tylko część tekstu znajdującego się na stronie. W przeglądarce wyświetlona została jednak pełna lista 100 tytułów filmów. Dołącz teraz plik biblioteki jQuery i dopisz kod JavaScript dzielący tę listę na strony. Na początek zdefiniuj liczbę elementów na stronie oraz ogólną liczbę stron. W tym przykładzie będziemy wyświetlać po dziesięć tytułów na stronie, co oznacza, że ogólnie dostępnych będzie dziesięć stron. Następnie zdefiniuj funkcję createNavigation(), która będzie tworzyć łącza do poprzedniej i następnej strony oraz listę rozwijaną z numerami stron. W kolejnym kroku dopisz funkcję setDataAndEvents(), tworzącą funkcje obsługi zdarzeń pochodzących z narzędzi nawigacyjnych. Kliknięcie łącza nawigacyjnego albo wybranie numeru strony z listy rozwijanej spowoduje wywołanie funkcji goToPage(), która wyświetli listę tytułów filmów przypisanych do wybranej strony. 264

Rozdział 8. • Wiązanie danych w PHP i jQuery



3. Uruchom teraz plik index.php w przeglądarce, a zobaczysz listę plików oraz znajdujące się na dole łącza nawigacyjne. Na liście rozwijanej wybrany będzie już domyślny numer pierwszej strony. Ze względu na to, że jest to pierwsza strona, widoczne będzie tylko łącze Następna. Po jego kliknięciu zmieni się widoczna lista filmów oraz numer strony wyświetlany w liście rozwijanej. Po przejściu do ostatniej strony łącze Następna zniknie.

Jak to działa? Przede wszystkim pobieramy z bazy danych listę filmów, wywołując w tym celu metodę query() klasy mysqli. Następnie iterujemy po otrzymanych wynikach zapytania i na ich podstawie tworzymy wypunktowaną listę o identyfikatorze list. Jak można się domyślić, każdy tytuł filmu staje się kolejnym elementem listy. Zaraz za listą umieszczamy element div o identyfikatorze navigation, w którym umieszczane będą elementy nawigacji. Po załadowaniu strony najpierw

266

Rozdział 8. • Wiązanie danych w PHP i jQuery

uruchamiany jest kod JavaScript, który odczytuje liczbę pozycji znajdujących się na liście (liczbę elementów li) i przypisuje ją do zmiennej totalMovies. Następnie zmiennej moviesPerPage przypisujemy wartość 10, a potem wyliczamy ogólną liczbę stron, dzieląc wartość ze zmiennej totalMovies przez wartość zmiennej moviesPerPage. Teraz wywoływana jest funkcja createNavigation(), która tworzy w nawigacyjnym elemencie div dwa łącza spełniające rolę przycisków Wstecz i Dalej i przypisuje im identyfikatory prev i next. Tworzony jest też element listy rozwijanej o identyfikatorze goTo. Na liście tej zapisywane są numery dostępnych stron. Po utworzeniu tych wszystkich elementów wstawiane są do nawigacyjnego elementu div. Na zakończenie łącze Wstecz jest ukrywane, a w liście rozwijanej wybierana jest wartość 1. Następnie definiowana jest funkcja setDataAndEvents(). Chcąc nawigować pomiędzy poprzednimi i następnymi stronami, musimy znać numer aktualnej strony, tak żeby móc go powiększyć lub pomniejszyć podczas zmiany strony. Informację tę możemy uzyskać, wykorzystując funkcję biblioteki jQuery data(). Do elementu ul zapisujemy informację o kluczu currentPage i początkowej wartości 1. W kolejnym wierszu ukrywamy wszystkie te elementy li, których index jest większy niż 10, co oznacza, że nie mieszczą się na pierwszej stronie. W dalszej części definiowane są funkcje obsługujące kliknięcia łączy Wstecz i Dalej. Przy kliknięciu tego pierwszego pobieramy wartość currentPage, zmniejszamy ją o 1 i przekazujemy do funkcji goToPage(). Podobnie kliknięcie łącza Dalej powoduje zwiększenie wartości currentPage o 1 i przekazanie jej do funkcji goToPage(). Do zdarzenia change listy rozwijanej również dołączamy funkcję, która przekazuje funkcji goToPage() wartość wybraną aktualnie z listy. Funkcja goToPage() pobiera jeden parametr o nazwie pageNumber. Wartość tego parametru określa numer strony, na którą chcemy przejść. Musimy tutaj sprawdzić dwie rzeczy. Jeżeli użytkownik jest na pierwszej stronie, to ukrywamy łącze Wstecz, a na ostatniej stronie ukrywamy łącze Dalej. Następnie aktualizujemy zmienną currentPage i wpisujemy tę samą wartość do listy rozwijanej z numerami stron. Na koniec trzeba jeszcze zdecydować, które tytuły filmów mają zostać wyświetlone na aktualnej stronie. W tym celu wyliczamy wartości dwóch zmiennych: to i from. Ostatnie trzy wiersze ukrywają wszystkie pozycje listy filmów z wyjątkiem tych znajdujących się w zakresie od from do to.

Dodawanie funkcji automatycznych podpowiedzi do pól tekstowych Chyba najlepszym przykładem zastosowania funkcji automatycznych podpowiedzi jest strona główna firmy Google. Wpisując w polu tekstowym treść zapytania, możemy zauważyć, że poniżej wyświetlana jest lista proponowanych zapytań, pasujących do wprowadzonego przez nas tekstu.

267

PHP i jQuery. Receptury

Przygotujemy tutaj bardzo podobne rozwiązanie, w którym tekst wprowadzany przez użytkownika będzie porównywany z nazwami użytkowników zapisanymi w bazie, a pasujące pozycje będą wyświetlane na formularzu jako lista sugestii. Użytkownik będzie mógł wtedy użyć klawiszy strzałek, żeby wybrać właściwą nazwę.

Przygotowania W katalogu rozdzial8 utwórz nowy katalog o nazwie receptura6. W tej recepturze będziemy potrzebowali jeszcze tabeli z listą nazw użytkowników. Otwórz zatem narzędzie phpMyAdmin i utwórz nową tabelę users, nadając jej następującą strukturę. CREATE TABLE `users` ( `id` int(11) NOT NULL AUTO_INCREMENT, `username` varchar(32) NOT NULL, `password` varchar(32) NOT NULL, PRIMARY KEY (`id`) ); INSERT INTO `users` (`id`, `username`, `password`) VALUES (1, 'holmes', 'sherlockholmes'), (2, 'watson', 'johnwatson'), (3, 'sati', 'pranay'), (4, 'mantu', 'ajayjoshi'), (5, 'sahji', 'brijsah'), (6, 'vijay', 'vijayjoshi'), (7, 'brij', 'brijsah'), (8, 'arjun', 'samant'), (9, 'jyotsna', 'sonawane'), (12, 'ravindra', 'pokharia'), (13, 'prakash', 'joshi'), (14, 'sahji2', 'aloklal'), (15, 'basant', 'bhandari'), (16, 'ajay', 'gamer')

Jak to zrobić? 1. W katalogu receptura6 utwórz nowy plik o nazwie index.html. Wpisz do niego kod HTML tworzący element div klasy autosuggest, a wewnątrz niego pole tekstowe o identyfikatorze suggest oraz listę wypunktowaną o identyfikatorze suggestions. To w tej liście będziemy wyświetlać pasujące wyniki wyszukiwania. Utwórz też znacznik obrazka, w którym umieścimy obracający się znaczek informujący o ładowaniu danych. Będzie on wyświetlany podczas pobierania danych z bazy. Na zakończenie utwórz jeszcze element span o identyfikatorze error, w którym będziemy umieszczać informację o braku pasujących nazw użytkownika.

268

Rozdział 8. • Wiązanie danych w PHP i jQuery

Automatyczne podpowiedzi
Ładowanie danych


2. Proszę zauważyć, że w sekcji head odwołujemy się do pliku style.css. W tym przykładzie atrybuty CSS są niezmiernie ważne, ponieważ musimy umieścić element ul w odpowiednim miejscu na stronie, tuż pod polem tekstowym. Utwórz zatem nowy plik o nazwie style.css i wpisz do niego poniższe style: body{ font-family: "Trebuchet MS", verdana, arial;width:400px;margin:0 auto; } .autosuggest { width:200px; top:5px; position:relative; } input { width:200px;} #suggestions { position:absolute; list-style:none; margin:0; padding:0; width:200px; display:none; background-color:#ECECF6; top:20px; left:0px; } #suggestions li { cursor:pointer; padding:5px; border-right:1px solid #000; border-bottom:1px solid #000;

269

PHP i jQuery. Receptury

border-left:1px solid #000; } .active { background-color:red; color:#fff; } #error { top:25px; font-weight:bold; color:#ff0000; } #loader { position:absolute; top:2px; right:0; display:none; }

3. Skupmy się teraz na wykorzystaniu biblioteki jQuery, dlatego tuż przez zamykającym znacznikiem body dołącz plik jquery.js. Zdefiniuj cztery funkcje obsługi zdarzeń, które będą odpowiadały za pobieranie podpowiedzi z bazy danych i wyświetlanie ich we właściwym miejscu na stronie. Do zdarzenia keyup pochodzącego z pola tekstowego podłącz funkcję getSuggestions(). Jest to główna funkcja naszego rozwiązania, która pobierając kolejne naciśnięte przez użytkownika klawisze, pobiera podpowiedz za pomocą żądań AJAX. Wartość znajdująca się w polu tekstowym wysyłana jest w żądaniu do serwerowego skryptu suggestions.php. Po otrzymaniu odpowiedzi z serwera uruchamiana jest funkcja showSuggestions(), która tworzy listę na podstawie otrzymanych danych i wyświetla ją pod polem tekstowym. 4. Funkcja navigaeList() wywoływana będzie przy każdym zdarzeniu keydown. Pozwoli ona nawigować w liście podpowiedzi za pomocą klawiszy strzałki w górę i w dół, a klawisz Enter będzie umożliwiał wybranie jednej z pozycji. Kolejne dwie funkcje będą obsługiwać zdarzenia myszy. Pierwsza — listHover() — będzie uruchamiana, w momencie gdy wskaźnik myszy znajdzie się nad elementem listy z podpowiedziami, zmieniając wygląd tego elementu. Drugą funkcję — listClick() — wykorzystamy do wypełnienia pola tekstowego wartością elementu listy klikniętego przez użytkownika.

5. W tym samym katalogu utwórz kolejny plik o nazwie suggestions.php. Skrypt z tego pliku powinien łączyć się z bazą danych exampleDB i uruchamiać w niej zapytanie wyszukujące w tabeli users wartości podobnych do pobranej z parametru żądania AJAX.

272

Rozdział 8. • Wiązanie danych w PHP i jQuery

Po uzyskaniu odpowiedzi należy zapisać ją w ciągu znaków JSON i wysłać do przeglądarki. 6. Uruchom plik index.html w przeglądarce i naciśnij dowolny klawisz. Wysłane zostanie żądanie AJAX, a wyniki pasujące do wprowadzonego tekstu pojawią się w postaci listy. Poniżej przedstawiam przykład listy podpowiedzi wyświetlanej po wpisaniu znaku a.

Jak to działa? Najpierw musimy się upewnić, że element ul będzie się zawsze pojawiał poniżej pola tekstowego. Istnieje tu bardzo prosty sposób realizacji. Po pierwsze pozycja zewnętrznego elementu div musi być względna (atrybut position:relative), co zapisujemy w pliku CSS. Teraz wszystkie elementy znajdujące się w tym elemencie div mogą otrzymać pozycję bezwzględną (position:absolute), liczoną względem współrzędnych elementu bazowego. Oznacza to, że poniższe właściwości CSS umieszczą element ul tuż pod polem tekstowym. position:absolute; top:20px; left:0px;

Pozostałe właściwości definiują już tylko ogólny wygląd listy podpowiedzi. W podobny sposób po prawej stronie umieszczamy rysunek informacji o ładowaniu danych. Teraz przystępujemy do implementowania mechanizmu automatycznych podpowiedzi. Na początek zajmiemy się funkcją obsługującą zdarzenie keyup pochodzące z pola tekstowego, która

273

PHP i jQuery. Receptury

wywołuje funkcję getSuggestions(). Pobiera ona wartość z pola tekstowego i kontynuuje prace tylko wtedy, gdy w polu tym został wprowadzony jakiś tekst. Następnie sprawdza, jaki klawisz został właśnie naciśnięty przez użytkownika, odczytując udostępnianą przez bibliotekę jQuery wartość event.which. Naciśnięcie klawiszy z zakresu a – z, A – Z, Delete lub Backspace spowoduje zmianę zawartości pola tekstowego, a zatem możemy pobrać znajdujący się w nim tekst i wysyłamy go do skryptu suggestions.php za pomocą żądania AJAX. Do obsługi odpowiedzi z tego żądania stosujemy natomiast funkcję showSuggestions(). W odpowiedzi może ona otrzymać tablicę pasujących nazw użytkownika albo wartość false, jeżeli serwerowy skrypt nie znalazł żadnych sugestii. W przypadku otrzymania wartości false ograniczamy się tylko do wyświetlenia komunikatu. Jeżeli jednak skrypt zwrócił nam tablicę wartości, to iterujemy po niej i z kolejnych jej wartości tworzymy elementy listy podpowiedzi. Po przejrzeniu całej tablicy wstawiamy otworzone elementy li do zbiorczego elementu ul o identyfikatorze suggestions. Tuż przed wysłaniem żądania wyświetlamy jeszcze obrazek z informacją o pobieraniu danych, a po otrzymaniu odpowiedzi funkcja showSuggestions() go ukrywa. Chcemy mieć możliwość wybierania najlepszej podpowiedzi za pomocą klawiszy strzałek i klawisza Enter. Przesuwając się w górę i w dół listy, wyróżniamy jeden z jej elementów za pomocą klasy CSS. W tym celu zdefiniowaliśmy funkcję navigateList() obsługującą zdarzenie keyDown. Za pomocą instrukcji switch obsługuje ona trzy różne przypadki. Pierwszym jest naciśnięcie klawisza strzałki w górę (kod klawisza 38). Sprawdzamy, czy któryś z elementów listy ma już przypisaną klasę active, a jeżeli takiego nie ma, to przypisujemy ją do ostatniego elementu listy. Jeżeli jednak znajdziemy element tej klasy, to funkcja usuwa klasę z tego elementu i przypisuje ją elementowi poprzedzającemu. W przypadku wykrycia naciśnięcia klawisza strzałki w dół postępujemy bardzo podobnie. Jeżeli nie jest zaznaczony żaden element listy, to zaznaczana jest jej pierwsza pozycja. Jeżeli jednak jeden z elementów jest już zaznaczony, to klasa active jest z niego usuwana, a nadawana jest następnemu elementowi. Trzecim i ostatnim przypadkiem jest naciśnięcie klawisza Enter o kodzie 13. W takiej sytuacji kod HTML aktualnie wybranego elementu listy jest wstawiany do pola tekstowego, a cały element ul zawierający podpowiedzi zostaje ukryty. Po zadbaniu o obsługę klawiatury musimy przyjrzeć się też funkcjom umożliwiającym obsługiwanie podpowiedzi za pomocą myszy. Umieszczenie wskaźnika myszy nad elementem listy powinno skutkować nadaniem temu elementowi klasy active, a przesunięcie wskaźnika poza ten element powinno spowodować usunięcie klasy. Oprócz tego kliknięcie jednej z podpowiedzi powinno przenieść jej zawartość do pola tekstowego. Ze względu na to, że początkowo w elemencie ul nie ma żadnych pozycji listy, funkcję listHover() przypisujemy do nich za pomocą metody live(). Będzie ona uruchamiana przy każdym wskazaniu elementu listy myszą, przesunięcia wskaźnika poza ten element albo kliknięcia elementu. W samej funkcji sprawdzamy, czy wywołana została zdarzeniem mouseover, a wtedy usuwamy klasę active z dowolnego wybranego aktualnie elementu, następnie wywołujemy funkcję toggleClass(), aby dodać lub usunąć tę klasę ze wskazywanego myszą elementu. W ten sposób klasa active będzie przypisywana elementowi wskazywanemu myszą i usuwana z każdego niewskazywanego elementu. 274

Rozdział 8. • Wiązanie danych w PHP i jQuery

Na zakończenie funkcja listHover() sprawdza, czy kliknięty został element li, a wtedy pobieramy zapisany w nim tekst HTML i umieszczamy go w polu tekstowym. Ostatecznie element ul jest opróżniany, a kursor umieszczany jest w polu tekstowym. Po stronie serwera skrypt suggestions.php odbiera przekazany w żądaniu tekst z pola tekstowego i poszukuje go w tabeli users, aby odnaleźć pasujące podpowiedzi. $query = 'SELECT username FROM users where username like "%'. $_GET['input']. '%"';

Zastosowanie znaku procentu (%) przed i za treścią pola tekstowego oznacza, że za lub przed podaną wartością mogą znajdować się jeszcze inne znaki. Oznacza to, że wprowadzona wartość sa zostanie dopasowana do słowa osa, ale także do słowa samochód. Po pobraniu wyników z bazy danych iterujemy po nich i zapisujemy do tablicy, którą po skonwertowaniu na format JSON wysyłamy do przeglądarki. Muszę tutaj też wspomnieć o bardzo ważnej zmiennej xhr, którą deklarowaliśmy już na samym początku pliku. Jeżeli użytkownik naciśnie wiele klawiszy, to do serwera zostanie wysłanych wiele żądań jednocześnie. Aby uniknąć takiej sytuacji, przypisujemy do zmiennej xhr obiekt otrzymany od funkcji getJSON(). Następnie przed wysłaniem żądania do serwera możemy przerwać ewentualne wcześniejsze żądania metodą abort(), tak żeby znaczenie miało tylko ostatnio wysłane żądanie.

Zobacz też Q Recepturę „Tworzenie skrótów klawiszowych” z rozdziału 1.

Tworzenie chmury znaczników Chmura znaczników jest wizualną reprezentacją słów kluczowych, w której wielkość i kolor danego słowa określa jego wagę. Wyobraźmy sobie bloga z wieloma artykułami, którym przypisano znaczniki kategorii, takich jak PHP, jQuery, XML, JSON itd. Jeżeli z kategorią PHP związanych jest 50 artykułów, z kategorią jQuery 30 artykułów, z XML 10, a z JSON 22 artykuły, to możemy powiedzieć, że znacznik PHP ma największą wagę, a znacznik XML najmniejszą. Jeżeli chcielibyśmy zaprezentować te znaczniki w formie graficznej, to ważniejsze słowa powinny zostać bardziej wyróżnione, co możemy zrealizować przez zastosowanie odpowiednio powiększonej i pogrubionej czcionki. Przygotujemy tu podobne rozwiązanie. Będziemy w nim pobierać z bazy danych listę miast, którym przypisywana jest ocena w skali od 0 do 100. Wszystkie te znaczniki zaprezentujemy w postaci chmury znaczników, w której wielkości poszczególnych znaczników będą uzależnione od oceny miasta.

275

PHP i jQuery. Receptury

Przygotowania W katalogu rozdzial8 utwórz nowy katalog o nazwie receptura7. Utwórz też w bazie danych tabelę o nazwie cities, stosując poniższe zapytanie SQL, którego możesz użyć w panelu phpMyAdmin. CREATE TABLE `cities` ( `id` int(3) NOT NULL AUTO_INCREMENT, `cityName` varchar(32) NOT NULL, `cityRating` int(3) NOT NULL, PRIMARY KEY (`id`) ); INSERT INTO `cities` (`id`, `cityName`, `cityRating`) VALUES (1, 'Udaipur', 71), (2, 'Leh', 55), (3, 'Mahabaleshwar', 28), (4, 'Mount Abu', 31), (5, 'Rishikesh', 15), (6, 'Hampi', 81), (7, 'Matheran', 29), (8, 'Manali', 85), (9, 'Mysore', 33), (10, 'Jaipur', 55), (11, 'Munnar', 89), (12, 'Bangalore', 66), (13, 'Wayanad', 42), (14, 'Amritsar', 29), (15, 'Gangtok', 69), (16, 'Havelock Islands', 27), (17, 'DharamShala', 57), (18, 'Kashmir', 78), (19, 'Tirupati', 22), (20, 'Goa', 75)

Jak to zrobić? 1. W katalogu receptura7 utwórz nowy plik o nazwie index.html. W tym pliku umieść znacznik div o identyfikatorze cloud i zdefiniuj style CSS dla tego elementu oraz znaczników a, które będziemy tworzyć na stronie. Chmura znaczników

Najczęściej odwiedzane miasta w Indiach



2. Przed zamykającym znacznikiem body dołącz plik biblioteki jQuery. Dopisz też kod wysyłający żądanie AJAX skierowane do pliku tags.php. Odpowiedź tego żądania powinna zostać obsłużona przez funkcję createTagCloud(). Będzie ona iterować po elementach odpowiedzi i tworzyć na ich podstawie chmurę znaczników.

277

PHP i jQuery. Receptury

3. Utwórz kolejny plik o nazwie tags.php. Zapisany w nim skrypt będzie łączył się z bazą danych i pobierał z nich informacje z tabeli cities. Na podstawie uzyskanych w ten sposób danych utworzymy ciąg znaków JSON i wyślemy go do przeglądarki, gdzie biblioteka jQuery utworzy chmurę znaczników. query($query)) { if ($result->num_rows > 0) { while($row = $result->fetch_assoc()) { array_push($arr, array('city' => $row['cityName'], 'rating' => $row['cityRating'])); } } } $result = array('tags' => $arr); header('Content-Type:text/json'); echo json_encode($result); ?>

4. Uruchom w przeglądarce plik index.php. Zobaczysz kolekcję nazw miast wyświetlonych w różnych kolorach i rozmiarach.

278

Rozdział 8. • Wiązanie danych w PHP i jQuery

Jak to działa? Po załadowaniu dokumentu HTML za pomocą metody getJSON() wysyłane jest żądanie AJAX skierowane do skryptu tags.php. Po otrzymaniu odpowiedzi wywoływana jest funkcja create ´TagCloud(). W pliku tags.php uruchamiane jest zapytanie SELECT, które pobiera z bazy nazwy miast oraz przypisane im oceny. Następnie wywołujemy metodę fetch_assoc(), aby odczytać dane z poszczególnych wierszy i umieścić je w asocjatywnej tablicy $arr. Po wypełnieniu tablicy $arr danymi przypisujemy je do tablicy asocjatywnej $result, stosując słowo tags jako klucz. Na zakończenie ustalamy typ odpowiedzi na text/json i przekształcamy tablicę $result w ciąg znaków JSON, przekazując ją metodzie json_encode(). Wynikowy ciąg znaków powinien wyglądać tak, jak na poniższym rysunku:

Teraz odpowiedź przekazywana jest do funkcji createTagCloud(), w ramach parametru o nazwie response. Za pomocą metody each() pochodzącej z biblioteki jQuery iterujemy po tablicy tags zapisanej w obiekcie JSON. Dla każdego elementu ustalamy różny kolor znacznika, sprawdzając

279

PHP i jQuery. Receptury

wartość zmiennej i. Wielkość czcionki znacznika ustalamy natomiast, dzieląc wartość oceny przez 30. Można oczywiście wybrać dowolny inny dzielnik zależnie od tego, jak wielkie lub jak małe chcemy uzyskać znaczniki. Po wybraniu wielkości i koloru czcionki tworzymy znacznik a, przypisujemy mu wszystkie wartości i dopisujemy do zmiennej str. Po zakończeniu iterowania po tablicy wstawiamy wartość zmiennej str do elementu div o identyfikatorze cloud. W efekcie powstaje wspaniała chmura znaczników.

Zobacz też Q Recepturę „Tworzenie danych w formacie JSON za pomocą PHP” z rozdziału 4. Q Recepturę „Korzystanie z danych w formacie JSON za pomocą jQuery” z rozdziału 4.

280

9 Rozbudowywanie stron za pomocą PHP i jQuery W tym rozdziale zajmiemy się: Q wysyłaniem żądań między domenami z wykorzystaniem serwera proxy, Q tworzeniem międzydomenowych żądań za pomocą biblioteki jQuery, Q tworzeniem strony przewijającej się w nieskończoność, Q tworzeniem wtyczki do biblioteki jQuery, Q wyświetlaniem kanałów RSS za pomocą PHP i jQuery.

Wprowadzenie W ostatnim rozdziale przyjrzymy się zaawansowanym technikom, których można użyć do rozbudowania funkcji oferowanych przez aplikację WWW. Przygotujemy tu kilka przykładów, w których będziemy szukać obrazów w usłudze Flickr i filmów na YouTubie, wykorzystując do tego API tych usług. Za pomocą biblioteki jQuery odczytamy też dane z kanału RSS zapisane w formacie XML i nauczymy się tworzyć przewijaną w nieskończoność stronę, taką jak w Google Reader albo w nowej wersji Twittera. Oprócz tego będziemy tworzyć wtyczki do biblioteki jQuery, których będziemy mogli użyć w dowolnej tworzonej później aplikacji WWW.

PHP i jQuery. Receptury

Wysyłanie żądań między domenami z wykorzystaniem serwera proxy Ze względów bezpieczeństwa przeglądarki nie pozwalają skryptom na wysyłanie żądań pomiędzy domenami. Oznacza to, że skrypt uruchomiony w domenie http://www.abc.com nie może wysłać żądania AJAX do domeny http://www.xyz.com. W tej recepturze dowiemy się, jak można obejść to ograniczenie za pomocą skryptów PHP działających po stronie serwera. Przygotujemy tu przykład pozwalający na wyszukiwanie obrazów w usłudze Flickr, która zwraca dane w formacie JSON, a te po przetworzeniu w bibliotece jQuery umożliwią nam wyświetlenie obrazków na naszej stronie. Na poniższym rysunku można zobaczyć przykład odpowiedzi serwera Flickr w formacie JSON.

Przygotowania W katalogu rozdzial9 utwórz nowy katalog o nazwie receptura1.

282

Rozdział 9. • Rozbudowywanie stron za pomocą PHP i jQuery

Oprócz tego pobierz też klucz dostępu do API Flickr dostępny pod adresem http://www. flickr.com/services/api/keys/.

Jak to zrobić? 1. W katalogu receptura1 utwórz plik o nazwie index.html. Zapisz w nim kod HTML tworzący formularz z trzema polami: znacznik, liczba obrazków i rozmiar obrazków. Oprócz tego utwórz też element ul, w którym będziemy wyświetlać wyniki naszych zapytań. Szukanie obrazków w usłudze Flickr
Kryteria wyszukiwania
  • Znacznik
  • Liczba obrazków
  • Rozmiar obrazka


W przeglądarce powinniśmy zobaczyć teraz stronę podobną do poniższej.

2. Dołącz teraz plik biblioteki jQuery, a następnie wpisz kod, który zajmie się wysłaniem żądania AJAX do serwerowego skryptu search.php. Jako parametry tego żądania podane zostaną wartości wprowadzone do formularza. Odpowiedź serwera obsłuży z kolei funkcja showImages(), która odczyta dane w formacie JSON i wyświetli na stronie zestaw obrazków.

3. Utwórz kolejny plik i nazwij go search.php. Zapisany w nim kod PHP nawiąże kontakt z API usługi Flickr i poda jej kryteria wyszukiwania. Po otrzymaniu odpowiedzi w formacie JSON zostanie ona odesłana do przeglądarki, gdzie biblioteka jQuery będzie mogła wyświetlić obrazki.
285

PHP i jQuery. Receptury

$url.= '&api_key='.API_KEY; $url.= '&tags='.$_POST['tag']; $url.= '&per_page='.$_POST['numImages']; $url.= '&format=json'; $url.= '&nojsoncallback=1'; header('Content-Type:text/json;'); echo file_get_contents($url); ?>

4. Teraz uruchom w przeglądarce plik index.html i wprowadź hasło wyszukiwania, wybierz liczbę zdjęć i ich wielkość, a na koniec kliknij przycisk Wyszukaj. Po kilku sekundach zobaczysz, że na stronie pojawiają się obrazki pobierane z usługi Flickr.

Jak to działa? Po kliknięciu przycisku Wyszukaj wartości z formularza wysyłane są do serwerowego skryptu search.php. Musimy się jednak skontaktować z serwerem Flickr i pobrać z niego obrazki. Interfejs API tej usługi definiuje kilka metod dostępu do obrazków. Wykorzystamy tu metodę flickr.photos.search() pozwalającą na wyszukiwanie hasłowe. Oprócz nazwy metody w adresie URL musimy zamieścić jeszcze kilka innych parametrów: Q api_key — jest to parametr obowiązkowy. Własny klucz można uzyskać pod adresem

http://www.flickr.com/services/api/keys/.

286

Rozdział 9. • Rozbudowywanie stron za pomocą PHP i jQuery

Q tags — hasła do wyszukiwania. Można je podać w postaci listy rozdzielanej

przecinkami. Wpiszemy tu wartość z pola tekstowego. Q per_page — Liczba obrazków prezentowanych na stronie. Maksymalnie może ich być 99. Podamy tu wartość z listy rozwijanej numImages. Q format — Można wybrać format JSON, XML i inne. W naszym przykładzie

wykorzystamy format JSON. Q nojsoncallback — Należy tu wpisać wartość 1, jeżeli nie chcemy, żeby Flickr opakował dane JSON własną funkcją. Po przygotowaniu adresu URL możemy skontaktować się z serwerem Flickr, aby pobrać z niego dane. W tym celu używamy funkcji języka PHP file_get_contents(), która pobierze nam ciąg znaków JSON ze wskazanego adresu URL. Uzyskany w ten sposób ciąg znaków zostanie przesłany do przeglądarki. Biblioteka jQuery odbierze dane w formacie JSON w ramach funkcji showImages(). W pierwszej kolejności funkcja ta sprawdzi status odpowiedzi. Jeżeli będzie to wartość OK, to możemy z odpowiedzi pobrać elementy typu photo, a następnie iterować po nich za pomocą metody each(). Aby wyświetlić pojedynczy obrazek, musimy najpierw poznać jego adres URL, który możemy uzyskać, składając ze sobą różne parametry obiektu photo. Według dokumentacji API Flickr adres URL należy konstruować według poniższego wzorca: http://farm{farm-id}.static.flickr.com/{server-id}/{id}_{secret}_[size].jpg

Oznacza to, że z obiektu photo musimy pobrać parametry farmId, serverId, id oraz secret. Ostatni parametr — size — możemy zdefiniować samodzielnie, wybierając jedną z poniższych wartości: Q s — małe kwadraciki, Q t — miniaturki, Q - — średnie obrazki, Q b — duże obrazki, Q o — oryginalna wielkość.

Wielkość obrazka wybraliśmy już wcześniej na formularzu. Teraz wystarczy tylko połączyć ze sobą wszystkie te wartości i już możemy pobierać obrazki z serwerów Flickr. Każdy z nich umieszczamy w elemencie li i powtarzamy ten sam krok dla wszystkich obrazków. Na koniec utworzoną listę wstawiamy do elementu ul o identyfikatorze results.

Zobacz też Q Recepturę „Tworzenie międzydomenowych żądań za pomocą biblioteki jQuery”.

287

PHP i jQuery. Receptury

Tworzenie międzydomenowych żądań za pomocą biblioteki jQuery W poprzedniej recepturze zademonstrowałem sposób użycia skryptu PHP jako pośrednika przy uruchamianiu międzydomenowych żądań AJAX. W tej recepturze wykorzystamy specyfikację JSONP, aby wykonywać międzydomenowe żądania bezpośrednio z biblioteki jQuery. Przygotujemy tu rozwiązanie, w którym będziemy wyszukiwać filmy w usłudze YouTube i wyświetlać je w postaci listy. Kliknięcie miniaturki filmu otworzy nowe okno przeglądarki, w którym użytkownik będzie mógł obejrzeć wybrany film. Na kolejnym rysunku można zobaczyć przykładową odpowiedź serwera YouTube w formacie JSON.

Przygotowania W katalogu rozdzial9 utwórz nowy katalog o nazwie receptura2.

Jak to zrobić? 1. W katalogu receptura2 utwórz nowy plik i nazwij go index.html. Wpisz do niego kod HTML tworzący formularz z pojedynczym polem tekstowym oraz element div o identyfikatorze results, w którym będziemy umieszczać wyniki wyszukiwania. Szukanie filmów na YouTubie


288

Rozdział 9. • Rozbudowywanie stron za pomocą PHP i jQuery

Kryteria wyszukiwania
  • Tekst wyszukiwania


  • 289

    PHP i jQuery. Receptury



2. Przed zamykającym znacznikiem body dołącz plik jquery.js. Teraz dopisz kod JavaScript, który pobierze kryterium wyszukiwania i będzie próbował uzyskać odpowiedź od serwera YouTube. Obsługująca tę odpowiedź funkcja showVideoList() przygotuje listę filmów i wyświetli ją na stronie.

3. I już wszystko gotowe, jesteśmy gotowi do wyszukiwania filmów na YouTubie. Uruchom w przeglądarce plik index.html i wprowadź hasło wyszukiwania. Po kliknięciu przycisku Szukaj zobaczysz listę filmów wraz z liczbą komentarzy oraz oceną.

291

PHP i jQuery. Receptury

Jak to działa? Znaczniki script stanowią wyjątek od zasady „tego samego źródła” (ang. same origin policy). Możemy to wykorzystać, żeby podać adres URL w atrybucie src znacznika script, a następnie opakować surową postać odpowiedzi w funkcję wywołania zwrotnego. W ten sposób odpowiedź nie będzie traktowana jak dane, ale jak kod JavaScript, który zostanie wykonany przez przeglądarkę. Adres URL wyszukiwania filmów w serwisie YouTube wygląda następująco: http://gdata.youtube.com/feeds/api/videos?q=' + query + '&alt=json-in-script

Parametr q definiuje zapytanie, które wprowadziliśmy do pola tekstowego, natomiast parametr alt określa rodzaj odpowiedzi, jaką chcemy otrzymać. Ze względu na to, że zamiast formatu JSON używamy tym razem formatu JSONP, w parametrze alt podajemy wartość json-in-script, zgodnie

292

Rozdział 9. • Rozbudowywanie stron za pomocą PHP i jQuery

z zaleceniami API serwisu YouTube. W momencie otrzymania odpowiedzi uruchamiana jest funkcja wywołania zwrotnego showVideoList(). Na początku sprawdza ona, czy w ogóle otrzymaliśmy jakieś wyniki, i ewentualnie wyświetla odpowiedni komunikat o błędzie. W kolejnym kroku pobieramy wszystkie elementy odpowiedzi i iterujemy po nich w ramach pętli for. Dla każdego filmu pobieramy wartości parametrów videoURL, thumbnail, thumbnailWidth, thumbnailHeight, numComments i rating. Następnie możemy wykorzystać pobrane wartości do przygotowania kodu HTML tworzącego listę z poszczególnymi filmami. Każdy z nich znajdzie się w znaczniku a, którego atrybutowi href przypisana zostanie wartość videoURL. Wewnątrz znacznika a znajdzie się jeszcze miniaturka filmu oraz znacznik p zawierający dane o liczbie komentarzy i ogólnej ocenie tego filmu. Po utworzeniu pełnego kodu HTML zostanie on wstawiony do elementu div o identyfikatorze result.

I coś jeszcze Co to jest JSONP Więcej informacji na temat formatu JSONP można znaleźć pod adresami: Q http://remysharp.com/2007/10/08/what-is-jsonp/ Q http://en.wikipedia.org/wiki/JSON#JSONP

Zobacz też Q Recepturę „Wysyłanie żądań między domenami z wykorzystaniem serwera proxy”.

Tworzenie strony przewijającej się w nieskończoność Jeżeli ktoś używa usługi Google Reader lub nowej wersji Twittera, to dokładnie wie, o czym będziemy mówić. W obu aplikacjach po przewinięciu strony na sam dół doładowywana jest dodatkowa treść, która doklejana jest jako ciąg dalszy strony. W ten sposób eliminowana jest konieczność podziału na strony i wstawiania przycisków Dalej i Wstecz. W tej recepturze przygotujemy przykład realizujący bardzo podobną funkcję. Po przewinięciu strony do dolnej krawędzi zostanie wysłane żądanie AJAX i dodatkowe dane zostaną załadowane ze skryptu PHP, a następnie dołączone jako ciąg dalszy strony.

293

PHP i jQuery. Receptury

Przygotowania W katalogu rozdzial9 utwórz nowy katalog o nazwie receptura3.

Jak to zrobić? 1. W katalogu receptura3 utwórz nowy plik i nazwij go index.html. Do tego pliku wpisz kod HTML tworzący element div o identyfikatorze container oraz kilka akapitów, dzięki którym strona stanie się naprawdę długa i będzie wymagała przewijania. Następnie utwórz kolejny akapit, którym będzie się pojawiać komunikat o ładowaniu danych, w czasie gdy będziemy je pobierać z serwera. Niekończące się przewijanie

Akapit testowy 1

Akapit testowy 2

Akapit testowy 3

Akapit testowy 4

Akapit testowy 5

Akapit testowy 6

Akapit testowy 7

Akapit testowy 8

Akapit testowy 9

Akapit testowy 10

Akapit testowy 11

Akapit testowy 12

Akapit testowy 13

Akapit testowy 14

Akapit testowy 15

Akapit testowy 16

Akapit testowy 17

Akapit testowy 18

Akapit testowy 19

Akapit testowy 20

Ładowanie danych...

 



294

Rozdział 9. • Rozbudowywanie stron za pomocą PHP i jQuery



2. Przed zamykającym znacznikiem body dołącz plik biblioteki jQuery. Dopisz kod JavaScript, który dołączy funkcję obsługującą zdarzenie przewijania zawartości okna. Jeżeli użytkownik dotrze do dolnej krawędzi, to wysłane zostanie żądanie AJAX do pliku data.php. Otrzymane od niego dane zostaną dołączone do już istniejących.

3. Po stronie serwera utwórz plik data.php. Zapisz w nim skrypt odsyłający po prostu krótki tekst do przeglądarki.
295

PHP i jQuery. Receptury

echo '

Te dane zostały
załadowane z serwera...

';

?>

4. Uruchom w przeglądarce plik index.html. Zobaczysz na stronie listę akapitów, którą można przewijać za pomocą myszy lub klawiatury. Po przewinięciu strony na sam dół pojawi się informacja o pobieraniu danych z serwera.

5. Po krótkiej chwili dane zostaną załadowane, ze strony zniknie informacja o komunikacji z serwerem, ale za to pojawi się tekst przesłany przez skrypt PHP.

296

Rozdział 9. • Rozbudowywanie stron za pomocą PHP i jQuery

Jak to działa? Na początek do zdarzenia przewijania zawartości okna przypięliśmy obsługującą je funkcję. Podczas przewijania strony za pomocą myszy lub klawiszy strzałek wywoływana jest funkcja loadData(). Zanim jednak załadujemy jakiekolwiek dane, musimy się upewnić, że użytkownik rzeczywiście przewinął stronę na sam dół. W tym celu wywołujemy funkcję isUserAtBottom(), która określa aktualną pozycję strony za pomocą poniższych obliczeń: return ((($(document).height() - $(window).height()) - $(window).scrollTop()) ´<= 50) ? true : false;

Wyrażenie $(document).height() zwraca całkowitą wysokość strony HTML, natomiast $(window). ´height() opisuje wysokość widocznej w przeglądarce części strony, a $(window).scrollTop() zwraca pozycję pionowego paska przewijania. Ostateczną wartość wyliczamy zatem, odejmując pozycję paska przewijania i wysokość okna od całkowitej wysokości strony. Jeżeli ta wartość jest mniejsza niż 50, to znaczy, że strona została przewinięta do pozycji mniejszej niż 50 pikseli od dołu. Na podstawie tych obliczeń funkcja zwraca wartość true lub false. Gdy mamy już pewność, że użytkownik przewinął stronę na sam dół, możemy wywołać funkcję getData(), która na początek odłącza obsługę zdarzenia przewijania okna, tak żeby do zakończenia obsługi tego żądania nie były wysyłane kolejne. Następnie wyświetlana jest informacja o ładowaniu danych i wysyłane jest żądanie AJAX do pliku data.php. W naszym przykładzie skrypt ten odsyła tylko jeden wiersz tekstu. Gdy przygotowana na serwerze odpowiedź dociera do przeglądarki, ukrywany jest komunikat o ładowaniu danych, a otrzymany tekst dodawany jest do elementu div o identyfikatorze container. Funkcja obsługująca zdarzenie przewijania strony jest ponownie aktywowana, na wypadek gdyby użytkownik chciał załadować jeszcze więcej danych. Proces ten będzie powtarzany tak długo, jak długo wartość zmiennej counter będzie mniejsza od 5. Oznacza to, że tylko pięć razy będziemy mogli pobrać dane z serwera.

I coś jeszcze Ładowanie danych z innych źródeł W tym przykładzie odsyłaliśmy tylko wiersz tekstu przygotowany w skrypcie PHP. W rzeczywistych aplikacjach dane pobierane są z baz danych lub za pośrednictwem interfejsów API. Oznacza to, że powinniśmy założyć sytuację, w której nie ma już więcej danych do załadowania, i odpowiednio zakomunikować to użytkownikowi.

297

PHP i jQuery. Receptury

Tworzenie wtyczki do biblioteki jQuery W tej recepturze dowiemy się, jak można tworzyć proste wtyczki do biblioteki jQuery. Użytkownik będzie mógł wprowadzić na stronie dwie liczby, a nasza wtyczka zajmie się odliczaniem od pierwszej do drugiej liczby, zachowując się jak stoper. Naszą wtyczkę nazwiemy Licznik pieniędzy, a w jej ustawieniach będziemy mogli zdefiniować szybkość działania animacji.

Przygotowania W katalogu rozdzial9 utwórz nowy katalog o nazwie receptura4.

Jak to zrobić? 1. W katalogu receptura4 utwórz nowy plik i nazwij go index.html. Do pliku wpisz kod HTML tworzący dwa pola tekstowe na liczbę początkową i końcową, element h1, w którym będzie wyświetlana zmieniająca się wartość, oraz przycisk uruchamiający cały proces. Licznik pieniędzy


  • 298

    Rozdział 9. • Rozbudowywanie stron za pomocą PHP i jQuery



2. Następnie utwórz jeszcze jeden plik i nazwij go jquery.counter.js. Wpisz do niego przedstawiony poniżej kod naszej wtyczki: (function( $ ) { $.fn.cashCounter = function(options) { return this.each(function() { settings = $.extend ( { start: 0, end: 0, step: .5 }, options ); var e = $(this); if(isNaN(settings.start) || isNaN(settings.end) || ((settings.start) == (settings.end))) { return this; } settings.increasing = (settings.start < settings.end) ? true : false; if(settings.increasing) { if(settings.start >= settings.end) { return this;

299

PHP i jQuery. Receptury

} } else { if(settings.start <= settings.end) { return this; } } var diff = parseInt(settings.end,10) - parseInt(settings.start,10); var changeBy; if(settings.increasing) { changeBy = Math.ceil(diff * settings.step); } else { changeBy = Math.floor(diff * settings.step); } settings.start = parseInt(settings.start,10) + changeBy; e.html(settings.start); setTimeout(function() { e.cashCounter(settings); }, 100); });//each }; })( jQuery );

3. Wróć teraz do pliku index.html i dołącz do niego plik jquery.js i utworzony przed chwilą plik wtyczki jquery.counter.js. Oprócz tego napisz też kod funkcji obsługującej kliknięcia przycisku, która będzie pobierała wartości z pola tekstowego i przekazywała je do naszej wtyczki.

4. Otwórz w przeglądarce plik index.html i wpisz do pól tekstowych Początek i Koniec dwie liczby, a następnie kliknij przycisk Zmień. Odliczanie rozpocznie się od wartości początkowej i będzie trwało aż do osiągnięcia wartości końcowej. Niestety w książce nie mam możliwości pokazania animacji, dlatego prezentuję tylko zrzut ekranu wykonany w trakcie jej trwania. Możesz też spróbować zmieniać wartość parametru step, aby zobaczyć, jak zachowuje się wolniejsze i szybsze odliczanie.

Jak to działa? Wtyczka cashCounter podczas inicjalizacji przyjmuje trzy parametry: start, end i step. Wartości parametrów start i end raczej nie wymagają dodatkowego opisu. Z kolei parametr step używany jest do definiowania szybkości odliczania. Jego wartość można zmieniać w zakresie od 0.1 do 0.9, przy czym wartość 0.1 oznacza najszybszą animację. Kod wtyczki zaczyna się od rozbudowania obiektu jQuery.fn. Naszą wtyczkę chcemy nazwać cashCounter, a zatem opakowujemy ją poniższym kodem: jQuery.fn.cashCounter = function(options) { };

301

PHP i jQuery. Receptury

Wewnątrz tego bloku kodu znajdzie się zatem całość naszej wtyczki. Następnie umieszczamy instrukcję return this.each(function(){}). Dzięki temu zyskujemy pewność, że obiekt biblioteki jQuery będzie zwracany do funkcji wywołującej, i utrzymamy możliwość stosowania łańcuchów wywołań, będących jedną z cech biblioteki jQuery. Następnie definiowany jest obiekt settings, który określa domyślne parametry pracy wtyczki, na wypadek gdyby nie zostały one podane w wywołaniu. Ostateczne parametry definiowane są przez połączenie podanych tu wartości domyślnych z obiektem options przekazanym przez użytkownika. Domyślnie wartość początkowa i końcowa jest równa zero, a parametr step otrzymuje wartość 0.5. Po wpisaniu tych wszystkich ustawień początkowych możemy przystąpić do tworzenia funkcji naszej wtyczki. Jeżeli parametry start lub end nie są wartościami liczbowymi albo jeżeli są sobie równe, to zatrzymujemy wykonanie kodu i wracamy do funkcji wywołującej. Następnie definiujemy właściwość increasing obiektu settings. Jeżeli wartość end jest większa od wartości start, to właściwość ta otrzymuje wartość true, a w przeciwnym wypadku wartość false. Teraz, jeżeli właściwość increasing ma wartość true, a wartość start jest większa od wartości end, kończymy pracę wtyczki. Podobnie, jeżeli właściwość increasing ma wartość false, a wartość end jest większa od wartości start, również kończymy pracę. W kolejnym kroku wyliczamy różnicę między wartościami start i end oraz wyliczamy wartość zmiennej changeBy, która w zależności od wartości zmiennej step będzie zmniejszała lub zwiększała wartość zmiennej start. Nowa wartość zmiennej start wstawiana jest również do elementu wywołującego wtyczkę, czyli w tym przypadku elementu h1 o identyfikatorze container. Na zakończenie wywołujemy jeszcze funkcję języka JavaScript setTimeout(), która wywoła funkcję cashCounter po upływie 100 milisekund. Przy każdym takim wywołaniu sprawdzane będą wszystkie warunki zdefiniowane w instrukcjach if, aż do osiągnięcia stanu nakazującego wyjście z funkcji.

Wyświetlanie kanałów RSS za pomocą PHP i jQuery W tej recepturze będziemy pobierać dane z kanału RSS (ang. Really Simple Syndication) pewnego bloga, wykorzystując do tego język PHP, i wyświetlać je na stronie za pomocą biblioteki jQuery. RSS jest standardowym formatem publikowania kanałów danych, choć wersji tego standardu istnieje już kilka. W tym przypadku będziemy używali wersji RSS 2.0, którego typową strukturę prezentuję poniżej.

302

Rozdział 9. • Rozbudowywanie stron za pomocą PHP i jQuery

Przygotowania W katalogu rozdzial9 utwórz nowy katalog o nazwie receptura5.

Jak to zrobić? 1. W katalogu receptura5 utwórz nowy plik i nazwij go index.html. W utworzonym pliku zdefiniuj kilka stylów CSS dla elementów strony, a następnie zdefiniuj na niej element div o identyfikatorze results, w którym będziemy wyświetlać dane pobrane z kanału. Kanał RSS

303

PHP i jQuery. Receptury

Ładowanie...


2. Przed zamykającym znacznikiem body dołącz plik biblioteki jQuery. Następnie wyślij żądanie AJAX do serwerowego pliku feed.php. W odpowiedzi otrzymamy dokument XML, który zostanie obsłużony przez funkcję showPosts(). Zdefiniuj tę funkcję tak, żeby na podstawie danych XML tworzyła odpowiadającą jej strukturę HTML, która ostatecznie zostanie wstawiona na stronę do elementu div o identyfikatorze results.

3. Teraz utwórz jeszcze plik feed.php. To właśnie tutaj będziemy pobierali dokument XML z kanału RSS o podanym adresie URL i wysyłali go do przeglądarki.

4. Uruchom plik index.html w przeglądarce. Na początek widoczny będzie tylko tekst informujący o ładowaniu danych. Po otrzymaniu odpowiedzi z serwera wyświetlona zostanie lista artykułów. Po kliknięciu jednego z nich rozwinięty zostanie ogólny opis treści, uzupełniony o datę publikacji oraz liczbę komentarzy. Dodatkowo dostępne będzie łącze Przeczytaj artykuł, którym będzie można otworzyć stronę z artykułem w nowym oknie.

305

PHP i jQuery. Receptury

Jak to działa? Po załadowaniu dokumentu DOM wywołane jest żądanie AJAX skierowane do pliku feed.php. W tym pliku wywoływana jest funkcja file_get_contents(), za pomocą której pobierana jest zawartość kanału RSS. Element rss jest zawsze głównym elementem dokumentu RSS XML, natomiast element channel jest jego podwęzłem zawierającym informacje o samym blogu oraz najnowszych artykułach. Każdy artykuł reprezentowany jest tutaj przez węzeł item. Możemy już teraz odesłać dokument XML do przeglądarki.

306

Rozdział 9. • Rozbudowywanie stron za pomocą PHP i jQuery

Po stronie klienta funkcja showPosts() zajmuje się obsługą odebranych danych XML, przekazanych jej w parametrze data. Biblioteka jQuery pozwala na korzystanie z dokumentów XML w dokładnie ten sam sposób, którego używamy wobec dokumentów HTML, a zatem pobieramy wszystkie artykuły za pomocą metody find(), która zwraca nam elementy item. var posts = $(data).find('channel>item');

Następnie iterujemy po zmiennej posts i przy każdym obiegu pobieramy wartości tytułu, łącza do treści artykułu, liczby komentarzy i daty publikacji. Korzystając z tych zmiennych, tworzymy kolejne elementy składające się na listę wypunktowaną. Tytuł artykułu umieszczany jest w nagłówku h3, za którym tworzony jest element div z krótkim opisem, łączem do całości tekstu, datą i liczbą komentarzy. Tak przygotowanemu elementowi div przypisywana jest jeszcze klasa content. W klasie tej właściwość display została wcześniej ustawiona na wartość none, w związku z tym zaraz po załadowaniu listy artykułów widoczne będą tylko ich nagłówki. Po zbudowaniu całej listy wstawiamy ją do elementu div o identyfikatorze results. Oprócz tego do elementów h3 dołączamy funkcję obsługującą zdarzenie click, która będzie wyszukiwała element div następujący po klikniętym nagłówku h3 i wywoływała dla niego funkcję slideToggle(). Oznacza to, że kliknięcie nagłówka będzie powodowało pojawienie się lub ukrycie podsumowania artykułu. Dopiero po kliknięciu łącza Przeczytaj artykuł otwarte zostanie nowe okno przeglądarki z załadowaną pełną treścią artykułu.

Zobacz też Q Recepturę „Dodawanie zdarzeń do elementów, które zostaną utworzone później”

z rozdziału 1.

307

PHP i jQuery. Receptury

308

A Firebug W tym dodatku zajmiemy się: Q badaniem elementów strony, Q edytowaniem kodu HTML i stylów CSS, Q debugowaniem kodu JavaScript.

Wprowadzenie Jeżeli ktoś nie zna jeszcze dodatku Firebug, to traci naprawdę świetne narzędzie do tworzenia stron WWW. Jest to dodatek do przeglądarki Firefox, który w samej przeglądarce udostępnia wiele narzędzi wspomagających nas w pracach nad stronami. Możemy w nim przeglądać strukturę dokumentu DOM lub HTML, analizować dołączone style CSS, debugować kod JavaScript i wiele więcej. Przede wszystkim zainstaluj ten dodatek ze strony http://getfirebug.com. Zaraz po zainstalowaniu będzie on gotowy do pracy, czyli będziemy mogli go aktywować, naciskając klawisz F12 albo klikając na pasku stanu ikonę z robaczkiem. Na pasku narzędzi dodatku Firebug zobaczymy sześć przycisków, które opiszę teraz w poniższej liście: Q Konsola — Wyświetla błędy pojawiające się w kodzie JavaScript, opakowując

je w przyjazne komunikaty, w których podany jest też numer wiersza. Oprócz tego wyświetlane są też żądania AJAX, w których możemy zobaczyć dane wysyłane z żądaniem, nagłówki żądania i odpowiedzi, a także dane przesłane w odpowiedzi. W konsoli możemy też protokołować dane z wykonywanego skryptu za pomocą metody console.log(). var x = 10; console.log('Zmienna x ma wartość: ' + x);

PHP i jQuery. Receptury

Powyższy kod umieszczony w naszym skrypcie spowoduje wyświetlenie w konsoli Firebuga poniższego tekstu: Zmienna x ma wartość 10

Q Q Q

Q

Q

310

W ten sposób można wyeliminować niewygodne i brzydkie okienka z komunikatami, które programiści często umieszczają w kodzie, aby sprawdzić wartości zmiennych i inne parametry skryptu. HTML — W tym panelu wyświetlana jest struktura kodu HTML. Po prawej stronie znajduje się też panel, w którym podawane są style CSS wybranego elementu. CSS — Wyświetla wszystkie style CSS, jakie są dostępne na danej stronie. Po wybraniu tego panelu możemy wybrać plik stylów CSS z listy rozwijanej i zacząć jego edycję. Skrypt — Tutaj wyświetlane są wszystkie pliki JavaScript wykorzystane na aktualnej stronie. Można tu wybrać jeden z plików, wstawić do niego punkty wstrzymania i obserwować wartości zmiennych. DOM — Podaje pełną listę wszystkich obiektów i funkcji DOM. Firebug wyświetli też ich odpowiednio sformatowane wartości. Istnieje też możliwość edytowania wartość poszczególnych zmiennych. Sieć — W tym panelu prezentowane są wszystkie zasoby, które zostały załadowane przez stronę. Firebug wyświetli rozmiar każdego z załadowanych plików, a także pasek postępu pokazujący czas ładowania poszczególnych elementów. Taki wykres można wykorzystać jako miarę szybkości działania naszej strony. Istnieje też możliwość monitorowania aktywności sieci z podziałem na rodzaj zasobów. W panelu Sieć dostępnych jest jeszcze więcej opcji, które umożliwiają grupowanie elementów HTML, CSS, JavaScript, żądań AJAX oraz obrazków.

Dodatek A • Firebug

Badanie elementów strony W tej recepturze zaprezentuję panel HTML dodatku Firebug i pokażę, jak należy go używać do kontrolowania struktury dokumentu, wybierania elementów HTML i sprawdzania ich stylów CSS.

Jak to zrobić? 1. Otwórz w przeglądarce stronę HTML, na przykład stronę http://www.google.com. 2. Teraz kliknij ikonę ze strzałką w pasku narzędzi Firebuga i przenieś wskaźnik myszy nad dowolny element strony. Zostanie on wyróżniony w panelu dodatku, a dodatkowo zostaną wyświetlone szczegóły wybranego elementu, tak jak widać to na poniższym obrazku.

3. Inna metoda jest znacznie szybsza i o wiele dokładniejsza. Wystarczy kliknąć dany element strony prawym przyciskiem myszy, a następnie wybrać z menu kontekstowego pozycję Zbadaj element. Dodatek Firebug wyświetli wszystkie informacje na temat tego elementu.

311

PHP i jQuery. Receptury

Jak to działa? Panel HTML dodatku Firebug podzielony jest na dwie części. W lewym panelu wyświetlana jest struktura dokumentu HTML, natomiast w prawym podawane są style CSS. Kliknięcie przycisku Zbadaj pozwala na sprawdzenie dowolnego elementu strony. Późniejsze wskazanie myszą elementu strony spowoduje wyświetlenie jego szczegółów w panelu HTML. W panelu tym dostępna jest pełna struktura HTML dokumentu. Dzięki temu możemy przejrzeć od razu całość dokumentu. Kontrolowanie dokumentu w panelu HTML ma jeszcze jedną zaletę. Pojawiają się w nim również elementy utworzone już po załadowaniu strony, czyli powstałe w wyniku działania skryptów JavaScript i biblioteki jQuery. Po wybraniu jednego elementu w prawym panelu okienka Firebuga wyświetlane będą też style CSS zdefiniowane w arkuszu stylów albo utworzone później w skrypcie.

I coś jeszcze Wtyczki do Firebuga To nie jest żart! Sam Firebug jest wtyczką, ale istnieje też kilka innych wtyczek użytecznych przy tworzeniu stron WWW, które działają w połączeniu z Firebugiem. Oba podane tu narzędzia bardzo pomagają kontrolować aktywność sieciową, wydajność pracy stron, czasy ładowania elementów itd. Oba dodatki podają wskaźniki wydajności wyznaczane zestawem reguł oraz podają zalecenia dotyczące poprawienia szybkości działania strony. Q Google Page Speed — Jest to wtyczka przygotowana przez firmę Google. Poniżej

podaję też opis podawany na stronach Google: Page Speed jest otwartym dodatkiem do Firebuga. Twórcy stron WWW mogą wykorzystać tę wtyczkę do oceniania szybkości działania swoich stron WWW i uzyskania podpowiedzi odnośnie do jej poprawiania. Dodatek ten można pobrać z poniższego adresu: http://code.google.com/speed/page-speed/download.html. Q Yahoo! YSlow — To wtyczka przygotowana przez firmę Yahoo, którą można pobrać

z adresu https://developer.yahoo.com/yslow/.

Zobacz też Q Recepturę „Edytowanie kodu HTML i stylów CSS”.

312

Dodatek A • Firebug

Edytowanie kodu HTML i stylów CSS Typowym sposobem edytowania strony jest otwarcie jej w edytorze, wprowadzenie w nim zmian i otwarcie jej w przeglądarce, aby ocenić uzyskane efekty. Jeżeli coś na stronie nie jest zgodne z naszymi oczekiwaniami, wraca się do edytora i cały cykl się powtarza. Dzięki zastosowaniu dodatku Firebug można to zrobić całkiem inaczej. W tej recepturze dowiemy się, jak należy edytować kod HTML i style CSS strony za pomocą panelu dodatku Firebug. Po wprowadzeniu zadowalających nas zmian można od razu wprowadzić je do kodu źródłowego.

Jak to zrobić? 1. Otwórz w przeglądarce plik dowolnej receptury z tej książki, na przykład receptury „Tworzenie menu harmonijkowego” z rozdziału 7.

2. Teraz za pomocą przycisku Zbadaj odszukaj na stronie element h1 z tekstem jQuery. Kliknij teraz przycisk Edytuj, aby uzyskać możliwość edytowania kodu HTML elementu h1. Zmień zatem znajdujący się w tym elemencie tekst na Biblioteka jQuery.

313

PHP i jQuery. Receptury

3. Teraz kliknij element div klasy container. W prawym panelu pojawi się klasa container i podane zostaną wszystkie jej właściwości. Możesz je edytować, klikając poszczególne wartości i zmieniając je zgodnie ze swoimi wymaganiami. Na przykład kliknij wartość właściwości background-color i zmień ją z #F0F8FF na #FF0000. Wszystkie elementy klasy container otrzymają teraz czerwony kolor tła. 4. Aby dodać nową właściwość do klasy, kliknij jej nazwę prawym przyciskiem myszy i wybierz z menu kontekstowego pozycję Nowa właściwość. Do istniejących już właściwości dopisany zostanie pusty wiersz, w którym możesz dopisać kolejną właściwość i nadać jej wartość. Do klasy container dodaj zatem dwie właściwości color i font-weight, a następnie nadaj im wartości #FFF i bold. Wprowadzona zmiana od razu będzie widoczna we wszystkich elementach klasy container.

I coś jeszcze Modyfikowanie stylu konkretnego elementu Oprócz zmieniania stylu CSS zdefiniowanej już klasy możemy też wprowadzać właściwości CSS poszczególnych elementów strony. W tym celu należy kliknąć prawym przyciskiem myszy w dowolnym miejscu prawego panelu i wybrać z menu kontekstowego pozycję Edytuj styl elementu. Pojawi się wtedy nowy wiersz w panelu właściwości CSS, w którym będziemy mogli wprowadzić dane tylko dla wybranego wcześniej elementu. 314

Dodatek A • Firebug

Debugowanie kodu JavaScript Dodatku Firebug można też użyć do debugowania kodu JavaScript bezpośrednio w przeglądarce. Możemy wstawiać w kodzie punkty wstrzymania i wykonywać go wiersz po wierszu. Oprócz tego możliwe jest też obserwowanie wartości zmiennych oraz elementów struktury DOM.

Jak to zrobić? 1. Aby umieścić w kodzie JavaScript punkt wstrzymania, otwórz dodatek Firebug, klikając jego ikonę na pasku stanu albo naciskając klawisz F12. 2. Następnie kliknij przycisk Skrypt na pasku narzędzi Firebuga. W ten sposób zostanie wyświetlona lista wszystkich skryptów związanych z daną stroną. 3. Wybierz z listy jeden ze skryptów, a jego zawartość zostanie wyświetlona w panelu treści Firebuga.

4. Po wybraniu pliku możesz umieścić w kodzie punkty wstrzymania, klikając tuż przed numerem wiersza kodu. Każdy punkt wstrzymania oznaczany jest za pomocą ciemnobrązowej kropki.

315

PHP i jQuery. Receptury

5. Teraz możemy rozpocząć debugowanie. W naszym przykładzie pokazanym na poniższym rysunku (gra w kółko i krzyżyk) punkt wstrzymania został umieszczony w 19. wierszu kodu. Sam skrypt zostanie uruchomiony w momencie kliknięcia jednego z pól planszy. 6. Kliknij jedno z pól, a zobaczysz, że wykonywanie kodu zostało zatrzymane w wybranym przez nas wierszu.

7. Teraz możesz wykonywać kod skryptu wiersz po wierszu. Aby przejść do kolejnego wiersza, naciśnij klawisz F10. Jeżeli natkniemy się na wywołanie funkcji, to naciskając klawisz F11, możemy wejść do niej i obserwować wykonywanie jej kodu. 8. Oprócz tego możesz też obserwować wartości zapisane w zmiennych. W prawym panelu widoczny jest wiersz z opisem Nowe wyrażenie czujki. Po jego kliknięciu możesz zapisać nazwę zmiennej lub wyrażenia, które chcesz obserwować. 9. Naciśnięcie klawisza F8 wznowi wykonywanie kodu JavaScript do momentu natknięcia się na kolejny punkt wstrzymania.

316

Dodatek A • Firebug

I coś jeszcze Debugowanie w skrócie Q F8 — Kontynuuj wykonywanie skryptu. Q F10 — Krok wykonania skryptu. Uruchamia skrypt do następnego wiersza. Q F11 — Krok z wejściem. Po naciśnięciu klawisza F11 w wierszu wywołującym

funkcję przejdziemy do pierwszego wiersza tej właśnie funkcji. Q F12 — Otwiera i zamyka Firebuga na wybranej stronie.

Sprawdzanie żądań AJAX Konsola Firebuga wyświetla też informacje o wszystkich żądaniach AJAX wysyłanych przez przeglądarkę. Podawany jest tutaj też kod odpowiedzi każdego z tych żądań. Oprócz tego wyświetlane są też parametry żądania, nagłówki żądania i odpowiedzi, a także treść odpowiedzi przesłanej przez serwer.

Pasek narzędzi Web developer Pasek narzędzi Web developer jest kolejnym przydatnym narzędziem umożliwiającym kontrolowanie zachowania poszczególnych elementów strony. On również udostępnia wiele narzędzi ułatwiających modyfikowanie stron WWW. Pozwala na włączanie lub wyłączanie wykonywania skryptów JavaScript, wyświetlania obrazków, podglądanie struktury strony, informacji o formularzach itd. Dodatek ten można pobrać ze strony http://addons.mozilla.org/firefox/addon/60.

317

PHP i jQuery. Receptury

318

Skorowidz A AJAX, 13, 52 Asynchroniczny, 52 JavaScript, 52 XML, 52 akapit, 43 aktualizowanie pozycji w koszyku, 192 aktywacja łącza Czytaj więcej, 215 animacja menu, 205 aplikacje WWW, 13 atrybut checked, 35 href, 205 name, 59, 162 src, 31, 292 value, 162 votes, 162 automatyczne podpowiedzi, 267

B baza danych exampleDB, 240 biblioteka libxml, 86 SimpleXML, 89 blokowanie buforowania żądań, 77 błędy, Patrz rodzaje błędów, 122

C chmura znaczników, 275, 278 czyszczenie danych, 240

D debugowanie kodu, Patrz Firebug dodawanie nowych kart, 225 DOM, 14, 98, 102

E efekt podświetlenia, 186 element channel, 306 rss, 306 textarea, 250

F filtrowanie zawartości listy, 251 filtrowanie znaczników, 163 filtry, 157 filtry poprawiające dane, 157 Firebug, 15, 199, 309 debugowanie kodu JavaScript, 315 modyfikowanie stylu konkretnego elementu, 314 Nowe wyrażenie czujki, 316 panel do edytowania kodu HTML i stylów CSS, 313 przyciski dodatku Firebug CSS, 310 DOM, 310 HTML, 310 Konsola, 309 Sieć, 310 Skrypt, 310

Skorowidz

Firebug sprawdzania stylów CSS, 311 sprawdzanie żądań AJAX, 317 format HTML, 52 JSON, 52, 113 tekstowy, 52 własny, 52 formularz, 28 dynamiczne dodawanie pól, 130 kontrola po stronie klienta, 152 kontrola po stronie serwera, 152 sprawdzanie danych na żywo, 148 sprawdzanie poprawności adresów e-mail i adresów WWW, 144 sprawdzanie poprawności danych, 28 sprawdzanie poprawności liczb, 141 szukanie pustych pól, 137 formularz rejestracyjny, 257 funkcja $(document).scrollTop(), 191, 220 addClass(), 225 addEvents(), 80 animate(), 191, 209, 220 checkForWin(), 171 clearSelection(), 135 data(), 267 displayData(), 126 displayDetails(), 126 displaySelectedValues(), 237 dragElement(), 48 each(), 112 eval(), 127 file_get_contents(), 287, 306 filter_var(), 156 getCurrentTabIndes(), 236 getData(), 215 getHTML, 56 getList(), 254 getPositions(), 45 hide(), 221 highlight(), 135 hover(),39, 174, 205, 209 index(), 225 isNaN(), 144 isset(), 156

320

isUserAtBottom(), 297 json_decode(), 119 json_encode(), 116, 279 json_last_error(), 122 libxml_get_errors(), 88 libxml_use_internal_errors(), 87 live(), 132, 230, 274 loadData(), 297 preventDefault(), 29 real_escape_string(), 250 removeClass(), 225 replace(), 137 session_start(), 198 setcookie(), 162 setInterval(), 188 setTimeout(), 302 show(), 180, 221 simplexml_load_file(), 87, 198 class_name, 88 filename, 88 options, 88 simplexml_load_string(), 88 sleep(), 178 slideToggle(), 221, 307 strip_tags(), 166 test(), 147 toggleClass(),112, 274 trim(), 140 validate(), 138 YFT(), 188 funkcja obsługi błędu, 76 obsługi zdarzenia change, 123 wywołania zwrotnego, 22, 126 showVideoList(), 293 zaznacz/usuń zaznaczenie, 32

G globalny obiekt game, 173

H harmonijka, 181

Skorowidz

I identyfikator all, 97 cart, 195 check, 259 cloud, 276, 280 container, 46, 169, 294 countryList, 256 error, 268 goTo, 267 information, 256 last, 97 loading, 180 myForm, 28 navigation, 263 next, 267 order, 237 prev, 267 result, 56, 90 rightPanel, 215 selectLanguage, 245 stateList, 256 suggest, 268 suggestions, 268 tip, 37 total, 97 townList, 256 year, 97 instrukcja echo, 56, 65 interaktywne aplikacje WWW, 13 interpreter PHP, 115

J język HTML, 83 PHP, 84 XML, 83 jQuery, 13, 39 JSON, 14 korzystanie z danych, 122 odczytywanie danych, 117 parsowanie ciągu znaków, 127 przechwytywanie błędów, 120, 127 stałe, 117 tworzenie danych, 115

typy danych, obiekt, 114 typy danych, tablica, 114 typy danych,ciąg znaków, 114 typy danych,liczba, 114 JSONP, 292

K karta aktywna, 224 karta elementy główne, 222 karta ustawienia domyślne, 230 karty, 221 klasa active, 185 autosuggest, 268 cross, 174 DOMAttr, 104 DOMDocument, 84, 101, 162 DOMElement, 104 dragMe, 47 hide, 230 highlight, 133 hoverMe, 37 last, 234 menu, 216 menuHeader, 205 menuItem, 205, 216 MySQLi, 244 next, 236 number, 144 numeric, 142 prev, 236 RegExp, 136 required, 137, 142 round, 174 SimpleXMLElement, 88 site, 147 tabContent, 225 toggle, 32 klucz HTTP_X_REQUESTED_WITH, 61 valid, 152 what, 56 komunikat Formularz poprawny, 144 konstruktor, 245 konstruktor klasy, 88, 104

321

Skorowidz

L LIBXML_NOBLANKS, 101 lista wypunktowana, 32, 205, 245

Ł ładowania plików na żądanie, 79

M menu, 201 harmonijkowe, 209 pływające, 216 rozwijane, 202, 205 zmieniające kolor tła, 206 metoda $(document).scrollTop(), 220 $.each(), 31 $objXMl.load(), 101 .bind(), 20, 24 .css(), 22 .live(), 25 .load(), 18 .ready(), 18 .unbind(), 20, 24 abort(), 275 ajax(), 65, 82 ajaxError(), 77 alert(), 58 animate(), 220 appandChild(), 104 append(), 132 asXML(), 93 createElement(), 104 css(), 50 data(), 152 delegate(), 112 die(), 26 each(), 144 fadeIn(), 39 fadeOut(), 39 fetch_assoc(), 245, 279 find(), 112 flickr.photos.search(), 286 GET, 59 get(), 53, 65, 215 getElementsByTagName(), 101, 108

322

getJSON(), 126 getScript(), 76, 81 hover(), 39 json_encode(), 279 live(), 132, 274 next(), 221 parseJSON(), 127 POST, 59 post(), 62, 65 query(), 245, 250 removeChild(), 109 save(), 104, 162 serialize(), 59 serializeArray(), 59 slideDown(), 205 slideUp(), 185, 205 toggleClass(), 112 toggleSlide(), 185 xpath(), 95 metody wyższego poziomu, 76 modyfikowanie wartości węzłów, 93 MySQL, 239

N nagłówek X-Requested-With, 61 XMLHttpRequest, 61 nagłówek karty, 222 nakładka, 180 narzędzie phpMyAdmin, 240 natychmiastowe ładowanie strony, 69

O obiekt $book, 93, 108 $quote, 108 $story, 108 $title, 108 DOMNodeList, 101 event, 29 jQuery.fn, 301 LibXMLError, 88 mysqli, 245 photo, 287 settings, 302 SimpleXMLElement, 87

Skorowidz

obliczenia aktualnej pozycji strony, 297 obsługa błędów, 73 odwiązywanie elementów, 20 okienko podpowiedzi, 39 opcja cache, 78 duration, 191 queue, 191

P parametr alt, 292 api_key, 286 end, 301 farmId, 287 format, 287 id, 287 nojsoncallback, 287 numComments, 293 pageNumber, 267 per_page, 287 q, 292 rating, 293 secret, 287 serverId, 287 size, 287 start, 301 step, 301 tags, 287 thumbnail, 293 thumbnailHeight, 293 thumbnailWidth, 293 videoURL, 293 pasek narzędzi Web developer, 317 PHP, 13 plik calculate.php, 195 check.php, 60, 259 common.xml, 85 data.php, 54, 214, 295 effects.core.js, 186 effects.highlight.js, 186 error.html, 29 feed.php, 304 jquery.js, 115, 247, 290 json.php, 124

main.css, 168 result.php, 243 tags.php, 277 validate.php, 165 pływające okienko, 188 pobieranie danych z PHP, 53 pole ID, 245 languageName, 245 textarea, 246 wyboru, 20 pozycja bezwzględna, 273 typu absolute, 50 względna, 273 zaznaczonego tekstu, 44 prawidłowa budowa dokumentu XML, 84 product, 237 programowe wysyłanie danych, 28 przeciąganie elementów, 47 przekazywanie metodzie .ready() funkcji, 19 przerywanie żądań AJAX, 66 przestrzeń nazw game, 170 przesyłanie formularza, 27 przezroczystość menu, 209 przycisk input, 26 submit, 27 przykład odpowiedzi serwera Flickr, 282

Q quantity, 237

R rodzaje błędów, stałe w PHP, 122 rozszerzenie MySQLi, 240

S sekcje harmonijki, 184 selektor .container:visible, 185 .toggle:checked, 35 dwukropek (:), 36 gt, 36

323

Skorowidz

selektory jQuery, 32 serwer Flickr, 286 SimpleXML, 14 składnia HEREDOC, 119 skrypt PHP validate.php, 164 slideToggle, 42 span, 137, 162, 216 struktura tablicy $booksInfo, 198 style CSS, 32, 168, 203, 276 superglobalna tablica $_GET, 91 superglobalna tablica $_SERVER, 61

T tabela users, 260 tablica $_GET, 240 $_POST, 107, 240 $_POST['browser'], 162 $_POST['sites'], 133 $arr, 279 $booksInfo, 198 $errorArray, 156 $names, 56 $result, 279 asocjatywna, 245 tekst zaznaczony przez użytkownika, 43 tworzenie kreatora, 231

U uniksowy znacznik czasu, 163 usuwanie pozycji z koszyka, 199 usuwanie węzłów, 109

W WampServer, 15 wartość $_POST['save'], 156 $find, 257 absolute, 37, 189 currentPage, 267 event.which, 274 false, 28 fast, 221

324

information, 257 json-in-script, 292 klucza find, 257 none, 37 normal, 221 scrollTop, 191 slow, 221 states, 257 stories, 93 true, 28 węzły, 162 podrzędne, 101 wiązanie danych, 239 elementów, 20 metoda skrócona, 23 wielu zdarzeń, 23 właściwość attributes, 101 dataType, 111 document.selection, 45 firstChild, 101 increasing, 302 item, 101 message, 88 nodeName, 102 nodeType, 102 nodeValue, 101, 102 pageX, 39 pageY, 39 position, 189 selectionEnd, 46 selectionStart, 46 which, 42 window.getSelection, 45 włączenie menu przeglądarki, 42 wskaźnik myszy, przechwytywanie zdarzeń 36 współrzędna wskaźnika myszy, 50 wtyczka cashCounter, 301 Google Page Speed, 312 Yahoo! YSlow, 312 easing, 186 biblioteki jQuery, 298 wyłączenie domyślnego zachowania przeglądarki, 42

Skorowidz

wyrażenie $('container').hide(), 214 $(document).height(), 297 $(window).scrollTop(), 297 //book/name[], 98 __construct(), 245 regularne, 147 wyszukiwanie tekstu, 133 wyświetlanie i ukrywanie podmenu, 204 wyświetlanie kanałów RSS, 302 wyświetlanie podpowiedzi, 37 wywołanie $.get() dane, 56 funkcja obsługująca, 56 typ danych, 56 URL, 56 wywołanie funkcji zwrotnej, 81 wywoływanie zdarzeń, 23 wzorzec adresu URL dla Flickr, 287 wzorzec adresu URL dla YouTube, 292

X XML, 14 dodawanie elementów, 93 ładowanie danych, 86 modyfikowanie dokumentów, 93, 105 odczytywanie dokumentów, 98 parsowanie dokumentów, 109 tworzenie nowych dokumentów, 102 wyszukiwanie elementów, 94 XMLHttpRequest, 52 XPath, 94

Y YFT, 186

Z zapis $(this), 22 zapytanie DELETE, 250 INSERT, 247 SELECT, 250 SHOW, 250 UPDATE, 250

zastępnik, 29 zdarzenie, 17 blur, 22 change, 21 click, 21, 24, 25, 152 dblclick, 24 focus, 22, 151 hover, 208 keydown, 22, 40 keypress, 24 keyup, 22, 40, 151, 273 load, 24 mousedown, 24, 48 mousemove, 24, 39, 48 mouseout, 24 mouseover, 24, 274 mouseup, 24 onkeydown, 262 przeciąganie, 18 przewijanie okna, 190 scroll, 24, 191 select, 24 skróty klawiszowe, 18, 39 submit, 24, 247 success, 56 unload, 24 zmienna $_COOKIE, 162 $action, 92 $bookId, 92 $objXML, 92 $result, 245 $resultStr, 245 $strResponse, 93 altPressed, 42 base, 188 changeBy, 302 currentTabIndex, 236 dataValid, 140, 152 defaultOffset, 191 divLeft, 50 divTop, 50 emailPattern, 147 from, 267 interval, 188 mousex, 50 mousey, 50

325

Skorowidz

zmienna moviesPerPage, 267 offsetTop, 191 page, 215 player, 175 posts, 307 searchText, 136 target, 256 textOnPage, 46 to, 267 totalMovies, 267 url, 256 who, 174 xhr, 275

326

zmienne globalne, 50 jsonResult, 126 znacznik form, 155 img, 31, 176 script, 292 znaczniki w harmonijce, 185

Ż żądania AJAX, 54, 251, 293 pomiędzy domenami, 282 typu GET, 65 typu POST, 65 AJAX do skryptu search.php, 284