GAJDAW


SZKOLENIA

Szkolenie Symfony 2.0 od podstaw

MOJE KSIĄŻKI

Książka pt. Symfony w przykładach
Książka pt. GIMP. Praktyczne projekty. Wydanie II
Książka pt. PHP, MySQL i MVC. Tworzenie witryn WWW opartych na bazie danych
Książka pt. PHP. Praktyczne projekty

PROGRAMY

1 2 3 4 5 6


Ajax. Kurs od podstaw. Część 1: Wprowadzenie

Włodzimierz Gajda

6. Aparaty fotograficzne

Przykład pt. „Aparaty fotograficzne” w pełni prezentuje możliwości Ajax-a. Strona główna zawiera listę nazw aparatów, każdy z nich jest umieszczony wewnątrz zielonego obszaru div (rysunek 3).

Rysunek 3. Witryna z aparatami fotograficznymi

Z lewej strony nazwy każdego aparatu znajduje się ikona + pozwalająca na wyświetlenie szczegółowych danych. Rysunek 4 przedstawia witrynę po rozwinięciu danych aparatu Canon EOS 20D.

Rysunek 4. Witryna z aparatami po rozwinięciu danych aparatu Canon EOS 20D

W tym samym momencie możemy rozwinąć dane dowolnej liczby aparatów. Rysunek 5 przedstawia wygląd witryny po rozwinięciu dwóch aparatów.

Rysunek 5. Witryna z aparatami po rozwinięciu danych dwóch aparatów

Wygląd pojedynczego aparatu w formie zwiniętej i rozszerzonej jest przedstawiony na rysunkach 6 oraz 7.

Rysunek 6. Dane pojedynczego aparatu w postaci zwiniętej

Rysunek 7. Dane pojedynczego aparatu w postaci rozwiniętej

Witryna pobiera dane o aparatach w sposób asynchroniczny. Na stronie WWW znajdują się wyłącznie nazwy aparatów. Po kliknięciu ikony +, skrypt JavaScript pobiera z serwera szczegółowe dane wybranego aparatu. Po odebraniu odpowiedzi, we wnętrzu odpowiedniego zielonego prostokąta umieszczane są dane pobrane z serwera. Serwer wysyła dane aparatu w formacie XML.

Jest więc zatem:

6.1 Rozwijanie i zwijanie jednej kontrolki

Pracę nad witryną Aparaty fotograficzne rozpoczynamy od opracowania pojedynczej zwijanej kontrolki. Kontrolka taka jest zawarta w pojemniku div#tresc i zawiera jedno hiperłącze a, tytuł Pojemnik na treść oraz drugi element div#minitresc:

<div id="tresc">
<a id="ikona" href="#" onclick="expandCollapse();">+</a>
Pojemnik na treść
<div id="minitresc"></div>
</div>

W obsłudze zdarzenia onclick ikony + należy zmienić wygląd całej kontrolki.

W zależności od wartości globalnej zmiennej expanded ukrywamy (style.display = 'none') lub pokazujemy (style.display = 'block') zawartość pojemnika div#minitresc. Ponadto zmieniamy ikonę oraz wstawiamy do elementu div#minitresc tekst A B C...:

var expanded = false;

function expandCollapse()
{
  if (expanded) {
    expanded = false;
    document.getElementById('minitresc').style.display = 'none';
    document.getElementById('ikona').innerHTML = '+';
  } else {
    expanded = true;
    document.getElementById('minitresc').style.display = 'block';
    document.getElementById('minitresc').innerHTML = 'A B C...';
    document.getElementById('ikona').innerHTML = '-';
  }
}

6.2 Rozwijanie i zwijanie wielu kontrolek

Jeśli na stronie WWW ma się znajdować seria podobnych rozwijanych kontrolek to najlepiej zrezygnować ze stosowania identyfikatorów. Cała kontrolka jest zawarta w elemencie div klasy tresc. Wewnątrz zawiera hiperłącze a, tytuł span oraz dodatkowy element div:

<div class="tresc">
  <a href="#" onclick="expandCollapse(this);">+</a>
  <span>Pojemnik na treść</span>
  <div></div>
</div>

Uwaga: w rozwiązaniu tym nie możesz umieścić białych znaków pomiędzy elementami HTML. Kod od znacznika <div class="tresc"> do znacznika </div> należy napisać w jednej linijce bez odstępów:

<div class="tresc"><a ...>+</a><span>...</span><div></div></div>

Powodem jest to, że białe znaki będą dodatkowymi dziećmi elementu div.tresc. Odwołanie Id.parentNode.childNodes[2] nie będzie dotyczyło wewnętrznego elementu div.

Zwróć uwagę, że obsługą zdarzenia onclick zajmuje się funkcja expandCollapse() wywołana z parametrem this. Parametrem this w modelu DOM jest ten węzeł drzewa, który wygenerował zdarzenie (w naszym przypadku: kliknięte hiperłącze). Takie rozwiązanie znacznie uprości treść funkcji expandCollapse():

function expandCollapse(Id)
{
  var n = Id.parentNode.childNodes[2];

  if (n.style.display == 'block') {
    n.style.display = 'none';
    Id.innerHTML = '+';
  } else {
    n.style.display = 'block';
    n.innerHTML = 'A B C...';
    Id.innerHTML = '-';
  }
}

To, czy element jest zwinięty, czy rozwinięty stwierdzamy (w warunku instrukcji if) na podstawie wartości właściwości display. Nie wprowadzamy do tego żadnych dodatkowych zmiennych. Zmienna o nazwie n jest drugim elementem div (tj. tym, który poprzednio miał identyfikator minitresc) wewnątrz bieżącej kontrolki. Docieramy do niego następująco:

We wnętrzu instrukcji if, podobnie jak poprzednio zmieniamy widoczność wewnętrznego elementu div, ustalamy jego treść (A B C...) oraz zamieniamy ikonę plus na minus, a minus na plus.

6.3 Aparaty fotograficzne — kompletny przykład

Przejdźmy do połączenia wszystkich elementów. Wykorzystamy serię rozwijanych kontrolek div, oraz Ajax do pobierania szczegółowych danych konkretnego aparatu.

Opisywany przykład składa się z pliku index.html oraz danych w formacie XML, zawartych w folderze dane-xml/.

Wszystkie pliki XML mają identyczną strukturę. Każdy z nich zawiera szczegółowe dane dokładnie jednego aparatu. Na przykład plik 1.xml przedstawiony na listingu 7 zawiera szczegółowe dane Canona EOS 20D.

<?xml version="1.0" encoding="iso-8859-1"?>
<aparat>
    <producent>Canon</producent>
    <model>EOS 20D</model>
    <typ>DSLR</typ>
    <megapixel>8.2</megapixel>
    <lcd>1.8</lcd>
    <matryca>COMOS</matryca>
    ...
</aparat>    

Listing 7. Fragment pliku XML ze szczegółowymi danymi aparatu Canon EOS 20D

W treści (tj. pomiędzy znacznikami <body> i </body>) W treści strony umieszczamy serię elementów div.tresc. Jeden element div.tresc dla każdego aparatu:

<body>

<div class="tresc">
  <h3>
    <a href="#" onclick="expandCollapse(this, 1);">+</a>
    Canon EOS 20D
  </h3>
  <div></div>
</div>

<div class="tresc">
  <h3>
    <a href="#" onclick="expandCollapse(this, 2);">+</a>
    Canon EOS 30D
  </h3>
  <div></div>
</div>

...

</body>

Są to opisane wcześniej rozwijalne elementy, mające ikony plus (do rozwinięcia) oraz minus (do zwinięcia). Obsługą zdarzenia onclick zajmuje się funkcja expandCollapse(), która tym razem otrzymuje dwa parametry: obiekt DOM o nazwie this (tj. kliknięte hiperłącze) oraz liczbę, identyfikującą kliknięty aparat.

W treści funkcji expandCollapse() po pierwsze zmieniamy wygląd elementu div.tresc. Zwijamy go lub rozwijamy. Jeśli element jest rozwijany (przypadek else) dodatkowo inicjalizujemy Ajax-owy transfer danych. Parametrem metody open() jest skrypt adres URL dokumentu XML ze szczegółową specyfikacją aparatu. Nazwa pliku XML powstaje na podstawie parametru Numer, który identyfikuje kliknięty aparat:

function expandCollapse(Id, Numer)
{
  element = Id.parentNode.parentNode.childNodes[1];
  if (element.style.display == 'block') {
    element.style.display = 'none';
    Id.innerHTML = '+';
  } else {
    element.style.display = 'block';
    Id.innerHTML = '-';

    r.open('GET', 'dane-xml/' + Numer + '.xml', true);
    r.onreadystatechange = processResponse;
    r.send(null);

  }
}

Ostatnim etapem przygotowania przykładu Aparaty fotograficzne jest opracowanie funkcji processResponse(), która zajmie się umieszczeniem danych odebranych z serwera w rozwiniętym elemencie. Ponieważ wykorzystujemy format XML, należy użyć właściwości r.responseXML. Pobieramy wszystkie dzieci elementu o nazwie aparat:

var x = r.responseXML.getElementsByTagName('aparat')[0].childNodes;

Elementy te przetwarzamy w pętli for rozpoczynając od elementu o indeksie 2 (elementy 0 oraz 1 to nazwa firmy i nazwa modelu, które są zawarte w tytule wyświetlanego rozwijanego elementu div). Pętla for przygotowuje napis tmp, który jest wstawiony jako treść (tj. element.innerHTML) rozwiniętego elementu:

var element;

function processResponse()
{
  if (r.readyState == 4) {
    if (r.status == 200) {

      var x = r.responseXML.getElementsByTagName('aparat')[0].childNodes;

      var tmp = '';

      for (i = 2; i < x.length; i++) {
        tmp = tmp
          + '<strong>' + opis[i] + ':</strong> '
	  + x[i].childNodes[0].nodeValue
	  + '<br />';
      }

      element.innerHTML = tmp;
    };
  }
}

Zwróć uwagę, że zmienna element jest zmienną globalną. Po raz pierwszy pojawia się ona w funkcji expandCollapse(). Funkcja expandCollapse() umieszcza w zmiennej element rozwinięty div przeznaczony na szczegółowy opis aparatu. W ten sposób funkcja processResponse() nie musi szukać w drzewie DOM elementu, w którym należy wstawić treść. Element ten jest już przygotowany i dostępny w zmiennej element.

Etykiety podpisujące poszczególne parametry aparatu (np. Migawka, Czułość, Autobracketing, itd.) są zawarte w tablicy opis zadeklarowanej przed funkcją processResponse().

Zarys pliku index.html jest przedstawiony na listingu 8.

<head>
<script type="text/javascript">
function getXMLHttpRequest()
{
  ...
}    

var r;
r = getXMLHttpRequest();    

var opis= new Array(20);
opis[0]  = 'Producent';
opis[1]  = 'Model';
opis[2]  = 'Typ';
...

var element;

function processResponse()
{
  ...
}

function expandCollapse(Id, Numer)
{
  ...
}   
</script>
</head>
<body>

<div class="tresc">
  <h3>
    <a href="#" onclick="expandCollapse(this, 1);">+</a>
    Canon EOS 20D
  </h3>
  <div></div>
</div>

<div class="tresc">
  <h3>
    <a href="#" onclick="expandCollapse(this, 2);">+</a>
    Canon EOS 30D
  </h3>
  <div></div>
</div>

...

</body>

Listing 8. Aparaty fotograficzne: zarys pliku index.html


Reklama

Szkolenia z Zend Framework 2.0


1 2 3 4 5 6