Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > PHP: Общие вопросы > Помогите реализовать


Автор: ramen 29.6.2008, 23:57
Подскажите простую идею как реализовать древовидный тип построения категорий?
При клике на определённый id допустим 3 в базе ищет другие категории с этим id в графе nomains и открывает  страницу со списком других категорий у которых как видно из нижнего листинга номер в nomains 10, а как реализовать сохранение основного списка?
Код

1-6
|  |
|  |
|  7-8
2-9
|
3-10-11
|     |
4    12
|
5


Код

$cat=$_GET["cat"];
if($cat<=0){
$req=mysql_query("select * from ".$conf["tb_prefix"]."cat where nomains=0");
}
else
{
$req=mysql_query("select * from ".$conf["tb_prefix"]."cat where nomains=$cat");
}
if(mysql_num_rows($req)==0) die("Категорий нет");


while($r=mysql_fetch_array($req)) {
echo"<a href=\"gallery.php?cat=".$r[id_cat]."\">".$r[namecat]."</a>$cat<br>";
}

Автор: skyboy 30.6.2008, 11:15
для хранения древовидных структур данных(к которым относится и изображенное тобою) возможно применить:
- списки смежность(для каждого узла указывается родительский узел; для узлов верхнего уровня указывается 0, NULL или другое значение, которое не может означать существуюший узел)
- materialized path("материализованный путь") - для каждого узла хранится список родительских узлов в порядке очередности; для узлов верхнего уровня в поле "списка родителей" просто пусто
- nested sets; по этой теме лучше посмотреть одну из большого количества существующих статей; там упор сделан на оптимизацию выбора ветви целиком(узла со всеми предками); вставка и изменение - довольно сложная в сравнении с остальными вариантами структуры операции.

Автор: Feldmarschall 30.6.2008, 11:51
я думаю, у него проблема не в хранении, а в интерфейсе.


ramen, все, что надо "сохранить" должно передаваться из браузера. То есть, все открытые категории должны быть в ссылке.

Автор: skyboy 30.6.2008, 11:59
Feldmarschall, да, вполне может быть так.

Автор: ramen 30.6.2008, 20:11
нужно именно построить интерфейс, пол дня ломал голову, никак...

Автор: skyboy 1.7.2008, 09:20
уже сформированный вариант в html есть?

Автор: MixerMsK 1.7.2008, 12:07
Я делаю так. 

1. Делаем таблицу:

Categories:
id[int]
name[varchar]
parent[int]

2. Логика в том, что если parent=0 - категория корневая. В противном случае в parent лежит id родителя.

3. Код(примерный, т.к. у меня все собрано в классы и объяснять суть самопальных функций смысла не вижу):

Код

function show_cats($parent=0)
{
    $cats=mysql_query("SELECT * FROM categories WHERE parent=$parent");
    $cats_n=mysql_num_rows($cats);
    for($c=0;$c<$cats_n;$c++)
    {
        $c_tmp=mysql_get_row($cats);
        $out.=$c_tmp[0];
        echo '<ol><li><a href="index.php?cat=' . $c_tmp[0] . '">' . $c_tmp[1] . '</a>';
        show_cats($c_tmp[2]);
        echo '</ol>';

        
    }
}

Автор: Feldmarschall 1.7.2008, 12:12
Вопрос, который задавал автор:
Цитата(ramen @  29.6.2008,  23:57 Найти цитируемый пост)
как реализовать сохранение основного списка?


Автор: IceDragon 1.7.2008, 16:33
Может конечно кое что не рационально делал давно smile
Создавал дерево так (на битриксе):
Код

   $arTree = array(); //массив дерева

   while($arItem = $items->GetNext()) //получаем лист  
   {

   $arFilter = Array(
   "IBLOCK_ID"=>IntVal($IBLOCK_ID), 
   "ACTIVE"=>"Y", 
   "PROPERTY_226_VALUE" => $arItem['ID']
   );

  //колво элементов
  $arTree[$arItem['ID']]['count_elements'] = '';
   $res = CIBlockElement::GetList(Array("SORT"=>"ASC"), $arFilter,Array("ID"));
      while($arItem1 = $res->GetNextElement()) {
        $arTree[$arItem['ID']]['count_elements'] ++;
      }


//уровень
$arTree[$arItem['ID']]['level'] = $arItem['DEPTH_LEVEL'];

//ИД
$arTree[$arItem['ID']]['id'] = $arItem['ID'];

//Имя
$arTree[$arItem['ID']]['name'] = $arItem['NAME'];

//родитель
$arTree[$arItem['ID']]['parent'] = $arItem['IBLOCK_SECTION_ID'];

//массив детей
if (!isset($arTree[$arItem['IBLOCK_SECTION_ID']]['childs'])) {
  $arTree[$arItem['IBLOCK_SECTION_ID']]['childs'] = array();
}

$arTree[$arItem['IBLOCK_SECTION_ID']]['childs'][$arItem['ID']] = $arItem['ID'];
$i++;

}


/* Функция строит дерево!
 * 
 * @param $res
 * @param $arTree
 * @param $ID
 * @return string $res - дерево.
/
function show_tree($res,$arTree,$ID) {

if (!empty($ID)) { //если у нас не корень
if(empty($drow)) {$drow="line";} //предварительная степень отрисовки - линия

$drow_im="line";
if($ID!=$SECT) {$dir_on="mpb"; $dir_off="mmb";}   //
if($ID==$SECT) {$dir_on="mps"; $dir_off="minus";} //непустая папка
if($ID==$SECT && (count($arTree[$ID]['childs'])==0)) {$drow_im="empty";}  //пустая папка

$el_id=$arTree[$ID]['parent']."_".$ID;

$res .= drow_line_site($arTree[$ID]['level'],$drow);

$res .= "\n\n".'<img src="/im/'.$dir_on.'.gif" onclick=\'chTel("'.$el_id.'","'.$dir_off.'",this)\'><a href="/firms/index.php?SECT='.$ID.'"><img id="tree_folder'.$el_id.'" src="/im/folder.gif">'.html_entity_decode($arTree[$ID]['name']).'</a><br/>
<div id="tree_div'.$el_id.'" style="display:none;">';
}

foreach($arTree[$ID]['childs'] as $child)
{
 $res = show_tree($res,$arTree,$child);
}

if(!empty($ID)) {
$res.="</div>";
}
    return $res;
}
// END function show_tree

$res='';

echo show_tree($res,$arTree,"");


Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)