4

Web サイトにツリービュー リストを作成する 2 つの関数があります。これは再帰に基づいており、無制限の数のノードを持つツリービューを構築できます。

しかし、私はそれを折りたたみ式にすることはできません。例: スクリプト$_GET['node'] == $node_idは、ブロック要素とそのすべての親を表示 (展開) するかどうかを決定する必要があります。したがって、その「表示」パラメーターをルートに渡す必要があります。

事はあり$display$display2varsです。

  • 3 つの列 (id、parent_id、name) を持つ従来の db テーブルがあります。ルート ノードには、parent_id フィールドが入力されていません。
  • hrefs は GET パラメータのみにリンクします。GET パラメータはノード番号を意味します。

選択したノードに基づいて機能するこの折りたたみ手法が必要です。

更新: OK、完全で精製された情報があります。テーブルを1つだけ含む、データベースを操作するphpファイルを作成しました。問題を理解するためだけに:

1 sqlite3 データベース形式を使用しています。これはDBダンプです:

        # sqlite3 カタログ.sqlite .dump
    PRAGMAforeign_keys=OFF;
    取引を開始します。
    CREATE TABLE groups(id INTEGER PRIMARY KEY NOT NULL, name TEXT, parent_id INTEGER);
    INSERT INTO "グループ" VALUES(1,'root1','');
    INSERT INTO "グループ" VALUES(2,'root2','');
    INSERT INTO "グループ" VALUES(3,'root3','');
    INSERT INTO "グループ" VALUES(4,'root4','');
    INSERT INTO "グループ" VALUES(5,'sub1',1);
    INSERT INTO "グループ" VALUES(6,'sub3',3);
    INSERT INTO "グループ" VALUES(7,'subsub1',5);
    INSERT INTO "グループ" VALUES(8,'subsubsub1',7);
    INSERT INTO "グループ" VALUES(9,'subb1',1);
    専念;

2 これは、データベースを扱う PHP ファイルです。

<?php

$db = new SQLite3('catalog.sqlite');

function build_catalog($db){ //build roots and diggs for childnodes for every root in a loop
    //$content_root="<ul id='collapsedlist'>";
    $content_root = '';
    $roots = $db->query('SELECT * from groups WHERE parent_id="" OR parent_id is null');
    while($root = $roots->fetchArray()){
        list ($content,$display)=get_children_of_node($db,$root['id']); 
        $content_root .= "<li id='".$root['id']."' ><a href='/?node=".$root['id']."'>".$root['name']."</a>";
        $content_root .= $content;
        $content_root .= "</li>\n";
    }
    $content_root = "<ul id='collapsedlist'>".$content_root."</ul>\n";

    return $content_root;
}

function get_children_of_node($db,$node_id){
    if(!isset($content)) $content = '';
    $display = (isset($_GET['node']) && $_GET['node'] == $node_id)? "style='display:block'" : "style='display:none'";
    $query = $db->querySingle('SELECT count(*) from groups WHERE parent_id='.$node_id);
    if ($query > 0){
        //$content .= "<ul class='subcategories'>\n";
        $children = $db->query('SELECT * from groups WHERE parent_id =\''.$node_id.'\'');
        while ($child = $children->fetchArray()){
            list($content2,$display)=get_children_of_node($db,$child['id']);
            $content .= "<li id='".$child['id']."' ".$display.">";
            $content .= "<a href='/?node=".$child['id']."'>".$child['name']."</a>";
            $content .= $content2;
            $content .= "</li>\n";
        }
        $content = "<ul class='subcategories' ".$display.">".$content."</ul>\n";
    }
    return array($content,$display);
}


?>

ここで、php ファイルは純粋な HTML を上に押し付けて終了します。ここで分割したため、エディターは HTML + PHP 構文を一度に解析できません。しかし、それは同じ index.php ファイルです。HTML 部分:

    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>Collapsible Nested List</title>
    </head>
    <body>
        <div id="sidebar">
            <?=build_catalog($db);?>
        </div>
    </body>
    </html>
4

1 に答える 1

3

同じ HTML を保持し、PHP を次のコードに置き換えるだけで、問題を簡単に解決できます。

function get_children($db, $parent_id) {
    $res = $db->query("SELECT * FROM groups WHERE parent_id='$parent_id'");
    if (!$res) return array();

    $out = array();
    while ($row = $res->fetchArray(SQLITE3_ASSOC)) $out[$row['id']] = $row;
    return $out;
}

function get_parent_id($db, $node_id) {
    return $db->querySingle("SELECT parent_id FROM groups WHERE id='$node_id'");
}

function get_menu($db, $node_id) {
    $menu = get_children($db, $node_id);
    while (($parent_id = get_parent_id($db, $node_id)) !== null) {
        $temp = get_children($db, $parent_id);
        $temp[$node_id]['children'] = $menu;
        $menu = $temp;
        $node_id = $parent_id;
    }
    return $menu;
}

function build_html(array $menu) {
    $str = '';
    foreach ($menu as $id => $item) {
        $str .= sprintf('<li><a href="?node=%s">%s</a></li>', $id, $item['name']);
        if (isset($item['children']))
            $str .= build_html($item['children']);
    }
    return "<ul>$str</ul>";
}

function build_catalog($db) {
    $menu = get_menu($db, isset($_GET['node']) ? intval($_GET['node']) : '');
    return build_html($menu);
}

「グループ」テーブルが非常に小さい場合、このコードは実際に最適化できます。$groups 配列内のすべてのレコードを取得し、parent_id インデックスを構築することが考えられます。これにより、カタログの作成がはるかに簡単になります。

于 2012-04-24T15:17:08.070 に答える