表格展示无限级分类(PHP版)


Posted in PHP onAugust 21, 2012

TreeTable通过对单元格的行合并和列合并实现了无限层级也能较好的展示层级架构。
1.构建ID/PID/NAME的数组,后期可通过数据库生成的动态数据。Tree算法请点击

array( 
* 1 => array('id'=>'1','parentid'=>0,'name'=>'一级栏目一'), 
* 2 => array('id'=>'2','parentid'=>0,'name'=>'一级栏目二'), 
* 3 => array('id'=>'3','parentid'=>1,'name'=>'二级栏目一'), 
* 4 => array('id'=>'4','parentid'=>1,'name'=>'二级栏目二'), 
* 5 => array('id'=>'5','parentid'=>2,'name'=>'二级栏目三'), 
* 6 => array('id'=>'6','parentid'=>3,'name'=>'三级栏目一'), 
* 7 => array('id'=>'7','parentid'=>3,'name'=>'三级栏目二') 
* )

 2. 导入TreeTable类库。
import('@.ORG.Util.TableTree'); //Thinkphp导入方法

3. 生成TreeTable HTML代码
$treeTable->init($treearr); 
echo $treeTable->get_treetable();

注意:get_treetable()只生产表体部门,<TALBE></TABLE>请自行构建。
完整代码
<?php 
/** 
* File name: TreeTable.class.php 
* Author: run.gao 312854458@qq.com Date: 2012-07-24 23:22 GMT+8 
* Description: 通用的表格无限级分类 
* */ 
/** 
* 表格展示无限分类是将无线分类已表格的形式表现出来,更好的能体现出分类的所属关系 
* 使用方法: 
* 1. 实例化分类 
* $treeTable = new TreeTable(); 
* 2. 初始化分类,$treearr必须是一个多维数组且包含 id,parentid,name字段 
* $treeTable->init($treearr); 
* 3. 获取无限分类HTML代码 
* echo $treeTable->get_treetable(); 
* */ 
class TreeTable { 
/** 
* 生成树型结构所需要的2维数组 
* @var array 
*/ 
public $arr = array(); 
/** 
* 表格列数 
* @var int 
*/ 
public $columns = 0; 
/** 
* 表格行数 
* @var int 
*/ 
public $rows = 0; 
/** 
* 初始化TreeTable数据 
* @param array 2维数组 
* array( 
* 1 => array('id'=>'1','parentid'=>0,'name'=>'一级栏目一'), 
* 2 => array('id'=>'2','parentid'=>0,'name'=>'一级栏目二'), 
* 3 => array('id'=>'3','parentid'=>1,'name'=>'二级栏目一'), 
* 4 => array('id'=>'4','parentid'=>1,'name'=>'二级栏目二'), 
* 5 => array('id'=>'5','parentid'=>2,'name'=>'二级栏目三'), 
* 6 => array('id'=>'6','parentid'=>3,'name'=>'三级栏目一'), 
* 7 => array('id'=>'7','parentid'=>3,'name'=>'三级栏目二') 
* ) 
*/ 
public function init($arr=array()){ 
if(!is_array($arr)) return false; 
foreach ($arr as $k=>$v) { 
$this->arr[$v['id']] = $v; 
} 
foreach ($this->arr as $k => $v){ 
$this->arr[$k]['column'] = $this->get_level($v['id']); // Y轴位置 
$this->arr[$k]['arrchildid'] = $this->get_arrchildid($v['id']); // 所有子节点 
$this->arr[$k]['arrparentid'] = $this->get_arrparentid($v['id']); // 所有父节点 
$this->arr[$k]['child_bottom_num'] = $this->get_child_count($v['id']); // 所有底层元素节点 
} 
$this->columns = $this->get_columns(); // 总行数 
$this->rows = $this->get_rows(); // 总列数 
// 按照arrparentid和id号进行排序 
$this->sort_arr(); 
foreach ($this->arr as $k => $v){ 
$this->arr[$k]['row'] = $this->get_row_location($v['id']); // X轴位置 
$this->arr[$k]['rowspan'] = $v['child_bottom_num']; // 行合并数 
$this->arr[$k]['colspan'] = $v['child_bottom_num'] == 0 ? $this->columns - $v['column'] + 1 : 0; //列合并数 
} 
return $this->get_tree_arr(); 
} 
/** 
* 获取数组 
* */ 
public function get_tree_arr(){ 
return is_array($this->arr) ? $this->arr : false; 
} 
/** 
* 按arrparentid/id号依次重新排序数组 
* */ 
public function sort_arr(){ 
// 要进行排序的字段 
foreach ($this->arr as $k => $v){ 
$order_pid_arr[$k] = $v['arrparentid']; 
$order_iscost[] = $v['sort']; 
$order_id_arr[$k] = $v['id']; 
} 
// 先根据arrparentid排序,再根据排序,id号排序 
array_multisort( 
$order_pid_arr, SORT_ASC, SORT_STRING, 
$order_iscost, SORT_DESC, SORT_NUMERIC, 
$order_id_arr, SORT_ASC, SORT_NUMERIC, 
$this->arr); 
// 获取每一个节点层次 
for ($column = 1; $column <= $this->columns; $column++) { 
$row_level = 0; 
foreach ($this->arr as $key => $node){ 
if ($node['column'] == $column){ 
$row_level++; 
$this->arr[$key]['column_level'] = $row_level; 
} 
} 
} 
// 重新计算以ID作为键名 
foreach ($this->arr as $k=>$v) { 
$arr[$v['id']] = $v; 
} 
$this->arr = $arr; 
} 
/** 
* 得到父级数组 
* @param int 
* @return array 
*/ 
public function get_parent($myid){ 
$newarr = array(); 
if(!isset($this->arr[$myid])) return false; 
$pid = $this->arr[$myid]['parentid']; 
$pid = $this->arr[$pid]['parentid']; 
if(is_array($this->arr)){ 
foreach($this->arr as $id => $a){ 
if($a['parentid'] == $pid) $newarr[$id] = $a; 
} 
} 
return $newarr; 
} 
/** 
* 得到子级数组 
* @param int 
* @return array 
*/ 
public function get_child($myid){ 
$a = $newarr = array(); 
if(is_array($this->arr)){ 
foreach($this->arr as $id => $a){ 
if($a['parentid'] == $myid) $newarr[$id] = $a; 
} 
} 
return $newarr ? $newarr : false; 
} 
/** 
* 获取当前节点所在的层级 
* @param $myid 当前节点ID号 
* */ 
public function get_level($myid, $init = true){ 
static $level = 1; 
if($init) $level = 1; 
if ($this->arr[$myid]['parentid']) { 
$level++; 
$this->get_level($this->arr[$myid]['parentid'], false); 
} 
return $level; 
} 
/** 
* 获取当前节点所有底层节点(没有子节点的节点)的数量 
* @param $myid 节点ID号 
* @param $init 第一次加载将情况static变量 
* */ 
public function get_child_count($myid, $init = true){ 
static $count = 0; 
if($init) $count = 0; 
if(!$this->get_child($myid) && $init) return 0; 
if($childarr = $this->get_child($myid)){ 
foreach ($childarr as $v){ 
$this->get_child_count($v['id'], false); 
} 
}else{ 
$count++; 
} 
return $count; 
} 
/** 
* 获取节点所有子节点ID号 
* @param $catid 节点ID号 
* @param $init 第一次加载将情况static初始化 
* */ 
public function get_arrchildid($myid, $init = true) { 
static $childid; 
if($init) $childid = ''; 
if(!is_array($this->arr)) return false; 
foreach($this->arr as $id => $a){ 
if($a['parentid'] == $myid) { 
$childid = $childid ? $childid.','.$a['id'] : $a['id']; 
$this->get_arrchildid($a['id'], false); 
} 
} 
return $childid ; 
} 
/** 
* 获取该节点所有父节点ID号 
* @param $id 节点ID号 
* */ 
public function get_arrparentid($id, $arrparentid = '') { 
if(!is_array($this->arr)) return false; 
$parentid = $this->arr[$id]['parentid']; 
if($parentid > 0) $arrparentid = $arrparentid ? $parentid.','.$arrparentid : $parentid; 
if($parentid) $arrparentid = $this->get_arrparentid($parentid, $arrparentid); 
return $arrparentid; 
} 
/** 
* 获取节点所在地行定位 
* @param $myid 节点ID号 
*/ 
public function get_row_location($myid){ 
$nodearr = $this->arr; 
// 获取每一个节点所在行的位置 
foreach ($nodearr as $key => $node){ 
if($myid == $node['id']) { 
$node_row_count = 0; 
$arrparentid = explode(',', $node['arrparentid']); 
// 所有父节点小于当前节点层次的底层节点等于0的元素 
foreach ($arrparentid as $pid){ 
foreach ($nodearr as $node_row){ 
if($node_row['column'] == $nodearr[$pid]['column'] && $nodearr[$pid]['column_level'] > $node_row['column_level'] && $node_row['child_bottom_num'] == 0){ 
$node_row_count ++; 
} 
} 
} 
// 所有当前节点并且节点层次(rowid_level)小于当前节点层次的个数 
foreach ($nodearr as $node_row){ 
if($node['column'] == $node_row['column'] && $node_row['column_level'] < $node['column_level']){ 
$node_row_count += $node_row['child_bottom_num'] ? $node_row['child_bottom_num'] : 1; 
} 
} 
$node_row_count++; 
break; 
} 
} 
return $node_row_count; 
} 
/** 
* 获取表格的行数 
* */ 
public function get_rows(){ 
$row = 0; 
foreach ($this->arr as $key => $node){ 
if($node['child_bottom_num'] == 0){ 
$rows++; // 总行数 
} 
} 
return $rows; 
} 
/** 
* 获取表格的列数 
* */ 
public function get_columns(){ 
$columns = 0 ; 
foreach ($this->arr as $key => $node){ 
if($node['column'] > $columns){ 
$columns = $node['column']; // 总列数 
} 
} 
return $columns; 
} 
/** 
* 获取分类的表格展现形式(不包含表头) 
* */ 
public function get_treetable(){ 
$table_string = ''; 
for($row = 1; $row <= $this->rows; $row++){ 
$table_string .= "\r\t<tr>"; 
foreach ($this->arr as $v){ 
if($v['row'] == $row){ 
$rowspan = $v['rowspan'] ? "rowspan='{$v['rowspan']}'" : ''; 
$colspan = $v['colspan'] ? "colspan='{$v['colspan']}'" : ''; 
$table_string .= "\r\t\t<td {$rowspan} {$colspan}> 
{$v['name']} 
</td>"; 
} 
} 
$table_string .= "\r\t</tr>"; 
} 
return $table_string; 
} 
} 
?>
PHP 相关文章推荐
php session安全问题分析
Jun 24 PHP
php数组函数序列之prev() - 移动数组内部指针到上一个元素的位置,并返回该元素值
Oct 31 PHP
php中删除字符串中最先出现某个字符的实现代码
Feb 03 PHP
PHP之生成GIF动画的实现方法
Jun 07 PHP
PHP连接MySQL查询结果中文显示乱码解决方法
Oct 25 PHP
php实现文件下载实例分享
Jun 02 PHP
php常用数学函数汇总
Nov 21 PHP
PHP实现股票趋势图和柱形图
Feb 07 PHP
php实现处理输入转义字符的代码
Nov 08 PHP
php 函数使用可变数量的参数方法
May 02 PHP
PHP实现的redis主从数据库状态检测功能示例
Jul 20 PHP
一次因composer错误使用引发的问题与解决
Mar 06 PHP
gd库图片下载类实现下载网页所有图片的php代码
Aug 20 #PHP
自己在做项目过程中学到的PHP知识收集
Aug 20 #PHP
用PHP+MySQL搭建聊天室功能实例代码
Aug 20 #PHP
PHP系列学习之日期函数使用介绍
Aug 18 #PHP
PHP中extract()函数的定义和用法
Aug 17 #PHP
Linux下实现PHP多进程的方法分享
Aug 16 #PHP
PHP基础知识回顾
Aug 16 #PHP
You might like
php读取xml实例代码
2010/01/28 PHP
基于Zookeeper的使用详解
2013/05/02 PHP
php的array数组和使用实例简明教程(容易理解)
2014/03/20 PHP
php异步多线程swoole用法实例
2014/11/14 PHP
PHP中生成UUID自定义函数分享
2015/06/10 PHP
PHP应用跨时区功能的实现方法
2019/03/21 PHP
详解Laravel服务容器的绑定与解析
2019/11/05 PHP
PHP架构及原理知识点详解
2019/12/22 PHP
Thinkphp 框架扩展之类库扩展操作详解
2020/04/23 PHP
PHP代码覆盖率统计详解
2020/07/22 PHP
JS控件autocomplete 0.11演示及下载 1月5日已更新
2007/01/09 Javascript
javascript attachEvent和addEventListener使用方法
2009/03/19 Javascript
用js做一个小游戏平台 (一)
2009/12/29 Javascript
Javascript 浮点运算的问题分析与解决方法
2013/08/27 Javascript
jQuery绑定事件on()与弹窗的简要概述
2016/04/27 Javascript
JS检测数组类型的方法小结
2017/03/14 Javascript
JavaScript选取(picking)和反选(rejecting)对象的属性方法
2017/08/16 Javascript
Antd-vue Table组件添加Click事件,实现点击某行数据教程
2020/11/17 Javascript
[58:59]完美世界DOTA2联赛PWL S3 access vs CPG 第一场 12.13
2020/12/16 DOTA
Python查看多台服务器进程的脚本分享
2014/06/11 Python
Python实现简单http服务器
2018/04/12 Python
python脚本开机自启的实现方法
2019/06/28 Python
python异常处理、自定义异常、断言原理与用法分析
2020/03/23 Python
python3代码中实现加法重载的实例
2020/12/03 Python
CSS3使用多列制作瀑布流
2016/05/10 HTML / CSS
HTML5新增元素如何兼容旧浏览器有哪些方法
2014/05/09 HTML / CSS
Helly Hansen工作服美国官方网上商店:为最恶劣的环境
2019/09/04 全球购物
送给程序员的20个Java集合面试问题
2014/08/06 面试题
优秀导游先进事迹材料
2014/01/25 职场文书
民族团结先进个人事迹材料
2014/06/02 职场文书
毕业生工作求职信
2014/06/30 职场文书
作弊检讨书
2015/01/27 职场文书
《检阅》教学反思
2016/02/22 职场文书
导游词之天津盘山
2019/11/01 职场文书
Python带你从浅入深探究Tuple(基础篇)
2021/05/15 Python
MySQL约束(创建表时的各种条件说明)
2022/06/21 MySQL