Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [PHP] Nested tree
Forum PHP.pl > Forum > PHP
Kostek.88
Witam, mam taką oto funkcję:

  1. <?php
  2. function displayTree($root) {
  3. // pobierz parametry glownego wezla
  4. $r = mysql_query('SELECT `left`, `right` FROM 
  5. menu WHERE id=''.$root.''');
  6. if($row = mysql_fetch_array($r)) {
  7. $right = array();
  8. // wyswietl wezly
  9. $r = mysql_query('SELECT * FROM menu WHERE `left` BETWEEN ''.$row['left'].'' AND ''.$row['right'].'' ORDER BY `left`');
  10.  echo '<table cellspacing="0" cellpadding="2">';
  11.  while($row = mysql_fetch_array($r)) {
  12.  // czysc stos
  13.  if(count($right) > 0) {
  14.  while($right[count($right)-1] < $row['right']) {
  15. array_pop($right);
  16.  } 
  17.  }
  18.  // wyswietl element
  19. echo '<form class="drzewo">';
  20.  echo '<tr onmouseover><td>';
  21. echo '<input type="hidden" name="edit" value="'.$row['id'].'">';
  22.  echo str_repeat(' <img src="icons/tree_galaz_przedluzenie.gif" align="top" />',count($right))."\n";
  23.  if(count($right) - 1 > 0) {
  24.  echo str_repeat(' <img src="icons/tree_galaz_przedluzenie.gif" align="top" />',count($right) - 1).' <img src="icons/tree_galaz.gif" align="top" /><img src="icons/tree_open.gif" align="top" /> <input type="text" name="nazwa" value="'.$row['nazwa'].'" class="nazwa" onfocus="this.className='nazwa_active'" onblur="this.className='nazwa'" /></td><td>&nbsp;&nbsp;&nbsp;&nbsp;<input type="submit" value="Zmień" class="button" /> <a href="index.php?'.$row['id'].'" onclick="return confirm('Czy na pewno chcesz usunąć to menu?')"><img src="icons/delete.png" border="0" /></a> <a href="#" onclick="pokazUkryj('dodaj'.$row['id'].'')"><img src="icons/add.gif" border="0" /></a>';
  25.  } else {
  26.  echo '<img src="icons/tree_galaz.gif" align="top" /><img src="icons/tree_open.gif" align="top" /> <input type="text" name="nazwa" value="'.$row['nazwa'].'" class="nazwa" onfocus="this.className='nazwa_active'" onblur="this.className='nazwa'" /></td><td>&nbsp;&nbsp;&nbsp;&nbsp;<input type="submit" value="Zmień" class="button" /> <a href="index.php?" onclick="return confirm('Czy na pewno chcesz usunąć to menu?')"><img src="icons/delete.png" border="0" /></a> <a href="#" onclick="pokazUkryj('dodaj'.$row['id'].'')"><img src="icons/add.gif" border="0" /></a>';
  27.  }
  28.  // zloz jego parametr 'right' na stos
  29.  $right[] = $row['right'];
  30.  echo '</form>';
  31.  echo '</td><td>';
  32.  echo '<div id="dodaj'.$row['id'].'" style="display: none">';
  33. echo '<form action="index.php">';
  34.  echo '<input type="hidden" name="create" value="'.$row['id'].'" />';
  35.  echo 'nazwa: <input type="text" name="title" class="nazwa" /> ';
  36.  echo '<input type="submit" value="Dodaj" />';
  37. echo '</form>';
  38.  echo '</div>';
  39.  echo '</td></tr>';
  40. }
  41. echo '</table>';
  42. // wszystko jest OK
  43. return 1;
  44. }
  45. // tere fere, nie ma takiego wezla
  46. return 0;
  47. } // end displayTree();
  48. ?>


Ten element służy do wyświetlania danych z tabeli w postaci drzewa (metodą left-right).

Przyznaję, że jest zerżnięta z gotowca, jednak kilka drobnych modyfikacji wprowadziłem. Problem tkwi w wyświetleniu drzewa jako rozwijane menu, takiego po boku, z prawej strony (jak w Windows). Przyznaję również, że nie do końca pojąłem mechanizmu wyświetlania tych danych. Dlatego proszę Was o pomoc. Jest tam funkcja count. Wydaje mi się, że w przypadku takiego menu, które chciałem stworzyć, jest ona zupełnie zbyteczna. Nie wiem po prostu jak się do tego zabrać. Nie chodzi mi o gotowy kod, ale o nakierowanie jakieś, jakie funkcje i rozwiązania mam wykorzystać.

Będę bardzo wdzięczny za pomoc.
orson
Witam.

Count i join jest kluczowy w tym zapytaniu.
Przykładowe zapytanie zwracające wszystkie elementy drzewa w poprawnej kolejności wraz z poziomem zagłębienia:
  1. -- otwarcie kursora z zapytaniem pobierającym dane
  2. open cur FOR
  3. SELECT
  4. p1.id, p1.name, p1.create_date, p1.creator, p1.active, p1.lt, p1.rt, COUNT(*) AS depth
  5. FROM product_groups AS p1,
  6. product_groups AS p2
  7. WHERE p1.lt BETWEEN p2.lt AND p2.rt
  8. GROUP BY
  9. p1.id, p1.name, p1.create_date, p1.creator, p1.active, p1.lt, p1.rt
  10. ORDER BY p1.lt;

Musisz zmienić sobie kolumny na odpowiednie.

Potem tylko ponowienie wcięcia razy kolumna depth i masz drzewo. Zmieniając to na tabele możesz ukrywać i pokazywać wiersze z takim samym parametrem depth i masz menu.

pozdrawiam
Kostek.88
Hmmmm.... czy to nie jest przypadkiem zapytanie PostGree? Jeśli tak, to niestety moja baza to MySQL i nie mam możliwości przesiadki na inną. Sam nie rozumiem nawet linijek ze swojej funkcji (chodzi o sam warunek z funkcją count):

  1. <?php
  2. echo str_repeat(' <img src="icons/tree_galaz_przedluzenie.gif" align="top" />',count($right))."\n";
  3. if(count($right) - 1 > 0) {
  4.  echo str_repeat(' <img src="icons/tree_galaz_przedluzenie.gif" align="top" />',count($right) - 1).' <img src="icons/tree_galaz.gif" align="top" /><img src="icons/tree_open.gif" align="top" /> <input type="text" name="nazwa" value="'.$row['nazwa'].'" class="nazwa" onfocus="this.className='nazwa_active'" onblur="this.className='nazwa'" /></td><td>&nbsp;&nbsp;&nbsp;&nbsp;<input type="submit" value="Zmień" class="button" /> <a href="index.php?'.$row['id'].'" onclick="return confirm('Czy na pewno chcesz usunąć to menu?')"><img src="icons/delete.png" border="0" /></a> <a href="#" onclick="pokazUkryj('dodaj'.$row['id'].'')"><img src="icons/add.gif" border="0" /></a>';
  5. } else {
  6.  echo '<img src="icons/tree_galaz.gif" align="top" /><img src="icons/tree_open.gif" align="top" /> <input type="text" name="nazwa" value="'.$row['nazwa'].'" class="nazwa" onfocus="this.className='nazwa_active'" onblur="this.className='nazwa'" /></td><td>&nbsp;&nbsp;&nbsp;&nbsp;<input type="submit" value="Zmień" class="button" /> <a href="index.php?" onclick="return confirm('Czy na pewno chcesz usunąć to menu?')"><img src="icons/delete.png" border="0" /></a> <a href="#" onclick="pokazUkryj('dodaj'.$row['id'].'')"><img src="icons/add.gif" border="0" /></a>';
  7. }
  8. ?>


Czy w Twoim fragmencie kodu COUNT samo oblicza głębię? Czy mogę później użyć tego jako zmiennąquestionmark.gif Do czego jest potrzebne w tym przypadku polecenie group by? A co oznaczają nazwy przez Ciebie nadane p1 i p2? Myślałem że to pozycja, ale chyba nie bardzo. Nie mów, że to są oddzielne tabele, bo ja mam przecież wszystko w 1 schowane. Jeśli mógłby mi ktoś jeszcze rozjasnić ten przykład, byłbym wdzięczny
orson
Witam.

Myślę że jak nie rozumiesz mojego zapytania to chyba porwałeś się na zbyt duże zadanie. Po za pierwszą linijką którą niepotrzebnie skopiowałem to zapytanie będzie działało bez problemu w mysql.
P1 i p2 to aliasy do tabeli product_groups. Zapytanie używa jednej tabeli łącząc się do niej samej. Musisz tylko zmienić nazwę tabeli oraz pobierane kolumny. Stosując moje zapytanie możesz całkowicie pozbyć się obliczeń w twojej funkcji. Wykonaj je i zobacz, że kolumna depth zwraca głębokość każdego elementu.

pozdrawiam
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.