再帰処理でHTMLリスト化しjsTreeでツリー表示

HTMLリストの構造

HTMLリストは<ul>で開始してリストの各アイテムを<li>と</li>で囲んで列挙し</ul>で終了します。当然以下のように入れ子に出来ますので、再帰処理でDBのテーブルから動的に入れ子のHTMLリストを生成することになります。

<ul>
  <li>node1_1
    <ul>
      <li>node2_1</li>
      <li>node2_2</li>
    </ul>
  </li>
  <li>node1_2</li>
</ul>

このHTMLリストをjsTreeでツリー表示するには、HTMLリストをdiv要素のidセレクタ指定で囲み、jQuery関数からidセレクタでHTMLリストを探して、jstreeメソッドでツリー表示します。

//HTMLリストをdiv要素で囲む

<div id="html">

<ul>
  <li>node1_1
    <ul>
      <li>node2_1</li>
      <li>node2_2</li>
    </ul>
  </li>
  <li>node1_2</li>
</ul>

</div>


// idセレクタでHTMLリストを取得しjstreeメソッドでツリー表示
$('#html').jstree({

で、今回やろうとしていることは以下のような部品構成の親子関係をHTMLリストに生成してjsTreeメソッドでツリー表示することです。

table

上記のテーブルの親子関係からこんな感じでツリー表示します。
drilldown




jQueryとjsTreeの呼び出し

Headタグ内にjsTreeのテーマテンプレートとjQuery関数とjsTreeプラグインの3つを読み込み、

<head>
	 <link rel="stylesheet" href="themes/default/style.min.css" />
     <script src="jquery.js"></script>
         <script src="jstree.min.js"></script>
</head>

ツリーのソース用DB(BOMの親子関係を定義するテーブル)のパラメータ定義。

$host = "localhost";
$user = "root";
$password = "password";
$db = "asp";
$table = "asp_integrated";

HTMLリストをdiv要素のidセレクタ(html)で囲み、ツリーの根っこ部分をRootとして定義。

<div id="html">
<ul>
    <li>Root
        <ul>

再帰処理関数による親子レコード取得とツリー実装の流れ

以上が前準備で、ここから処理が始まります。
1.子品目データが存在すればマッチする親品目のレコードセットを配列$mainに格納。
2.子品目データが存在しなければそのまま親品目のレコードセットを配列$mainに格納。

$con = mysql_connect($host, $user, $password);
$db_selected = mysql_select_db($db, $con);
$sql = "SELECT C_ITM_CD from $table";
$result = mysql_query($sql);
		
if(isset($_GET['node']) and $_GET['node']<>""){
	$sql = "select P_ITM_CD from $table where P_ITM_CD='".$_GET['node']."'";

}else{
	$sql = "select P_ITM_CD from $table";
			
}
		
$result = mysql_query($sql);
		
while ($row = mysql_fetch_array($result, MYSQL_ASSOC)) {
	$main[] = $row["P_ITM_CD"];
}

配列$mainから要素(親品目のレコード)を1個ずつ取り出して再帰処理関数getChild()に渡す。

if(isset($main)){
	foreach($main as $main_item){
					
		echo "<li>".$main_item;
		echo getChild($con, $main_item, $table)."</li>\n";
	}
}
		
mysql_close($con);

この再帰処理関数が難しいのですがポイントです。

function getChild($con, $item, $table){
	
	$sql = "select * from $table where P_ITM_CD='".$item."'";
	$result = mysql_query($sql, $con);
	$num_rows = mysql_num_rows($result);
	
	if($num_rows > 0){
		//子品目ありの場合
		unset($sem);
		while ($row = mysql_fetch_array($result, MYSQL_ASSOC)) {
			if($row["C_ITM_CD"] != ""){
				$sem[] = $row["C_ITM_CD"];
			}
		}
		$str = "";
		foreach($sem as $sem_item){
			$child = getChild($con, $sem_item, $table);
			if( $child == ""){ 					
				$str .= "<ul><li>".$sem_item."</li></ul>\n";
			}else{
				$str .= "<ul><li>".$sem_item."$child</li></ul>\n";
			}
		}
		return $str;
	}else{
		//子品目なしの場合
	}
}

上記までで生成した再帰HTMLリストをツリービューで表示します。まずjstreeメソッドでツリー表示のインスタンスを生成する部分ですが、基本JavaScriptですので<script>タグ内に記述します。

jstreeメソッドのオプションとしてcoreとdndとpluginsの3つを指定しています。

<script>
//jstreeメソッドでツリービューのインスタンス作成
$('#html')
	.jstree({
		"core" : {
			'check_callback' : function (operation, node, node_parent, node_position, more) {
				node_dest = node_parent["text"].replace(regex, "").trim();
				var res = node_dest.split("[");

				if(res[0] == "Root"){
					return false;
					node_dest = "";
				}else{
					node_dest = res[0];
					return true;
				}
			}
		},

		"dnd" : {
	        },

        	"plugins" : [ "themes", "html_data", "dnd" ]
	});

ノードの各種情報をuiGetParents()関数で取得しています。

function uiGetParents(loSelectedNode) {
        try {
            var lnLevel = loSelectedNode.node.parents.length;
            var lsSelectedID = loSelectedNode.node.id;
            var loParent = $("#" + lsSelectedID);
            var lsParents =  loSelectedNode.node.text + ' >';
            for (var ln = 0; ln <= lnLevel -1 ; ln++) {
                var loParent = loParent.parent().parent();
                if (loParent.children()[1] != undefined) {
                    lsParents += loParent.children()[1].text + " > ";
                }
            }
            if (lsParents.length > 0) {
                lsParents = lsParents.substring(0, lsParents.length - 1);
            }
			str_parent = lsParents.replace(/(<([^>]+)>)/ig,"");
        }
        catch (err) {
            alert('Error in uiGetParents');
        }
    }
	
</script>