PHP i jQuery. Receptury

Zbiór kilkudziesięciu sprawdzonych receptur i szybkich rozwiązań problemów niezbędnych do sprawnego tworzenia interaktyw

582 157 8MB

Polish Pages [325] Year 2011

Report DMCA / Copyright

DOWNLOAD FILE

Polecaj historie

PHP i jQuery. Receptury

Table of contents :
Spis treści
Podziękowania
O autorze
O recenzentach
Wstęp
Rozdział 1. Obsługa zdarzeń w jQuery
Wprowadzenie
Wykonywanie funkcji w momencie załadowania strony
Wiązanie i odwiązywanie elementów
Dodawanie zdarzeń do elementów, które zostaną utworzone później
Przesyłanie formularza za pomocą jQuery
Kontrola brakujących obrazków
Tworzenie funkcji zaznacz/usuń zaznaczenie wszystkich pól wyboru
Przechwytywanie zdarzeń myszy
Tworzenie skrótów klawiszowych
Wyświetlanie tekstu wybranego przez użytkownika
Przeciąganie elementów na stronie
Rozdział 2. Łączenie PHP i jQuery
Wprowadzenie
Pobieranie danych z PHP za pomocą jQuery
Automatyczne tworzenie tekstu zapytania na podstawie elementów formularza
Wykrywanie żądań AJAX w skryptach PHP
Wysyłanie danych do PHP
Przerywanie żądań AJAX
Tworzenie pustej strony i ładowanie jej w częściach
Obsługa błędów w żądaniach AJAX
Blokowanie w przeglądarce buforowania żądań AJAX
Ładowanie JavaScriptu na żądanie, aby zmniejszyć czas ładowania strony
Rozdział 3. Praca z dokumentami XML
Wprowadzenie
Ładowanie danych XML z plików oraz ciągów znaków za pomocą SimpleXML
Korzystanie z elementów i atrybutów za pomocą SimpleXML
Wyszukiwanie elementów za pomocą XPath
Odczytywanie dokumentów XML za pomocą rozszerzenia DOM
Tworzenie dokumentów XML za pomocą rozszerzenia DOM
Modyfikowanie dokumentów XML za pomocą rozszerzenia DOM
Parsowanie dokumentów XML za pomocą biblioteki jQuery
Rozdział 4. Praca z formatem JSON
Wprowadzenie
Tworzenie danych w formacie JSON za pomocą PHP
Odczytywanie danych w formacie JSON za pomocą PHP
Przechwytywanie błędów analizy danych w formacie JSON
Korzystanie z danych w formacie JSON za pomocą jQuery
Rozdział 5. Praca z formularzami
Wprowadzenie
Dynamiczne dodawanie pól do formularza
Wyszukiwanie na stronie tekstu wprowadzonego przez użytkownika
Szukanie pustych pól za pomocą biblioteki jQuery
Sprawdzanie poprawności liczb za pomocą biblioteki jQuery
Sprawdzanie poprawności adresów e-mail i adresów WWW za pomocą wyrażeń regularnych
Wyświetlanie błędów w czasie wprowadzania danych, czyli sprawdzanie danych na żywo
Mocniejsza kontrola formularza, czyli ponowne kontrolowanie w PHP
Tworzenie systemu do głosowania
Zezwalanie na kod HTML w polach tekstowych i ograniczanie zbioru dozwolonych znaczników
Rozdział 6. Efekty specjalne w formularzach
Wprowadzenie
Tworzenie gry w kółko i krzyżyk
Informowanie użytkownika o przetwarzaniu żądania AJAX
Tworzenie rozwijanych i zwijanych ramek (harmonijek)
Stopniowe ukrywanie elementu po jego zaktualizowaniu
Wyświetlanie pływającego okienka na żądanie
Aktualizowanie pozycji w koszyku na zakupy
Rozdział 7. Tworzenie menu nawigacyjnych
Wprowadzenie
Tworzenie prostych menu rozwijanych
Tworzenie menu zmieniającego kolor tła po wskazaniu myszą
Tworzenie menu harmonijkowego
Tworzenie menu pływającego
Tworzenie interfejsu do nawigacji w kartach
Dodawanie nowych kart
Tworzenie kreatora za pomocą kart
Rozdział 8. Wiązanie danych w PHP i jQuery
Wprowadzenie
Pobieranie danych z bazy i wyświetlanie ich w formie tabeli
Zbieranie danych z formularza i zapisywanie ich w bazie
Wypełnianie powiązanych ze sobą list rozwijanych
Sprawdzanie w bazie danych dostępności nazwy użytkownika
Podział dużych ilości danych na strony
Dodawanie funkcji automatycznych podpowiedzi do pól tekstowych
Tworzenie chmury znaczników
Rozdział 9. Rozbudowywanie stron za pomocą PHP i jQuery
Wprowadzenie
Wysyłanie żądań między domenami z wykorzystaniem serwera proxy
Tworzenie międzydomenowych żądań za pomocą biblioteki jQuery
Tworzenie strony przewijającej się w nieskończoność
Tworzenie wtyczki do biblioteki jQuery
Wyświetlanie kanałów RSS za pomocą PHP i jQuery
Dodatek A. Firebug
Wprowadzenie
Badanie elementów strony
Edytowanie kodu HTML i stylów CSS
Debugowanie kodu JavaScript
Skorowidz

Citation preview

Spis treści Podziękowania

7

O autorze

9

O recenzentach

11

Wstęp

13

Rozdział 1. Obsługa zdarzeń w jQuery

17

Wprowadzenie Wykonywanie funkcji w momencie załadowania strony Wiązanie i odwiązywanie elementów Dodawanie zdarzeń do elementów, które zostaną utworzone później Przesyłanie formularza za pomocą jQuery Kontrola brakujących obrazków Tworzenie funkcji zaznacz/usuń zaznaczenie wszystkich pól wyboru Przechwytywanie zdarzeń myszy Tworzenie skrótów klawiszowych Wyświetlanie tekstu wybranego przez użytkownika Przeciąganie elementów na stronie

Rozdział 2. Łączenie PHP i jQuery Wprowadzenie Pobieranie danych z PHP za pomocą jQuery Automatyczne tworzenie tekstu zapytania na podstawie elementów formularza Wykrywanie żądań AJAX w skryptach PHP Wysyłanie danych do PHP Przerywanie żądań AJAX Tworzenie pustej strony i ładowanie jej w częściach Obsługa błędów w żądaniach AJAX Blokowanie w przeglądarce buforowania żądań AJAX Ładowanie JavaScriptu na żądanie, aby zmniejszyć czas ładowania strony

17 18 20 24 27 29 32 36 39 43 47

51 51 53 57 60 62 66 69 73 77 79

Spis treści

Rozdział 3. Praca z dokumentami XML Wprowadzenie Ładowanie danych XML z plików oraz ciągów znaków za pomocą SimpleXML Korzystanie z elementów i atrybutów za pomocą SimpleXML Wyszukiwanie elementów za pomocą XPath Odczytywanie dokumentów XML za pomocą rozszerzenia DOM Tworzenie dokumentów XML za pomocą rozszerzenia DOM Modyfikowanie dokumentów XML za pomocą rozszerzenia DOM Parsowanie dokumentów XML za pomocą biblioteki jQuery

Rozdział 4. Praca z formatem JSON Wprowadzenie Tworzenie danych w formacie JSON za pomocą PHP Odczytywanie danych w formacie JSON za pomocą PHP Przechwytywanie błędów analizy danych w formacie JSON Korzystanie z danych w formacie JSON za pomocą jQuery

Rozdział 5. Praca z formularzami Wprowadzenie Dynamiczne dodawanie pól do formularza Wyszukiwanie na stronie tekstu wprowadzonego przez użytkownika Szukanie pustych pól za pomocą biblioteki jQuery Sprawdzanie poprawności liczb za pomocą biblioteki jQuery Sprawdzanie poprawności adresów e-mail i adresów WWW za pomocą wyrażeń regularnych Wyświetlanie błędów w czasie wprowadzania danych, czyli sprawdzanie danych na żywo Mocniejsza kontrola formularza, czyli ponowne kontrolowanie w PHP Tworzenie systemu do głosowania Zezwalanie na kod HTML w polach tekstowych i ograniczanie zbioru dozwolonych znaczników

Rozdział 6. Efekty specjalne w formularzach Wprowadzenie Tworzenie gry w kółko i krzyżyk Informowanie użytkownika o przetwarzaniu żądania AJAX Tworzenie rozwijanych i zwijanych ramek (harmonijek) Stopniowe ukrywanie elementu po jego zaktualizowaniu Wyświetlanie pływającego okienka na żądanie Aktualizowanie pozycji w koszyku na zakupy

Rozdział 7. Tworzenie menu nawigacyjnych Wprowadzenie Tworzenie prostych menu rozwijanych Tworzenie menu zmieniającego kolor tła po wskazaniu myszą Tworzenie menu harmonijkowego

4

83 83 86 89 94 98 102 105 109

113 113 115 117 120 122

129 129 130 133 137 141 144 148 152 158 163

167 167 168 175 181 185 188 192

201 201 202 206 209

Spis treści

Tworzenie menu pływającego Tworzenie interfejsu do nawigacji w kartach Dodawanie nowych kart Tworzenie kreatora za pomocą kart

216 221 225 231

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

239

Wprowadzenie Pobieranie danych z bazy i wyświetlanie ich w formie tabeli Zbieranie danych z formularza i zapisywanie ich w bazie Wypełnianie powiązanych ze sobą list rozwijanych Sprawdzanie w bazie danych dostępności nazwy użytkownika Podział dużych ilości danych na strony Dodawanie funkcji automatycznych podpowiedzi do pól tekstowych Tworzenie chmury znaczników

Rozdział 9. Rozbudowywanie stron za pomocą PHP i jQuery Wprowadzenie Wysyłanie żądań między domenami z wykorzystaniem serwera proxy Tworzenie międzydomenowych żądań za pomocą biblioteki jQuery Tworzenie strony przewijającej się w nieskończoność Tworzenie wtyczki do biblioteki jQuery Wyświetlanie kanałów RSS za pomocą PHP i jQuery

Dodatek A. Firebug Wprowadzenie Badanie elementów strony Edytowanie kodu HTML i stylów CSS Debugowanie kodu JavaScript

Skorowidz

239 240 246 251 257 262 267 275

281 281 282 288 293 298 302

309 309 311 313 315

319

5

Spis treści

6

Podziękowania Autor Vijay Joshi Reviewers Anis Ahmad Md. Mahmud Ahsan Joe Wu Shameemah Kurzawa Aquisition Editor Chaitanya Apte Development Editor Neha Mallik Technical Editors Mohd. Sahil Hitches Uchil

Editorial Team Leader Aanchal Kumar Project Team Leader Ashwin Shetty Project Coordinator Michelle Quadros Proofreader Mario Cecere Indexer Hemangini Bari Production Coordinator Aparna Bhagat Cover Work Aparna Bhagat

PHP i jQuery. Receptury

8

Wstęp

O autorze Vijay Joshi jest programistą z ponad sześcioletnim doświadczeniem w pracy na różnych platformach. Cztery lata temu odkrył w sobie pasję do pracy z otwartymi źródłami, kiedy to zaczął poznawać język PHP w ramach hobbistycznego projektu realizowanego po uzyskaniu tytułu magistra nauk komputerowych. Vijay jest teraz zawodowym twórcą stron WWW i zdecydowanie woli tworzyć ich kod w postaci otwartych źródeł (co niestety nie zawsze jest możliwe). W każdej chwili może dostosować się do aktualnych potrzeb. Pracuje na stanowisku głównego programisty w firmie Philogy, jest niezależnym konsultantem dla kilku wybranych firm, którym doradza w zakresie różnych przedsięwzięć związanych z internetem, a przy okazji nadal jest aktywnym blogerem prowadzącym serwis http://vijayjoshi.org. Poza swoją pracą Vijay lubi czytać, chodzić po górach, a czasami dostaje obsesji na punkcie fitnessu. Tworzenie książki jest długotrwałym i skomplikowanym procesem, który wymaga współpracy i koordynacji działań wielu osób. Jestem wdzięczny całemu zespołowi wydawnictwa Packt, a w szczególności Michelle, Chaitanyi oraz Nehe za doskonałą współpracę i wiele cierpliwości wobec mojej osoby. Tę książkę chciałbym zadedykować wszystkim twórcom oprogramowania o otwartych źródłach, ich współpracownikom i entuzjastom z całego świata, dzięki którym PHP i jQuery stały się głównymi narzędziami programistycznymi w naszej niszy. Jeszcze raz wielkie podziękowania dla wszystkich. Jestem dumny i podekscytowany faktem, że mogę udzielać się w tej społeczności, dzięki której tak wiele się nauczyłem. Chciałbym też podziękować swoim rodzicom, bratu Ajayowi oraz Sheethalowi za ich nieustające wsparcie i zachęty do dalszej pracy. Specjalne podziękowania kieruję też do Randivy Vikram Singh za pomoc przy uruchomieniu tego projektu.

9

PHP i jQuery. Receptury

10

Wstęp

O recenzentach Md. Mahmud Ahsan ukończył wydział nauk komputerowych i inżynierii na międzynarodowym uniwersytecie islamskim w Chittagong (IIUC) w Bangladeszu. Jest certyfikowanym inżynierem biblioteki Zend i ekspertem w tworzeniu aplikacji WWW, aplikacji dla Facebooka, aplikacji typu Mashup oraz aplikacji dla iPhona. Oprócz swojej normalnej pracy prowadzi też bloga pod adresem http://thinkdiff.net, a także pisze artykuły na temat różnych technologii, w szczególności na temat tworzenia aplikacji dla Facebooka. Mieszka w Bangladeszu ze swoją żoną Jinat. Aktualnie Mahmud pracuje jako Software Ingeneer (zdalnie) w firmie i2we inc., dla której tworzy społecznościowe aplikacje WWW, wykorzystując przy tym PHP, MySQL, JavaScript, biblioteki Zend, CodeIgniter, jQuery oraz różne API. Prowadzi także kilka małych i średnich projektów. Mahmud jest też twórcą aplikacji dla iPhona, a swoje dzieła publikuje na stronie http://ithinkdiff.net. Był już recenzentem technicznym książki Zend Framework 1.8 Web Application Development wydanej przez wydawnictwo Packt. Jestem niezmiernie wdzięczny swojemu ojcu, który dał mi komputer w 2001 roku. Od tego czasu pokochałem programowanie i prace z różnymi technologiami.

Joe Wu pracuje jako starszy programista PHP, a w branży działa już od 2005 roku. Pracował już nad wieloma projektami o różnej wielkości, dzięki czemu poznał większość istniejących technologii o otwartych źródłach otaczających język PHP. Joe zawsze entuzjastycznie podchodzi do nowo powstających technologii i bardzo chętnie zdobywa umiejętności wspomagające jego pracę nad aktualnymi i przyszłymi projektami. Bardzo chętnie też poznaje nowe możliwości i rodzące się na świecie innowacyjne idee. Wierzy, że rynek jest zawsze szeroko otwarty na wszelkie innowacje poprawiające jakość naszego życia.

11

PHP i jQuery. Receptury

Pomijając całą tę pracę przy komputerach, Joe jest zawodowym graczem w badmintona i jakoś stara się pogodzić swój harmonogram treningów z pracą zawodową. Do tej pory Joe znalazł się na 59. miejscu światowej listy najlepszych badmintonistów i uczestniczył w Igrzyskach Wspólnoty Narodów w Delhi w 2010 roku. Jak widać, jest równie doskonałym ekspertem w badmintonie, jak i w programowaniu. Oprócz tych wszystkich zajęć Joe pracuje też w swojej własnej firmie (razem ze wspólnikiem), udostępniając swoje umiejętności i doświadczenie wszystkim potrzebującym pomocy przy tworzeniu aplikacji WWW. Firma Wackyinnovation (www.wackyinnovation.com) promuje ideę ciągłego parcia naprzód i wykorzystywania nowych technologii oraz pomysłów. Zawsze pełni entuzjazmu oraz chęci realizacji tworzą rozwiązania niemal doskonałe i zdecydowanie bardziej innowacyjne niż konkurencja. Shameemah Kurzawa zajmowała się programowaniem od czasu szkoły średniej. Chcąc uzyskać stanowisko analityka systemowego, zajęła się studiami dziennymi i podyplomowymi na kierunkach Biznesowych systemów informacyjnych i Inżynierii oprogramowania. Przez ostatnich pięć lat pracowała dla znanej australijskiej firmy SBS (ang. Special Broadcasting Service) jako twórca aplikacji WWW i analityk. Oprócz tego chętnie spędza czas ze swoją rodziną (jest mamą dwuletniego chłopca), uwielbia podróże i poznawanie nowych technologii. Chciałabym podziękować swojemu mężowi, synowi oraz zespołowi wydawnictwa Packt za wsparcie oraz okazane zrozumienie podczas recenzowania tej książki.

12

Wstęp

Wstęp Dzisiejsze aplikacje WWW coraz bardziej zaczynają przypominać typowe aplikacje komputerowe, wymagają mniejszej liczby przeładowań stron, pozwalają na lepszą interakcję z użytkownikiem oraz tworzenie różnych efektów. Sieć WWW zdecydowanie przyspieszyła, a takie aplikacje jak Gmail i Facebook nadały sieci nowego znaczenia. Język PHP po stronie serwera i biblioteka jQuery po stronie klienta (przeglądarki) to doskonały zestaw do tworzenia interaktywnych aplikacji WWW. PHP jest podstawowym językiem wybieranym przez twórców stron WWW, a jQuery jest wykorzystywana na jednej trzeciej spośród tysiąca największych stron w internecie, co czyni ją najczęściej stosowaną biblioteką. Jedną ze wspólnych cech języka PHP i biblioteki jQuery jest to, że bardzo łatwo można się ich nauczyć. Po poznaniu podstaw bez większych problemów możemy przejść na wyższy poziom zaawansowania. Podobnie ma działać niniejsza książka. Ma być skrzynką zawierającą multum najróżniejszych narzędzi. Dzięki niej Czytelnik będzie mógł szybciej tworzyć aplikacje WWW, upodabniać je do aplikacji komputerowych, a to wszystko z wykorzystaniem PHP i jQuery. Niezależnie od tego, czy chcemy nauczyć się na bieżąco kontrolować dane z formularzy, tworzyć wtyczki, przeciągać elementy, tworzyć menu, oglądać filmy za pomocą API YouTube albo współpracować z bazą danych, wystarczy tylko zajrzeć do właściwego przepisu. Dokładnie opisywana jest również technologia AJAX, która jest podstawową funkcją dzisiejszych rozbudowanych aplikacji WWW. Nie wymagamy przeczytania tej książki od deski do deski. Każda receptura jest niezależna od pozostałych i koncentruje się na pewnym problemie lub opisuje niewielką aplikację. Wystarczy zatem poszukać rozwiązania męczącego nas kłopotu. Mam nadzieję, że książka okaże się pomocna w codziennej pracy i przyczyni się do podniesienia umiejętności Czytelnika.

13

PHP i jQuery. Receptury

Co znajdziemy w tej książce W rozdziale 1. „Obsługa zdarzeń w jQuery” poznamy metody biblioteki jQuery na obsługę zdarzeń w różnych przeglądarkach. Nauczymy się pracy ze zdarzeniami generowanymi przez mysz i klawiaturę. Oprócz tego omawiane będą też zaawansowane zagadnienia, takie jak przeciąganie i stosowanie skrótów klawiszowych. Rozdział 2. „Łączenie PHP i jQuery” poświęcony zostanie metodom wysyłania żądań AJAX za pomocą biblioteki jQuery oraz sposobom odpowiadania na takie żądania w języku PHP. Znajdą się tu również receptury buforowania żądań AJAX oraz obsługi błędów podczas obsługi takich żądań. W rozdziale 3. „Praca z dokumentami XML” wyjaśniać będziemy metody pracy z plikami XML w języku PHP oraz bibliotece jQuery. Poszczególne receptury będą opisywały sposoby odczytywania, zapisywania i modyfikowania dokumentów XML za pomocą rozszerzeń języka PHP — DOM i SimpleXML. Oprócz tego omawiane będzie też analizowanie dokumentów XML za pomocą biblioteki jQuery. Rozdział 4. „Praca z JSON” w całości poświęcony zostanie formatowi JSON. Przedstawione zostaną sposoby odczytywania i zapisywania danych w tym formacie, a także omówimy wbudowane w bibliotekę jQuery metody pracy z tak zapisanymi danymi. W rozdziale 5. „Praca z formularzami” zajmiemy się obsługą formularzy i kontrolą wprowadzonych do nich danych. Nauczymy się sprawdzać poprawność różnych rodzajów danych. Zajmiemy się kontrolą pustych pól, liczb, adresów e-mail, adresów WWW i wielu innych. Dodatkowo przeanalizujemy znacznie bardziej rozbudowane metody kontroli formularzy po stronie serwera. Rozdział 6. „Efekty specjalne w formularzach” stanowić będzie ciąg dalszy poprzedniego rozdziału, ale tym razem receptury będą dotyczyły upiększania formularzy różnymi efektami graficznymi. Dzięki nim będziemy mogli budować formularze przyjazne dla użytkownika poprzez dodanie do nich takich efektów, jak podświetlenia, rozwijane ramki i inne. W rozdziale 7. „Tworzenie menu nawigacyjnych” znajdą się receptury dotyczące tworzenia różnego rodzaju menu, takich jak menu animowane, harmonijki albo karty. Nie pominiemy też zaawansowanych technik, dzięki którym na bieżąco możliwe jest dodawanie i usuwanie kart. Rozdział 8. „Wiązanie danych w PHP i jQuery” dokładnie wyjaśni nam tajniki używania baz danych w połączeniu z PHP i jQuery. Podawane tu przykłady zaprezentują metody pobierana danych z bazy i prezentowania ich w formularzach WWW. W rozdziale 9. „Rozbudowywanie stron za pomocą PHP i jQuery” poznamy kilka zaawansowanych technik wykorzystania PHP i jQuery. Dowiemy się, jak można obejść niektóre ogra-

14

Wstęp

niczenia przeglądarek, takie jak żądania przesyłane między domenami. Nauczymy się też tworzyć wtyczki biblioteki jQuery, między innymi wtyczkę do ciągłego przewijania strony. Dodatek „Firebug” zostanie poświęcony wykorzystaniu narzędzia Firebug do debugowania kodu HTML i JavaScript użytego na stronach WWW. Nauczymy się edytować kod HTML i zmieniać wygląd stron w samej przeglądarce bez modyfikowania samych plików z kodem. Będziemy mogli wykonywać kod JavaScript bezpośrednio w Firebugu i nauczymy się debugować skrypty za pomocą tego dodatku.

Co będzie potrzebne W systemie konieczne będzie zainstalowanie serwera Apache (lub innego serwera WWW), interpretera PHP (wersja 5.0 lub nowsza) oraz bazy danych MySQL. Tylko w ten sposób możliwe będzie uruchomienie przykładów z tej książki. Można zainstalować te elementy jednocześnie za pomocą oprogramowania typu WampServer albo instalować poszczególne elementy osobno. Oczywiście niezbędne będzie też pobranie biblioteki jQuery (wersja 1.3.2 lub nowsza). Pod względem technicznym w naszej książce zakładamy, że Czytelnik ma już doświadczenie w pracy z językiem PHP, biblioteką jQuery oraz językami HTML i CSS. Wymagana będzie tylko znajomość podstaw, a resztą zajmiemy się już w książce.

Dla kogo jest ta książka Ta książka przeznaczona jest dla programistów korzystających z PHP i jQuery chcących lepiej poznać te technologie, aby za ich pomocą tworzyć rozbudowane aplikacje WWW. W każdym rozdziale książki zostanie podanych wiele przykładów opisujących kolejne kroki wykonywania poszczególnych zadań, dzięki którym nawet początkujący programista będzie mógł zostać zawodowcem.

Konwencje W niniejszej książce zostanie wykorzystanych wiele stylów tekstu, za pomocą których wyróżnione będą różne rodzaje informacje. Poniżej prezentuję przykłady poszczególnych stylów wraz z ich dokładnym opisem.

15

PHP i jQuery. Receptury

Wycinki kodu znajdujące się w tekście zostaną wyróżnione w następujący sposób: „Przycisk input również zostanie połączony ze zdarzeniem click”. Blok kodu będzie wyglądał tak jak poniżej: $('input:text').bind( { focus: function() { $(this).val(''); }, blur: function() { $(this).val('Wprowadź tutaj tekst'); } });

Nowe pojęcie oraz ważne słowa wyróżniane będą pogrubieniem. Słowa pojawiające się na ekranie w ramach menu albo okienek dialogowych zostaną wyróżnione tak: „Teraz kliknij kilka razy przycisk Utwórz nowy element, aby utworzyć elementy DIV”. Wskazówki, sugestie i ważne informacje pojawiać się będą w takich ramkach.

16

1 Obsługa zdarzeń w jQuery W tym rozdziale zajmiemy się: Q uruchamianiem funkcji po załadowaniu strony, Q wiązaniem i odwiązywaniem elementów, Q dodawaniem zdarzeń do elementów, które zostaną utworzone później, Q przesyłaniem formularzy za pomocą jQuery, Q wyszukiwaniem brakujących obrazków, Q tworzeniem funkcji zaznaczającej lub usuwającej zaznaczenie wszystkich pól wyboru, Q przechwytywaniem ruchów myszy, Q tworzeniem skrótów klawiszowych, Q wyświetlaniem tekstu wybranego przez użytkownika, Q przeciąganiem elementów na stronie.

Wprowadzenie Zdarzenia są akcjami wykonującymi kod JavaScript w celu osiągnięcia określonego efektu. Może tu chodzić o różnego rodzaju manipulacje na dokumencie albo o wykonanie wewnętrznych obliczeń. Ze względu na to, że poszczególne przeglądarki inaczej obsługują zdarzenia, napisanie kodu JavaScript pracującego poprawnie we wszystkich przeglądarkach jest niezwykle trudne. W tym rozdziale poznamy tajniki obsługi zdarzeń oraz metody biblioteki jQuery związane z tym zagadnieniem,

PHP i jQuery. Receptury

dzięki którym nasze skrypty będą działały prawidłowo we wszystkich przeglądarkach. Nie możemy też pominąć zaawansowanych metod obsługi zdarzeń, takich jak przeciąganie i skróty klawiszowe.

Wykonywanie funkcji w momencie załadowania strony Aplikacje wykorzystujące technologię AJAX bardzo intensywnie używają języka Javascript do manipulowania zawartością i wyglądem stron WWW. Przed uruchomieniem jakiegokolwiek kodu JavaScript, który chciałby dokonać operacji, strony te powinny mieć załadowany kompletny dokument DOM. W tej recepturze podam sposób uruchomienia kodu JavaScript dopiero po całkowitym załadowaniu dokumentu DOM.

Przygotowania Wystarczy pobrać kopię najnowszej wersji biblioteki jQuery.

Jak to zrobić? 1. Utwórz plik i nazwij go domReady.html. 2. Aby uruchomić kod JavaScript po załadowaniu dokumentu DOM zapisz go pomiędzy klamrowymi nawiasami metody .ready():

Jak to działa? Biblioteka jQuery gwarantuje, że kod zapisany wewnątrz metody .ready() zostanie wykonany dopiero po całkowitym załadowaniu dokumentu DOM. Dotyczy to zarówno pełnego drzewa dokumentu HTML, arkuszy stylów oraz innych skryptów. Oznacza to, że możemy tu manipulować stroną, dodawać zdarzenia i wykonywać dowolne inne operacje. Trzeba jednak pamiętać, że metoda .ready() nie czeka na załadowanie obrazków. Na nie można zaczekać za pomocą metody .load(), o której będziemy mówić w innej recepturze z tego rozdziału.

18

Rozdział 1. • Obsługa zdarzeń w jQuery

Jeżeli nie skorzystamy z metody .ready(), to biblioteka jQuery nie poczeka na załadowanie całego dokumentu, a kod wykona się od razu po przesłaniu go do przeglądarki. Oznacza to, że mogą się w nim pojawić błędy, jeżeli będziemy próbowali manipulować elementami HTML, CSS lub innymi, które jeszcze nie zostały załadowane.

Przekazywanie metodzie .ready() funkcji obsługującej W poprzednim przykładzie podaliśmy metodzie .ready() funkcję anonimową. Możemy też przekazać do niej zwyczajną funkcję, tak jak pokazano poniżej:

Inny sposób używania metody .ready() Nie musimy jednak tworzyć kodu według podanego wyżej wzorca. Możemy też skorzystać z jednego z poniższych sposobów na określenie momentu pełnego załadowania dokumentu DOM: $(function () { });

lub $(doSomething); function doSomething() { // Dokument DOM jest już gotowy }

Wiele metod .ready() Jeżeli w naszej aplikacji działa wiele skryptów, to możemy w każdym z nich wykorzystać metodę .ready(). Biblioteka jQuery uruchomi wszystko po załadowaniu dokumentu. Przykładem takiej sytuacji może być użycie na stronie kilku wtyczek, z których każda zapisana jest w osobnym pliku .js.

19

PHP i jQuery. Receptury

Wiązanie i odwiązywanie elementów W tej recepturze zademonstrujemy sposoby dowiązywania zdarzeń do elementów DOM za pomocą metody .bind(). Oprócz tego nauczymy się usuwać takie dowiązania za pomocą metody .unbind().

Przygotowania Wystarczy pobrać kopię najnowszej wersji biblioteki jQuery.

Jak to zrobić? 1. W katalogu o nazwie rozdzial1 utwórz nowy plik i nazwij go binding.html. 2. Napisz kod HTML zawierający przynajmniej kilka elementów. Utwórz w nim wypunktowanie z nazwami kilku krajów. Następnie utwórz pole wyboru zawierające listę nazw kontynentów. Na zakończenie utwórz jeszcze przycisk, którego użyjemy do usuwania metody obsługi zdarzenia z pola wyboru.

Wiązanie elementów



  • Indie
  • USA
  • UK
  • Francja


Afryka Antarktyda Azja Australia Europa Ameryka północna

20

Rozdział 1. • Obsługa zdarzeń w jQuery

Ameryka południowa



3. Teraz możemy skorzystać z magii biblioteki jQuery. Za pomocą metody .bind() dowiąż metodę obsługi zdarzenia click do elementów listy. Metoda ta zmieni kolor tła klikniętego elementu na czerwony. Do pola wyboru dowiąż metodę obsługującą zdarzenie change. Powinna ona wyświetlać wartość wybraną z tego pola. Na koniec potrzebna będzie jeszcze metoda obsługująca zdarzenie click przycisku. Kliknięcie go będzie odwiązywało metodę obsługi zdarzenia z pola wyboru.

4. Otwórz plik binding.html w przeglądarce i kliknij kilka pozycji z listy. Tło każdego klikniętego elementu powinno przyjąć czerwoną barwę. Następnie wybierz jedną z wartości pola wyboru, a powinno się pojawić okienko z wybraną właśnie wartością, takie jak na poniższym rysunku:

21

PHP i jQuery. Receptury

Kliknięcie przycisku Usuń wiązanie z pola wyboru spowoduje odłączenie metody obsługi zdarzenia change, w wyniku czego wybieranie wartości z pola wyboru nie będzie powodowało już żadnych dodatkowych akcji.

Jak to działa? Biblioteka jQuery wykorzystuje metodę .bind() do przywiązania standardowych zdarzeń JavaScriptu do elementów strony. Metoda ta pobiera dwa parametry. Pierwszy określa rodzaj wiązanego zdarzenia. Parametr ten przekazywany jest jako ciąg znaków i można w nim zawrzeć takie zdarzenia, jak click, change, keyup, keydown, focus, blur i inne. Drugi parametr definiuje funkcję wywołania zwrotnego, która ma zostać wykonana w momencie uruchomienia zdarzenia. W podanym kodzie użyliśmy metody .bind(), aby przypiąć metodę obsługi zdarzenia click do elementów listy. Wewnątrz funkcji wywołania zwrotnego zapis $(this) opisuje element, który to zdarzenie wywołał. Następnie używana jest metoda .css(), za pomocą której modyfikowany jest kolor tła klikniętego elementu. W podobny sposób za pomocą metody .bind() przypięliśmy metodę obsługującą zdarzenie change do pola wyboru. Podana tu funkcja wywołania zwrotnego będzie wywoływana za każdym razem, gdy zmieni się wartość w polu wyboru. Oprócz tego do przycisku input przyłączone zostało zdarzenie click. Kliknięcie tego przycisku powoduje wywołanie metody .unbind(), która przyjmuje w parametrze nazwę rodzaju zdarze-

22

Rozdział 1. • Obsługa zdarzeń w jQuery

nia, a następnie usuwa to zdarzenie z elementu. W naszym przykładzie usuwamy zdarzenie change z pola wyboru. Oznacza to, że od teraz zmiana wartości w polu wyboru nie będzie powodowała wyświetlenia okienka z komunikatem.

I coś więcej Wiązanie wielu zdarzeń Za pomocą metody .bind() można też wiązać wiele różnych zdarzeń. W poniższym kodzie wiązane są zdarzenia focus i blur pola tekstowego. Umieszczenie kursora w polu tekstowym spowoduje usunięcie jego zawartości, natomiast przeniesienie kursora poza to pole spowoduje wpisanie do niego jakiegoś tekstu. $('input:text').bind( { focus: function() { $(this).val(''); }, blur: function() { $(this).val('Wprowadź tutaj tekst'); } }); Trzeba pamiętać, że taka możliwość została wprowadzona dopiero w wersji 1.4 biblioteki jQuery. Przed uruchomieniem tego kodu proszę się upewnić, czy mamy dostępną właściwą wersję.

Skrócona metoda wiązania Nie musimy korzystać z metody .bind(), aby powiązać zdarzenia z metodami. Takie powiązanie można wykonać bezpośrednio na zdarzeniu przy zastosowaniu odpowiedniej składni. Na przykład zapis $(element).click(function() { }); może zostać użyty zamiast wywołania $(element). ´bind('click', function() { });. Pozostałe zdarzenia można wiązać w podobny sposób.

Wywoływanie zdarzeń Zdarzenia mogą być też wywoływane w kodzie. W tym celu wystarczy wpisać nazwę zdarzenia bez podawania żadnych parametrów.

23

PHP i jQuery. Receptury

$(element).click(function() { $(element2).keydown(); });

Podany kod wywoła zdarzenie keydown elementu element2 w przypadku kliknięcia elementu element1.

Często używane zdarzenia Poniżej podaję listę najczęściej używanych zdarzeń, które można przekazywać metodom .bind() i .unbind(). blur

focus

load

unload

scroll

click

dblclick

mousedown

mouseup

mousemove

mouseover

mouseout

change

select

submit

keydown

keypress

keyup

Usuwanie wszystkich zdarzeń z elementu Jeżeli do metody .unbind() nie podamy żadnych parametrów, to usunie ona wszystkie zdarzenia powiązane z danym elementem. $(element).unbind();

Dodawanie zdarzeń do elementów, które zostaną utworzone później Metoda .bind() jest w stanie dodać zdarzenie tylko do tych elementów, które w danej chwili istnieją na stronie. Jeżeli później zostaną utworzone kolejne elementy spełniające warunki podane w wywołaniu tej metody, to nie będą one miały żadnych metod obsługi zdarzeń.

24

Rozdział 1. • Obsługa zdarzeń w jQuery

Jak to zrobić? 1. W katalogu rozdzial1 utwórz nowy plik o nazwie live.html. 2. Wpisz do pliku kod HTML tworzący przycisk i element div, a następnie dodaj do nich kilka stylów.

Dodawanie zdarzeń do elementów



Jest już na stronie

3. Teraz możemy dodać troszkę magii biblioteki jQuery. Do przycisku dodaj zdarzenie click. Kliknięcie tego przycisku będzie tworzyć nowy element div i wstawiać go do kodu strony. Do tak utworzonych elementów div dodamy obsługę zdarzenia click za pomocą metody .live(). Kliknięcie takiego elementu spowoduje zmianę jego kodu HTML i CSS.

4. Uruchom plik live.html w przeglądarce i kliknij na stronie element div. Jak widać, kod HTML i CSS tego elementu uległ zmianie. Teraz kliknij kilka razy przycisk Utwórz nowy element, aby na stronę wstawić nowe elementy div. Okazuje się, że kliknięcie tych elementów również powoduje zmianę ich wyglądu. Poniżej przedstawiam typowy wygląd strony, na której kliknięto już niektóre elementy.

25

PHP i jQuery. Receptury

Jak to działa? Przycisk input tworzy nowe elementy div i dodaje je do kodu dokumentu. Cała magia znajduje się w następnej funkcji. Metoda live() biblioteki jQuery dodaje po prostu zdarzenie click do elementu div. Pod tym względem zachowuje się dokładnie tak samo, jak metoda bind(), czyli związuje element strony z metodami obsługi zdarzeń. Istnieje jednak między nimi pewna istotna różnica. Metoda bind() może dodać zdarzenie tylko do istniejących już elementów, natomiast metoda live() zachowuje sobie selektor CSS oraz zdarzenie i będzie je stosowała wobec wszystkich elementów, które w późniejszym czasie zostaną utworzone i wstawione do kodu strony. Oznacza to, że nowe elementy div utworzone w wyniku kliknięcia przycisku Utwórz nowy element również będą miały dodaną metodę obsługi zdarzenia click.

Usuwanie metod obsługi zdarzeń za pomocą metody die() Metoda die() ma podobne działanie jak metoda unbind(). Używana jest do usuwania metod obsługi zdarzenia utworzonych za pomocą metody live(). Podobnie jak metoda unbind(), die() również występuje w dwóch wariantach. Jeżeli zostanie wywołana bez parametrów, to usunie z elementu wszystkie metody obsługi zdarzeń. $(element).die();

Drugi wariant przyjmuje w parametrze rodzaj zdarzenia i usuwa z elementu tylko metodę obsługującą podane zdarzenie: $(element).die('click');

26

Rozdział 1. • Obsługa zdarzeń w jQuery

Jeżeli element ma przypiętych kilka metod obsługi zdarzeń, to podany wyżej kod usunie tylko metodę obsługującą zdarzenie click, ale pozostałe pozostawi nienaruszone.

Zobacz też Q Receptura „Wiązanie i odwiązywanie elementów” podaje podstawowe informacje

na temat dodawania i usuwania zdarzeń z elementów.

Przesyłanie formularza za pomocą jQuery Wiemy, że przyciski typu submit używane są w formularzach HTML do przesyłania danych na serwer. Niezależnie od tych przycisków język JavaScript również udostępnia metodę pozwalającą na takie przesyłanie informacji. W tej recepturze nauczymy się wysyłać dane formularzy z wykorzystaniem biblioteki jQuery i kontrolować ten proces za pomocą przycisku typu submit.

Przygotowania Wystarczy pobrać kopię najnowszej wersji biblioteki jQuery.

Jak to zrobić? 1. W katalogu rozdzial1 utwórz nowy plik o nazwie formSubmit.html. 2. Zapisz do pliku poniższy kod, który tworzy formularz z przyciskiem typu input (nie submit). Następnie dopisz kod korzystający z biblioteki jQuery, który będzie uruchamiany po kliknięciu przycisku i zajmie się wysłaniem danych.

Wysyłanie formularzy







1. Otwórz w przeglądarce plik formSubmit.html i kliknij przycisk. Dane formularza zostaną wysłane.

Jak to działa? W tym przykładzie dodaliśmy metodę obsługującą zdarzenie click przycisku typu input. Funkcja ta zostanie zatem wykonana po kliknięciu przycisku, a wtedy wywołana zostanie metoda submit() biblioteki jQuery, która wyśle dane z formularza na serwer. Każda przeglądarka ma swoją własną metodę do programowego wysyłania danych, a biblioteka jQuery opakowała tę funkcję w ramach własnej metody submit().

Coś więcej Kontrolowanie przesyłania danych Jeżeli na formularzu jest już przycisk typu submit, to możemy mimo wszystko zadecydować, czy dane mają zostać wysłane czy też nie. W takiej sytuacji trzeba podłączyć do formularza metodę obsługi zdarzenia, która zostanie wykonana po kliknięciu przycisku typu submit tego formularza. $('#myForm').submit(function() { return false; });

Podany kod zostanie wykonany po kliknięciu przycisku typu submit znajdującego się na formularzu o identyfikatorze myForm. Jeżeli funkcja obsługi tego zdarzenia zwraca wartość false, to formularz nie zostanie przesłany do serwera. Jest to niezmiernie wygodne w przypadku sprawdzania poprawności danych z formularza, ponieważ kod wykonujący to zadanie może zostać umieszczony w funkcji obsługi zdarzenia. Jeżeli wartości w formularzu są poprawne, to funkcja zwróci wartość true, a formularz zostanie przesłany. Jeżeli jednak wykryte zostaną nieprawidłowości, to funkcja zwróci wartość false i zablokuje możliwość wysłania danych.

28

Rozdział 1. • Obsługa zdarzeń w jQuery

Innym rozwiązaniem jest zastosowanie funkcji preventDefault(). Jak sugeruje jej nazwa, blokuje ona wykonanie domyślnej metody obsługi wskazanego zdarzenia. Funkcja ta jest właściwością obiektów typu event. $('#myForm').submit(function(event) { event.preventDefault() });

Zobacz też Q Receptura „Wiązanie i odwiązywanie elementów” objaśnia metody dodawania i usuwania

zdarzeń z elementów.

Kontrola brakujących obrazków Jeżeli na stronie wyświetlanych ma być kilka obrazków, ale niestety części z nich brakuje, to przeglądarka wyświetli albo puste miejsce, albo specjalny symbol zastępujący obrazek (czerwony krzyżyk). Z pewnością nie poprawia to wyglądu strony, dlatego lepiej byłoby unikać takich sytuacji. Czy nie byłoby wspaniale, gdybyśmy mieli metodę, która byłaby w stanie odszukać brakujące obrazki albo te, których nie udało się pobrać? Po przeczytaniu tej receptury będziemy mogli wykrywać problemy z obrazkami i zastępować je wybranym przez siebie obrazem.

Przygotowania Przygotuj sobie trzy lub cztery obrazki, które wykorzystamy w ramach tej receptury. Oprócz tego potrzebna będzie też kopia biblioteki jQuery. Za pomocą programu graficznego (choćby najprostszego) przygotuj kolejny obrazek z tekstem „Nie można załadować obrazka”, który wykorzystamy jako zastępnik dla brakujących obrazków.

Jak to zrobić? 1. W katalogu rozdzial1 utwórz nowy plik i nazwij go error.html. 2. Na stronie umieść element div, w którym umieścimy obrazki. Oprócz tego wpisz jeszcze kilka stylów CSS dla elementu div i samych obrazków.

29

PHP i jQuery. Receptury

Kontrola brakujących obrazków





3. Dopisz kod korzystający z biblioteki jQuery do utworzenia tablicy z nazwami obrazków. Celowo umieść kilka losowych nazw obrazków, które na pewno nie istnieją. Następnie wypełnij element div znacznikami obrazków z tej tablicy. W kolejnym kroku trzeba powiązać metodę obsługi zdarzenia error z elementami obrazków.

30

Rozdział 1. • Obsługa zdarzeń w jQuery

4. Uruchom plik error.html w przeglądarce. Zobaczysz, że przynajmniej dwóch obrazków brakuje, dlatego zostały one zastąpione naszym zastępnikiem z tekstem Nie można załadować obrazka.

Jak to działa? Na początek używamy metody $.each(), aby przejść elementy tablicy z nazwami plików i utworzyć znaczniki img wewnątrz elementu div. Następnie do każdego znacznika img przywiązywana jest metoda obsługi zdarzenia error. Metoda ta jest wykonywana, w przypadku gdy obrazka nie uda się załadować albo atrybut src znacznika ma nieprawidłową wartość. W ramach tej metody nieistniejący obrazek zastępowany jest przygotowanym przez nas obrazkiem zastępującym. W naszym przypadku wstawiany jest obrazek z tekstem Nie można załadować obrazka.

Zobacz też Q Receptura „Wiązanie i odwiązywanie elementów” objaśnia metody dodawania

i usuwania zdarzeń z elementów.

31

PHP i jQuery. Receptury

Tworzenie funkcji zaznacz/usuń zaznaczenie wszystkich pól wyboru Jest to często wykorzystywana funkcja aplikacji WWW. Na stronie dostępna jest grupa pól wyboru, które można kontrolować za pomocą jednego, dodatkowego pola. Kliknięcie tego nadrzędnego pola wyboru powoduje zaznaczenie lub usunięcie zaznaczenia wszystkich pól podrzędnych. W tej recepturze przygotujemy zatem funkcję przełączania zaznaczenia grupy pól wyboru. Oprócz tego dowiemy się, jak odczytywać wartości zaznaczonych elementów za pomocą selektorów jQuery.

Przygotowania Upewnij się, że masz gotową kopię biblioteki jQuery.

Jak to zrobić? 1. W katalogu rozdzial1 utwórz nowy plik o nazwie checkbox.html. 2. Najpierw musimy przygotować stronę. Utwórz listę wypunktowaną i dodaj do niej kilka stylów CSS. Pierwszy element tej listy będzie polem wyboru nadrzędnym w stosunku do pozostałych. W pozostałych elementach listy umieść pola wyboru z nazwami książek. Każde z tych pól powinno mieć tę samą klasę: toggle. Utwórz też dodatkowy element listy zawierający przycisk, którego kliknięcie wyświetlać będzie nazwy zaznaczonych książek. Na koniec utwórz jeszcze jeden element listy i przypisz do niego identyfikator. To właśnie tutaj będą wyświetlane nazwy wybranych książek.

Zaznacz/usuń zaznaczenie pola wyboru





  • Przełącz wszystkie

    32

    Rozdział 1. • Obsługa zdarzeń w jQuery



  • Przeminęło z wiatrem


  • Pan Samochodzik i Templariusze


  • Przygody Sherlocka Holmesa


  • Dolina strachu


  • Ostatni Mohikanin




3. Po uruchomieniu pliku checkbox.html w przeglądarce powinniśmy zobaczyć następującą stronę.

33

PHP i jQuery. Receptury

4. Aby tak przygotowana strona zaczęła żyć, dołącz do niej bibliotekę jQuery i dowiąż metody obsługi zdarzeń do pól wyboru. Pierwsza z tych metod zostanie związana z pierwszym polem wyboru i zajmie się zaznaczaniem i usuwaniem zaznaczenia z pozostałych pól. Drugą metodę powiążemy z poszczególnymi polami wyboru. Będzie ona sprawdzać stan wszystkich pól i odpowiednio ustawiać wartość pola nadrzędnego. Ostatnia metoda obsługi zdarzenia związana zostanie z przyciskiem typu input i zajmie się wyświetlaniem nazw zaznaczonych książek.

5. Teraz odśwież stronę w przeglądarce i poklikaj trochę pola wyboru. Po kliknięciu pola Przełącz wszystkie wszystkie pozostałe pola zostaną zaznaczone lub ich zaznaczenie zostanie usunięte. Na koniec kliknij jeszcze przycisk Wyświetl zaznaczone książki, a pojawi się okienko z listą nazw książek rozdzielanych przecinkami.

34

Rozdział 1. • Obsługa zdarzeń w jQuery

Jak to działa? Kliknięcie pola wyboru Przełącz wszystkie powoduje włączenie lub wyłączenie zaznaczenia w tym polu. Jeżeli pole to zostało zaznaczone, to zaznaczamy też wszystkie te pola wyboru, które mają klasę toggle. W tym celu używamy selektora klasy i przypisujemy wybranym elementom wartość true do atrybutu checked. Z drugiej strony, jeżeli zaznaczenie zostało usunięte, to usuwamy też ze wszystkich pozostałych pól wyboru atrybut checked. W tym miejscu trzeba zająć się jeszcze jednym problemem. Jeżeli wszystkie pola wyboru zostały już zaznaczone, a następnie z jednego z nich usunięto zaznaczenie, to główne pole wyboru również powinno stracić swoje zaznaczenie. Podobnie, jeżeli wszystkie pola wyboru zostaną zaznaczone pojedynczo, to pole nadrzędne również powinno zostać zaznaczone. W tym celu osobną metodę obsługi zdarzenia wiążemy ze wszystkimi polami wyboru o klasie toggle. Selektor .toggle:checked wybiera wszystkie te pola, które mają klasę toggle, a jednocześnie zostały już zaznaczone. Jeżeli liczba wybranych elementów jest równa całkowitej liczbie pól wyboru, to możemy z tego wywnioskować, że wszystkie są zaznaczone i możemy zaznaczyć też główne pole wyboru. Jeżeli liczba zaznaczonych elementów jest mniejsza od całkowitej liczby pól wyboru, to możemy usunąć atrybut checked z głównego pola i w ten sposób usunąć jego zaznaczenie.

35

PHP i jQuery. Receptury

Coś więcej Używanie selektorów W poprzednim przykładzie korzystaliśmy z selektora .toggle:checked, aby wybrać wszystkie zaznaczone pola wyboru klasy toggle. Dwukropek (:) jest selektorem, który może służyć jako filtr listy elementów. Poniżej przedstawiam przykład obrazujący sposób filtrowania elementów za jego pomocą: $('div:first').click(function() { //zrób coś });

Podany kod wybierze pierwszy element div znajdujący się na stronie i dowiąże do niego metodę obsługującą zdarzenie click. $(p:gt(2)').hide();

Selektor gt oznacza „więcej niż” (ang. greater than). Przyjmuje on indeks (liczony od zera) i dopasowuje elementy o indeksie większym niż podany w parametrze. Jeżeli na stronie znajduje się pięć elementów p, to przykładowy kod ukryje elementy o numerze 3 i 4. Trzeba pamiętać, że indeksy liczone są od zera. Więcej informacji na temat selektorów biblioteki jQuery znaleźć można pod adresem http://api.jquery.com/category/selectors/.

Przechwytywanie zdarzeń myszy Za pomocą biblioteki jQuery możemy określić pozycję wskaźnika myszy na ekranie. W tej recepturze poznamy technikę odczytywania tej informacji. Nauczymy się, jak należy tworzyć wyskakujące podpowiedzi, które pojawiać się będą wtedy, gdy wskaźnik myszy znajdzie się nad określonym elementem.

Przygotowania Niezbędna będzie aktualna kopia biblioteki jQuery.

36

Rozdział 1. • Obsługa zdarzeń w jQuery

Jak to zrobić? 1. W katalogu rozdzial1 utwórz nowy plik o nazwij go mouse.html. 2. Utwórz element div o identyfikatorze tip i atrybucie display o wartości none. Element ten będzie nam służył do wyświetlania podpowiedzi. Utwórz też trzy kolejne elementy div, a do pierwszego i ostatniego z nich przypisz klasę hoverMe. Dla tych elementów konieczne będzie też przygotowanie stylów CSS. Element div używany do wyświetlania podpowiedzi musi otrzymać styl CSS z atrybutem position o wartości absolute.

Ruchy myszy



Hura! Jestem podpowiedzią. Wskaż mnie myszą, aby uzyskać podpowiedź. Ten element div nie będzie wyświetlał podpowiedzi. Wskaż mnie myszą, aby uzyskać podpowiedź.

3. Dopisz kod korzystający z biblioteki jQuery, który zajmie się wyświetlaniem podpowiedzi, gdy wskaźnik myszy znajdzie się nad elementem div. Będą nam do tego potrzebne dwie funkcje. Pierwsza z nich zajmie się wyświetlaniem i ukrywaniem podpowiedzi z efektem łagodnego pojawiania się i znikania. Druga funkcja ustali pozycję podpowiedzi i będzie ją przesuwać wraz z ruchem myszy.

37

PHP i jQuery. Receptury



4. Otwórz w przeglądarce plik mouse.html. Po umieszczeniu wskaźnika myszy nad pierwszym i ostatnim elementem div łagodnie pojawi się podpowiedź. Co więcej, podpowiedź ta będzie podążała za ruchami wskaźnika myszy.

38

Rozdział 1. • Obsługa zdarzeń w jQuery

Jak to działa? Wykorzystaliśmy metodę hover() przypisaną do elementów div, aby wyświetlać i ukrywać okienko podpowiedzi. Metoda ta wiąże z danym elementem dwie metody obsługi zdarzeń. Pierwsza metoda jest wywoływana, w momencie gdy wskaźnik myszy pojawia się nad elementem, a druga, gdy wskaźnik opuszcza element. Użyliśmy tu metody fadeIn(), aby wyświetlić podpowiedź na ekranie w momencie pojawienia się wskaźnika myszy nad elementem, a metody fadeOut() do ukrycia podpowiedzi, gdy wskaźnik myszy został przesunięty poza element. Najważniejszą rzeczą jest teraz umieszczenie podpowiedzi w tym miejscu na ekranie, w którym znajduje się wskaźnik myszy. W tym celu przygotowaliśmy metodę obsługującą zdarzenie mousemove elementu div. Jak wskazuje nazwa zdarzenia, metoda ta jest uruchamiana przy każdym poruszeniu wskaźnika myszy nad elementem div. Biblioteka jQuery udostępnia metodzie obsługującej to zdarzenie specjalny obiekt, w którym zapisana jest pozycja wskaźnika myszy. Właściwość pageX tego obiektu przechowuje pozycję wskaźnika myszy względem lewego brzegu dokumentu. Podobnie z właściwości pageY możemy odczytać pozycję wskaźnika myszy względem górnej krawędzi dokumentu. Mamy już pełną informację na temat pozycji wskaźnika myszy na ekranie. Możemy zatem przypisać wartości właściwości pageX i pageY do właściwości stylu CSS (left i top) pozycjonujących element div. Do każdej z tych wartości dodajemy jeszcze 5, tak żeby wskaźnik myszy nie zasłaniał części okienka podpowiedzi.

Tworzenie skrótów klawiszowych Sterowanie klawiszami jest bardzo powszechne wśród aplikacji komputerowych. Jest to bardzo wygodna metoda często stosowana przez osoby lepiej radzące sobie z klawiaturą niż z myszą. Skróty klawiszowe można też tworzyć w aplikacjach WWW, ale niestety są one trudne do zaimplementowania ze względu na niezgodności między przeglądarkami. W tej recepturze utworzymy prosty przykład, w którym poznamy podstawowe sposoby tworzenia skrótów klawiszowych. Nauczymy się tworzyć własne skróty ułatwiające obsługę naszych aplikacji.

Przygotowania Pobierz najnowszą wersję biblioteki jQuery.

39

PHP i jQuery. Receptury

Jak to zrobić? 1. W katalogu rozdzial1 utwórz nowy plik o nazwie keyboard.html. 2. W kodzie HTML nowej strony utwórz dwa elementy div, a w sekcji dopisz kilka stylów CSS zmieniających wygląd elementów div.

Skróty klawiszowe



Skorzystaj z klawiszy Alt+S Skorzystaj z klawiszy Alt+G

 

Naciśnij Alt+B, aby przełączyć oba elementy div



3. Dopisz kod korzystający z biblioteki jQuery, który utworzy skróty klawiszowe przełączające elementy div. Do zaimplementowania takiego zachowania użyjemy metody obsługi zdarzenia keydown. Będzie ona sprawdzała naciśnięte klawisze i wprowadzała odpowiednie reakcje. Utworzymy tu trzy różne skróty klawiszowe. Naciśnięcie klawiszy Alt+S będzie przełączało pierwszy element div, klawisze Alt+G będą odpowiadały za przełączanie drugiego elementu div, natomiast klawisze Alt+B spowodują przełączanie obu tych elementów. Metoda obsługi zdarzenia keyup zajmować się będzie kasowaniem zmiennej kontrolnej.

4. Otwórz w przeglądarce plik keyboard.html. Spróbuj nacisnąć zdefiniowane właśnie skróty klawiszowe. Zobaczymy wtedy elementy div zmieniające się z wykorzystaniem specjalnej animacji.

41

PHP i jQuery. Receptury

Jak to działa? Chcąc tworzyć w programie skróty klawiszowe, musimy się najpierw dowiedzieć, jakie klawisze zostały naciśnięte. Każda przeglądarka udostępnia swoje własne metody odczytywania wartości naciśniętego klawisza, natomiast biblioteka jQuery ujednolica sposób wykonania tej operacji we wszystkich przeglądarkach. Metoda obsługująca zdarzenie otrzymuje obiekt event, którego właściwość which przechowuje kod naciśniętego klawisza. Klawisz Alt ma tutaj kod 18. W podanych tu przykładowych skrótach klawiszowych wykorzystujemy kombinację klawisza Alt z innym klawiszem. Zaczynamy zatem od zadeklarowania globalnej zmiennej altPressed, której nadajemy wartość false. Do samej strony przypinamy natomiast dwie metody obsługi zdarzenia. Zdarzenie keydown wywoływane jest w momencie naciśnięcia klawisza, natomiast zdarzenie keyup — w momencie jego puszczenia. Gdy naciśnięty zostanie klawisz Alt, wywoływane jest zdarzenie keydown, które nadaje zmiennej altPressed wartość true, natomiast puszczenie tego klawisza wiąże się z wywołaniem zdarzenia keydown, które tej zmiennej nada wartość false. Następnie należy przyjrzeć się instrukcji if, której warunek będzie prawdziwy, jeżeli aktualnie wciśnięty jest klawisz Alt. Jeżeli w takiej sytuacji naciśnięty jest jeszcze jakiś inny klawisz, to instrukcja switch sprawdza kod tego klawisza i wykonuje odpowiednią sekcję kodu. Kod naciśnięcia klawisza S to 83. Oznacza to, że naciśnięcie klawisza S w połączeniu z klawiszem Alt spowoduje wybranie pierwszego elementu div i zastosowanie na nim efektu slideToggle. Podobnie naciśnięcie kombinacji Alt+G odnosić się będzie do drugiego elementu div, a klawisze Alt+B wpłyną na oba te elementy. Proszę zwrócić uwagę na to, że każda sekcja instrukcji switch zwraca wartość false. Jest to niezbędne, żeby wyłączyć domyślne zachowanie przeglądarki. Jeżeli ta wartość nie zostanie zwrócona przez funkcję, to naciśnięcie klawisza Alt spowoduje włączenie menu przeglądarki.

I coś więcej… Lista kodów klawiszy Listę kodów klawiszy można znaleźć na stronie http://goo.gl/v2Fk.

Zobacz też Q Receptura „Wiązanie i odwiązywanie elementów” objaśnia metody dodawania

i usuwania zdarzeń z elementów.

42

Rozdział 1. • Obsługa zdarzeń w jQuery

Wyświetlanie tekstu wybranego przez użytkownika Każdy z pewnością widział już edytory typu WYSIWYG (ang. What You See Is What You Get) działające w aplikacjach WWW, które pozwalają na zaznaczenie części tekstu za pomocą myszy lub klawiatury, a następnie sformatowanie go (włączając styl pogrubienia, zmieniając kolor itd.). W tej recepturze nauczymy się, jak odczytywać tekst zaznaczony przez użytkownika i wykonać na nim pewne operacje.

Przygotowania Wystarczy nam biblioteka jQuery.

Jak to zrobić? 1. W katalogu rozdzial1 utwórz plik o nazwie textSelect.html. 2. W tym pliku utwórz cztery przyciski, z których trzy pierwsze posłużą nam do nadawania tekstowi pogrubienia, kursywy lub podkreślenia. Następnie utwórz pole tekstowe i wpisz do niego jakiś tekst. Na zakończenie wprowadź akapit, którego użyjemy do wyświetlenia sformatowanego kodu HTML. Ostatni przycisk wykorzystamy do pobierania zawartości pola tekstowego i wstawiania go do akapitu.

Manipulowanie tekstem zaznaczonym przez użytkownika





Szlachetne zdrowie, nikt się nie dowie, jako smakujesz, aż się zepsujesz.

43

PHP i jQuery. Receptury



3. Dopisz kod korzystający z biblioteki jQuery i napisz funkcję, która będzie pobierać początek i koniec zaznaczenia tekstu.



4. Otwórz przeglądarkę i uruchom w niej plik drag.html. Oba elementy div powinny dać się teraz przeciągnąć. Wystarczy tylko nacisnąć nad nimi przycisk myszy i przesunąć je w inne miejsce.

49

PHP i jQuery. Receptury

Jak to działa? Zmienne globalne mousex i mousey będą używane do przechowywania współrzędnych wskaźnika myszy, natomiast zmienne divLeft i divTop będą przechowywały współrzędne górnego lewego narożnika elementu div. Do każdego elementu klasy dragMe przypięte zostały dwie metody obsługi zdarzeń. Pierwsza z nich zajmuje się zdarzeniem mousedown, które wywoływane jest w momencie naciśnięcia przycisku myszy nad wybranym elementem. W tej funkcji pobieramy pozycję przeciąganego elementu div i zapisujemy ją w zmiennych divLeft i divTop. Poza tym współrzędne wskaźnika myszy pobierane są z obiektu zdarzenia i zapisywane do zmiennych mousex i mousey. Teraz, dopóki przycisk będzie naciśnięty, przypisujemy zdarzenie mousemove do przeciąganego elementu div. W ramach tego zdarzenia funkcja dragElement zostanie wywołana, o ile wskaźnik myszy się przesunął, podczas gdy naciśnięty był jej przycisk. W ramach funkcji dragElement wyznaczana jest nowa pozycja przeciąganego elementu div. W ramach wyliczania nowej wartości współrzędnej poziomej używana jest aktualna współrzędna elementu (zmienna divLeft) i dodawana jest do niej wartość przesunięcia w pozycji myszy. Różnica pozycji myszy wyliczana jest przez odjęcie poprzedniej współrzędnej wskaźnika myszy od jej aktualnej pozycji. W podobny sposób wyliczana jest nowa współrzędna pionowa elementu div. Po wyliczeniu obu tych wartości za pomocą metody css() wpisywane są one do przeciąganego elementu. Nie można zapominać o tym, że są to pozycje typu absolute. Bez zastosowania tego rodzaju pozycjonowania nie bylibyśmy w stanie przeciągać elementów po stronie.

Zobacz też Q Receptura „Przechwytywanie zdarzeń myszy” wyjaśnia sposoby odczytywania

współrzędnych wskaźnika myszy. Q Receptura „Wiązanie i odwiązywanie elementów” objaśnia metody dodawania

i usuwania zdarzeń z elementów.

50

2 Łączenie PHP i jQuery W tym rozdziale zajmiemy się: Q pobieraniem danych z PHP za pomocą jQuery, Q automatycznym tworzeniem tekstu zapytania na podstawie elementów formularza, Q wykrywaniem żądań AJAX w PHP, Q wysyłaniem danych do PHP, Q przerywaniem żądań AJAX, Q tworzeniem pustej strony i ładowaniem jej części, Q obsługą błędów w żądaniach AJAX, Q blokowaniem w przeglądarce buforowania żądań AJAX, Q ładowaniem JavaScriptu na żądanie, aby zmniejszyć czas ładowania strony.

Wprowadzenie Z pewnością każdy wie, jak działają aplikacje WWW. Wprowadzamy adres URL do przeglądarki, a ta ładuje dla nas stronę. Jeżeli musimy przesłać dane z formularza, to najpierw taki formularz wypełniamy, a następnie przeglądarka wysyła zebrane dane do serwera, gdzie są one przetwarzane. W tym czasie musimy czekać na ponowne załadowanie strony. Jeżeli korzystamy z wolnego łącza, to czas takiego oczekiwania może się znacznie wydłużyć. Przedstawię tu jeszcze inny przykład strony, na której umieszczono dwa pola wyboru. W pierwszym z nich możemy wybrać nazwę państwa, a po dokonaniu wyboru strona jest przeładowywana, tak żeby do drugiego pola wprowadzić nazwy miast z wybranego kraju. Jeżeli przez pomyłkę wybierzemy nie tę pozycję, to korekta tego błędu wymagać będzie kolejnego przeładowania strony. Irytujące?

PHP i jQuery. Receptury

Chodzi mi tutaj o to, że, być może, nie zawsze konieczne jest każdorazowe ładowanie całej strony. Dlaczego nie moglibyśmy po prostu wybrać z listy państwa, a w tle, przy pomocy jakiejś magii, drugie pole wyboru samo załadowałoby się nazwami miast. W przypadku gdy takie żądanie będzie trwać dłużej, moglibyśmy wypełnić kilka innych pól. W tym miejscu na scenę wkracza technologia AJAX. Jej nazwa jest skrótem od Asynchronous JavaScript and XML (asynchroniczny JavaScript i XML), a oznacza technikę pozwalającą na komunikację skryptów działających po stronie klienta ze skryptami działającymi po stronie serwera, z wykorzystaniem standardowych protokołów HTML. Dzięki temu dane mogą być przesyłane między klientem a serwerem bez konieczności przeładowywania strony. Przyjrzyjmy się teraz dokładniej nazwie tej technologii: Q Asynchroniczny — Oznacza to, że żądania realizowane są w tle, przez co znika

konieczność przeładowywania całej strony. Można je też wysyłać równolegle, a w międzyczasie użytkownik może pracować z innymi elementami strony. Nie jest zatem zmuszany do oczekiwania na zakończenie obsługi żądania. Wracając do przykładu z państwami i miastami… owszem, to można zrobić. Q JavaScript — Oznacza, że żądania przesyłane do serwera tworzone są w skryptach

JavaScriptu. Przeglądarki udostępniają własne implementacje obiektu o nazwie XMLHttpRequest. Nie jest on standaryzowany, dlatego poszczególne przeglądarki udostępniają swoje własne implementacje. Q XML — Żądania AJAX mogą być przesyłane do dowolnej platformy, niezależnie,

czy będzie to PHP czy też Java. Oznacza to, że w celu wymiany danych między klientem a serwerem musimy mieć wspólny format danych zrozumiały zarówno dla JavaScriptu, jak i języków serwerowych. Jednym z takich formatów jest XML, za pomocą którego możemy bezproblemowo przesyłać dane. Q Skrót XML w nazwie AJAX nie oznacza, że koniecznie musimy korzystać z formatu

XML. Dane można wymieniać też w innych formatach. Możliwe jest zastosowanie własnego formatu, formatu tekstowego, HTML lub JSON. Najczęściej stosowane są dzisiaj formaty HTML i JSON. Ze względu na to, że implementacja obiektu XMLHttpRequest różni się w poszczególnych przeglądarkach, biblioteka jQuery opakowuje ten obiekt tak, żeby ułatwić przesyłanie danych między językami JavaScript i PHP. Nauczymy się tutaj tworzyć żądania AJAX, wysyłać dane do skryptów PHP i wykonywać różne operacje na otrzymanych danych. Oprócz tego przyjrzymy się mechanizmom obsługi błędów udostępnianym przez bibliotekę jQuery. W tym rozdziale będziemy pracować przede wszystkim z odpowiedziami tekstowymi i w formacie HTML. Ze względu na to, że formaty JSON i XML wymagają dokładniejszego zbadania, poświęcimy im osobny rozdział. 52

Rozdział 2. • Łączenie PHP i jQuery

We wszystkich przedstawionych tu recepturach odwołanie do biblioteki jQuery i związany z nią kod będziemy umieszczać tuż przed zamykającym znacznikiem body, a nie w sekcji head, tak jak do tej pory. Umieszczenie tych plików w sekcji head blokuje rysowanie strony do momentu załadowania wszystkich skryptów. Dzięki umieszczeniu ich na końcu strony cały kod HTML może zostać od razu narysowany, a dokument DOM będzie już gotowy. Po zakończeniu ładowania strony możemy dodać jeszcze pliki JavaScript i jQuery. W ten sposób strona będzie działać szybciej.

Pobieranie danych z PHP za pomocą jQuery W tej recepturze nauczymy się korzystać z metody get udostępnianej przez bibliotekę jQuery do pobierania danych ze skryptów PHP. Zobaczymy tu prosty przykład pobierania danych z serwera z wykorzystaniem metody get na podstawie wyboru dokonanego przez użytkownika w formularzu.

Przygotowania W głównym katalogu serwera WWW utwórz katalog o nazwie rozdzial2 i umieść w nim plik biblioteki jQuery. Utwórz teraz nowy katalog i nazwij go receptura1. Teraz receptury będą składały się z kilku plików, więc lepiej umieszczać je w osobnych katalogach.

Jak to zrobić? 1. W katalogu receptura1 utwórz plik index.html. W tym pliku zapisz kod HTML tworzący pole wyboru z kilkoma opcjami.

jQuery.get()



Pokaż listę:

53

PHP i jQuery. Receptury

wybierz Dobrych bohaterów Czarne charaktery





2. Tuż przed zamykającym znacznikiem body wstaw plik biblioteki jQuery i zapisz kod, który dołączy metodę obsługi zdarzenia change do pola wyboru. Funkcja obsługująca zdarzenie otrzyma wybraną w polu wartość i wyśle do skryptu PHP żądanie AJAX, używając do tego metody get. Po zakończeniu obsługi żądania otrzymany w odpowiedzi kod HTML zostanie wstawiony na stronę do istniejącego już na niej akapitu.

3. Przygotujmy teraz skrypt PHP odpowiadający na żądanie AJAX. W tym samym katalogu utwórz plik data.php i wpisz do niego kod sprawdzający, jaki parametr otrzymał w żądaniu. W zależności od wartości tego parametru skrypt PHP utworzy odpowiedni kod HTML i odeśle go z powrotem do przeglądarki.

4. Uruchom plik index.html w przeglądarce, a następnie z pola wyboru wybierz jedną z wartości. Biblioteka jQuery wyśle żądanie do skryptu PHP i w odpowiedzi otrzyma sformatowany kod HTML i wyświetli go w przeglądarce.

Jak to działa? W momencie wybrania wartości z listy rozwijanej uruchamiana jest metoda obsługi zdarzenia. Po sprawdzeniu, że wybrana wartość nie jest pusta, wysyłane jest żądanie za pomocą metody get udostępnianej przez bibliotekę jQuery.

55

PHP i jQuery. Receptury

Metoda ta wysyła do skryptu PHP żądanie typu HTTP GET. Wywołanie $.get() przyjmuje cztery parametry, które dokładniej opiszę poniżej. Za wyjątkiem pierwszego wszystkie parametry są opcjonalne: Q URL — wskazuje plik na serwerze, do którego zostanie przesłane żądanie. Może to

być nazwa pliku PHP lub strony HTML. Q Dane — w tym parametrze podawane są dane, które mają zostać przesłane na

serwer. Może on przyjmować postać ciągu znaków lub zbioru par klucz-wartość. Q Funkcja obsługująca — określa funkcję wywoływaną w przypadku udanej obsługi

żądania, czyli w momencie odesłania odpowiedzi przez serwer. Q Typ danych — można tu określić typ HTML, XML, JSON lub skrypt. Jeżeli nie

podamy wartości, to biblioteka jQuery będzie próbowała sama ustalić typ danych. Trzeba pamiętać, że URL podany w żądaniu musi dotyczyć tej samej domeny, w której działa nasza aplikacja. Po prostu przeglądarki ze względów bezpieczeństwa nie pozwalają na uruchamianie żądań pomiędzy domenami. Na przykład, jeżeli dana strona działa w domenie http://abc.com, to może ona wysyłać żądania AJAX tylko do skryptów również działających w domenie http://abc.com lub w jej poddomenach. Próba wysłania żądania na inny adres, taki jak http://innastrona.com/, zostanie zablokowana.

W adresie URL podaliśmy plik data.php. Jako dane żądania przesłany został klucz o nazwie what i wartości wybranej przez użytkownika z listy rozwijanej. Na koniec podano jeszcze nazwę funkcji wywołania zwrotnego. Ze względu na to, że dane wysyłane są metodą GET, zostaną one dołączone do adresu URL. Po wysłaniu żądania musi ono dotrzeć do skryptu PHP zapisanego w pliku data.php. Ze względu na to, że jest to żądanie typu GET, skrypt otrzyma wypełnioną tablicę superglobalną $_GET. W zależności od wartości klucza what (może się tam znaleźć tekst good lub bad) skrypt utworzy tablicę o nazwie $names i przekaże ją do funkcji getHTML(). Funkcja ta tworzy listę wypunktowaną na podstawie nazwisk zapisanych w tablicy i przesyła ją do przeglądarki. Proszę zauważyć, że w skrypcie zastosowano instrukcję echo. Jest ona stosowana do wypisywania ciągów znaków na stronie. W tym przypadku jest jednak używana w ramach obsługi żądania AJAX. Oznacza to, że wynik działania skryptu odsyłany jest do funkcji, która go wywołała. Biblioteka jQuery odbiera takie odpowiedzi i dzięki temu możemy je odebrać w metodzie obsługi zdarzenia success. W tej metodzie wstawiamy tylko otrzymany kod HTML do elementu p o identyfikatorze result.

Zobacz też Q Recepturę „Wysyłanie danych do skryptu PHP” w dalszej części tego rozdziału. Q Recepturę „Tworzenie pustej strony i ładowanie jej w częściach”.

56

Rozdział 2. • Łączenie PHP i jQuery

Automatyczne tworzenie tekstu zapytania na podstawie elementów formularza Przygotowania W katalogu rozdzial2 utwórz katalog receptura2. W tak przygotowanym katalogu utwórz nowy plik o nazwie index.html.

Jak to zrobić? 1. Otwórz plik index.html i wpisz do niego kilka elementów HTML, takich jak pola tekstowe, przyciski i pola wyboru.

Serializowanie wartości z formularzy



  • Email:
  • Imię i nazwisko
  • Płeć Mężczyzna Kobieta
  • Kraj

    Indie UK USA

    57

    PHP i jQuery. Receptury

    Polska

  • Newsletter Prześlij mi więcej informacji






2. Wprowadź łącze do pliku biblioteki jQuery. Następnie dodaj metodę obsługi zdarzenia click dla przycisku typu input. Użyjemy w niej metody serialize(), a otrzymany ciąg znaków zaprezentujemy za pomocą metody alert().

3. Otwórz w przeglądarce plik index.html, wypełnij formularz i kliknij przycisk Wyślij. Przeglądarka wyświetli wartości pobrane z poszczególnych elementów w formacie tekstu zapytania, podobnym do przedstawionego na poniższym rysunku:

58

Rozdział 2. • Łączenie PHP i jQuery

Jak to działa? Metoda serialize() udostępniana przez bibliotekę jQuery przekształca dane z pól formularza do postaci tekstu zapytania. Zamiast ręcznego pobierania wszystkich wartości i składania tekstu zapytania możemy wywołać tę funkcję, aby w prosty sposób przesłać zawartość wszystkich pól formularza jako dane żądania AJAX. Podczas przesyłania danych na serwer możemy skorzystać z dowolnej metody: GET lub POST.

I coś jeszcze Metoda serializeArray() Inną ciekawą funkcją pobierającą wartości z elementów jest funkcja serializeArray(), która zmienia wszystkie elementy formularza w obiekty JavaScriptu. var data = $('form:first').serializeArray();

Jeżeli w formularzu znajdują się dwa pola tekstowe o nazwach input1 i input2, a w polach tych znajdują się teksty wartość1 i wartość2, to w efekcie działania tej funkcji otrzymamy następujący tekst: [ { input1: 'wartość1' }, { input2: 'wartość2' }, ]

Nie wszystkie wartości są serializowane Proszę pamiętać, że przyciski typu submit oraz elementy wyboru plików nie podlegają serializacji.

Elementy muszą mieć nazwy Aby serializacja elementów formularza przebiegła pomyślnie, nie można zapomnieć o przypisaniu im wszystkim atrybutu name. Jeżeli elementowi przypisano identyfikator, ale nie przypisano nazwy, to nie zostanie on zserializowany.

Zobacz też Q Recepturę „Pobieranie danych z PHP za pomocą jQuery”. Q Recepturę „Wysyłanie danych do PHP”.

59

PHP i jQuery. Receptury

Wykrywanie żądań AJAX w skryptach PHP Po przeczytaniu tej receptury będziemy mogli w skryptach PHP odróżnić żądania AJAX od prostych żądań HTTP.

Przygotowania W katalogu rozdzial2 utwórz nowy katalog receptura3. W nowym katalogu utwórz plik o nazwie index.html oraz drugi o nazwie check.php.

Jak to zrobić? 1. Otwórz plik index.html i wpisz do niego przycisk, który będzie ładował ciąg znaków ze skryptu PHP za pomocą metody get().

Wykrywanie żądań AJAX









2. Następnie dołącz do pliku bibliotekę jQuery i dopisz metodę obsługującą zdarzenie click przycisku. Kliknięcie tego przycisku spowoduje wysłanie żądania AJAX do pliku check.php, który zwróci w odpowiedzi ciąg znaków. Tak otrzymany ciąg znaków zostanie dopisany do strony zaraz za przyciskiem.

3. W ramach sprawdzenia, czy otrzymane żądanie jest rzeczywiście żądaniem AJAX, a nie bezpośrednim wywołaniem z przeglądarki, otwórz plik check.php i wpisz do niego poniższy kod:

4. Uruchom plik index.php w przeglądarce i kliknij przycisk Załaduj dane. Na stronie, tuż za przyciskiem, pojawi się tekst Hura! Żądanie obsłużone!. Teraz w innym oknie przeglądarki wprowadź bezpośrednią ścieżkę do pliku check.php. Na stronie pojawi się tylko tekst komunikatu: To nie jest żądanie AJAX. Ta strona nie może być otwierana bezpośrednio.

Jak to działa? Przeglądarki wysyłają nagłówki HTTP, dołączając je do każdego żądania wysyłanego do serwera. W ramach rozróżnienia między normalnymi żądaniami a żądaniami AJAX nowoczesne biblioteki dołączają do tych ostatnich specjalny nagłówek. Nazwa tego nagłówka to X-Requested-With, a jego wartość to XMLHttpRequest. Superglobalna tablica $_SERVER przechowuje nagłówki wysłane wraz z żądaniem. W naszym przykładzie sprawdziliśmy, czy w tablicy $_SERVER znajduje się klucz o nazwie HTTP_X_REQUESTED_WITH. Jeżeli taki klucz został znaleziony, a jego wartością jest XMLHttpRequest, to możemy założyć, że mamy do czynienia z żądaniem AJAX. W zależności od uzyskanego wyniku instrukcja if wyświetli odpowiedni komunikat.

61

PHP i jQuery. Receptury

I coś jeszcze Nie sprawdzaj tylko klucza X-Requested-With Biblioteka jQuery i większość nowoczesnych bibliotek (takich jak Prototype lub Dojo) wysyła nagłówek X-Requested-With do serwera. Nie zaleca się jednak sprawdzania wyłącznie tego nagłówka. Wynika to z faktu, że nagłówki HTTP mogą zostać poddane manipulacji. Oznacza to, że użytkownik może wysłać żądanie z takim nagłówkiem, a nasz kod założy wtedy, iż ma do czynienia z żądaniem AJAX, choć nie będzie to prawdą. Istnieją jeszcze inne metody sprawdzania rodzaju otrzymanego żądania, ale ich dokładny opis wykracza już poza ramy tej książki.

Wysyłanie danych do PHP GET i POST to dwie najczęściej używane metody dostępu do stron. W pierwszej recepturze poznaliśmy sposoby tworzenia żądań za pomocą metody GET.

W tej recepturze skorzystamy z dostępnej w bibliotece jQuery metody post() i z jej pomocą odczytamy dane ze skryptu PHP. Zobaczymy tu prosty przykład, w ramach którego wypełnimy formularz danymi i wyślemy je do skryptu PHP za pomocą metody POST. Dane te zostaną przetworzone w skrypcie PHP, a na koniec wyświetlone na stronie.

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

Jak to zrobić? 1. W katalogu receptura4 utwórz nowy plik o nazwie index.html. W tej recepturze wykorzystamy ten sam formularz, którego użyliśmy już w drugiej recepturze (Automatyczne tworzenie tekstu zapytania na podstawie elementów formularza) tego rozdziału. Przygotuj zatem kod HTML tworzący formularz z wieloma kontrolkami.

Wysyłanie danych metodą post

62

Rozdział 2. • Łączenie PHP i jQuery



  • Email:
  • Imię i nazwisko
  • Płeć Mężczyzna Kobieta
  • Kraj

    Indie UK USA Polska







2. Dołącz plik biblioteki jQuery i dopisz metodę obsługi zdarzeń przycisku. Kliknięcie tego przycisku spowoduje wysłanie żądania AJAX do skryptu PHP za pośrednictwem metody HTTP POST. Po zakończeniu obsługi tego żądania formularz zostanie ukryty, a tekst odpowiedzi przesłanej przez skrypt PHP zostanie wstawiony do akapitu.

3. Żądanie zostanie przesłane do pliku PHP, dlatego w tym samym katalogu utwórz nowy plik o nazwie process.php. Kod zapisany w tym pliku utworzy ciąg znaków na podstawie danych wprowadzonych przez użytkownika do formularza. Tak przygotowany tekst zostanie odesłany do przeglądarki, aby potwierdzić wartości z formularza. '

4. Uruchom w przeglądarce plik index.html, a zobaczysz formularz z kilkoma polami. Wypełnij wszystkie pola i kliknij przycisk Wyślij. Formularz zostanie wtedy ukryty, a na stronie pojawi się tekst potwierdzający dane z formularza. Drogi/droga Vijay Joshi, Twoje informacje kontaktowe zostały zapisane. Otrzymaliśmy od Ciebie następujące dane: E-mail: [email protected] Płeć: Mężczyzna Kraj: Indie

64

Rozdział 2. • Łączenie PHP i jQuery

Jak to działa? Do przycisku Wyślij dowiązaliśmy metodę obsługi zdarzenia click. Kliknięcie przycisku wysyła żądanie do serwera za pośrednictwem metody post() z biblioteki jQuery. Metoda post() jest bardzo podobna do metody get(). Istnieje między nimi tylko kilka drobnych różnic. Pierwszą i podstawową różnicą jest fakt, że metoda post() uruchamia żądania typu POST, a metoda get() żądania typu GET. Druga różnica polega na tym, że żądania POST nie są buforowane przez przeglądarkę, a żądania typu GET zawsze lądują w buforze. Oznacza to, że włączenie opcji buforowania w żądaniach typu POST nie będzie miało żadnego efektu. Poza tym obie te metody mają identyczne sygnatury. W naszym przykładzie żądanie kierowane jest do pliku process.php, któremu przekazywane są zserializowane dane z formularza. Ze względu na to, że jest to żądanie typu POST, danymi wypełniana jest superglobalna tablica $_POST. Następnie pobieramy poszczególne pola z tej tablicy i umieszczamy zawarte w nich dane w sformatowanym ciągu znaków. Po przygotowaniu tego tekstu odsyłamy go do przeglądarki za pomocą instrukcji echo. Po otrzymaniu pozytywnej odpowiedzi ukrywamy formularz i wstawiamy otrzymany kod HTML do akapitu.

I coś więcej Alternatywa dla metody post() Metody post(), get() i inne z tej grupy można też zaimplementować za pomocą metody ajax(). Poniżej prezentuję implementację metody post() za pomocą metody ajax(). W kolejnych recepturach zobaczymy jeszcze kilka innych zastosowań metody ajax(). $.ajax( { url: 'process.php', method: 'post', data: $('form:first').serialize(), dataType: 'html', success: function(response) { $('#information').hide(); $('#response').html(response); } });

65

PHP i jQuery. Receptury

Ze względu na to, że metoda ajax() daje nam większe pole manewru niż metoda post(), możemy z niej skorzystać, w przypadku gdybyśmy chcieli przypisać do żądania funkcję obsługi błędu.

Zobacz też Q Recepturę „Pobieranie danych z PHP za pomocą jQuery”, która dokładniej objaśnia działanie metody get(). Q Recepturę „Automatyczne tworzenie tekstu zapytania na podstawie elementów

formularza”. Q Recepturę „Obsługa błędów w żądaniach AJAX”, która prezentuje metodę obsługi błędów powstających podczas obsługi żądań AJAX.

Przerywanie żądań AJAX Rozważmy teraz sytuację, w której użytkownik wybiera na stronie WWW datę, a następnie wysyłane jest do serwera żądanie AJAX nakazujące pobranie danych związanych z tą datą. Jeżeli w czasie przetwarzania pierwszego żądania użytkownik wybierze inną datę, to wysłane zostanie kolejne żądanie, a serwer będzie musiał obsłużyć dwa żądania równolegle. Wyobraźmy sobie, co będzie się działo, jeżeli z aplikacji będzie korzystać wielu użytkowników ciągle powtarzających tę samą operację. W takiej sytuacji najlepiej byłoby anulować wcześniejsze żądanie i pozwolić na obsługę tylko najaktualniejszego. W tej recepturze wyjaśnimy, jak należy anulować wysłane wcześniej żądania.

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

Jak to zrobić? 1. Wykorzystamy tutaj ten sam kod HTML, którego użyliśmy już w pierwszej recepturze tego rozdziału. Utwórz zatem plik index.html i wpisz do niego kod strony zawierającej dwie listy rozwijane i dwie opcje. Oprócz tego utwórz element akapitu (p), w którym będziemy wyświetlać otrzymane odpowiedzi.

Przerywanie żądań AJAX

66

Rozdział 2. • Łączenie PHP i jQuery



Pokaż listę:

wybierz Dobrych bohaterów Czarne charaktery





2. Teraz wpisz kod korzystający z biblioteki jQuery. Zdefiniuj zmienną globalną, a następnie dołącz metodę obsługi zdarzeń do listy rozwijanej. Funkcja obsługi zdarzenia sprawdza, czy do serwera zostało już wysłane żądanie. Jeżeli jakieś żądanie jest już obsługiwane, to nasza funkcja je anuluje i wyśle nowe.

3. Na koniec potrzebujemy jeszcze skryptu PHP. Utwórz nowy plik i nazwij go wait.php. Wpisz do niego ten sam kod, którego użyliśmy w recepturze „Pobieranie danych z PHP za pomocą jQuery”. Nasz skrypt będzie sprawdzał otrzymane wartości i odsyłał dopasowaną do nich odpowiedź. W tym przykładzie jednak skrypt będzie czekał 10 sekund na wysłanie odpowiedzi, tak żebyśmy mieli okazję wysłać w tym czasie kilka żądań.

4. Teraz uruchom w przeglądarce plik index.php i wybierz z listy rozwijanej jedną z wartości. Skrypt PHP odeśle nam odpowiedź dopiero po 10 sekundach. Teraz wybierz z listy inną wartość. Poprzednie żądanie zostanie anulowane, a do serwera zostanie wysłane nowe. Otrzymana w końcu odpowiedź dotyczyła będzie tylko ostatnio wysłanego żądania. Nie otrzymamy natomiast odpowiedzi na żadne z wcześniejszych żądań.

68

Rozdział 2. • Łączenie PHP i jQuery

Jak to działa? Wszystkie metody biblioteki jQuery związane z technologią AJAX zwracają obiekt XMLHttpRequest. Zadeklarowaliśmy zatem globalną zmienną ajax, w której zapisujemy ten obiekt. W momencie wybrania wartości z listy rozwijanej funkcja obsługująca to zdarzenie sprawdza zawartość zmiennej ajax. W przypadku dokonania pierwszego wyboru zawartość tej zmiennej nie będzie zdefiniowana, a zatem żądanie zostanie wysłane do pliku wait.php. Utworzony przy tym obiekt XMLHttpRequest zostanie natomiast zapisany w zmiennej ajax. Przy następnej zmianie wartości wybranej z listy rozwijanej w zmiennej ajax zapisany będzie już obiekt XMLHttpRequest utworzony na potrzeby poprzedniego żądania. Obiekt ten udostępnia metodę abort(), która anuluje dane żądanie. W naszym przykładzie takie obsługiwane jeszcze przez serwer żądanie jest anulowane i przygotowywane jest nowe, które również zapisywane jest do zmiennej ajax. Jak widać, wybranie nowej wartości z listy wyboru w ciągu 10 sekund od dokonania ostatniego wyboru spowoduje anulowanie dotychczasowego żądania i wysłanie do nowego.

Zobacz też Q Recepturę „Obsługa błędów w żądaniach AJAX”.

Tworzenie pustej strony i ładowanie jej w częściach Im większa będzie nasza strona, tym więcej czasu potrzebować będzie przeglądarka, aby ją załadować. Może to mieć negatywny wpływ na zadowolenie użytkownika, szczególnie korzystającego z wolniejszego łącza. Jednym z rozwiązań tego problemu jest natychmiastowe ładowanie tylko niezbędnych elementów strony i doładowywanie pozostałych elementów tylko wtedy, gdy faktycznie będą potrzebne. W końcu niektóre części strony używane są niezmiernie rzadko. Dzięki temu strona będzie ładowała się szybciej, co z pewnością ucieszy użytkownika. W tej recepturze zademonstrujemy prosty przykład zastosowania tej metody. Utworzymy prostą stronę HTML i pozwolimy użytkownikowi załadować jedną z jej sekcji.

69

PHP i jQuery. Receptury

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

Jak to zrobić? 1. Utwórz nowy plik i nadaj mu nazwę index.html. Nowa strona będzie składała się z trzech części: nagłówka, treści i stopki. Kod HTML stopki nie zostanie jednak umieszczony w pliku strony, ale będzie ładowany później, na żądanie. Oprócz tego w sekcji head strony umieściliśmy kilka stylów CSS zmieniających wygląd strony.

Ładowanie strony po kawałku



Moja nowa, doskonała strona

Aliquam quis massa at elit fermentum vestibulum. Vestibulum id nunc et nulla placerat gravida. Praesent sed purus ante. Vestibulum pulvinar tortor sed odio accumsan a cursus magna pellentesque. In hac habitasse platea dictumst. Cras viverra sodales sem in facilisis. Nulla congue, risus eget gravida feugiat, nisi ante laoreet est, ullamcorper hendrerit lacus velit eget urna. Suspendisse rutrum lacus eget nulla semper sit amet egestas tellus scelerisque. Maecenas at vulputate enim. Etiam blandit magna iaculis tellus tincidunt vel ornare diam.

Pokaż stopkę



70

Rozdział 2. • Łączenie PHP i jQuery

2. Następnie musimy utworzyć plik zawierający kod HTML stopki. Utwórz nowy plik o nazwie footer.html i zapisz w nim poniższy kod: Link5

3. W ramach łączenia tych dwóch elementów wracamy do pliku index.html i zapisujemy do niego kod korzystający z biblioteki jQuery, powiązany z łączem Pokaż stopkę.

4. Otwórz w przeglądarce plik index.html i kliknij na stronie łącze Pokaż stopkę. Biblioteka jQuery załaduje wtedy kod HTML stopki z pliku footer.html i wstawi go w odpowiednie miejsce na stronie.

71

PHP i jQuery. Receptury

Jak to działa? Biblioteka jQuery udostępnia metodę load(), która działa na elementy HTML. Pobiera ona dane z serwera i wstawia je do elementu HTML, który ją wywołał. Metoda load() przyjmuje trzy parametry. Pierwszym jest adres URL, z którego mają być pobrane dane. Drugi to dane, które mają zostać wysłane do serwera, a trzecim jest funkcja wywołania zwrotnego, która wywoływana jest po otrzymaniu danych. W poprzednim przykładzie kliknięcie łącza Pokaż stopkę wywołuje metodę load() na rzecz elementu o identyfikatorze footer. W efekcie ładowana jest zawartość pliku footer.html, w którym zapisany jest cały kod HTML stopki. Po udanym pobraniu tego pliku z serwera kod HTML wstawiany jest do stopki strony.

I coś jeszcze Różnica między metodą load() i get() Obie te metody są do siebie bardzo podobne, z tym że zadaniem metody load() jest praca na elemencie strony wybranym przez selektor. Po zakończeniu żądania kod HTML wpisywany jest do elementu określonego selektorem. Z drugiej strony metoda get() jest metodą globalną, która ma ściśle zdefiniowaną metodę wywołania zwrotnego.

72

Rozdział 2. • Łączenie PHP i jQuery

Zobacz też Q Recepturę „Pobieranie danych z PHP za pomocą jQuery”. Q Recepturę „Wysyłanie danych do PHP”. Q Recepturę „Ładowanie JavaScriptu na żądanie, aby zmniejszyć czas ładowania strony”.

Obsługa błędów w żądaniach AJAX Błędy są nieuniknione. Kropka. Czasami rzeczy pozostają poza naszą kontrolą (na przykład awarie serwera) i w takich sytuacjach musimy mieć gotowy mechanizm obsługi błędów, który odpowiednio zareaguje, informując użytkownika o zaistniałej sytuacji. W recepturach prezentowanych w tym rozdziale zawsze implementowaliśmy funkcje wywołania zwrotnego wykonywane w momencie zakończenia obsługi żądania. Może się jednak zdarzyć (i obiecuję, że na pewno się zdarzy), iż nieprawidłowo podamy nazwę pliku albo w serwerze wystąpi błąd i zamiast właściwej odpowiedzi dostaniemy tylko informację o błędzie. W tej recepturze wyjaśnię metody radzenia sobie w takiej sytuacji.

Przygotowania W katalogu rozdzial2 utwórz katalog receptura7.

Jak to zrobić? 1. W katalogu receptura7 utwórz nowy plik o nazwie index.html. Zdefiniuj w nim kilka stylów CSS i utwórz przycisk oraz pole tekstowe, w które użytkownik będzie wpisywał nazwę pliku do załadowania. Oprócz tego utwórz też akapit, w którym wyświetlana będzie zawartość załadowanego pliku.

Obsługa błędów



Podaj nazwę pliku:



2. Przed zamykającym znacznikiem body dołącz plik biblioteki jQuery i wpisz kod korzystający z metody ajax(), który uruchomi żądanie AJAX ładujące plik zdefiniowany przez użytkownika. W kodzie trzeba zdefiniować dwie metody wywołania zwrotnego, obsługujące sukces i błąd żądania.

3. Utwórz kolejny plik HTML i nazwij go books.html. W pliku tym wpisz listę wypunktowaną z tytułami książek:
  • Studium w szkarłacie


  • 74

    Rozdział 2. • Łączenie PHP i jQuery

    Znak Czterech
  • Przygody Sherlocka Holmesa
  • Wspomnienia Sherlocka Holmesa
  • Pies Baskerville'ów
  • Powrót Sherlocka Holmesa
  • Księga przypadków Sherlocka Holmesa


4. Uruchom w przeglądarce plik index.html. Wprowadź w polu tekstowym nazwę pliku books.html i kliknij przycisk Załaduj plik. Biblioteka jQuery wyśle wtedy żądanie AJAX, a na stronie pojawi się ładnie sformatowana lista książek. Jeżeli jednak pole tekstowe będzie puste, a klikniemy przycisk Załaduj plik, to pojawi się komunikat o błędzie.

5. Teraz proszę wprowadzić nazwę nieistniejącego pliku, taką jak brak.html lub none.html. Po kliknięciu przycisku Załaduj plik wyświetlony zostanie komunikat o błędzie.

75

PHP i jQuery. Receptury

Jak to działa? W tym przykładzie korzystamy z niskopoziomowej implementacji technologii AJAX w bibliotece jQuery. Inne metody, takie jak get() lub post() i inne, są tylko specjalizowanymi implementacjami metody ajax(). Jak widzieliśmy, metoda get() zajmuje się obsługą żądań GET, natomiast metoda getScript() używana jest tylko do ładowania skryptów. Jedną z wielu opcji metody ajax() jest funkcja wywołania zwrotnego na wypadek wystąpienia błędu. Jeżeli w czasie obsługi żądania wystąpi błąd, taki jak brak pliku, opóźnienie na serwerze albo inny błąd serwera, to wywołana zostanie ta właśnie funkcja. Metody wyższego poziomu w takiej sytuacji nie wykonują żadnej operacji. W poprzednim przykładzie wykorzystaliśmy funkcję wywołania zwrotnego do wyświetlenia na stronie komunikatu o błędzie. Celowo wpisaliśmy nazwę nieistniejącego pliku, a biblioteka jQuery przekazała sterowanie do funkcji obsługującej błędy.

I coś jeszcze Parametry przekazywane do funkcji obsługi błędu Biblioteka jQuery przekazuje funkcji obsługi błędu trzy parametry. Pierwszym jest obiekt XMLHttpRequest utworzony w ramach żądania, drugim — ciąg znaków z typem błędu, a trzecim (opcjonalnym) wyjątek powstały w kodzie JavaScript.

76

Rozdział 2. • Łączenie PHP i jQuery

W ciągu znaków przekazywanym w drugim parametrze mogą się znaleźć następujące teksty: timeout, notmodified, parseerror lub null.

Błąd ajaxError() Inną metodą, którą można przyłączyć do elementów HTML, jest metoda ajaxError(). Metoda ta będzie wykonywana za każdym razem, gdy podczas obsługi żądania AJAX powstanie jakiś błąd. $('#result').ajaxError(function() { $(this).html('Wystąpił błąd.'); })

Powyższy kod wystarczy umieścić wewnątrz metody document.ready(), a następnie usunąć funkcję obsługi błędu z kodu naszego przykładu. Teraz po wprowadzeniu nieprawidłowej nazwy pliku i kliknięciu przycisku zobaczymy, że komunikat o błędzie nadal się pojawia. Ta metoda może okazać się bardzo użyteczna, jeżeli żądania AJAX na naszej stronie generowane są w wielu miejscach, a chcielibyśmy mieć centralny punkt obsługi wszystkich błędów. Taki komunikat o błędzie będzie pojawiał się zawsze, ponieważ funkcja wywoływana jest niezależnie od tego, gdzie wygenerowano żądanie.

Zobacz też Q Recepturę „Pobieranie danych z PHP za pomocą jQuery”. Q Recepturę „Wysyłanie danych do PHP”. Q Recepturę „Tworzenie pustej strony i ładowanie jej w częściach”. Q Recepturę „Ładowanie JavaScriptu na żądanie, aby zmniejszyć czas ładowania strony”.

Blokowanie w przeglądarce buforowania żądań AJAX W przypadku żądań typu GET przeglądarka umieszcza je w swojej pamięci podręcznej i w przypadku ponownego wysłania tego samego żądania nie jest ono przesyłane na serwer, tylko obsługiwane z bufora. W tej recepturze wyjaśnię, jak zmusić przeglądarkę do wysłania żądania do serwera za każdym razem, z pominięciem pamięci podręcznej.

77

PHP i jQuery. Receptury

Jak to zrobić? 1. Podczas wysyłania żądania AJAX użyj opcji cache, aby wyłączyć buforowanie tego żądania w przeglądarce. Nadanie opcji cache wartości false nie pozwala przeglądarce na buforowanie jakichkolwiek żądań AJAX, a zatem za każdym razem dane są pobierane z serwera. $.ajax({ url : 'someurl.php', cache: false, success: function(data) { //zrób coś z otrzymanymi danymi } });

Jak to działa? W przypadku żądań AJAX przeglądarka sprawdza najpierw, czy żądanie z takim adresem URL znajduje się już w jej pamięci podręcznej. Jeżeli takie żądanie zostanie w niej znalezione, to nie jest ono wysyłane do serwera, ale odpowiedź pobierana jest z pamięci podręcznej. Biblioteka jQuery udostępnia nam opcję cache, której można użyć, aby zablokować zachowanie przeglądarki. Domyślnie opcja ta ma wartość true, a po przypisaniu jej wartości false biblioteka jQuery doda do adresu URL żądania klucz znaku podkreślenia (_) i losowo wybraną liczbę. Dzięki temu przeglądarka będzie zakładała, że za każdym razem ma do czynienia z osobnym żądaniem, mimo iż zmieni się tylko jedna nieistotna wartość w adresie URL. Oznacza to, że przeglądarka nie będzie mogła buforować żądań, a te będą za każdym razem przesyłane do serwera.

I coś jeszcze Buforowane są tylko żądania typu GET Warto tutaj wspomnieć, że w pamięci podręcznej przeglądarki umieszczane są tylko żądania typu GET, ale już żądania typu POST nie podlegają buforowaniu. Oznacza to, że opcja cache zastosowana wobec żądania typu POST nie ma na nie żadnego wpływu. Po prostu każde żądanie tego typu jest unikalne.

78

Rozdział 2. • Łączenie PHP i jQuery

Zobacz jeszcze Q Receptura „Pobieranie danych z PHP za pomocą jQuery” wyjaśnia zasady używania metody get() do tworzenia żądań typu GET. Q Receptura „Wysyłanie danych do PHP” objaśnia sposoby użycia metody post() do tworzenia żądań typu POST.

Ładowanie JavaScriptu na żądanie, aby zmniejszyć czas ładowania strony Wyobraźmy sobie rozbudowaną aplikację internetową, która często korzysta z JavaScriptu, aby komunikować się z użytkownikiem. Taka strona zwykle składa się z kilku plików zawierających skrypty JavaScript. Na przykład w jednym pliku zdefiniowana jest kontrolka kalendarza, w drugim powstają efekty specjalne, a jeszcze jeden zajmuje się tworzeniem harmonijek. Wszystko to powoduje wydłużenie czasu ładowania strony, ponieważ przeglądarki nie mogą pobierać wszystkich tych plików jednocześnie. Najlepszym rozwiązaniem jest zatem ładowanie tylko absolutnie niezbędnych plików i późniejsze doładowywanie kolejnych w razie potrzeby. W tej recepturze nauczymy się używać JavaScriptu do ładowania plików na żądanie.

Przygotowania W katalogu rozdzial2 utwórz nowy katalog receptura9.

Jak to zrobić? 1. W katalogu receptura9 utwórz plik index.html. Zapisz w nim kod HTML tworzący stronę składającą się z akapitu i czterech przycisków. Pierwszego przycisku użyjemy do załadowania kolejnego pliku JavaScript, a pozostałe przyciski będą manipulowały zawartością akapitu.

Przykład z getScript



79

PHP i jQuery. Receptury

Ten tekst zostanie



2. Przed zamykającym znacznikiem body dołącz plik biblioteki jQuery i dopisz funkcję obsługi zdarzenia click pierwszego przycisku. Po kliknięciu tego przycisku biblioteka jQuery załaduje zewnętrzny plik JavaScript. Po udanym załadowaniu tego pliku wywołana zostanie funkcja o nazwie addEvents(), która doda funkcje obsługi kliknięć pozostałych trzech przycisków.

3. Teraz w tym samym katalogu utwórz nowy plik i nazwij go new.js. Zdefiniuj w nim funkcję addEvents(), która będzie dodawała funkcje obsługi zdarzenia click w trzech przyciskach. function addEvents() { $('.bold').click(function() { $('#container').css('font-weight', 'bold'); }); $('.color').click(function() { $('#container').css('color', 'red'); }); $('.change').click(function() { $('#container').html('Wstawiono nowy kod HTML'); }); }

80

Rozdział 2. • Łączenie PHP i jQuery

4. Otwórz w przeglądarce plik index.html. Kliknij dowolny z przycisków oprócz przycisku Załaduj skrypt. Okaże się, że takie klikanie nie daje żadnych efektów i tekst w akapicie się nie zmienia. Teraz kliknij przycisk Załaduj skrypt. Pojawi się okienko z informacją, że skrypt został załadowany. Od tego momentu klikanie pozostałych trzech przycisków będzie powodowało zmiany w akapicie.

Jak to działa? Kliknięcie przycisku Załaduj skrypt powoduje wywołanie metody getScript() udostępnianej przez bibliotekę jQuery. Funkcja ta przyjmuje dwa parametry: nazwę pliku do załadowania oraz funkcję wywołania zwrotnego wywoływaną po zakończeniu ładowania pliku. Wskazany plik jest ładowany z serwera w sposób asynchroniczny. Po zakończeniu ładowania wszystkie zmienne i funkcje z tego pliku stają się dostępne w kontekście globalnym. Oznacza to, że mogą być używane przez inne funkcje i pliki JavaScript. Wywołanie funkcji zwrotnej gwarantuje nam, że plik został w pełni załadowany i możemy bezpiecznie pracować z zawartymi w nim zmiennymi i funkcjami. W naszym przykładzie funkcja addEvents() została zdefiniowana w pliku new.js. Funkcja ta zajmuje się definiowaniem obsługi zdarzenia click w przyciskach dostępnych na stronie. Początkowo plik new.js nie jest dostępny na stronie, dlatego przyciski te nie spełniają żadnej funkcji. Po załadowaniu tego pliku wywoływana jest jednak funkcja addEvents(), która przypisuje przyciskom konkretne działania. Od tego momentu przyciski zaczynają wpływać na akapit.

81

PHP i jQuery. Receptury

I coś jeszcze Alternatywy dla metody getScript() Metoda getScript() przeznaczona jest do ładowania skryptów. Ten sam efekt można jednak uzyskać za pomocą metody ajax(). $.ajax( { url: 'new.js', dataType: 'script', success: function() { alert('Skrypt został załadowany!'); addEvents(); } });

Powyższy kod również załaduje plik new.js i wykona znajdującą się w nim funkcję. Z tego rozwiązania można skorzystać, w przypadku gdy chcemy zająć się obsługą ewentualnych błędów, co nie jest możliwe, jeżeli skorzystamy z metody getScript(). Proszę też zwrócić uwagę na wykorzystanie w tym rozwiązaniu opcji dataType, dla której zdefiniowaliśmy wartość script. Parametr ten informuje bibliotekę jQuery, jakiego typu będą dane, które otrzyma z serwera (w tym przypadku będzie to skrypt).

Zobacz też Q Recepturę „Pobieranie danych z PHP za pomocą jQuery”, która wyjaśnia sposób użycia metody get() do pobierania danych. Q Recepturę „Wysyłanie danych do PHP”, w której wyjaśniane są sposoby wysyłania

danych do skryptów PHP za pomocą biblioteki jQuery. Q Recepturę „Tworzenie pustej strony i ładowanie jej w częściach”.

82

3 Praca z dokumentami XML W tym rozdziale zajmiemy się: Q ładowaniem danych XML z plików oraz ciągów znaków za pomocą SimpleXML, Q korzystaniem z elementów i atrybutów za pomocą SimpleXML, Q wyszukiwaniem elementów za pomocą XPath, Q odczytywaniem dokumentów XML za pomocą rozszerzenia DOM, Q tworzeniem dokumentów XML za pomocą rozszerzenia DOM, Q modyfikowaniem dokumentów XML za pomocą rozszerzenia DOM, Q parsowaniem dokumentów XML za pomocą biblioteki jQuery.

Wprowadzenie Język XML (ang. Extensible Markup Language — elastyczny język znaczników) jest strukturą reprezentacji danych w formacie zrozumiałym dla człowieka. W przeciwieństwie do tego, co sugeruje nazwa, tak naprawdę nie jest to język, ale zbiór znaczników ukierunkowanych na definiowanie struktury danych. Składnia języka XML jest bardzo podobna do składni języka HTML, z tą różnicą, że ten ostatni przeznaczony jest do prezentacji danych, a pierwszy do ich przechowywania i wymiany. Co więcej wszystkie znaczniki języka XML są zdefiniowane przez użytkownika i można je formatować zgodnie z własnymi potrzebami. Niemniej jednak dokumenty XML muszą przestrzegać zasad określonych przez organizację W3C.

PHP i jQuery. Receptury

Dzięki znacznemu wzrostowi liczby aplikacji rozproszonych działających w internecie format XML stał się najczęściej stosowaną metodą wymiany danych. Usługi sieciowe korzystają z formatu XML do przenoszenia danych pomiędzy poszczególnymi częściami aplikacji. Dzięki temu, że język XML jest całkowicie niezależny od platformy i można go zapisać w postaci ciągu znaków, korzystają z niego aplikacje działające na różnego rodzaju technologiach serwerowych, komunikując się ze sobą za jego pośrednictwem. Proszę przyjrzeć się poniższemu dokumentowi XML:

Na podstawie tego dokumentu możemy wywnioskować, że jest to lista stron WWW zawierająca nazwę, adres URL oraz dodatkowe informacje na temat poszczególnych stron. W języku PHP dostępnych jest kilka klas i funkcji pozwalających na pracę z dokumentami XML. Za ich pomocą możemy łatwo odczytywać, zapisywać, modyfikować i przeszukiwać dokumenty. W tym rozdziale omawiać będziemy funkcje z dodatku SimpleXML oraz klasy DOMDocument pozwalające na manipulowanie dokumentami XML w języku PHP. Nauczymy się, jak należy czytać i modyfikować pliki XML, używając do tego interfejsów API bibliotek SimpleXML i DOM. Poznamy też metodę XPath, która bardzo ułatwia wyszukiwanie danych w dokumentach. Trzeba tu zauważyć, że możemy pracować tylko z prawidłowo sformatowanymi i zbudowanymi dokumentami XML. Istnieje wiele reguł opisujących prawidłową budowę dokumentu XML, spośród których poniżej przedstawiam zaledwie kilka: „ Dokument XML musi mieć tylko jeden element główny. „ Nie można wykorzystywać znaków specjalnych, takich jak nawiasy ostre (< i >) itp. „ Każdy znacznik XML musi mieć swój znacznik zamykający. „ W nazwach znaczników rozróżniane są wielkości znaków. Więcej informacji na temat prawidłowej budowy dokumentu XML znaleźć można pod adresem: http://pl.wikipedia.org/wiki/XML#Poprawno.C5.9B.C4.87_dokumentu.

84

Rozdział 3. • Praca z dokumentami XML

W większości receptur z tego rozdziału korzystać będziemy ze wstępnie przygotowanego pliku XML. Utwórz nowy plik o nazwie common.xml i zapisz go w katalogu rozdzial3. Do utworzonego pliku zapisz poniższy dokument XML.

Przygody Sherlocka Holmesa

Skandal w Bohemii Patrzysz, ale nie widzisz. Różnica jest oczywista.

Związek rudowłosych To problem na trzy fajki, dlatego proszę, żebyś nie mówił do mnie nic przez pięćdziesiąt minut.

Człowiek z wywiniętą wargą To jest oczywiście drobiazg, ale nie ma nic ważniejszego niż drobiazgi.

Księga przypadków Sherlocka Holmesa

Willa o trzech daszkach Nie jestem prawem, ale reprezentuję sprawiedliwość na tyle, na ile mi siły pozwalają.

Zabójstwo przy moście Musimy szukać niesprzeczności. Gdzie tylko pojawi się jej zalążek, należy oczekiwać podstępu.

Tajemnica dworu w Shoscombe Psy nie popełniają błędów.

Wspomnienia Sherlocka Holmesa

Żółta twarz Każda prawda jest lepsza od nieokreślonych wątpliwości.

Urzędnik maklerski Efekty bez przyczyny robią o wiele większe wrażenie.

85

PHP i jQuery. Receptury

Ostatnia zagadka Jeżeli miałbym pewność twojej ostatecznej zagłady, to w interesie ogółu z chęcią zaakceptowałbym swoją.



Ładowanie danych XML z plików oraz ciągów znaków za pomocą SimpleXML Zgodnie ze swoją nazwą funkcje ze zbioru SimpleXML umożliwiają łatwy dostęp do danych zapisanych w dokumentach XML. Pliki lub ciągi znaków XML można konwertować do postaci obiektów, a następnie odczytywać z nich dane. Dowiemy się tu, jak odczytać dokument XML z pliku lub ciągu znaków za pomocą funkcji SimpleXML. Nauczymy się też radzić sobie z błędami w dokumentach XML.

Przygotowania Utwórz nowy katalog o nazwie rozdzial3. W tym katalogu będziemy umieszczać podkatalogi poszczególnych receptur. Utwórz zatem jeszcze jeden katalog o nazwie receptura1.

Jak to zrobić? 1. W katalogu receptura1 utwórz plik index.php i wpisz do niego kod PHP, który będzie ładował plik common.xml. Po załadowaniu tego pliku na stronie zostanie wyświetlona lista z tytułami książek. Skorzystamy też z funkcji biblioteki libxml, która wykryje ewentualne błędy i wyświetli na ekranie szczegółowe informacje na ich temat.

2. Otwórz w przeglądarce plik index.php. Dzięki temu, że już wcześniej sprawdziliśmy poprawność pliku XML, zobaczymy na ekranie następujące tytuły książek: Przygody Sherlocka Holmesa Księga przypadków Sherlocka Holmesa Wspomnienia Sherlocka Holmesa

3. Spróbujmy teraz zepsuć nasz plik XML. W tym celu otwórz plik common.xml w edytorze i usuń dowolny ze znaczników (na przykład znacznik zamykający tytułu pierwszej książki). Zapisz plik i ponownie załaduj plik index.php w przeglądarce. Zobaczysz tylko komunikat o błędzie podobny do poniższego:

Jak to działa? W pierwszym wierszu przekazujemy wartość true do funkcji libxml_use_internal_errors, która blokuje wszystkie błędy XML i pozwala nam na obsłużenie ich w naszym kodzie. W drugim wierszu próbujemy załadować plik XML za pomocą funkcji simplexml_load_file. Jeżeli uda się go załadować bez problemów, to otrzymamy od funkcji obiekt SimpleXMLElement, a w przypadku wystąpienia błędów — wartość false.

87

PHP i jQuery. Receptury

Następnie kontrolujemy wartość otrzymaną od wywołanej funkcji. Jeżeli jest to wartość false, to za pomocą funkcji libxml_get_errors() pobieramy listę błędów w postaci tablicy. Elementy tablicy będą tu obiektami typu LibXMLError, a każdy z nich będzie udostępniał kilka właściwości. W zaprezentowanym kodzie iterujemy po całej tablicy errors i wypisujemy na stronie właściwość message każdego z obiektów, która powinna dokładnie opisywać dany błąd. Jeżeli w dokumencie XML nie ma żadnych błędów, to otrzymujemy obiekt typu SimpleXMLElement, który zawiera wszystkie dane z załadowanego dokumentu. Iterujemy zatem po elementach book za pomocą instrukcji foreach i wypisujemy nazwy książek.

I coś jeszcze Parametry funkcji simplexml_load_file() Funkcja simplexml_load_file() może przyjmować jeszcze inne parametry: Q filename — Pierwszy parametr jest obowiązkowy. Może to być ścieżka do lokalnego

pliku albo adres URL. Q class_name — Klasę SimpleXMLElement można jeszcze rozbudować. W takiej sytuacji

możemy tutaj podać nazwę klasy, a funkcja będzie zwracała obiekty tej właśnie klasy. Tan parametr jest opcjonalny. Q options — Trzeci parametr funkcji pozwala podać opcje dla biblioteki libxml,

dzięki którym dokładniej panujemy nad procesem ładowania pliku XML. Ten parametr jest opcjonalny.

Funkcja simplexml_load_string() Funkcja simplexml_load_string() jest bardzo podobna do funkcji simplexml_load_file(). Po udanym załadowaniu dokumentu XML również zwraca obiekt typu SimpleXMLElement. Jeżeli funkcji przekażemy prawidłowo zbudowany ciąg znaków XML, to otrzymamy obiekt, a w przeciwnym przypadku tylko wartość false. $objXML = simplexml_load_string('Moja ulubiona książka');

Podany wyżej kod zwraca obiekt SimpleXMLElement z danymi załadowanymi z ciągu znaków XML. Drugi i trzeci parametr tej funkcji jest dokładnie taki sam, jak w przypadku funkcji simplexml_load_file().

Tworzenie obiektu za pomocą klasy SimpleXMLElement Możemy też wykorzystać konstruktor klasy SimpleXMLElement do tworzenia nowych obiektów.

88

Rozdział 3. • Praca z dokumentami XML

$objXML = new SimpleXMLElement('Moja ulubiona książka');

Więcej informacji na temat bibliotek SimpleXML i libxml Więcej informacji na temat biblioteki SimpleXML można znaleźć na stronie PHP pod adresem http://www.php.net/manual/pl/book.simplexml.php. Z kolei informacje na temat biblioteki libxml można znaleźć pod adresem http://www.php.net/manual/pl/book.libxml.php.

Zobacz też Q Recepturę „Korzystanie z elementów i atrybutów za pomocą SimpleXML”. Q Recepturę „Wyszukiwanie elementów za pomocą XPath”.

Korzystanie z elementów i atrybutów za pomocą SimpleXML W tej recepturze dowiemy się, jak można pobrać wartości węzła lub atrybutu z pliku XML, wykorzystując do tego bibliotekę SimpleXML. Przedstawiony tu przykład będzie używał pliku common.xml, z którego pobierać będziemy rok wydania lub listę opowiadań z danej książki.

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

Jak to zrobić? 1. W katalogu rozdzial2 utwórz nowy plik o nazwie index.php i wpisz do niego listę rozwijaną razem z opcjami, którymi będą nazwy książek z pliku common.xml. Następnie utwórz dwa przyciski, które będą pobierały rok publikacji i listę opowiadań wybranej wcześniej książki. Każdy z tych przypadków powinien mieć atrybut ID — za jego pomocą będziemy określać, który z nich został kliknięty. Na koniec utwórz jeszcze akapit, w którym wyświetlane będą wyniki.

Dostęp do wartości węzłów i atrybutów

89

PHP i jQuery. Receptury





Wybierz książkę





2. Wykorzystamy bibliotekę jQuery do wybrania wartości z formularza i wysłania żądania AJAX do pliku, który obsłuży żądanie i wyśle na stronę odpowiednio przygotowane dane odpowiedzi. W tym celu musimy napisać kilka wierszy kodu i umieścić je tuż przed zamykającym znacznikiem body. Dołącz też plik biblioteki jQuery, nie zapominając o zastosowaniu właściwej ścieżki, a następnie podłącz funkcję obsługi zdarzenia click do obu przycisków. Po kliknięciu przycisku funkcja ta wyśle żądanie AJAX do pliku PHP, podając mu dane wybranej książki i klikniętego przycisku. Otrzymana odpowiedź zostanie wstawiona do akapitu o identyfikatorze result.

3. Teraz w tym samym katalogu utwórz plik process.php. W tym pliku wartości wybranych książek i klikniętych przycisków będą odczytywane z superglobalnej tablicy $_GET. Ładowany jest plik common.xml i w zależności od wartości zmiennych action i ID pobranych z tablicy $_GET iterujemy po książkach. Jednocześnie tworzona jest zawartość zmiennej odpowiedzi, która na zakończenie przesyłana jest do przeglądarki.

4. Uruchom w przeglądarce plik index.php. Zobaczysz na stronie listę rozwijaną i dwa przyciski. Wybierz z listy jedną z książek, a następnie kliknij dowolny z przycisków. Poniższy obrazek przedstawia listę opowiadań wyświetlanych po wybraniu książki i kliknięciu przycisku Pobierz listę opowiadań.

91

PHP i jQuery. Receptury

Jak to działa? Aby pobrać wartość węzła, możemy odwołać się do niego przez nazwę, traktując ją jak właściwość obiektu SimpleXMLElement. W pliku index.php utworzyliśmy obiekt SimpleXMLElement na podstawie pliku common.xml, ładując jego zawartość za pomocą funkcji simplexml_load_file(). Ze względu na to, że w pliku tym zostało zapisanych kilka węzłów książek, otrzymamy tablicę obiektów, po których możemy iterować, tak jak po każdej innej tablicy. Podobnie atrybuty węzła możemy pobierać jak wartości z tablicy, stosując nazwę atrybutu jako indeks tablicy asocjatywnej. Dla każdej książki tworzymy jeden element option, którego atrybutowi value przypisywana jest wartość atrybutu index książki, a tekst opcji wypełniany jest wartością atrybutu name książki. Sposób pobrania tych wartości pokazuje nam, jak prosto można odczytywać dane za pomocą metod biblioteki SimpleXML. Kod biblioteki jQuery rejestruje funkcje obsługi zdarzeń dla obu przycisków znajdujących się na stronie. Kliknięcie przycisku powoduje pobranie wartości wybranej książki oraz identyfikatora klikniętego przycisku i wysłanie ich do pliku process.php. Do wysłania żądania używamy tutaj metody get(). Wartości przesłane przez bibliotekę jQuery są dostępne w superglobalnej tablicy $_GET. Wartości te zapisywane są następnie do zmiennych PHP o nazwach $bookId i $action. W kolejnym kroku ładujemy plik XML i w ten sposób otrzymujemy obiekt typu SimpleXMLElement zapisany w zmiennej $objXML. Aby znaleźć książkę wybraną na stronie przez użytkownika, możemy iterować po wszystkich książkach i sprawdzać, czy atrybut index pokrywa się z tym zapisanym w zmiennej $bookId. Po 92

Rozdział 3. • Praca z dokumentami XML

znalezieniu pasującej książki sprawdzamy wartość zmiennej $action. Jeżeli znajduje się w niej wartość year, to pobieramy z węzła książki atrybut o nazwie year i wpisujemy go do ciągu znaków odpowiedzi zapisanej w zmiennej $strResponse. Jeżeli zmienna $action zawiera wartość stories, to z aktualnego obiektu $book pobieramy tablicę obiektów story. Następnie iterujemy po tej tablicy i tworzymy wypunktowaną listę nazw opowiadań. Na koniec zapisujemy ją do zmiennej $strResponse. W ostatnim kroku wypisujemy zawartość zmiennej $strResponse za pomocą instrukcji echo, wysyłając ją do przeglądarki, która wyświetla tekst w akapicie.

I coś jeszcze Modyfikowanie dokumentu XML za pomocą biblioteki SimpleXML Wartości węzłów w istniejącym dokumencie XML możemy też modyfikować za pomocą funkcji biblioteki SimpleXML. Na przykład, jeżeli chcielibyśmy zmienić nazwę pierwszej książki w naszym pliku common.xml, to możemy zrobić to za pomocą poniższego kodu: $objXML->book[0]->name = 'Nowa nazwa książki'; $result = $objXML->asXML();

Jeżeli metodzie asXML() nie przekażemy żadnych parametrów, to zwróci ona zmodyfikowany dokument XML w postaci ciągu znaków albo wartość false w przypadku problemów przy dokonywaniu zmiany. Metodzie asXML() można też przekazać nazwę pliku, a wtedy zapisze ona do tego pliku wynikowy dokument XML.

Dodawanie elementów do dokumentu XML Do dokumentu XML można też dodawać nowe elementy, tak jak pokazano to w poniższym kodzie: $objXML->book[0]->addChild('remark','Narrację opowiadań z tej książki prowadzi ´sam Sherlock Holmes'); $objXML->book[0]->remark->addAttribute('totalStories','13'); $result = $objXML->asXML();

Przedstawiony kod dodaje węzeł remark do pierwszego elementu book i uzupełnia ten węzeł o atrybut totalStories. Nie można zapomnieć, że wynikowy dokument XML zostanie zapisany w zmiennej $result, a nie w oryginalnym pliku XML. Można jednak zapisać dokument w tym pliku, podając odpowiednią nazwę jako parametr metody asXML(), o czym mówiłem już w poprzednim podpunkcie.

93

PHP i jQuery. Receptury

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

SimpleXML”. Q Recepturę „Wyszukiwanie elementów za pomocą XPath”. Q Recepturę „Pobieranie danych z PHP za pomocą jQuery” z rozdziału 2.

Wyszukiwanie elementów za pomocą XPath Technologia XPath lub XML Path (ścieżka XML) jest używana do nawigowania w dokumencie XML. Jest to tak naprawdę język zapytań, który udostępnia standardowy zestaw wyrażeń oraz funkcji pozwalających na przeglądanie drzewa dokumentu. Język XPath działa na drzewie dokumentu i dzięki temu można go wykorzystywać w wielu funkcjach, takich jak przeszukiwanie, porównywanie i inne. PHP ma już wbudowaną obsługę języka XPath. W tej recepturze wyjaśnionych zostanie kilka koncepcji wykorzystanych w tym języku, a także pokazane zostaną sposoby pobierania informacji z dokumentów XML. Wykorzystamy tu plik common.xml i napiszemy prosty przykład demonstrujący możliwości języka XPath.

Przygotowania Podobnie jak w poprzednich recepturach, w katalogu rozdzial3 utwórz nowy katalog o nazwie receptura3.

Jak to zrobić? 1. Utwórz nowy plik HTML i nadaj mu nazwę index.html. Utwórz cztery przyciski, których użyjemy do zaprezentowania różnych zastosowań języka XPath. Oprócz tego utwórz też pusty element div, w którym będziemy wyświetlać wyniki naszych działań. Na koniec zdefiniuj jeszcze kilka stylów CSS w sekcji head, które poprawią czytelność naszej strony.

Używanie XPath

94

Rozdział 3. • Praca z dokumentami XML







2. Dołącz bibliotekę jQuery i dopisz kod, który wyśle żądanie AJAX do pliku process.php. Żądanie to będzie zawierało identyfikator klikniętego przycisku, wywoła odpowiednią reakcję po stronie serwera. Odpowiedź skryptu PHP zostanie wstawiona do elementu div.

3. Przejdźmy teraz na stronę serwera. W tym samym katalogu utwórz plik PHP o nazwie process.php. W ramach tego skryptu będziemy ładować plik XML i wykonywać na nim określone operacje, zależnie od tego, który przycisk został kliknięty na stronie. Wykorzystamy tu metodę xpath(), aby przeszukać dokument i wypisać wyniki w oknie przeglądarki. Przesłana odpowiedź zostanie wstawiona w odpowiednie miejsce na stronie za pomocą biblioteki jQuery.

4. Uruchom w przeglądarce plik index.php i kliknij dowolny przycisk. Uruchomione zostanie wtedy żądanie AJAX, które uruchomi plik process.php, a wyniki jego pracy zostaną wyświetlone na stronie. Na przykład kliknięcie ostatniego przycisku spowoduje wyświetlenie książek, dla których atrybut value ma wartość mniejszą niż 1900.

Jak to działa? Na stronie zdefiniowaliśmy cztery przyciski. Pierwszy przycisk pobiera nazwy i lata wydania wszystkich książek, drugi wyświetla listę książek z listą opowiadań i cytatów, trzeci pobiera nazwę i rok wydania ostatniej książki, a czwarty wyświetla wszystkie książki, których wartość atrybutu year jest mniejsza niż 1900. Każdemu z tych przycisków przypisany został identyfikator, wśród których wymienić można: all, total, last i year. Kliknięcie przycisku powoduje wysłanie identyfikatora tego przycisku w ramach żądania AJAX do pliku process.php, gdzie jest on odbierany i zapisywany do zmiennej $action. Plik common.xml został już załadowany do zmiennej $objXML. Następnie za pomocą instrukcji switch wybierany jest rodzaj obsługi żądania pasujący do otrzymanego identyfikatora. Biblioteka SimpleXML udostępnia metodę xpath(), za pomocą której możemy wykonywać zapytania XPath na załadowanym dokumencie. Metoda ta pobiera w parametrze zapytanie XPath i zwraca tablice elementów typu SimpleXMLElement lub wartość false w przypadku wystąpienia błędu.

97

PHP i jQuery. Receptury

Wyrażenie //book wybierze nam z dokumentu wszystkie elementy book, niezależnie od ich pozycji. Wyrażenie //book/name wybierze z dokumentu wszystkie elementy name będące podelementami elementów book. Wyrażenie //book[last()] wybierze ostatni element book znajdujący się w dokumencie. Wyrażenie //book/name[@year

99

PHP i jQuery. Receptury

3. Dla urozmaicenia wykorzystamy jeszcze bibliotekę jQuery, aby wyświetlać listę opowiadań z poszczególnych książek. Funkcja obsługująca zdarzenie click zostanie dołączona do wszystkich nazw książek i będzie ona wyświetlać i ukrywać listę opowiadań.

4. Uruchom plik index.php w przeglądarce, a zobaczysz na ekranie listę książek. Kliknięcie dowolnej książki spowoduje wyświetlenie listy znajdujących się w niej opowiadań z wykorzystaniem odpowiedniej animacji.

100

Rozdział 3. • Praca z dokumentami XML

Jak to działa? Na początku w zmiennej $objXML tworzymy obiekt klasy DOMDocument. Klasa ta udostępnia zestaw właściwości i metod, z których możemy skorzystać do manipulowania dokumentami XML. Z plików XML możemy za ich pomocą pobierać nazwy węzłów, ich wartości, atrybuty i inne elementy. Następnie wywołujemy metodę $objXMl.load(), która pobiera dwa parametry. Pierwszy z nich to nazwa pliku, a drugi to opcje dla biblioteki libxml, przy czym drugi parametr jest opcjonalny. Metodzie tej przekazujemy w pierwszym parametrze plik common.xml, a w drugim opcję LIBXML_NOBLANKS. Dzięki zastosowaniu tej opcji w dokumencie nie będą pojawiały się puste węzły. Ze względu na to, że chcemy skorzystać ze wszystkich węzłów book, wywołujemy metodę Get ´ElementsByTagName() i przekazujemy jej wartość book, a w odpowiedzi otrzymujemy obiekt typu DOMNodeList. Pętla foreach pozwala nam na iterowanie po takiej kolekcji. Obiekty klasy DOMNode również udostępniają kilka użytecznych metod, z których skorzystaliśmy w naszym przykładzie. Właściwość firstChild zwraca pierwszy element podrzędny względem aktualnego elementu, czyli w naszym przypadku będzie to element book. Właściwość nodeValue zwraca wartość zapisaną wewnątrz elementu book, czyli w tym przypadku nazwę książki. Otrzymaną wartość opakowujemy jeszcze w element h1. Aby odczytać wartość atrybutu, należy skorzystać z właściwości attributes. Uzyskamy w ten sposób dostęp do słownika atrybutów. Po takiej kolekcji atrybutów możemy iterować za pomocą właściwości item. Pobraliśmy wartość atrybutu na pozycji zerowej i w ten sposób uzyskaliśmy wartość atrybutu year. Podobnie listę opowiadań danej książki otrzymaliśmy za pomocą ponownego wywołania metody getElementsByTagName() i iterowania po zwróconych przez nią wartościach. Na zakończenie całość została zapakowana w listę wypunktowaną. Po przygotowaniu struktury DOM dokumentu w przeglądarce biblioteka jQuery dołącza funkcję obsługi zdarzenia click do wszystkich elementów h1 znajdujących się na stronie. Od tego momentu kliknięcie elementu h1 będzie powodować wyświetlenie lub ukrycie następującego po nim elementu ul.

I coś jeszcze Pobieranie węzłów podrzędnych Możemy też sprawdzić, czy dany węzeł ma węzły podrzędne, i ewentualnie je pobrać. W powyższym przykładzie można pobrać węzły podrzędne węzła book za pomocą poniższego kodu:

101

PHP i jQuery. Receptury

if($book->hasChildNodes()) { $children = $book->childNodes; }

Właściwości nodeType, nodeName i nodeValue Jeżeli nie znamy dokładnie struktury dokumentu XML albo jego struktura jest niejednoznaczna, to możemy dodatkowo w swoim skrypcie skontrolować nazwę oraz wartość węzłów i atrybutów. $node->nodeType $node->nodeName $node->nodeValue

Właściwość nodeType będzie zwracać różne wartości w zależności od rodzaju węzła. Wartości te zdefiniowane są jako stałe biblioteki libxml. Najczęściej spotykanymi wartościami właściwości nodeType są: Q XML_ELEMENT_NODE Q XML_ATTRIBUTE_NODE Q XML_TEXT_NODE Q XML_CDATA_SECTION_NODE

Zobacz też Q Recepturę „Tworzenie dokumentów XML za pomocą rozszerzenia DOM”. Q Recepturę „Wyszukiwanie elementów za pomocą XPath”.

Tworzenie dokumentów XML za pomocą rozszerzenia DOM Rozszerzenie DOM daje nam możliwość tworzenia nowych dokumentów XML za pomocą całego zestawu udostępnianych metod. W tej recepturze dowiemy się, jak należy tworzyć nowe dokumenty XML za pomocą funkcji rozszerzenia DOM. Jak wiemy, w naszym przykładowym pliku common.xml mamy kilka elementów book, a zatem utworzymy podobne elementy składające się z nazwy oraz podelementów story, wykorzystując przy tym metody rozszerzenia DOM.

102

Rozdział 3. • Praca z dokumentami XML

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

Jak to zrobić? 1. W katalogu recepture5 utwórz nowy plik o nazwie index.php. 2. Napisz kod PHP tworzący nowy dokument XML, a następnie przygotuj kilka elementów i dodaj je do nowego dokumentu. Niektóre z tych elementów powinny zawierać w sobie tekst, a także atrybuty z wartościami. Na zakończenie przygotowany dokument XML zostanie zapisany na dysku. */ $books = $objXML->createElement('books');//książki $book = $objXML->createElement('book'); $attrIndex = new DOMAttr("index", "4"); $book->appendChild($attrIndex); $bookName = $objXML->createElement('name','Księga przypadków Sherlocka ´Holmesa'); $attrYear = new DOMAttr("year", "1894"); $bookName->appendChild($attrYear); $book->appendChild($bookName); $story = $objXML->createElement('story'); $title = $objXML->createElement('title', 'Przypadek ....'); $quote = $objXML->createElement('quote', 'Jeszcze jeden cytat'); $story->appendChild($title); $story->appendChild($quote); $book->appendChild($story); $books->appendChild($book); $objXML->appendChild($books); if($objXML->save('new.xml') != FALSE) { echo 'Plik XML został wygenerowany.'; } else {

103

PHP i jQuery. Receptury

echo 'Wystąpił błąd.'; } ?>

3. Teraz uruchom plik index.php w przeglądarce. Jeżeli kod zostanie wykonany bez błędów, to powinien pojawić się komunikat z informacją, że plik XML został wygenerowany. Zajrzyj teraz do katalogu receptura5, a znajdziesz w nim nowy plik XML o strukturze identycznej ze strukturą pliku common.xml.

Księga przypadków Sherlocka Holmesa

Przypadek .... Jeszcze jeden cytat



Jak to działa? Konstruktor klasy DOMDocument tworzy nowy obiekt typu DOMDocument. Konstruktorowi możemy przekazać dwa opcjonalne parametry. Pierwszy z nich określa wersję specyfikacji XML. Domyślną wartością jest tutaj 1.0. Drugi parametr definiuje natomiast sposób kodowania dokumentu. W celu utworzenia nowego węzła wywołujemy metodę createElement(), która tworzy nowy obiekt klasy DOMElement. Metoda da przyjmuje dwa parametry, przy czym drugi z nich jest opcjonalny. Pierwszy parametr określa nazwę węzła, a drugi definiuje tekst znajdujący się w tym węźle. Tworząc nowy atrybut, musimy utworzyć obiekt klasy DOMAttr. Podobnie jak to było w przypadku metody createElement(), konstruktor tej klasy przyjmuje dwa parametry: nazwę i wartość atrybutu. Przygotowane w ten sposób elementy i atrybuty są od siebie całkowicie niezależne i nie są częścią dokumentu. Aby wstawić je do struktury dokumentu, należy wywołać metodę appandChild(). Metoda ta pobiera element jako swój parametr i dołącza go do listy elementów podrzędnych obiektu wywołującego. W naszym przykładzie tworzyliśmy elementy za pomocą metody createElement() i dodawaliśmy je do dokumentu zgodnie z wcześniej założonym formatem. Po zakończeniu tworzenia elementów dokumentu zapisujemy wygenerowany dokument XML do pliku za pomocą metody save().

104

Rozdział 3. • Praca z dokumentami XML

Zobacz też Q Receptura „Odczytywanie dokumentów XML za pomocą rozszerzenia DOM”. Q Receptura „Modyfikowanie dokumentów XML za pomocą rozszerzenia DOM”.

Modyfikowanie dokumentów XML za pomocą rozszerzenia DOM Oprócz tworzenia nowego dokumentu XML od zera, tak jak robiliśmy to w poprzedniej recepturze, możemy też modyfikować istniejące już pliki XML. Do takiego pliku możemy dodawać nowe elementy, a także usuwać już istniejące. W tej recepturze przygotujemy stronę, która pozwoli nam dodawać nowe opowiadania do poszczególnych książek. Oprócz tego będziemy mogli też uzupełnić wybraną książkę o nowy tytuł oraz cytaty.

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

Jak to zrobić? 1. Utwórz nowy plik o nazwie index.php. Następnie utwórz w tym pliku formularz składający się z listy książek oraz dwóch pól tekstowych umożliwiających wprowadzenie tytułu opowiadania oraz cytatu. Poza tym utwórz też przycisk, którego użyjemy do dodawania tytułu opowiadania oraz wprowadzonego cytatu do dokumentu XML.

Modyfikowanie dokumentu XML





    105

    PHP i jQuery. Receptury

  • Książka:

    wybierz książkę

  • Nazwa opowiadania

  • Cytat





2. Teraz zapisz kod korzystający z biblioteki jQuery, który zostanie wywołany w przypadku kliknięcia przycisku. Zostaną wtedy zebrane wartości zapisane w polach tekstowych i wysłane do skryptu PHP o nazwie process.php, w ramach żądania AJAX. Odpowiedź otrzymana od skryptu zostanie wyświetlona zaraz obok przycisku.

3. Teraz zajmiemy się skryptem PHP, w którym wykonywane są interesujące nas działania. W tym samym katalogu utwórz nowy plik o nazwie process.php. Zawarty w nim skrypt będzie pobierał wartości z tablicy $_POST, a następnie załaduje zawartość pliku common.xml i wyszuka w nim wybraną przez użytkownika książkę. W kolejnym kroku utworzone zostaną nowe elementy, wypełnione otrzymanymi od przeglądarki danymi i zapisane w strukturze dokumentu XML.

4. Uruchom w przeglądarce plik index.php, a zobaczysz formularz, w którym z listy rozwijanej będzie można wybrać tytuł jednej z książek. Po wybraniu książki wpisz w pola tekstowe tytuł opowiadania oraz cytat i kliknij przycisk Dodaj nowe opowiadanie. Jeżeli uda się wprowadzić opowiadanie do dokumentu, to obok przycisku pojawi się stosowny komunikat. Otwórz teraz plik XML w edytorze i sprawdź, czy dane opowiadania zostały wprowadzone przy właściwej książce.

107

PHP i jQuery. Receptury

Jak to działa? Po wprowadzeniu wartości do formularza i kliknięciu przycisku biblioteka jQuery wysyła dane z formularza do pliku process.php. Na początku skrypt ten odczytuje otrzymane wartości z tablicy $_POST. W kolejnym kroku za pomocą klasy DOMDocument ładowany jest plik XML. Następnie korzystamy z metody getElementsByTagName(), aby pobrać wszystkie książki i przejrzeć je za pomocą pętli foreach. Naszym głównym zadaniem na tym etapie jest sprawdzenie, która książka została wybrana, i odpowiednie zmodyfikowanie jej węzła w strukturze XML. Za pomocą właściwości attributes możemy porównać wartość atrybutu index z wartością zmiennej $bookId i w ten sposób wyszukać odpowiednią książkę. Pętla zostanie przerwana, gdy tylko znajdziemy pasujący węzeł. Teraz mamy już książkę wybraną przez użytkownika, a zatem możemy skorzystać z funkcji rozszerzenia DOM, aby dodać do niej nowe elementy. W naszym przykładzie utworzyliśmy trzy takie elementy: story, title i quote, a następnie przypisaliśmy im otrzymane od przeglądarki teksty tytułu i cytatu. Aby dodać te nowo utworzone elementy do drzewa dokumentu, stosujemy metodę appendChild(), z której korzystaliśmy już w poprzedniej recepturze. Dołączyliśmy w ten sposób obiekty $title i $quote do obiektu $story, a następnie dołączyliśmy obiekt $story do obiektu $book. Na koniec musimy jeszcze zmienić zmodyfikowany obiekt XML w ciąg znaków. W tym celu możemy użyć jednej z dwóch metod: save() i saveXML(). Pierwsza z nich zapisuje dokument do pliku, natomiast metoda saveXML() zwraca tylko ciąg znaków reprezentujący cały dokument. Nie można jeszcze zapomnieć o odesłaniu do przeglądarki odpowiedniego komunikatu, który zostanie wyświetlony na stronie. Teraz możemy już sprawdzić, czy nowe wartości zostały faktycznie zapisane do pliku XML.

108

Rozdział 3. • Praca z dokumentami XML

I coś jeszcze Usuwanie węzłów Metoda removeChild() ma działanie odwrotne do działania metody createElement(), ponieważ służy do usuwania elementów z dokumentu. $objXML = new DOMDocument(); $objXML->load('new.xml'); $book = $objXML->getElementsByTagName('book')->item(0); $book->parentNode->removeChild($book); $objXML->save('new.xml');

Powyższy kod usunie z dokumentu pierwszy element book (razem z wszystkimi elementami podrzędnymi). Jeżeli chcielibyśmy wywołać metodę removeChild() na rzecz węzła głównego, to wystarczy tylko zamienić w powyższym kodzie wiersz: $book->parentNode->removeChild($book);

za pomocą poniższej instrukcji: $objXML->documentElement->removeChild($book);

Zobacz też Q Recepturę „Odczytywanie dokumentów XML za pomocą rozszerzenia DOM”. Q Recepturę „Tworzenie dokumentów XML za pomocą rozszerzenia DOM”. Q Recepturę „Korzystanie z elementów i atrybutów za pomocą SimpleXML”.

Parsowanie dokumentów XML za pomocą biblioteki jQuery Do analizy dokumentu XML można wykorzystać też bibliotekę jQuery. Plik z dokumentem XML możemy pobrać za pomocą żądań AJAX, a następnie obsłużyć go w przeglądarce, analizując zawarte w nim dane. Ponownie wykorzystamy tu przykład z receptury „Odczytywanie dokumentów XML za pomocą rozszerzenia DOM”. Różnica polegać będzie na tym, że poprzednio używaliśmy metod modelu DOM po stronie serwera, a teraz wykorzystamy funkcje selektorów biblioteki jQuery do przeglądania dokumentu XML.

109

PHP i jQuery. Receptury

Przygotowania W katalogu rozdzial3 utwórz nowy katalog o nazwie receptura 7. Oprócz tego skopiuj do tego katalogu plik common.xml.

Jak to zrobić? 1. W katalogu receptura7 utwórz nowy plik o nazwie index.html. W pliku tym zdefiniuj style dla elementów h1 i ul, które zostaną utworzone później za pomocą biblioteki jQuery. Utwórz też element div, do którego wstawiać będziemy kod HTML.

Czytanie dokumentów XML za pomocą jQuery





2. Dołącz jeszcze plik biblioteki jQuery. W kolejnym kroku za pomocą metody live() połącz funkcję obsługującą zdarzenie click z wszystkimi elementami h1. Następnie wyślij żądanie AJAX, aby pobrać plik common.xml. Po jego otrzymaniu przejrzyj strukturę dokumentu i utwórz kod HTML w odpowiadającym nam formacie. Na zakończenie wstaw przygotowany kod HTML do elementu div.

3. Uruchom w przeglądarce plik index.html, a zobaczysz listę wszystkich książek w pliku XML. Kliknij dowolny z tytułów książek, aby wyświetlić lub ukryć listę opowiadań w tej książce.

Jak to działa? Po załadowaniu strony wysyłane jest żądanie AJAX w celu pobrania pliku common.xml. Proszę zauważyć, że właściwości dataType została przypisana wartość xml. Teraz biblioteka jQuery wie już, że w odpowiedzi może oczekiwać pliku XML. Oznacza to, że po otrzymaniu ciągu znaków XML biblioteka będzie próbowała zmienić go w obiekt dokumentu. 111

PHP i jQuery. Receptury

Teraz możemy zastosować na tym obiekcie dowolne funkcje selektorów biblioteki jQuery, aby pobrać z niego dane. W naszym przykładzie skorzystaliśmy z metody find(), aby pobrać wszystkie elementy book. Za pomocą funkcji each() iterowaliśmy po tych elementach, a także po zawartych w nich elementach story. W ramach tego procesu umieszczaliśmy nazwy książek w elementach h1, a tytuły opowiadań w elementach listy. Po zakończeniu pracy pętli będziemy mieli ciąg znaków z kodem HTML, który możemy wstawić na stronę. Dzięki temu, że wcześniej użyliśmy metody live() dla elementów h1, kliknięcie nazwy książki spowoduje wyświetlenie lub ukrycie listy opowiadań. Pamiętamy, że metoda live() pozwala na podłączanie metod obsługi zdarzeń do elementów, które zostaną utworzone w przyszłości.

I coś jeszcze Metoda delegate() Metoda delegate() jest bardzo podobna do metody live(). Różnica polega na tym, że pobiera ona w dodatkowym parametrze selektor elementu i z jego pomocą przeszukuje zbiór elementów wywołujących zdarzenie. $('div').delegate("span", "click", function(){ $(this).toggleClass("hover"); });

Jeżeli kliknięty zostanie element div, to kod sprawdzi, czy zdarzenie to zostało wywołane kliknięciem elementu span znajdującego się w elemencie div. Metoda toggleClass() zostanie wywołana tylko wtedy, gdy rzeczywiście kliknięty będzie element span w elemencie div. W tym przypadku odpowiednim filtrowaniem zajęła się metoda delegate().

Zobacz też Q Recepturę „Odczytywanie dokumentów XML za pomocą rozszerzenia DOM”. Q Recepturę „Korzystanie z elementów i atrybutów za pomocą SimpleXML”. Q Recepturę „Dodawanie zdarzeń do elementów, które zostaną utworzone później”

z rozdziału 1.

112

4 Praca z formatem JSON W tym rozdziale zajmiemy się: Q tworzeniem danych w formacie JSON za pomocą PHP, Q odczytywaniem danych w formacie JSON za pomocą PHP, Q przechwytywaniem błędów analizy danych w formacie JSON, Q korzystaniem z danych w formacie JSON za pomocą jQuery.

Wprowadzenie W ostatnim czasie format JSON (ang. JavaScript Object Notation) stał się bardzo popularnym formatem wymiany danych i coraz więcej programistów zaczyna przedkładać go nad format XML. Coraz więcej witryn WWW korzysta z tego formatu jako domyślnej formy udostępniania danych. JSON jest formatem tekstowym, który jest niezależny od języka programowania, ale stanowi wewnętrzną formę prezentacji danych w języku JavaScript. Jest to format znacznie szybszy i lżejszy niż XML, ponieważ w porównaniu do niego wymaga zastosowania mniejszej liczby znaczników. Ze względu na to, że format JSON jest wewnętrznym formatem danych języka JavaScript, możemy znacznie łatwiej korzystać z niego po stronie klienta w aplikacjach korzystających z technologii AJAX. Obiekty zapisane w formacie JSON zaczynają się od otwierającego nawiasu klamrowego ({), a kończą się zamykającym nawiasem klamrowym (}). Zgodnie ze specyfikacją formatu dozwolone jest w nim stosowanie następujących typów danych:

PHP i jQuery. Receptury

Q obiektów — Obiekt jest kolekcją par klucz-wartość zamkniętych pomiędzy nawiasami klamrowymi ({ i }), a rozdzielanych przecinkiem. Klucze i wartości są od siebie oddzielane za pomocą dwukropka (:). O takich obiektach można myśleć jak o tablicach

asocjatywnych lub tabelach skrótów. Klucze są tutaj prostymi ciągami znaków, a wartościami mogą być tablice, ciągi znaków, liczby, wartości logiczne lub wartość null. Q tablic — Podobnie jak w innych językach tablica jest uporządkowanym zbiorem

danych. Dane w tablicy rozdzielane są za pomocą przecinka, a wszystkie muszą znaleźć się między nawiasami kwadratowymi ([ i ]). Q ciągów znaków — Każdy ciąg znaków musi być zamknięty za pomocą znaków

cudzysłowu. Q liczb — To ostatni typ danych.

Dane w formacie JSON mogą być tak proste jak poniższe: { "name":"Superman", "address": "gdzieś" }

Poniżej przedstawiam też przykład korzystających z tablic: { "name": "Superman", "phoneNumbers": ["8010367150", "9898989898", "1234567890" ] }

I jeszcze jeden, troszkę bardziej skomplikowany przykład, w którym użyłem obiektów, tablic oraz wartości: { "people": [ { "name": "Vijay Joshi", "age": 28, "isAdult": true }, { "name": "Charles Simms", "age": 13, "isAdult": false } ] }

114

Rozdział 4. • Praca z formatem JSON

Należy tutaj wspomnieć o ważnym szczególe: { 'name':'Superman', 'address': 'gdzieś' }

Powyższy ciąg znaków jest prawidłowym obiektem JavaScript, ale nie jest zgodny z formatem JSON. Format ten wymaga, aby nazwa i wartość były umieszczone pomiędzy znakami cudzysłowu, i nie dopuszcza stosowania znaków apostrofu.

Inną rzeczą, o której trzeba pamiętać, jest konieczność stosowania właściwego zestawu znaków. Proszę pamiętać, że format JSON wymaga zapisywania danych w kodowaniu UTF-8, natomiast język PHP domyślnie zakłada stosowanie kodowania ISO-8859-1.

Trzeba też pamiętać o tym, że format JSON nie jest językiem JavaScript, a jedynie specyfikacją formatu danych lub jednym z wielu elementów języka JavaScript. Skoro wiemy już, czym jest format JSON, możemy przystąpić do tworzenia receptur, w których nauczymy się korzystać z tego formatu za pomocą języka PHP i biblioteki jQuery. Utwórz zatem nowy katalog i nadaj mu nazwę rozdzial4. Wszystkie receptury z tego rozdziału będziemy umieszczać w tym katalogu, dlatego skopiuj do niego jeszcze plik jquery.js. Chcąc skorzystać z funkcji obsługi formatu JSON w języku PHP, należy zainstalować interpreter PHP w wersji 5.2 lub wyższej.

Tworzenie danych w formacie JSON za pomocą PHP W tej recepturze można tworzyć struktury danych w formacie JSON za pomocą tablic i obiektów PHP.

Przygotowania W katalogu rozdzial4 utwórz nowy katalog i nazwij go receptura1.

115

PHP i jQuery. Receptury

Jak to zrobić? 1. W katalogu receptura1 utwórz nowy plik i nazwij go index.php. 2. Do pliku wpisz kod PHP tworzący ciąg znaków w formacie JSON na podstawie tablicy.

3. Uruchom plik w przeglądarce, a wyświetlony zostanie ciąg znaków w formacie JSON. Po wprowadzeniu odpowiednich wcięć całość będzie wyglądała następująco: { "origin":"Delhi", "destination":"London", "passengers":[ { "name":"Mr. Perry Mason", "type":"Adult", "age":28 }, { "name":"Miss Irene Adler", "type":"Adult", "age":28 } ], "travelDate":"17-Dec-2010" }

Jak to działa? Język PHP udostępnia nam funkcję json_encode(), która tworzy ciąg znaków w formacie JSON na podstawie obiektów i tablic. Funkcja ta przyjmuje dwa parametry: pierwszy z nich jest wartością przeznaczoną do zakodowania, a w drugim można podać opcje sterujące kodowaniem znaków specjalnych. Ten drugi parametr jest opcjonalny. 116

Rozdział 4. • Praca z formatem JSON

W podanym tu kodzie utworzyliśmy dość złożoną tablicę asocjatywną przechowującą dane o podróżach dwojga pasażerów. Przekazanie tej tablicy do funkcji json_encode() pozwoliło nam uzyskać reprezentację tej tablicy w formacie JSON.

I coś jeszcze Wstępnie zdefiniowane stałe Dowolną z podanych niżej stałych można przekazać jako drugi parametr funkcji json_encode(). Q JSON_HEX_TAG — Zamienia znaki < i > na encje \u003C i \u003E. Q JSON_HEX_AMP — Zamienia znak &s na \u0026. Q JSON_HEX_APOS — Zamienia znak ' na \u0027. Q JSON_HEX_QUOT — Zamienia znak " na \u0022. Q JSON_FORCE_OBJECT — Wymusza, żeby wartość zwracana w ciągu znaków była

obiektem, a nie tablicą. Podane tu stałe zdefiniowane są w języku PHP od wersji 5.3 wzwyż.

Zobacz również Q Recepturę „Odczytywanie danych w formacie JSON za pomocą PHP”. Q Recepturę „Przechwytywanie błędów analizy danych w formacie JSON”.

Odczytywanie danych w formacie JSON za pomocą PHP W przeciwieństwie do poprzedniej receptury tym razem zajmiemy się odczytywaniem ciągów znaków w formacie JSON i tworzeniem na ich podstawie obiektów lub tablic, a także dekodowaniem takich ciągów znaków dzięki udostępnianym przez język PHP funkcjom JSON.

117

PHP i jQuery. Receptury

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

Jak to zrobić? 1. W katalogu receptura2 utwórz plik o nazwie index.php. 2. Spróbuj teraz zmienić ciąg znaków w formacie JSON w obiekt, używając do tego metody json_decode(). Po zakończeniu konwersji wypisz wynikowy obiekt na ekranie. Na potrzeby funkcji json_decode() możesz użyć wyniku działania poprzedniej receptury, ponieważ na pewno będzie to prawidłowy ciąg znaków JSON.

3. Uruchom plik index.php w przeglądarce, a zobaczysz wynik przekształcenia ciągu znaków JSON do postaci obiektu. Chcąc skorzystać z wartości zapisanych w tym obiekcie, można się do nich odwołać dokładnie tak samo, jak do wartości każdego innego obiektu w języku PHP.

118

Rozdział 4. • Praca z formatem JSON

Jak to działa? Funkcja json_decode() przekształca prawidłowo zbudowane ciągi znaków JSON w obiekty języka PHP. Przyjmuje ona trzy parametry, które opisuję poniżej: Q Ciąg znaków w formacie JSON. Q Opcjonalny parametr assoc, którego domyślną wartością jest false. Jeżeli zmienimy ją na true, to funkcja json_decode() będzie przekształcała obiekty w tablice asocjatywne. Q Opcjonalny parametr depth, który definiuje maksymalną głębokość zagnieżdżania

rekursywnych struktur w ciągu znaków JSON. Przed wersją PHP 5.3 parametr ten miał domyślną wartość 128, ale od wersji 5.3 jego wartość wzrosła do 512. W podanym kodzie do zdefiniowania ciągu znaków JSON wykorzystaliśmy składnię HEREDOC. Następnie przekazaliśmy ten ciąg znaków do funkcji json_decode(), która przekształca go w obiekt. Teraz możemy już korzystać z wartości tego obiektu za pomocą standardowych operatorów języka PHP. Na przykład datę wycieczki możemy pobrać za pomocą następującej instrukcji: $objJson->travelDate

Podobnie instrukcja: $objJson->passengers[1]->name

zwróci nam nazwisko drugiego pasażera, czyli Miss Irene Adler.

119

PHP i jQuery. Receptury

Zobacz również Q Recepturę „Tworzenie danych w formacie JSON za pomocą PHP”. Q Recepturę „Korzystanie z danych w formacie JSON za pomocą jQuery”. Q Recepturę „Przechwytywanie błędów analizy danych w formacie JSON”.

Przechwytywanie błędów analizy danych w formacie JSON Błędy są nieodłączną częścią procesu tworzenia aplikacji. Dlatego właśnie powinniśmy jak najlepiej obsługiwać powstające błędy, tak żeby ułatwić życie użytkownikom naszych produktów. Podczas tworzenia i dekodowania ciągów znaków w formacie JSON mogą powstać różne błędy. Na przykład wartość przekazana do funkcji może mieć nieprawidłową postać i naruszać zasady budowy obiektów JSON. W takich przypadkach musimy wyłapać wszystkie błędy i odpowiednio je obsłużyć. W tej recepturze będziemy się zajmować obsługą błędów w funkcjach obsługujących format JSON. Wykorzystamy przy tym metody wbudowane w interpreter PHP, przeznaczone do wykrywania błędów w strukturach JSON. Proszę pamiętać o tym, że obsługa błędów w strukturach JSON dostępna jest dopiero od wersji PHP 5.3. W związku z tym proszę się upewnić, że mamy zainstalowaną właściwą wersję interpretera.

Przygotowania W katalogu rozdzial4 utwórz nowy katalog o nazwie receptura3. Sprawdź też, czy masz zainstalowany interpreter w wersji 5.3 lub nowszej.

Jak to zrobić? 1. W katalogu receptura3 utwórz nowy plik o nazwie index.php. 2. Korzystając z tego samego ciągu znaków w formacie JSON, którego użyliśmy w poprzedniej recepturze, spróbuj przekształcić go w obiekt. Następnie za pomocą instrukcji switch sprawdź, czy w czasie przekształcania nie wystąpiły żadne błędy, i odpowiednio wypisz wyniki na ekranie.

120

Rozdział 4. • Praca z formatem JSON

3. Uruchom plik index.php w przeglądarce. Ciąg znaków JSON ma prawidłową strukturę, dlatego na ekranie powinien pojawić się tekst Data wylotu: 17-Dec-2010. Teraz usuń przecinek z wiersza "destination":"London". Po zapisaniu pliku załaduj go ponownie w przeglądarce. Tym razem pojawi się w niej komunikat Nieprawidłowa struktura JSON : Proszę sprawdzić składnię.

121

PHP i jQuery. Receptury

Jak to działa? Od wersji PHP 5.3 dostępna jest funkcja json_last_error(), która nie pobiera żadnych parametrów, ale zwraca dane ostatniego błędu, jaki wystąpił podczas analizy ciągu znaków JSON. Zwraca ona wartość całkowitą, na podstawie której można określić rodzaj błędu. W PHP zdefiniowane zostały też stałe dla poszczególnych rodzajów błędów: Q JSON_ERROR_NONE — oznacza, że ciąg znaków JSON był prawidłowy i przy jego

analizie nie powstały żadne błędy. Q JSON_ERROR_SYNTAX — oznacza, że w ciągu znaków JSON pojawiły się błędy składniowe. Q JSON_ERROR_CTRL_CHAR — napotkano nieprawidłowy znak kontrolny. Q JSON_ERROR_DEPTH — ciąg znaków JSON przekroczył maksymalną dopuszczalną

głębokość stosu.

Zobacz również Q Recepturę „Odczytywanie danych w formacie JSON za pomocą PHP”.

Korzystanie z danych w formacie JSON za pomocą jQuery Wiemy już, jak należy generować obiekty JSON w języku PHP. Możemy zatem wykorzystać tę wiedzę w małym praktycznym projekcie. Napiszemy tutaj przykład, w którym będziemy żądali danych w formacie JSON od skryptu PHP (do tworzenia żądania wykorzystamy oczywiście bibliotekę jQuery), a następnie wyświetlimy je na stronie WWW.

Przygotowania W katalogu rozdzial4 utwór nowy katalog o nazwie receptura4.

Jak to zrobić? 1. W utworzonym przed chwilą katalogu receptura4 utwórz plik o nazwie index.html. 2. Do tego pliku zapisz kod HTML tworzący pustą listę rozwijaną oraz pustą listę wypunktowaną. W sekcji head zdefiniuj też kilka stylów CSS, tak żeby te elementy ładniej wyglądały. 122

Rozdział 4. • Praca z formatem JSON

Korzystanie z danych w formacie JSON

Wybierz datę, aby zobaczyć szczegóły lotu





3. Teraz dopiszemy kod używający biblioteki jQuery. Po pierwsze tuż przed zamykającym znacznikiem body dodaj referencję do pliku biblioteki. Następnie dopisz własny kod, który przygotuje żądanie danych w formacie JSON przesłane do pliku json.php. W momencie otrzymania odpowiedzi lista rozwijana zostanie wypełniona i dołączona zostanie do niej funkcja obsługi zdarzenia change. Po wybraniu wartości z listy wywoływana jest kolejna funkcja, która poszuka w otrzymanej wcześniej odpowiedzi w formacie JSON wybranej daty i wyświetli pasujące do niej informacje.

4. Teraz przyjrzyjmy się plikowi obsługującemu żądanie. Utwórz zatem nowy plik i nadaj mu nazwę json.php. W pliku tym zapisz tablicę z informacjami o lotach oraz dane kilku podróżników, a następnie przekształć ją do formatu JSON i odeślij do przeglądarki.

5. I to już wszystko! Otwórz w przeglądarce plik index.html. Pojawi się wtedy lista wyboru, w której dostępnych będzie kilka dat. Wybierz jedną z nich, a zobaczysz dodatkowe informacje na temat wybranej opcji.

125

PHP i jQuery. Receptury

Jak to działa? Gdy struktura DOM dokumentu jest już gotowa, wywołujemy metodę getJSON(). Do tej pory poznaliśmy metody get() i post(). Tym razem korzystamy ze specjalizowanej metody używanej w przypadku, gdy chcemy pobrać z serwera dane w formacie JSON. Oto lista parametrów, jakie możemy przekazać funkcji getJSON(): Q URL — Adres URL, na który ma zostać wysłane żądanie. Q Dane — Dane, które mają zostać wysłane do serwera. Q Funkcja wywołania zwrotnego — Ta funkcja zostanie wywołana po odebraniu

odpowiedzi z serwera. W przypadku otrzymania danych JSON biblioteka jQuery najpierw je przeanalizuje i utworzy obiekt JavaScriptu, a następnie przekaże je do wskazanej w parametrze funkcji. W naszym przykładzie żądanie jest wysyłane do pliku json.php, w którym zadeklarowana została tablica z wieloma elementami. Następnie za pomocą metody json_encode() tablica ta przekształcana jest w ciąg znaków JSON i wysyłana do przeglądarki. W momencie otrzymania odpowiedzi biblioteka jQuery przekształca ją w obiekt i przekazuje do funkcji wywołania zwrotnego o nazwie displayData(). Otrzymany obiekt zapisywany jest w globalnej zmiennej jsonResult. Następnie iterujemy po tym obiekcie i wstawiamy do listy rozwijanej kolejne daty wylotów. Ze względu na to, że dane są teraz obiektem JavaScriptu, musimy stosować też składnię tego języka. Po wypełnieniu danymi listy rozwijanej dołączamy do niej funkcję obsługi zdarzenia change. W momencie wybrania wartości z listy wywołana zostanie zatem funkcja displayDetails(). Funkcja ta poszukuje w obiekcie wybranej przez użytkownika daty. Po jej znalezieniu odczytuje ona informacje o miejscu wylotu, przylotu oraz listę pasażerów. Wszystkie te dane są następnie wyświetlane na stronie.

I coś jeszcze Inne metody pozwalające na pobranie danych JSON Jak wspominałem już wcześniej, funkcja getJSON() została zaprojektowana do używania wyłącznie w sytuacji, w której z góry wiemy, że w odpowiedzi serwer przyśle nam dane w formacie JSON. Działanie tej funkcji można też symulować za pomocą innych metod biblioteki jQuery, takich jak get() lub post(), a nawet za pomocą niskopoziomowej funkcji ajax(). $.get( 'json.php',

126

Rozdział 4. • Praca z formatem JSON

displayData, 'json' );

Dzięki podaniu w ostatnim parametrze wartości json biblioteka jQuery będzie zakładała, że otrzymana od serwera odpowiedź jest ciągiem znaków JSON i spróbuje przekształcić go w obiekt. Podobne zachowanie można też zrealizować za pomocą funkcji post() i ajax().

Obsługa błędów podczas odbierania danych JSON Przedstawione powyżej sposoby pobierania danych wykorzystujące metody getJSON() lub get() nie pozwalają na samodzielną obsługę błędów. Na przykład, jeżeli żądaliśmy danych za pomocą metody getJSON(), a serwer prześle nam źle zbudowany ciąg znaków, to całe żądanie zostanie uznane w tle za nieudane. Istnieją zatem dwa sposoby radzenia sobie w takiej sytuacji. Albo skorzystamy z funkcji ajaxError(), która jest uruchamiana, w przypadku gdy w żądaniu AJAX powstaną jakieś błędy, albo użyjemy niskopoziomowej funkcji ajax(), która pozwala na wskazanie funkcji wywoływanej w przypadku wystąpienia błędu. Obie te funkcje zostały omówione dokładniej w recepturze „Obsługa błędów w żądaniach AJAX” w poprzednim rozdziale.

Parsowanie ciągu znaków w formacie JSON Oprócz używania funkcji getJSON() i podawania odpowiedniego typu danych w żądaniach AJAX możemy też samodzielnie parsować ciągi znaków JSON i przekształcać je w obiekty. Biblioteka jQuery udostępnia metodę parseJSON(), która przekształca ciąg znaków w obiekt języka JavaScript. var objJSON = jQuery.parseJSON('{"klucz":"wartość"}');

Od tego momentu w zmiennej objJSON zapisany jest obiekt JavaScriptu. Inną, niezalecaną, metodą jest wykorzystanie funkcji eval() udostępnianej przez język JavaScript. var objJSON = eval('(' + '{"klucz":"wartość"}' + ')')

Zastosowanie funkcji eval() może mieć fatalne skutki dla naszej strony, ponieważ funkcja ta wykona wszelkie przekazane jej dane. Oznacza to, że zalecanym sposobem jest używanie funkcji parseJSON() lub specjalnych metod biblioteki jQuery przeznaczonych do obsługi żądań AJAX.

Zobacz również Q Recepturę „Tworzenie danych w formacie JSON za pomocą PHP”. Q Recepturę „Pobieranie danych z PHP za pomocą jQuery” z rozdziału 2.

127

PHP i jQuery. Receptury

128

5 Praca z formularzami W tym rozdziale zajmiemy się: Q dynamicznym dodawaniem pól do formularza, Q wyszukiwaniem na stronie tekstu wprowadzonego przez użytkownika, Q szukaniem pustych pól za pomocą biblioteki jQuery, Q sprawdzaniem poprawności liczb za pomocą biblioteki jQuery, Q sprawdzaniem poprawności adresów e-mail i adresów WWW za pomocą wyrażeń Q Q Q Q

regularnych, wyświetlaniem błędów w czasie wprowadzania danych, czyli sprawdzaniem danych na żywo, mocniejszą kontrolą formularzy, czyli ponownym kontrolowaniem w PHP, tworzeniem systemu do głosowania, zezwalaniem na kod HTML w polach tekstowych i ograniczaniem zbioru dozwolonych znaczników.

Wprowadzenie Formularze i strony są jedyną częścią naszej aplikacji WWW, z których użytkownik korzysta w sposób bezpośredni. W związku z tym zadaniem twórców aplikacji jest przygotowanie formularzy tak, żeby były one łatwe w obsłudze i nawigacji oraz jak najbardziej interaktywne. Co więcej atakujący mogą próbować zaszkodzić naszej aplikacji przez wprowadzanie złośliwych danych do pól formularza. W tym rozdziale zajmiemy się formularzami oraz metodami kontroli formularzy, takimi jak szukanie danych zarówno po stronie klienta, jak i po stronie serwera. Co prawda formularz można skontrolować w przeglądarce za pomocą biblioteki jQuery, ale ponowna kontrola po stronie

PHP i jQuery. Receptury

serwera jest równie istotna. Jeżeli w przeglądarce wyłączona zostanie obsługa języka JavaScript, to wszystkie mechanizmy kontroli po stronie klienta staną się bezużyteczne. Po prostu kontrola formularzy w przeglądarce sprawia, że aplikacja staje się bardziej przyjazna użytkownikowi i mniej podatna na błędy. Nauczymy się tutaj zatem kontrolować w formularzach różne typy danych, takie jak puste pola, liczby, adresy e-mail lub adresy stron WWW i inne. Kontrola formularza po stronie serwera jest czymś absolutnie niezbędnym i nie można traktować kontroli po stronie klienta jako wygodnego zastępnika, ponieważ ta ostatnia może zostać bardzo łatwo wyłączona.

Dynamiczne dodawanie pól do formularza Przygotujemy tutaj formularz, w którym będziemy mogli dodawać kolejne pola bez konieczności odwoływania się do serwera. W naszym formularzu przedstawimy użytkownikowi jedno pole tekstowe oraz przyciski umożliwiające wstawianie i usuwanie kolejnych pól tekstowych.

Przygotowania W katalogu rozdzial5 utwórz nowy katalog dla tej receptury i nadaj mu nazwę receptura1. Nie zapomnij skopiować pliku jquery.js do utworzonego właśnie katalogu.

Jak to zrobić? 1. W katalogu receptura1 utwórz nowy plik o nazwie index.html i wpisz do niego kod, który będzie tworzyć listę o jednym tylko elemencie. Tym elementem będzie nasze jedyne pole tekstowe. Na koniec dodaj jeszcze przycisk umożliwiający dodawanie kolejnych pól tekstowych do naszego formularza.

Dynamiczne dodawanie pól



130

Rozdział 5. • Praca z formularzami

Codziennie odwiedzane witryny
  • Nazwa




2. Teraz dołącz plik biblioteki jQuery i dopisz funkcje obsługi zdarzeń. Pierwsza z nich będzie obsługiwać kliknięcia przycisku Dodaj kolejną i będzie dodawała do formularza nowe pole tekstowe razem z przyciskiem pozwalającym na jego usunięcie. W związku z tym druga funkcja będzie musiała zająć się usuwaniem wybranego pola tekstowego.

3. Uruchom teraz plik w przeglądarce. Kliknięcie przycisku Dodaj kolejną dodaje do strony nowe pole tekstowe. Można też usunąć dodatkowe pola tekstowe, klikając znajdujące się przy nich przyciski Usuń.

Jak to działa? Metoda obsługująca zdarzenie click przycisku Dodaj kolejną tworzy nowy element li zawierający pole tekstowe oraz przycisk Usuń, a następnie wywołuje metodę append() (udostępnianą przez bibliotekę jQuery), aby dodać go do istniejącej już listy. Proszę zauważyć, że przyciskowi Usuń zostaje przypisana klasa remove. Wcześniej użyliśmy już metody live(), aby podłączać funkcję obsługi zdarzenia click wszystkich elementów tej klasy. Jak pamiętamy, metoda ta dołącza funkcję obsługi zdarzenia do każdego istniejącego już elementu, a także do wszystkich tych elementów, które zostaną utworzone w przyszłości. Oznacza to, że kliknięcie przycisku Usuń spowoduje odszukanie nadrzędnego w stosunku do niego elementu li i usunięcie go ze struktury DOM.

I coś jeszcze Pobieranie wartości po stronie serwera Wszystkie te pola tekstowe generowane są po stronie klienta za pomocą biblioteki jQuery. Aby skorzystać z nich po stronie serwera, każde pole powinno otrzymać atrybut name. Ze względu na to,

132

Rozdział 5. • Praca z formularzami

że wszystkie należą do tej samej grupy (strony WWW), możemy zdefiniować wartości atrybutu name w postaci tablicy, dzięki czemu będziemy mogli odczytać wprowadzone wartości z tablicy. Wystarczy tylko dodać do istniejącego pola tekstowego, a także do wszystkich utworzonych później, atrybut name="sites[]". Teraz po przekazaniu formularza do serwera będziemy mogli odczytać wszystkie wartości z tablicy $_POST['sites']. Poniżej przedstawiam przykładową zawartość tablicy $_POST po przesłaniu formularza z kilkoma wypełnionymi polami. Array ( [sites] => Array ( [0] => Purpurowy [1] => Fioletowy [2] => Czerwony [3] => Zielony [4] => Żółty ) )

Wyszukiwanie na stronie tekstu wprowadzonego przez użytkownika Użyjemy tutaj biblioteki jQuery, aby wyróżnić słowo wprowadzone przez użytkownika. Dane wyświetlane w przeglądarce mogą być też udostępniane przez serwer, na przykład z bazy danych. W tym przykładzie umieścimy na stronie trochę tekstu. Użytkownik będzie wprowadzał do pola tekstowego zapytanie i po kliknięciu przycisku wyróżnione zostaną wszystkie słowa pasujące do tego zapytania.

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

Jak to zrobić? 1. Utwórz nowy plik, nazwij go index.html i zapisz w katalogu receptura2. Zaczniemy od przygotowania podstawowego kodu strony. Wprowadź kilka akapitów i wpisz do nich trochę tekstu. Na końcu przygotuj jeszcze pole tekstowe i dwa przyciski. Zdefiniuj dodatkowo klasę CSS highlight, której będziemy używać do wyróżniania tekstu.

133

PHP i jQuery. Receptury

Wyszukiwanie



Litwo! Ojczyzno moja! ty jesteś jak zdrowie: Ile cię trzeba cenić, ten tylko się dowie, Kto cię stracił. Dziś piękność twą w całej ozdobie Widzę i opisuję, bo tęsknię po tobie.

Panno święta, co Jasnej bronisz Częstochowy I w Ostrej świecisz Bramie! Ty, co gród zamkowy Nowogródzki ochraniasz z jego wiernym ludem! Jak mnie dziecko do zdrowia powróciłaś cudem (Gdy od płaczącej matki, pod Twoją opiekę Ofiarowany, martwą podniosłem powiekę; I zaraz mogłem pieszo, do Twych świątyń progu Iść za wrócone życie podziękować Bogu), Tak nas powrócisz cudem na Ojczyzny łono. Tymczasem przenoś moją duszę utęsknioną Do tych pagórków leśnych, do tych łąk zielonych, Szeroko nad błękitnym Niemnem rozciągnionych; Do tych pól malowanych zbożem rozmaitem, Wyzłacanych pszenicą, posrebrzanych żytem; Gdzie bursztynowy świerzop, gryka jak śnieg biała, Gdzie panieńskim rumieńcem dzięcielina pała, A wszystko przepasane jakby wstęgą, miedzą Zieloną, na niej z rzadka ciche grusze siedzą.

Śród takich pól przed laty, nad brzegiem ruczaju, Na pagórku niewielkim, we brzozowym gaju, Stał dwór szlachecki, z drzewa, lecz podmurowany; Świeciły się z daleka pobielane ściany, Tym bielsze, że odbite od ciemnej zieleni Topoli, co go bronią od wiatrów jesieni. Dom mieszkalny niewielki, lecz zewsząd chędogi, I stodołę miał wielką, i przy niej trzy stogi Użątku, co pod strzechą zmieścić się nie może. Widać, że okolica obfita we zboże, I widać z liczby kopic, co wzdłuż i wszerz smugów

134

Rozdział 5. • Praca z formularzami

Świecą gęsto jak gwiazdy, widać z liczby pługów Orzących wcześnie łany ogromne ugoru, Czarnoziemne, zapewne należne do dworu, Uprawne dobrze na kształt ogrodowych grządek: Że w tym domu dostatek mieszka i porządek. Brama na wciąż otwarta przechodniom ogłasza, Że gościnna, i wszystkich w gościnę zaprasza.







2. Przed zamykającym znacznikiem body dołącz plik biblioteki jQuery. Na formularzu umieściliśmy dwa przyciski, przy czym pierwszy z nich będzie uruchamiał procedurę szukania wprowadzonego tekstu, a drugi będzie usuwał podświetlenie z tekstu. Aby uruchomić szukanie, klikamy przycisk Szukaj i tym samym wywołujemy funkcję highlight(). Funkcja ta wyszukuje na stronie podany tekst i w przypadku znalezienia go umieszcza wokół niego znaczniki HTML, dołączając do nich klasę highlight. Drugi z przycisków wywołuje funkcję clearSelection(), która przywraca stronę do pierwotnej postaci.

3. Uruchom w przeglądarce plik index.html i wprowadź do pola tekstowego jakieś słowo. Kliknij przycisk Szukaj, a wszystkie słowa pasujące do wprowadzonego wzorca zostaną wyróżnione. Kliknięcie przycisku Wyczyść przywróci stronę do pierwotnego stanu.

Jak to działa? Po wprowadzeniu tekstu do pola tekstowego i kliknięciu przycisku Szukaj wywoływana jest funkcja highlight(). W pierwszej kolejności usuwa ona wszystkie istniejące wyróżnienia, wywołując w tym celu funkcję clearSelection(). W kolejnym kroku wprowadzona w polu tekstowym fraza wyszukiwania zapisywana jest w zmiennej searchText. Następnie tworzony jest obiekt na podstawie dostępnej w języku JavaScript klasy RegExp. To właśnie to wyrażenie regularne zajmie się faktycznym wyszukiwaniem tekstu na stronie.

136

Rozdział 5. • Praca z formularzami

Teraz iterujemy po wszystkich akapitach znajdujących się na stronie. Pobieramy kod HTML każdego z nich i wywołujemy funkcję replace(), która pobiera dwa parametry. Pierwszym z nich jest obiekt wyrażenia regularnego, a drugim tekst, który ma zastąpić fragmenty pasujące do wyrażenia. W tym przypadku umieszczamy po prostu wyszukiwany tekst w elemencie span, któremu przypisana została klasa highlight. Funkcja replace() zwraca całość tekstu z wprowadzonymi już do niego poprawkami, dlatego w ostatnim kroku musimy tylko podmienić oryginalny kod HTML akapitu.

I coś jeszcze Wyszukaj i zamień Rozbudowując przedstawiony tu mechanizm, można przygotować proste narzędzie do wyszukiwania i podmiany tekstu. Zamiast wyróżniać znaleziony tekst możemy wstawić w jego miejsce inny tekst.

Szukanie pustych pól za pomocą biblioteki jQuery Kontrola danych to bardzo ważny element skryptów działających po stronie klienta. Kontrola wykonywana po stronie klienta może znacząco zmniejszyć liczbę odwołań do serwera, prezentując użytkownikowi natychmiastowe informacje o danych w formularzu. Mimo tego nie zaleca się korzystania wyłącznie z kontroli po stronie klienta. Użytkownicy mogą wyłączyć w przeglądarce obsługę języka JavaScript, dlatego dane powinny być zawsze kontrolowane ponownie po stronie serwera.

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

Jak to zrobić? 1. W katalogu receptura3 utwórz nowy plik i nazwij go index.html. W pliku tym przygotuj kilka pól tekstowych oraz przycisk typu input. Pamiętaj, że wszystkie pola tekstowe, z wyjątkiem pola city, muszą otrzymać klasę required. Będziemy z niej korzystać podczas kontrolowania zawartości formularza.

137

PHP i jQuery. Receptury

Kontrola pustych pól



Dane osobowe



Nazwisko:*
Adres:*
Miasto:
Kraj:*








2. Przed zamykającym znacznikiem body dołącz jeszcze plik biblioteki jQuery. Dopisz też kod sprawdzający i dołącz funkcję obsługującą zdarzenie click do przycisku. Funkcja validate() zostanie wywołana w momencie kliknięcia przycisku i sprawdzi, czy w polach tekstowych znajdują się jakieś wartości.

3. Uruchom w przeglądarce plik index.html. Nie wypełniaj pól tekstowych i od razu kliknij przycisk Sprawdź. Przy każdym wymaganym polu pojawi się komunikat o błędzie.

Po wprowadzeniu niezbędnych informacji do formularza ponownie kliknij przycisk Sprawdź. Tym razem ponad przyciskiem pojawi się zielony komunikat informujący o tym, że wszystkie dane w formularzu są poprawne.

139

PHP i jQuery. Receptury

Jak to działa? Na początek przypisujemy klasę required do każdego pola tekstowego, które uznajemy za wymagane. Dzięki temu będziemy mogli użyć selektora biblioteki jQuery, aby potem odszukać te pola. Najpierw do przycisku Sprawdź dołączamy funkcję obsługującą zdarzenie click, w ramach której wywołujemy tylko funkcję validate(). W tej funkcji na początek deklarowana jest zmienna dataValid i nadawana jest jej wartość true. Następnie wybierane są z formularza wszystkie pola tekstowe z przypisaną klasą required. W kolejnym kroku iterujemy po tej kolekcji i usuwamy ewentualne elementy span umieszczone obok pola tekstowego, które mogą być pozostałością nieaktualnych już komunikatów o błędach. Jeżeli nie usunęlibyśmy ich, to przy jednym polu tekstowym mogłoby się pojawić kilka komunikatów. Po tym wszystkim instrukcja if sprawdza wartość aktualnego pola tekstowego. Proszę zauważyć, że skorzystaliśmy tutaj z funkcji trim() udostępnianej przez bibliotekę jQuery. Ze względu na to, że znaki białe nie są uznawane za prawidłowe wartości, musimy je usunąć z pola tekstowego. Jeżeli w polu znajduje się pusta wartość, to umieszczamy przy nim element span z komunikatem o błędzie, a zmiennej dataValid przypisujemy wartość false. Po przejrzeniu wszystkich pól tekstowych sprawdzamy wartość zmiennej dataValid. Jeżeli nadal ma wartość true, to znaczy, że w każdym wymaganym polu wprowadzony został jakiś tekst i możemy wyświetlić na ekranie informację o poprawnej zawartości formularza.

140

Rozdział 5. • Praca z formularzami

I coś jeszcze Kontrolowanie pojedynczych pól Jeżeli nie chcielibyśmy wyświetlać wszystkich komunikatów naraz, ale nakazać użytkownikowi wypełnienie jednego pola i przejście do kolejnego, to należałoby zmodyfikować przedstawiony powyżej kod. W tym celu zmień instrukcję if, tak jak pokazano poniżej: if ($.trim(cur.val()) == '') { cur.after('To pole jest wymagane'); dataValid = false; }

Następnie usuń jeszcze tę instrukcję: if(dataValid) { $('#info').html('Formularz poprawny'); }

Zobacz też Q Recepturę „Sprawdzanie poprawności liczb za pomocą biblioteki jQuery”. Q Recepturę „Sprawdzanie poprawności adresów e-mail i adresów WWW za pomocą

wyrażeń regularnych”. Q Recepturę „Wyświetlanie błędów w czasie wprowadzania danych, czyli sprawdzanie danych na żywo”.

Sprawdzanie poprawności liczb za pomocą biblioteki jQuery W poprzedniej recepturze sprawdzaliśmy, czy w formularzu znajdują się niewypełnione pola. Tym razem rozbudujemy ten mechanizm kontrolny i oprócz wymogu wprowadzenia danych do pola będziemy sprawdzać, czy wprowadzona została liczba.

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

141

PHP i jQuery. Receptury

Jak to zrobić? 1. W katalogu receptura4 utwórz nowy plik i nazwij go index.html. Wykorzystamy tutaj ten sam kod, którego użyliśmy w poprzedniej recepturze, ale dodamy do niego nowe elementy. Możesz zatem skopiować cały kod z poprzedniej receptury do pliku index.html. Teraz dodamy do niego nowe pola, w których użytkownik będzie mógł wprowadzić liczby. Utwórz zatem kolejną tabelę z opisem Inne dane. Trzeba tu nadmienić, że pola tekstowe w tej tabeli muszą zostać przypisane do klas numeric i required. Dzięki temu będziemy mogli sprawdzić, czy pola nie są puste i czy wpisano do nich liczbę.

Inne dane



Wiek:*
Miesięczne wydatki:*


142

Rozdział 5. • Praca z formularzami

2. Przejdźmy teraz do kodu JavaScript. Ponownie dołącz plik biblioteki jQuery i dopisz kod sprawdzający poprawność danych w formularzu. Tym razem kliknięcie przycisku najpierw uruchomi procedurę sprawdzania, czy pola nie są puste. Jeżeli takie zostaną znalezione, to wyświetlane są odpowiednie komunikaty, a funkcja kończy pracę. Gdy tylko wszystkie wymagane pola zostaną wypełnione, funkcja zacznie dodatkowo sprawdzać zawartość tych, w których mają znaleźć się tylko liczby. Poniżej przedstawiam pełny kod kontrolujący formularz:

143

PHP i jQuery. Receptury

Jak to działa? W podanym tu kodzie najpierw sprawdzamy, czy wszystkie pola zostały wypełnione, iterując po elementach klasy required. Po zakończeniu tej pętli sprawdzamy wartość zmiennej dataValid. Jeżeli ma ona wartość false, to natychmiast kończymy działanie funkcji. Jeżeli jednak wszystkie wymagane pola zostały wypełnione, to przechodzimy do sprawdzania pól liczbowych. Wybieramy zatem wszystkie elementy, którym przypisano klasę number, i za pomocą metody each() kontrolujemy zawartość tych elementów. Funkcja isNaN() języka JavaScript pozwala na stwierdzenie, czy podana jej wartość jest liczbą czy też nie. Jeżeli wartość z danego pola nie jest liczbą, to wstawiamy przy tym polu odpowiedni komunikat. Jeżeli wszystkie pola poprawnie przejdą wszystkie etapy kontroli formularza, to nad przyciskiem Sprawdź wyświetlany jest komunikat Formularz poprawny.

Zobacz też Q Recepturę „Szukanie pustych pól za pomocą biblioteki jQuery”. Q Recepturę „Sprawdzanie poprawności adresów e-mail i adresów WWW za pomocą

wyrażeń regularnych”. Q Recepturę „Wyświetlanie błędów w czasie wprowadzania danych, czyli sprawdzanie danych na żywo”.

Sprawdzanie poprawności adresów e-mail i adresów WWW za pomocą wyrażeń regularnych Podczas wypełniania formularzy w internecie bardzo często jesteśmy proszeni o podanie adresu e-mail lub adresu strony WWW. Te dwie wartości troszkę różnią się od zwyczajnych ciągów znaków, ponieważ charakteryzują się określonym wzorcem. Na przykład w adresach e-mail musi znaleźć się znak ampersand (@), natomiast adresy stron WWW zwykle zaczynają się od przedrostka http:// lub https://. Dla takich adresów można też zdefiniować wiele innych warunków. Tutaj na pomoc przychodzą nam wyrażenia regularne. W tej recepturze nauczymy się używać wyrażeń regularnych do sprawdzania poprawności takich wzorców, jak adresy e-mail lub adresy URL.

144

Rozdział 5. • Praca z formularzami

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

Jak to zrobić? 1. W katalogu receptura5 utwórz nowy plik o nazwie index.html. Podobnie jak w poprzedniej recepturze, utwórz w nim dwa pola tekstowe. W jedno z nich wprowadzany będzie adres e-mail, a w drugie adres strony WWW. Oprócz tego pierwszemu polu przypisz klasę mail, a drugiemu klasę site.

Sprawdzanie adresu e-mail



Dane kontaktowe - oba pola są wymagane



E-mail:
Strona WWW:
(z przedrostkiem http://)








145

PHP i jQuery. Receptury

2. W ramach realizowania funkcji kontroli formularza najpierw dołącz plik biblioteki jQuery. Następnie dopisz funkcję obsługi zdarzenia click w przycisku Sprawdź. W pierwszej kolejności funkcja ta wyszuka wszystkie elementy klasy mail i skontroluje znajdujący się w niej tekst, wykorzystując do tego wyrażenie regularne. Następnie sprawdzone zostaną adresy stron WWW. Tym razem również użyte zostanie odpowiednie wyrażenie regularne. Jeżeli tekst z pola nie będzie pasował do wyrażenia sprawdzającego, to przy polu pojawi się komunikat.

Jak to działa? Po kliknięciu przycisku Sprawdź wywoływana jest funkcja validate(). W funkcji tej najpierw definiowana jest zmienna dataValid i przypisywana jest jej wartość true. Następnie pobierane są wszystkie pola tekstowe klasy mail i zaczynamy iterować po takiej kolekcji. Deklarujemy tu zmienną emailPattern, w której zapisywane jest wyrażenie regularne. Teraz wewnątrz instrukcji if używamy funkcji test(), aby porównać zawartość pola tekstowego z wyrażeniem regularnym. Jeżeli pole nie pasuje do wzorca, to obok pola tekstowego umieszczamy komunikat i nadajemy zmiennej dataValid wartość false. Tę samą procedurę powtarzamy jeszcze dla elementów klasy site. W tym przypadku stosujemy jednak nieco inne wyrażenie regularne. Jeżeli formularz pomyślnie przejdzie wszystkie etapy kontroli, to nad przyciskiem wyświetlamy tekst Formularz poprawny.

I coś jeszcze Wyrażenie regularne Więcej informacji na temat wyrażeń regularnych znaleźć można pod podanymi niżej adresami: Q http://www.regular-expressions.info/ Q http://pl.wikipedia.org/wiki/Wyrażenie_regularne

147

PHP i jQuery. Receptury

Zobacz też Q Recepturę „Szukanie pustych pól za pomocą biblioteki jQuery”. Q Recepturę „Sprawdzanie poprawności liczb za pomocą biblioteki jQuery”.

Wyświetlanie błędów w czasie wprowadzania danych, czyli sprawdzanie danych na żywo Czy nie byłoby lepiej, gdybyśmy mogli kontrolować dane wprowadzane przez użytkownika wtedy, gdy on je wprowadza? Nie musielibyśmy czekać na kliknięcie przycisku, komunikaty byłyby też znacznie czytelniejsze. W tej recepturze mocno rozbudujemy przykłady z poprzednich receptur i nauczymy się na żywo kontrolować poprawność danych w formularzu. Dzięki temu użytkownik będzie otrzymywał informacje w trakcie wprowadzania danych do pola tekstowego.

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

Jak to zrobić? 1. W katalogu receptura6 utwórz nowy plik i nazwij go index.html. Zapisz do niego kod HTML tworzący dwa panele: jeden dla Danych osobowych, a drugi dla Innych. Pola tekstowe z pierwszego panelu zostaną związane z klasą required. Podobnie pola z drugiego panelu otrzymają klasy required i number.

Kontrola formularza na żywo



148

Rozdział 5. • Praca z formularzami



Dane osobiste



Nazwisko:*
Adres:*
Kraj:*


Inne dane



Wiek:*
Miesięczne wydatki:*







2. Teraz dołącz plik biblioteki jQuery. Następnie dodaj do pól tekstowych funkcję obsługi zdarzenia, która zostanie wywołana, gdy w danym polu pojawi się kursor albo zostanie w nim puszczony klawisz. Nasz kod będzie wykonywany, w czasie gdy użytkownik będzie wpisywał dane, a ewentualne komunikaty będą się

149

PHP i jQuery. Receptury

pojawiały, w przypadku gdy użytkownik popełni błąd. Na koniec potrzebna będzie jeszcze funkcja obsługująca kliknięcia przycisku Zapisz, tak żeby użytkownik mógł go kliknąć przed wprowadzeniem do formularza jakichkolwiek danych.

Ekran ze źle wprowadzonymi danymi powinien wyglądać podobnie do poniższego rysunku.

Jak to działa? Ze względu na to, że chcemy na bieżąco kontrolować dane wprowadzane do formularza przez użytkownika, musimy podłączyć do pól tekstowych funkcje obsługujące dwa zdarzenia: focus i keyup. Pierwsze z nich wywoływane jest w momencie, gdy użytkownik umieści kursor w polu tekstowym (klikając je myszą albo naciskając klawisz Tab), a drugie w momencie puszczenia klawisza. W obu przypadkach wywoływana jest funkcja validate(). W ten sposób możemy natychmiast kontrolować wartość wprowadzaną do pola tekstowego.

151

PHP i jQuery. Receptury

Funkcja validate() wykonuje te same działania, które widzieliśmy już w kilku poprzednich recepturach. Pobierze wartość z pola tekstowego i w zależności od klasy, jaką przypisano temu polu, sprawdzi, czy pole nie jest puste albo czy wprowadzono do niego liczbę. Mamy tu jednak pewien problem. Jeżeli użytkownik kliknie przycisk Zapisz bez uprzedniego wypełnienia danych w formularzu, to nie dowie się, że formularz ten jest nieprawidłowy. Aby zapobiec takiej sytuacji, musimy przedsięwziąć odpowiednie kroki. Po pierwsze w ramach funkcji validate() każdemu polu tekstowemu przypisujemy wartość true lub false. Wykorzystujemy tutaj metodę data() biblioteki jQuery, która pozwala na zapisywanie dodatkowych informacji w elementach DOM. Podczas kontrolowania pola tekstowego zapisujemy do niego wartość z kluczem valid, przypisując mu jednocześnie wartość true lub false. Do przycisku Zapisz również przypinamy funkcję obsługi zdarzenia click. Załóżmy teraz, że użytkownik kliknął ten przycisk, nie wprowadzając wcześniej danych do pól tekstowych. Pobieramy wtedy wszystkie te pola i sprawdzamy, czy została z nimi związana jakaś wartość. Interesuje nas klucz o nazwie valid i przypisana mu wartość true. Jeżeli nie znajdziemy takiej kombinacji, to znaczy, że dane pole nie przeszło wcześniejszej kontroli, a wtedy zmiennej dataValid przypisujemy wartość false. Tę samą procedurę powtarzamy dla pól tekstowych klasy number. Na koniec wyświetlamy jeszcze komunikat odpowiedni do wartości zmiennej dataValid.

Zobacz też Q Recepturę „Szukanie pustych pól za pomocą biblioteki jQuery”. Q Recepturę „Sprawdzanie poprawności liczb za pomocą biblioteki jQuery”. Q Recepturę „Sprawdzanie poprawności adresów e-mail i adresów WWW za pomocą

wyrażeń regularnych”. Q Recepturę „Mocniejsza kontrola formularza, czyli ponowne kontrolowanie w PHP”.

Mocniejsza kontrola formularza, czyli ponowne kontrolowanie w PHP Jak już wcześniej wspominałem, kontrola formularzy po stronie klienta powinna być zawsze powiązana z podobnym mechanizmem kontroli po stronie serwera. Jeżeli użytkownik wyłączy w przeglądarce obsługę języka JavaScript, a nie będziemy mieli kontroli po stronie serwera, to będzie mógł wprowadzić do formularza absolutnie dowolne dane. Może to prowadzić do tragicznych efektów, takich jak utrata bazy danych itp.

152

Rozdział 5. • Praca z formularzami

W tej recepturze przyjrzymy się metodom kontroli oraz funkcjom dostępnym w języku PHP, które możemy wykorzystać do sprawdzenia poprawności danych w formularzu.

Przygotowania W katalogu rozdzial5 utwórz nowy katalog o nazwie receptura7. Upewnij się, że korzystasz z interpretera PHP w wersji wyższej niż 5.2. Będziemy tu używać funkcji filtrujących, które dostępne są dopiero od wersji 5.2.

Jak to zrobić? 1. W katalogu receptura7 utwórz plik o nazwie index.php. Przygotuj w nim formularz z różnymi polami przeznaczonymi do wprowadzania ciągów znaków, liczb, adresów e-mail i adresów stron WWW.

Kontrola formularza po stronie serwera



Formularz informacyjny (Wszystkie pola są wymagane)



153

PHP i jQuery. Receptury



Nazwisko:
Adres:
Wiek:
Adres e-mail:
Adres strony WWW:







Formularz powinien wyglądać podobnie do przedstawionego poniżej:

2. Po przesłaniu formularza na serwer uruchamiany jest plik index.php. Oznacza to, że procedury kontrolne musimy umieścić na samym początku tego pliku. Poniżej prezentuję kod PHP, który należy wstawić na sam początek pliku. Sprawdza on wszystkie pola formularza i w przypadku znalezienia jakiegoś błędu umieszcza komunikat w specjalnej tablicy.





2. Teraz utwórz kolejny plik i nazwij go index.php. Odczytamy w nim zawartość pliku XML i zaprezentujemy użytkownikowi listę przeglądarek, na które może oddać głos. W tym samym pliku umieścimy też kod zajmujący się przesyłaniem formularza na serwer. Oprócz tego ograniczymy możliwość głosowania do jednego głosu dziennie.







Wybierz swoją ulubioną przeglądarkę


  • LUB ´Zobacz wyniki




3. Uruchom plik index.php w przeglądarce, a zobaczysz na stronie kilka opcji do wyboru oraz przycisk Głosuj, taki jak na poniższym rysunku.

4. Na powyższej stronie znajdziemy też łącze do strony z wynikami głosowania. Aby przygotować tę stronę, utwórz nowy plik i nazwij go results.php. Kod z tego pliku załaduje plik XML i wyświetli w przeglądarce aktualne wyniki głosowania.

Wyniki głosowania

160

Rozdział 5. • Praca z formularzami



Wyniki głosowania



5. Wszystko jest już gotowe i możemy sprawdzić działanie naszego przykładu. Uruchom zatem plik index.php w przeglądarce, aby zobaczyć formularz. Wybierz ostatnią opcję i kliknij przycisk Głosuj. Pojawi się wtedy komunikat Twój głos został zapisany. Następnie wybierz inną przeglądarkę i jeszcze raz kliknij przycisk Głosuj. Tym razem pojawi się komunikat Twój głos został już przyjęty. Można glosować tylko raz dziennie. 6. Teraz kliknij przycisk Zobacz wyniki. Otwarta zostanie nowa strona, na której będziemy mogli zobaczyć liczbę głosów oddanych na każdą z przeglądarek. Oddany wcześniej głos zwiększył liczbę głosów na IE z 30 do 31.

161

PHP i jQuery. Receptury

Jak to działa? Na początek przyjrzyjmy się strukturze pliku browsers.xml. W tym pliku zapisane są trzy węzły przeglądarek, po jednym dla każdej z nich. Każdy z tych węzłów ma trzy atrybuty: name, value i votes. Wartość atrybutu name będzie wyświetlana na stronach, atrybut value używany jest w skryptach PHP, natomiast atrybut votes przechowuje liczbę głosów oddanych na daną przeglądarkę. Przejdźmy teraz do pliku index.php, w którym najpierw zajmiemy się kodem HTML. Za pomocą klasy DOMDocument ładujemy plik XML i na podstawie jego zawartości tworzymy listę wypunktowaną. Dla każdej przeglądarki tworzony jest jeden przycisk opcji. Na koniec tworzymy jeszcze przycisk Głosuj oraz łącze do strony z wynikami. A teraz podsumowanie operacji, jakie wykonywane są po przesłaniu formularza na serwer. Q Sprawdzamy, czy użytkownik już wcześniej oddał głos. W tym celu przyglądamy się superglobalnej zmiennej $_COOKIE. Jeżeli w ciasteczku zapisana jest już informacja

o głosowaniu, to musimy tylko wyświetlić komunikat o błędzie. Q Jeżeli użytkownik jeszcze nie głosował, to w pliku XML dodajemy jeden głos do

węzła wybranej przeglądarki. Q Aby dodać głos oddany na wybraną przeglądarkę, ładujemy dokument XML za pomocą klasy DOMDocument. Q Następnie przeszukujemy wszystkie węzły browser i porównujemy wartość atrybutu value z wartością wybraną przez użytkownika, którą odczytujemy z tablicy $_POST['browser']. Q Po znalezieniu właściwego węzła zwiększamy wartość jego atrybutu votes o jeden. Q W kolejnym kroku tworzymy ciasteczko o nazwie voted, które od teraz będzie

przechowywane przez przeglądarkę użytkownika. Wykorzystujemy do tego funkcję języka PHP setcookie(), która tworzy ciasteczko i ustala jego czas ważności na 24 godziny. W ten sposób użytkownik nie będzie mógł zagłosować częściej niż raz na dzień. Q Na zakończenie zapisujemy plik XML za pomocą metody save() z rozszerzenia DOM. Plik results.php generuje stronę wyników, ładując plik XML za pomocą klasy DOMDocument i iterując po węzłach browser, i tworząc jednocześnie listę wypunktowaną. Dla każdej przeglądarki tworzone są dwa elementy. W pierwszy element li wpisujemy nazwę przeglądarki oraz liczbę oddanych na nią głosów. W drugi element li wstawiamy element span, nadając mu szerokość w pikselach równą liczbie głosów oddanych na przeglądarkę. W ten sposób powstaje efekt słupka wykresu.

162

Rozdział 5. • Praca z formularzami

I coś jeszcze Czas życia ciasteczka W naszym przykładzie tworzyliśmy ciasteczka, które przedawniały się po jednym dniu. To ustawienie można oczywiście zmieniać zgodnie z własnymi potrzebami. Trzeba tylko pamiętać, że czas wygaśnięcia ciasteczka definiowany jest jako uniksowy znacznik czasu, dlatego trzeba podawać go w sekundach.

Zobacz też Q Recepturę „Odczytywanie dokumentów XML za pomocą rozszerzenia DOM”

z rozdziału 3. Q Recepturę „Modyfikowanie dokumentów XML za pomocą rozszerzenia DOM” z rozdziału 3.

Zezwalanie na kod HTML w polach tekstowych i ograniczanie zbioru dozwolonych znaczników Pozwalając użytkownikowi na wypełnianie formularza, możemy chcieć ograniczyć zbiór znaczników HTML, jakie będą dozwolone we wprowadzanych danych. Do niechcianych znaczników można na przykład dodać znacznik script, ponieważ może on źle wpłynąć na działanie naszej strony oraz na nasze dane. W tej recepturze nauczymy się filtrować znaczniki z danych otrzymanych z formularza i przyjmować tylko określony zbiór znaczników.

Przygotowania W katalogu rozdzial5 utwórz nowy katalog o nazwie receptura9.

163

PHP i jQuery. Receptury

Jak to zrobić? 1. W katalogu receptura9 utwórz nowy plik o nazwie index.html. W pliku tym utwórz dwa elementy typu textarea oraz jeden przycisk. W pierwszym polu tekstowym użytkownik będzie mógł wprowadzić tekst w formacie HTML. W drugim będziemy wyświetlać ten sam tekst po usunięciu z niego niedozwolonych znaczników.

Usuwanie znaczników



Wpisz poniżej tekst ze znacznikami HTML
(Dozwolone są tylko znaczniki
,,< i> oraz .
Wszystkie inne znaczniki zostaną usunięte):


Tak będzie wyglądał twój kod HTML:





2. Dołącz plik biblioteki jQuery, a następnie dodaj funkcję obsługi zdarzenia click przycisku Sprawdź. Kliknięcie tego przycisku wyśle dane z pierwszego pola tekstowego do skryptu PHP validate.php. W momencie otrzymania odpowiedzi wpiszemy ją do drugiego pola tekstowego.

3. Utwórz kolejny plik i nazwij go validate.php. Wpisz do niego kod usuwający niedozwolone znaczniki HTML z danych wprowadzonych przez użytkownika i wyślij wyniki tej pracy do przeglądarki.

4. Teraz otwórz w przeglądarce plik index.html i wpisz do pierwszego pola tekstowego nieco tekstu ze znacznikami HTML. Po kliknięciu przycisku Sprawdź w drugim polu pojawi się ten sam tekst z usuniętymi niedozwolonymi znacznikami.

165

PHP i jQuery. Receptury

Jak to działa? Po kliknięciu przycisku Sprawdź żądanie AJAX wysyłane jest do pliku validate.php. I tutaj wykonywana jest główna praca. Otrzymane dane pobierane są z tablicy $_POST. Następnie wywołujemy funkcję PHP strip_tags(), która usuwa z podanego jej ciągu znaków wszystkie znaczniki HTML. W pierwszym parametrze trzeba jej przekazać ciąg znaków, z którego chcemy usunąć znaczniki. Drugi parametr jest opcjonalny. Jeżeli nie zostanie przekazany do funkcji, to usunie ona z tekstu wszystkie znalezione znaczniki. W naszym przykładzie chcemy jednak zezwolić na stosowanie czterech znaczników: , , oraz , a zatem musimy podać je funkcji w drugim parametrze. W takiej sytuacji funkcja usunie z tekstu wszystkie znaczniki HTML z wyjątkiem tych czterech. Zwraca ona ciąg znaków, który możemy teraz bezpiecznie zapisać do bazy danych albo wykonać na nim kolejne operacje. W naszym przykładzie odsyłamy tekst do przeglądarki, aby użytkownik mógł sprawdzić, jak będzie on wyglądać. W samej przeglądarce biblioteka jQuery wstawi otrzymany tekst do drugiego pola tekstowego.

I coś jeszcze Usuwane są też znaczniki PHP Automatycznie usuwane są również komentarze HTML oraz znaczniki PHP.

166

6 Efekty specjalne w formularzach W tym rozdziale zajmiemy się: Q tworzeniem gry w kółko i krzyżyk, Q informowaniem użytkownika o przetwarzaniu żądania AJAX, Q tworzeniem rozwijanych i zwijanych ramek (harmonijek), Q stopniowym ukrywaniem elementu po jego zaktualizowaniu, Q wyświetlaniem pływającego okienka na żądanie, Q aktualizowaniem pozycji w koszyku na zakupy.

Wprowadzenie Właściwe zastosowanie na stronach WWW biblioteki jQuery może wprowadzić do nich niezwykłe efekty oraz spowodować poprawę interakcji z użytkownikiem. Istnieje wiele wtyczek do tej biblioteki, które udostępniają wiele narzędzi i gadżetów prezentowanych w tym rozdziale. W wielu przypadkach niestety wtyczki te próbują oferować tak wiele, że pojawiają się w nich zupełnie bezużyteczne funkcje.

PHP i jQuery. Receptury

W tym rozdziale zajmiemy się tworzeniem różnych gadżetów, takich jak harmonijki, pływające elementy div oraz znikające żółte tło, które są często wykorzystywane w dzisiejszych aplikacjach. Efekty te będziemy tworzyć najprostszymi metodami i za pomocą minimalnej ilości kodu.

Tworzenie gry w kółko i krzyżyk Formularze WWW powinny być jak najbardziej przyjazne użytkownikom, tak żeby ułatwiać im pracę. Oznacza to, że użytkownik nie powinien mieć kłopotów z określeniem, co do czego służy na stronie. W tej recepturze przygotujemy prostą grę w kółko i krzyżyk. Każdy z pewnością grał już w tę grę w dzieciństwie, a teraz wykorzystamy ją jako doskonały przykład tego, jak można wyróżniać poszczególne części strony, aby poinformować użytkownika, gdzie może dalej współpracować ze stroną. Będziemy tworzyć grę dla dwóch graczy, którym zaprezentujemy planszę o wielkości 3×3 lub 5×5 pól, zależnie od dokonanego wcześniej wyboru. Umieszczenie wskaźnika myszy nad polem planszy spowoduje wyróżnienie go, a kliknięciem będzie można umieścić w tym polu kółko lub krzyżyk, zależnie od tego, który gracz wykonuje ruch. Po wykonaniu każdego ruchu będziemy zmieniać gracza i sprawdzać, czy któryś z nich już nie wygrał.

Przygotowania W katalogu rozdzial6 utwórz nowy katalog o nazwie receptura1. Na potrzeby tej receptury będziemy potrzebowali dwóch obrazków: jednego z krzyżykiem i jednego z kółkiem, zgodnie z zasadami gry. Za pomocą dowolnego prostego programu graficznego przygotuj zatem oba obrazki. W swoim przykładzie zastosowałem poniższe:

Jak to zrobić? 1. Najpierw w katalogu receptura1 utwórz plik o nazwie main.css. W pliku tym umieścimy style CSS definiujące wygląd naszej gry. body{color:#FA6766;font-family:Trebuchet MS,arial,verdana;margin:20px; ´padding:0pt;}

168

Rozdział 6. • Efekty specjalne w formularzach

h3{margin:0pt:padding:0pt;} div{float:left;} #table{ width:100%; } .row {width:100%;} .col {width:75px;float:left;height:75px;cursor:pointer;} .hr{ border-right:2px solid #FA6766;} .vr{ border-bottom:2px solid #FA6766;} .cross{background-image:url(cross.png);} .round{background-image:url(round.png);} #log{clear:both;margin:0pt;padding:0pt;} .reset{cursor:pointer;display:none;text-decoration:underline;}

2. Po zdefiniowaniu stylów utwórz kolejny plik w tym samym katalogu i nazwij go index.html. W tym pliku dołącz oczywiście plik main.css, a następnie utwórz listę rozwijaną, z której użytkownik będzie mógł wybrać wielkość pola gry (3×3 lub 5×5). Potem dopisz dwa elementy h2. Pierwszy z nich posłuży nam do wyświetlania danych gracza wykonującego ruch, a drugi pozwoli rozpocząć nową grę po zakończeniu poprzedniej. Na koniec utwórz jeszcze element div o identyfikatorze container, w którym znajdzie się plansza do gry. Tę najlepiej będzie przygotować za pomocą biblioteki jQuery. 3. W ostatnim kroku dodaj jeszcze referencję pliku biblioteki jQuery. Sam kod JavaScript będzie troszkę przydługawy, dlatego zapiszemy go w osobnym pliku o nazwie tictactoe.js. Oczywiście nie można też zapomnieć o dodaniu odwołania do tego pliku.

Kółko i krzyżyk



Wielkość planszy:

3 * 3 5 * 5

 

Czekam na gracza numer 1 Od nowa

 





169

PHP i jQuery. Receptury

4. Teraz w katalogu receptura1 utwórz plik tictactoe.js. Tutaj zdefiniujemy osobną przestrzeń nazw game, w której umieścimy wszystkie nasze zmienne i funkcje. Kod zapisany w tym pliku musi między innymi definiować funkcję createGrid(), która będzie tworzyć pole gry zgodne z wybraną przez użytkownika wielkością. Następnie będzie ona dołączać funkcje obsługi zdarzeń kliknięcia poszczególnych pól planszy. $(document).ready(function() { function game() {}; game.init = function(size) { if(parseInt(size,10)

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

Jak się nazywasz?



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



Liczba 1 2 3



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.

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.

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

  • Pozycja menu 1
  • Pozycja menu 2


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ę Nazwa karty

Kod HTML karty




  • 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

Koszula Spodnie Buty



Wybierz liczbę sztuk

1 2 3





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

Wybierz język

wybierz







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.

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



Dodaj nową funkcję

Wybierz język

wybierz



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

    wybierz

  • Region

    wybierz

  • Miasto

    wybierz



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.

wybierz

255

PHP i jQuery. Receptury