Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Drzewo kategorii i podkategorii
Forum PHP.pl > Forum > PHP
kukix
Witam.
Mam maly problem, ze znalezieniem odpowiedniego skryptu wyświetlającego drzewo kategorii i podkategorii..

szukałem na wielu forach, jednak nic konkretnego nie znalazłem... czytalem artukuł na php_pl, jednak tam jest ograniczenie do 9 dzieci dla każdej kategorii...

znalazłem coś odpowiedniego dla mnie http://www.klempert.de/nested_sets/demo/ ... jednak autor skryptu nie dołączył do archiwum paru plików, które są wymaganbe do odpalenia tego skryptu (nie znam niemieckiego i nie rozumie instrukcji na stronie)...
prosze o naprowadzenie na temat na forum, gdzie rozwiązano sprawe drzewa kategorii i nieograniczonej liczby podkategorii (nie musi być ograniczona, ale żebvy było więcej niż 2 podkategorie...)

czytałem wiele tamatów na forach.. np., :
http://forum.webcity.pl/index.php?act=ST&f=15&t=2461&st=30
http://forum.webcity.pl/index.php?act=ST&f=4&t=498
+ dużo na webhelp.pl .. prosze o jakies namiary...

jeżeli ktoś siedział nad tym samym problemem i znalazł rozwiązanie, to prosze o podpowiedź...
kukix
sam sql, to troche mało... nie dam rady z tego coś zrobić...
próbowałem napisac coś takiego w php... wyszło b.duzo zapytań... i dlatego chciałem zobaczyć, jak można by to zrobić inaczej....
AcidBurnt
no sam SQL daje duzo winksmiley.jpg teraz tylko kwestia napisana kilku procedur w php aby Sobie z tym radził, mam to napisane ale nie jestem w stanie tego udotpanic z racji tego ze wplecione jest w troszke inny kod... (jeszcze nie pisałem obiektowo) ;p
kukix
Przeglądałem dokładniej adres http://www.depesz.com/various/various-sqlt...lementation.php. Zrobienie z tego kody php, nie jest wielkim problemem. Problem jest w tym, że jest to oparte o baze danych postgresql, którą niestety nie dysponuje mój serwer.

Nie znacie jakiegoś innego adresu, który jednak był by oparty o MySQL?

P.S. Pierwszy problem jaki napotkałem to funkcja currval, która pod MySQL nie działa... może znacie jakiś zamiennik pod MySQL?
Prosze o podpowiedź...
dcooper
tutaj masz artykul kolegi Zyxa z WebCity.pl: http://artykuly.zyxist.com/czytaj.php/drzewa_w_php_i_mysql
batman
Napisałem pewną klasę, która działa jak najprawdziwsze drzewko windowsowe;) Klasa rozwijanie i zwijanie gałęzi realizowane jest za pomocą JS, trochę panuje tam bałagan ale nadaje się do użycia smile.gif Nie ma ograniczenia na ilość podgałęzi, a dane pobiera z tablicy a nie z bazy danych, więc możesz to podpiąć pod MySQL Postgresa, XML-a itd. Jedynym wymogiem jest podanie poprawnie zbudowanej tablicy.

Klasa jest ciągle rozwijana, więc pewnie niedługo będzie znacznie lepsza.

  1. <?php
  2. class cTree
  3. {
  4. var $aTree;
  5. var $brozwiniete;
  6.  
  7. function cTree($brozwiniete=true) {
  8. $this->brozwiniete=$brozwiniete;
  9. ?>
  10.  
  11. <link href="css/tree.css" rel="stylesheet" type="text/css" />
  12.  
  13. <script language="javascript">
  14. function zwin_rozwin(id,ile,ids,ukryj,lewel) {
  15. // id - id elementu kliknietego
  16. // ile - ilosc elementow potomych
  17. // ids - id wszystkich elementow potomnych dla wybranego wezla
  18. // ukryj - 1 lub 0. jesli 1 ukrywa line pionowe dla ostaniego elementu drzewa
  19. // lewel - aktualny poziom drzewa
  20.  
  21. if(ids.length>0) aids = ids.split(" ");
  22.  
  23. // pokazywanie i ukrywanie podgalezi
  24. var bclose = false; // zmienna okreslajaca, czy zamykac galaz drzewa
  25. for(i=1;i<=ile;i++) {
  26. el = eval("document.getElementById(""+id+"_"+i+"")");
  27.  
  28. if(el.style.display == "block") {
  29. el.style.display = "none";
  30. bclose = true;
  31. }
  32. else {
  33. el.style.display = "block";
  34. }
  35. }
  36.  
  37. var img_src, img_src_plus, img_src_child, img_linia; // zmienne zawierajace obrazki
  38. el_img = eval("document.getElementById(""+id+"_img")");
  39. el_img_plus = eval("document.getElementById(""+id+"_img_plus")");
  40. img_src = el_img.src;
  41. img_src_plus = el_img_plus.src;
  42.  
  43. // podmiana ikony folderu zamknietego i otwartego, jesli uzywa folderu
  44. if(img_src.match("/dir")) {
  45. if(bclose) el_img.src = "img/tree/dir.gif";
  46. else el_img.src = "img/tree/dir_open.gif";
  47.  }
  48.  
  49. // podmiana plusa i minusa
  50. if(bclose) {
  51. if(img_src_plus.match("/tree_101.gif")) el_img_plus.src = "img/tree/tree_100.gif";
  52.  if(img_src_plus.match("/tree_103.gif")) el_img_plus.src = "img/tree/tree_102.gif";  
  53.  }
  54.  else {
  55. if(img_src_plus.match("/tree_100.gif")) el_img_plus.src = "img/tree/tree_101.gif";
  56. if(img_src_plus.match("/tree_102.gif")) el_img_plus.src = "img/tree/tree_103.gif";
  57.  }
  58.  
  59. // ukrycie niepotrzebnych lini pionowych na koncu drzewa
  60. if(ids.length>0 && ukryj==1) {
  61. for(j=0;j<aids.length;j++) {
  62. for(k=0; k<lewel; k++) {
  63. el_linia = aids[j] + "_" + lewel + "_linia";
  64. img_linia = eval("document.getElementById(""+el_linia+"")");
  65. img_linia.style.display = "none";
  66. }
  67. }
  68. }
  69.  
  70. // ukrywanie galezi drzewa
  71. if(ids.length>0 && bclose) {
  72. for(j=0;j<aids.length;j++) {
  73. el_child = eval("document.getElementById(""+aids[j]+"")");
  74. el_child.style.display = "none";
  75.  
  76. el_img_child = eval("document.getElementById(""+aids[j]+"_img")");
  77. el_img_child_plus = eval("document.getElementById(""+aids[j]+"_img_plus")");
  78.  
  79. if(el_img_child_plus) {
  80. if(el_img_child_plus.src.match("/tree_101.gif")) el_img_child_plus.src = "img/tree/tree_100.gif";
  81. if(el_img_child_plus.src.match("/tree_103.gif")) el_img_child_plus.src = "img/tree/tree_102.gif";
  82. }
  83. }
  84. }
  85. }
  86. </script>
  87. <?php
  88. }
  89.  
  90. function renderTree($aTree) {
  91. return $this->buildTree($aTree);
  92. }
  93.  
  94. function buildTree($aTree,$level=0,$idup=0,$arods=array()) {
  95. $level++;
  96. for($i=0,$count=count($aTree);$i<$count;$i++) {
  97. $blast = ($i==$count-1);
  98. $row = $aTree[$i];
  99. $row['id'] = $i+1;
  100. $id_tab = $idup.'_'.$row['id']; // id wiersza (galezi)
  101.  
  102. // sprawdzenie czy galaz ma elementy potomne
  103. if(is_array($row['child'])) {
  104. $nchildren = count($row['child']); // ilosc elementów potomnych
  105. $sids = trim($this->getAllChildren($row['child'],$id_tab)); // id wszystkich potomnych elementow
  106.  
  107. if($i==($count-1)) $ukryj = 1;
  108. else $ukryj = 0;
  109.  
  110. $link_start = '<span style="cursor:hand;" onclick="zwin_rozwin(''.$id_tab.'',''.$nchildren.'',''.$sids.'',''.$ukryj.'',''.$level.'');">';
  111. $link_end = '</span>';
  112. }
  113.  
  114. // ukrywanie galezi drzewa
  115. if($level>&& !$this->brozwiniete) $style = ' style="display:none;" ';
  116. else $style = ' style="display:block;" ';
  117.  
  118. $sout .= '<table border="0" width="100%" cellpadding="0" cellspacing="0" '.$style.' id="'.$id_tab.'">';
  119. $sout .= '<tr>';
  120.  
  121. // dodatkowe pola przed nazwa elementu (na ikonki i linie nawigacyjne)
  122. $arodsnow = $arods;
  123. $arodsnow[$level]=($i==$count-1);
  124. for($j=1;$j<$level;$j++) {
  125. $sout .= '<td width="17">';
  126. if($arodsnow[$j]) $sout .= '<img src="img/tree/tree_01.gif" id="'.$id_tab.'_'.$j.'_linia" alt="j='.$j.' lev='.$level.' blast='.$blast.'"/>';
  127. else $sout .= '<img src="img/tree/tree_02.gif" id="'.$id_tab.'_'.$j.'_linia" alt="j='.$j.' lev='.$level.' blast='.$blast.'"/>';
  128. $sout .= '</td>';
  129. }
  130. $sout .= "n<td width="17"><nobr>";
  131. if($count==($i+1)) {
  132. if($row['child']) {
  133. if($this->brozwiniete) $sout .= $link_start.'<img src="img/tree/tree_103.gif" id="'.$id_tab.'_img_plus" />'.$link_start;
  134. else $sout .= $link_start.'<img src="img/tree/tree_102.gif" id="'.$id_tab.'_img_plus" />'.$link_start;
  135. }
  136. else $sout .= '<img src="img/tree/tree_04.gif" />';
  137. }
  138. else {
  139. if($row['child']) {
  140. if($this->brozwiniete) $sout .= $link_start.'<img src="img/tree/tree_101.gif" id="'.$id_tab.'_img_plus" />'.$link_end;
  141. else $sout .= $link_start.'<img src="img/tree/tree_100.gif" id="'.$id_tab.'_img_plus" />'.$link_end;
  142. }
  143. else $sout .= '<img src="img/tree/tree_03.gif" />';
  144. }
  145.  
  146. $sicon = "img/tree/dir.gif";
  147. if(!is_array($row['child'])) $sicon = "img/tree/tree_leaf.gif";
  148. if($row['sicon']) $sicon = $row['sicon'];
  149.  
  150. $sout .= $link_start.'<img src="'.$sicon.'" id="'.$id_tab.'_img" />'.$link_end;
  151. $sout .= '</nobr></td>';
  152. $sout .= '<td>';
  153. if($row['onclick']) $sout .= "<span class="tree_link" onclick="".$row['onclick']."">";
  154. else $sout .= "<span class="tree_element">";
  155. $sout .= $row['sname'];
  156. if($row['onclick']) $sout .= "</span>";
  157. $sout .= '</td>';
  158. $sout .= '</tr>';
  159. $sout .= "</table>nn";
  160.  
  161. if(is_array($row['child'])) {
  162. $sout .= $this->buildTree($row['child'],$level,$id_tab,$arodsnow);
  163. }
  164. }
  165. return $sout;
  166. }
  167.  
  168. function getAllChildren($aArray,$idup)
  169. {
  170. for($i=0;$i<count($aArray);$i++) {
  171. $id.=$idup.'_'.($i+1).' ';
  172.  
  173. if($aArray[$i]['child'])
  174. $id.=$this->getAllChildren($aArray[$i]['child'],$idup.'_'.($i+1));
  175. }
  176. return $id;
  177. }
  178. }


A tak się tego używa:

  1. <?php
  2. // jeśli chcemy by drzewo było domyślnie zwinięte, to w konstruktorze przekazujemy
     false: $oTree = new cTree(false);
  3. $oTree = new cTree();
  4. echo $oTree->renderTree($adata);
  5.  
  6. //$adata - tablica o następującej strukturze:
  7.  
  8. $achild[] = array('sname'=>'nazwa 12');
  9. $achild[] = array('sname'=>'nazwa 13','sicon'=>'img/fortree/user_status_1.gif');
  10. $achild[] = array('sname'=>'nazwa 14','sicon'=>'img/fortree/calendar.gif');
  11.  
  12. $adata[] = array('sname'=>'nazwa 1');
  13. $adata[] = array('sname'=>'nazwa 2','child'=>$achild);
  14. ?>


Jeśli ktoś będzie to rozwijał chętnie bym spojrzał na efekt końcowy.
kukix
Dzieki batman za kodzik..
po przeanalizowaniu kodu, klasa wydaje sie być ciekawa..

Była by możliwość abyś udostępnił plik tree.css? ... i ewentualnie reszte plików graficznych (gif)?
batman
Nie ma sprawy. Wyślij mi PW z adresem e-mail, na jaki wysłać w/w pliki. Niedługo postawię drzewko na jakiejś stronce ze źródłami do pobrania.
TomASS
Bardzo ładna klasa, mam tylko parę i sugesti pytań do Szanownego Autora:


1. Dodałbym funkcję JS:
Kod
function $(id){
    return document.getElementById(id);
}

w zamian za wszystkie:
Kod
document.getElementById


2. Takie coś:
  1. <?php
  2. for($i=0,$count=count($aTree);$i<$count;$i++) {
  3. ?>

prawdopodobnie będzie Ci liczyć za każdym razem rozmiar $aTree, lepiej jest dać:
  1. <?php
  2. $count=count($aTree);
  3. for($i=0;$i<$count;$i++)
  4. ?>


3. Używasz php4, czy nie warto by się było pofatygować na php5? tongue.gif

Czekam na jakieś demo - bo wygląda to na prawdę bardzo fajnie smile.gif Gratulejszyn
siemakuba
Cytat
prawdopodobnie będzie Ci liczyć za każdym razem rozmiar $aTree, lepiej jest dać:
@TomASS: nie będzie liczył za każdym razem :)
pierwszy parametr z pętli for jest sprawdzany przed rozpoczęciem pętli, więc:
  1. <?php
  2. for($i=0, $count=count($aTree); $i<$count; $i++)  // ustawia wartość i _nie_liczy_ za kazdym przebiegiem
  3. for($i=0; $i<count($aTree); $i++) // w takim wypadku _liczy_ za kazdym przebiegiem
  4. ?>


A co do klasy - nie przeglądałem kodu, ale jedno co mi się mocno nie podoba, to metoda cTree - wykakiwanie do HTMLa wewnątrz metody to chyba średni pomysł.. robi się bałagan :)

pozdr.
batman
Witam

Jak już napisałem klasa jest w fazie rozwoju i docelowo wszystko co nie jest php zostanie zamknięte w osobnych plikach. Natomiast co do pętli for, czasami pisałem

  1. <?php
  2. for($i=0, $count=count($aTree); $i<$count; $i++)
  3. ?>


a czasami

  1. <?php
  2. for($i=0; $i<count($aTree); $i++)
  3. ?>


Wszystko zostanie przerobione do pierwszej postaci. Ponadto do drzewa zostanie dodana obsługa akcji (nazwa robocza). Polegać to będzie na wyświetlaniu obok nazwy dodatkowych ikonek, np. podgląd kategorii, edycja kategorii, itp. Do tego dojdą jeszcze dwa przyciski - rozwiń całe i zwiń całe.

PHP5. Wersja dla tego języka jest właśnie testowana i w przeciągu kilkunastu dni będzie skończona.

Dziekuję za sugestie i czekam na kolejne.
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.