Autor Zpráva
unlucky
Profil
mam v sql
categories: id, category, seo_category,parent_id

Potreboval bych vypsat kategorie a kdyz hlavni kategorie ma subkategorii, tak se po kliknuti rozjede s pomoci js subkategorie. Dival jsem se na interval a na skript j.vrany ale porad mi to nefrci :D

muzete mi pls poradit? zatim se mi zobrazuji podkategorie jenom z getu. Potreboval bych vypsani vsech najednou a pomoci js je zobrazit

 function &getThreads($nodes) {
$all = array();
foreach($nodes as $node) {
$id = $node['id'];
$idp = $node['parent_id'];
$text = $node['text'];
if(!array_key_exists($id, $all)) {
$all[$id] = array(
'text' => $text,
'childs' => array()
);
} //koniec if
else {
$all[$id]['text'] = $text;
} //koniec else
if(!array_key_exists($idp, $all)) {
$all[$idp] = array();
} //koniec if
$all[$idp]['childs'][$id] = &$all[$id];
} //koniec foreach
return $all[0];
}
function echoTree(&$tree,$b,$last) {
static $level = 0;
if(count($tree)) {
foreach($tree['childs'] as $id => $node) {
$i++;
$q=mysql_query("select count(*) from categories where
parent_id='$id'");
$zaznam=mysql_fetch_row($q);
$pocet=$zaznam[0];

if($level>0 and count($tree['childs'])==$i) {
$last[$level]=1;
}
else $last[$level]=0;

for($f=1;$f<=($level-1);$f++) {
if($last[$f]<>1) echo '<img src="./images/arr_thrue.gif"
width="10" height="10" alt="" />';
else echo '<img src="./images/spacer.gif" width="10"
height="10" alt="" />'; 
}

if($level>0 and count($tree['childs'])<>$i) echo '<img
src="./images/arr_start.gif" width="10" height="10" alt="" />';
if($level>0 and count($tree['childs'])==$i) echo '<img
src="./images/arr_end.gif" width="10" height="10" alt="" />';

if(count($node['childs']) or $pocet<1) echo '<img
src="images/minus.gif" style="margin-right:3px;" border="0" alt=""
/>';
else echo '<img src="images/plus.gif"
style="margin-right:3px;" border="0" alt="" />';

if($id == $_GET['id']) {
$q=mysql_query("select parent_id from categories where
id='$id'");
$zaznam=mysql_fetch_row($q);
$id=$zaznam[0];
}

echo '<a href="index.php?id='.$id.'"
onclick="zobraz();">'.$node['text'].'</a>&nbsp;('.$pocet.')<br />';

if(count($node['childs'])) {
$level++;
echoTree($node,$b,$last);
$level--;
}
}
}
}
function getNodesArray($parent) {
do {
$query=mysql_query("select id,parent_id,category from categories where
parent_id='$parent' order by category");
while($zaznam=mysql_fetch_row($query)) {

$polea=array('id'=>$zaznam[0],'parent_id'=>$zaznam[1],'text'=>$zaznam[2]);
$pole[]=$polea;
if($zaznam[1]>0) $otec=$zaznam[1];
else $otec=0;
}
$query2=mysql_query("select parent_id from categories where id='$otec' order by
category");
if(mysql_num_rows($query2)>0) {
$zaznam2=mysql_fetch_row($query2);
$parent=$zaznam2[0];
$parentExists=1;
}
else $parentExists=0;
}
while ($parentExists);
return $pole;
}

function checkParent($parent) {
$query=mysql_query("select count(*) from categories where
parent_id='$parent'");
$zaznam=mysql_fetch_row($query);
if($zaznam[0]>0) return $parent;
else {
$query=mysql_query("select parent_id from categories where id='$parent'");
$zaznam=mysql_fetch_row($query);
return $zaznam[0];
}
}




if(!$_GET['id']) $id=0;
else $id=$_GET['id'];

$parent = checkParent($id);
$nodes = getNodesArray($parent);
if($id<>$parent) {
$zobraz_produkty=1;
$category_id=$id;
}

$nodes = getNodesArray($parent);
$tree = getThreads($nodes);
echoTree(&$tree,$b,$last);
Alphard
Profil
Ten kód je neodsazený a moc dlouhý, na diskusi naprosto nečitelný. Ale na první pohled je tam strašně moc dotazů. Máte-li jen 2 úrovně kategorií, použijte left join a spojte tabulku podle vazby rodič-potomek samu se sebou. Je-úrovní kategorií více, Jakub Vrána to dělá jinak (u traverzování kolem stromu je důležité pochopit princip řazení, který obchází všechny větve stromu daným směrem).
unlucky
Profil
co si myslite o tomhle:


$s=mysql_query("select NAD.id as NAD,NAD.category as NAD_NAZ,POD.id as POD, POD.category as POD_NAZ, POD.parent_id as PAR
from categories NAD left join categories POD on (NAD.id=POD.parent_id)
");

$cat="";
while($z=mysql_fetch_assoc($s)){
  if ($z['POD_NAZ']!=""){
    if($cat==$z['NAD_NAZ']){
      echo "--- $z[POD_NAZ] $z[PAR]<br />"; 
    }else{
      echo "$z[NAD] $z[NAD_NAZ]<br />";
    }
  $cat=$z['NAD_NAZ'];
  }
}
Alphard
Profil
Nebyl by k tomu nějaký komentář? Funguje to, nefunguje to? Bez přesné znalosti struktury databáze těžko hodnotit.
Řazení by šlo zjednodušit vhodným order by, pak by pro rozhodnutí rodič/potomek stačila podmínky if($parent_id == 0).
unlucky
Profil
Alphard:
tohle mi funguje. Ale chtel bych zjistit, jestli kategorie ma podkategorie nebo ne
Kcko
Profil
Tak si to při první iteraci uložte do pole a vypisujte až při druhé iteraci, v tu chvíli budete mít veškeré informace, které potřebujete.
unlucky
Profil
Kcko:
Zkousel jsem to a porad mi to nejede. Nevim totiz kdy, kde a jak :)
Kcko
Profil
unlucky:
hodte na pastebin kompletní tabulku včetně funkčního php kódu a já se o to pokusím. Ale máte na to tak 10 minut, pak začnu usínat.
unlucky
Profil
Kcko:
categories:
id/ category / seo_category / parent_id

zatim funkcni kod:
$s=mysql_query("select NAD.id as NAD,NAD.category as NAD_NAZ,POD.id as POD, POD.category as POD_NAZ, POD.parent_id as PAR
from categories NAD left join categories POD on (NAD.id=POD.parent_id)
");
 
$cat="";
while($z=mysql_fetch_assoc($s)){
  if ($z['POD_NAZ']!=""){
    if($cat==$z['NAD_NAZ']){
      echo "--- $z[POD_NAZ] $z[PAR]<br />"; 
    }else{
      echo "$z[NAD] $z[NAD_NAZ]<br />";
    }
  $cat=$z['NAD_NAZ'];
  }
}
Kcko
Profil
unlucky:
Strukturu tabulky + data (ručně to vytvářet nebudu).
unlucky
Profil
Kcko:
--
-- Struktura tabulky `categories`
--

CREATE TABLE IF NOT EXISTS `categories` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `category` varchar(50) NOT NULL,
  `seo_category` varchar(50) NOT NULL,
  `description` text NOT NULL,
  `parent_id` int(11) NOT NULL,
  `lang` varchar(2) NOT NULL,
  `sort_order` int(11) NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `category` (`category`,`seo_category`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=36 ;

--
-- Vypisuji data pro tabulku `categories`
--

INSERT INTO `categories` (`id`, `category`, `seo_category`, `description`, `parent_id`, `lang`, `sort_order`) VALUES
(17, 'Anime a filmy', 'anime-a-filmy', '', 0, 'cs', 0),
(13, 'Novinky', 'novinky', '', 0, 'cs', 0),
(14, 'Manga', 'manga', '', 0, 'cs', 0),
(15, 'Informace', 'informace', '', 0, 'cs', 0),
(16, 'Galerie', 'galerie', '', 0, 'cs', 0),
(18, 'Download', 'download', '', 0, 'cs', 0),
(19, 'Ostatní', 'ostatni', '', 0, 'cs', 0),
(20, 'Příběh', 'pribeh', '', 15, 'cs', 0),
(21, 'Postavy', 'postavy', '', 15, 'cs', 0),
(28, 'Útoky', 'utoky', '', 15, 'cs', 0),
(23, 'Levely', 'levely', '', 15, 'cs', 0),
(24, 'Power level', 'power-level', '', 15, 'cs', 0),
(31, 'Online', 'online', '', 0, 'cs', 0),
(27, 'Hry', 'hry', '', 0, 'cs', 0),
(30, 'Vzhled postav', 'vzhled-postav', '', 0, 'cs', 0),
(32, 'Dragon Ball', 'dragon-ball', '', 31, 'cs', 0),
(33, 'Dragon Ball Z', 'dragon-ball-z', '', 31, 'cs', 0),
(34, 'Dragon Ball GT', 'dragon-ball-gt', '', 31, 'cs', 0),
(35, 'Dragon Ball animované filmy', 'dragon-ball-animovane-filmy', '', 31, 'cs', 0);
Kcko
Profil
Nic moc kód, ale na pochopení idey a funkčnosti by to mohlo stačit. (Neomezeny počet úrovní)

$q = mysql_query("SELECT * FROM categories order by category");

$tree = array();

while ($r = mysql_fetch_object($q))
{
    $tree['rodic'][$r->id] = $r->parent_id;
    $tree['deti'][$r->parent_id][] = $r->id;
    $tree['pages'][$r->id] = $r;
}


$menu = new Tree($tree);
echo $menu->dump(0);



class tree
{
    public $tree;
    public $parents = array();
    
    public $childs = array();
    
    public function __construct($tree)
    {
        $this->tree = $tree;
   
    }
    

    public function dump($parent)
    {
        $out = '';
        if (isset($this->tree['deti'][$parent])) // ma deti 
        {
            $out .= "<ul>";
                foreach ($this->tree['deti'][$parent] as $item)
                {
                    
                  $out .= "<li>";
                  $out .= "<a href='?p=".$item."'>".$this->tree['pages'][$item]->category."</a>";
                  $out .= $this->dump($item);
                  $out .= "</li>";  
                }
            $out .= "</ul>";
        }
        
        return $out;
    }

    
    
}
unlucky
Profil
dekuji za kod. ALe chtel jsem to takto:

pokud ma hlavni kategorie podkategorie, hlavni kategorie se nebude chovat jako odkaz. Pokud nema, je odkazem.

Napr.:

Hlavni
--<a>vedle</a>
--<a>vedle</a>
<a>Hlavni2</a>
<a>Hlavni3</a>
Hlavni4
--<a> vedle</a>
--<a>vedle</a>
Kcko
Profil
unlucky:
 public function dump($parent, $level = 0)
    {
        
        
   
        if (isset($this->tree['deti'][$parent])) 
        {
            
                foreach ($this->tree['deti'][$parent] as $item)
                {
                   
                  $out .=   ($level > 0 ) ? str_repeat('&nbsp;&nbsp;&nbsp;', $level) . '-- ' : '';
                  
                  if (isset($this->tree['deti'][$item])) 
                    $out .= $this->tree['pages'][$item]->category . "<br />";
                  else
                    $out .= "<a href='?p=".$item."'>".$this->tree['pages'][$item]->category."</a> <br />";
                  
                  
                  $out .= $this->dump($item, $level + 1);
                  
                    
                }
            
        }
        
        
        
        return $out;
    }



A jestli to máš k tooglovaní (rozbalování / zabalování) tak se to dalo snadno udělat pomocí JS / jQuery.
Jdu se dívat na Underworld ;) snad už si s tím poradíš.
unlucky
Profil
puvodni myslenka byla s rozbalovanim v js. Pak jsem chtel univerzalni skript. Ten druhy kod nevypisuje vsechny kategorie :(

Jak by se dalo pomoci jq/jquery?
Kcko
Profil
Vypisuje, pokud jsi to zkopíroval dobře.

Tady i s kontrolou


 public function dump($parent, $level = 0)
    {
        
        
        ++$this->counter;
        if (isset($this->tree['deti'][$parent])) 
        {       
            
                foreach ($this->tree['deti'][$parent] as $item)
                {
                   
                  $out .=   ($level > 0 ) ? str_repeat('&nbsp;&nbsp;&nbsp;', $level) . '-- ' : '';
                  
                  if (isset($this->tree['deti'][$item])) 
                    $out .= $this->tree['pages'][$item]->category . "<br />$this->counter ";
                  else
                    $out .= "<a href='?p=".$item."'>".$this->tree['pages'][$item]->category."</a> $this->counter<br />";
                  
                  
                  $out .= $this->dump($item, $level + 1);
                  
                    
                }
            
        }
        
        
        
        
        
        return $out;
    }
    
    
}
unlucky
Profil
mam celkem 50 zaznamu, ale vypisuje pouze 33. ZKopirovany to mam spravne :)

nakonec jsem si to vyresil klasickym zpusobem:


 $main_cat=mysql_query("select * from categories  order by sort_order asc");
 while($m=mysql_fetch_assoc($main_cat)){
if($m['parent_id==0']){
  $main['category'][]=$m['category'];
  $main['seo_category'][]=$m['seo_category'];  
  $main['id'][] =$m['id'];
 }ELSE{
  $sub['category'][]=$m['category'];
  $sub['seo_category'][]=$m['seo_category'];  
  $sub['parent_id'][] =$m['parent_id'];
 } 
} 

for ($z=0;$z<count($main['category']);$z++){
  $get_sub=array_keys($sub['parent_id'],$main['id'][$z]);
  if(empty($get_sub)){
    //zadna sub
    echo "<a href=''>".$main['category'][$z].$main['id'][$z]."</a><br/>";
  }else{
    //vic sub
    echo $main['category'][$z].$main['id'][$z]." <br/>";
    foreach($get_sub as $value){
        //zobrazime subcat
        echo  "--".$sub['category'][$value].$sub['parent_id'][$value]."<br />";
    }
  }
}
Kcko
Profil
Ach jo.
unlucky
Profil
to je divny, muj skript a tvuj nezobrazuji presne 1 kategorii a jeji podkategorie kvuli order by sort_order asc

Vaše odpověď

Mohlo by se hodit

Odkud se sem odkazuje


Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm: