Ajax: 3 powiązane pola select

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ę.

Comments

widaw

Dokonałe! No i powodzenia na sesji 😉

Reply
Michał

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

Reply
Michał

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

Reply
    Arkadiusz Tobiasz

    Właśnie tak miałem odpisać 😉 cieszę się, że problem już rozwiązany

    Reply
      pablosanchez

      Niestety nie pomaga. Ajax uparcie nie chce podczytywać polskich znaków.
      jak zakodować bazę aby ajax był pomocny w edycji polskich fontów?

      Reply
        Arkadiusz Tobiasz

        Można spróbować z wykorzystaniem iconv()

        1
        iconv('iso-8859-2', 'utf-8', 'ąśżźć');
        Reply
bojownik

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ć?

Reply
    Arkadiusz Tobiasz

    nie znam się na joomli, więc trudno mi coś poradzić. Może spróbuj zmienić nazwę divów? czy skrypt marki.php też jest zaincludowany? On nie powinien mieć niczego innego oprócz kodu jaki podałem we wpisie.

    Ew. możesz spróbować powalczyć z jQuery i dynamicznym generowaniem selectów: http://blog.tobiasz.org/2010/08/jquery-powiazane-pola-select/

    Reply
MedicalITLogistic

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

Reply
MK2009

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

Reply
    Arkadiusz Tobiasz

    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

    Reply
tom66

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 ?

Reply
    Arkadiusz Tobiasz

    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.

    Reply

Leave a Comment

7 + 4 =