Ajax: 3 powiązane pola select

Autor: Arkadiusz Tobiasz 16 stycznia 2010

W związku z licznymi mailami z pytaniem w jaki sposób można powiązać ze sobą 3 pola select, aby generowały się dynamicznie postanowiłem w wolnej chwili, a raczej szukając czegokolwiek, aby tylko się nie uczyć do sesji napisać mały tutorial, który podpowie Wam jak można zrobić 3 powiązane pola select, a nawet więcej. Tutorial ten będzie kontynuacją opublikowanego ponad rok temu wpisu Ajax: powiązane pola select, więc zanim przystąpisz do czytania dalszej części wpisu wykonaj wszystkie rzeczy w podanym przeze mnie powyżej linku.

Mając już generowanie dynamiczne modeli samochodów na podstawie wybranej marki chcielibyśmy jeszcze utworzyć nadrzędną kategorię, która będzie wyznaczała typ pojazdu, np. osobowe, ciężarowe itp. W związku z tym w naszej bazie danych tworzymy nową tabelę i wprowadzamy przykładowe dane:

1
2
3
4
5
6
7
8
CREATE TABLE `kategorie` (
`id` INT(9) NOT NULL AUTO_INCREMENT,
`tytul` VARCHAR(255) NOT NULL DEFAULT '',
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin2 ;

INSERT INTO `kategorie` VALUES(1, 'osobowe');
INSERT INTO `kategorie` VALUES(2, 'ciężarowe');

Dodatkowo do tabeli marki musimy dodać jeszcze jedną kolumnę z identyfikatorem kategorii:

1
2
3
4
ALTER TABLE marki ADD cid INT(9);

UPDATE marki SET cid = 1 WHERE id = 1;
UPDATE marki SET cid = 2 WHERE id = 2;

Mając już dane w tabeli musimy stworzyć odpowiedni skrypt generujący marki samochodów na bazie wybranej kategorii, który będzie wykorzystywany przy generowaniu listy dostępnych marek samochodów dla kategorii, którą wybierzemy z selecta. Plik nazwiemy marki.php, a zawierać będzie następującą treść:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?php
      $cid = $_GET['cid'];
      if(!empty($cid)) {
        include("config.php");
        $dropdown = "<select name=\"mid\"  id=\"mid\" width=\"25\"  onchange=\"ajaxFunction()\">";
        $dropdown .= "<option value=\"\">--wybierz--</option>";

        $result2 = mysql_query("SELECT id, marka FROM marki WHERE cid=".$cid." ORDER BY marka");

        while ($row = mysql_fetch_array($result2)) {
          $mid = intval($row['id']);
          $marka = $row['marka'];
          $dropdown .= "<option value=\"".$mid."\">".$marka."</option>";
        }
        $dropdown .= "</select><br>";
      echo $dropdown;
}
      ?>

W porównaniu ze skryptem z poprzedniego tutoriala dochodzi wywołanie metody ajaxFunction2(), a reszta pozostaje taka sama, jeśli chodzi o budowę, bowiem dane czerpane są z innych źródeł. Teraz musimy edytować nasz plik ajax.js, gdzie na końcu dodajemy:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
function ajaxFunction2(){
 
  var ajaxRequest;  // magic variable
 
  try{
    // Opera 8.0+, Firefox, Safari
    ajaxRequest = new XMLHttpRequest();
  } catch (e){
    // Internet Explorer Browsers
    try{
      ajaxRequest = new ActiveXObject("Msxml2.XMLHTTP");
    } catch (e) {
     
      try{
        ajaxRequest = new ActiveXObject("Microsoft.XMLHTTP");
      } catch (e){
        // Something went wrong
        alert("Your browser broke!");
        return false;
      }
    }
  }
 
  // Receive Data Function
  ajaxRequest.onreadystatechange = function(){
   
    if(ajaxRequest.readyState == 4){
      var ajaxDisplay = document.getElementById('ajaxDiv2');
      ajaxDisplay.innerHTML = ajaxRequest.responseText;
    }
   
  }
 
  var cid = document.getElementById('cid').value;
 
  var queryString = "?cid=" + cid;
  ajaxRequest.open("GET", "marki.php" + queryString, true);
  ajaxRequest.send(null);
}

Mając te dwie rzeczy możemy przejść do wywołania naszych 3 powiązanych pól select. W tym celu w pliku samochody.php kod:

1
2
3
4
5
6
7
8
9
10
11
12
<?php
        include("config.php");
        echo "<select name=\"mid\" onchange=\"ajaxFunction()\" id=\"mid\" width=\"25\">"
        ."<option value=\"\">--wybierz--</option>";
        $result2 = mysql_query("SELECT id, marka FROM marki ORDER BY marka");
        while ($row = mysql_fetch_array($result2)) {
          $mid = intval($row['id']);
          $marka = $row['marka'];
          echo"<option value=\"".$mid."\">".$marka."</option>";
        }
        echo"</select><br>";
      ?>

zamieniamy na:

1
2
3
4
5
6
7
8
9
10
11
12
<?php
        include("config.php");
      echo "<select name=\"cid\" onchange=\"ajaxFunction2()\" id=\"cid\" width=\"25\">"
        ."<option value=\"\">--wybierz--</option>";
        $result2 = mysql_query("SELECT id, tytul FROM kategorie ORDER BY tytul");
        while ($row = mysql_fetch_array($result2)) {
          $cid = intval($row['id']);
          $tytul = $row['tytul'];
          echo"<option value=\"".$cid."\">".$tytul."</option>";
        }
        echo"</select><br>";
      ?>

oraz po:

1
</td>

dodajemy:

1
2
3
<td width="100">
      <div id='ajaxDiv2'></div>
      </td>

W taki oto sposób otrzymujemy trzy powiązane ze sobą pola select. Działanie skryptu można przetestować na tej stronie. Treść tutoriala z racji ograniczonego czasu pisałem z ręki, więc jeśli gdzieś znajdziecie błąd, to proszę o takową informację.

komentarzy 13

  1. widaw napisał(a):

    Dokonałe! No i powodzenia na sesji 😉

  2. Michał napisał(a):

    nie wiem dlaczego, ale w pierwszym selekcie, wszystko jest ok, a w drugim i trzecim nie mam polskich znaków

  3. Michał napisał(a):

    już wiem, sorki. ajax/js domyślnie używa utf a ja miałem wszędzie kodowanie iso i w bazie też latin2. gdyby ktoś miał podobny problem i nie mógł/nie chciał zmieniać kodowania to wystarczy w plikach model i marka dodać linię

    header(„Content-type: text/html; charset=iso-8859-2”);

    tylko nie po echo

  4. bojownik napisał(a):

    Zamieściłem skrypt na stronie, ale mam pewien problem.
    Gdyż strona oparta jest o joomle i inkludowałem pliki do templatki.
    Skrypt działa poprawnie tylko na głównej domenie np:

    http://www.domena.pl/dowolny_adres.php

    natomiast rozwala mi cały układ strony przy czymś takim:

    http://www.domena.pl/a/b/dowolny_adres.php

    w sensie ze w miejscu gdzie ma się pojawić rozwijana druga lista inkluduje mi strone główną.

    Da się coś z tym zrobić?

  5. MedicalITLogistic napisał(a):

    Witam,

    Na poczatku bardzo chcę podziękować za możliwość analizy Pana informacji na stronie. Dzięki rozwiązaniu które Pan przedstawił dotyczącego powiązania select-ów, ruszyłem z miejsca.

    Jeżeli można mam pytanie: Analizując Pana stronę o powiązaniu dwóch selectów. Co dopisać aby select I jak i II był widoczny cały czas. W moim wykonaniu po odświeżeniu strony pokazuje się I select a dopiero po wyborze z I select pokazuje się II select. Powiązanie między selectami działa super.

    I drugie pytanie. Chciałbym dodać jeszcze trzeci select. Docelowo pierwszy celec to „Wybór działu”, drugi chcę założyć „Kategoria” a trzeci który jest teraz jako drugi to „Wybór formularza”. Wykonałem wszystko zgodnie z opisem jednak coś nie zadziałało. Proszę o informacje co oznacza:

    UPDATE marki SET cid = 1 WHERE id = 1;
    UPDATE marki SET cid = 2 WHERE id = 2;

    Czy cid=1 to kolejne ID a where id=1 to id – czego, jakiej tabeli czy pola.

    Bardzo proszę o odpowiedz. I jeszcze raz dziękuje za wiedzę przekazaną na stronie.

    Pozdrawiam

  6. MK2009 napisał(a):

    wszystko ładnie opisane , ale Tworząc np. formularz rejestracyjny
    można dokonać wyboru modelu itd. , tylko w jaki sposób później to przesłać z powrotem do bazy danych np w inne miejsce w tabeli

    • Arkadiusz Tobiasz napisał(a):

      Przecież selecty mają określony atrybut name i po przesłaniu formularza metodą POST można się odwołać do zmiennych formularza poprzez $_POST[‚marka’], gdzie ‚marka’ to wartość atrybutu name

  7. tom66 napisał(a):

    bardzo przydatny artykuł, a jak by wyglądał skrypt gdyby założyc ze drugi select miałby własnośc multiple a w 3 pokazywały sie wartosci dla tych wybranych opcji ?

    • Arkadiusz Tobiasz napisał(a):

      Można, w pierwszym name=”mid” zamieniamy na name=”mid[]”

      Następnie w pliku modele.php otrzymujemy tablicę ze zmiennymi, następnie do zapytania podajemy wszystkie dostępne w tablicy klucze marek WHERE mid = 1 OR mid = 5 itd.

Odpowiedz

 

Arkadiusz Tobiasz student Akademii Ekonomicznej im. Karola Adamieckiego w Katowicach na specjalnościach informatyka ekonomiczna oraz rachunkowość. Więcej...

jQuery Validation i funkcja remote

Jakiś czas temu zwrócił się do mnie użytkownik z problemem. Chodzi o to, że korzysta on z pluginu walidacji jQuery, […]

Zend Framework: integracja z Uploadify

W tym wpisie postaram się przedstawić Wam w jaki sposób zintegrować skrypt Uploadify z Zend Frameworkiem. Dzięki temu będziemy mogli […]

Javascript: Czasowe wyświetlanie reklamy

Czasami chcemy, aby na pewnym elemencie naszej strony wyświetlała się reklama przez jakiś czas, a następnie zniknęła. W tym wpisie […]

Linux: backup wszystkich baz danych MySQL

Swego czasu pisałem o tym jak z poziomu konsoli można szybko i przyjemnie zrobić backup bazy MySQL. Wszystko jest ładnie […]