表格展示无限级分类(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数字转汉字代码(算法)
Oct 08 PHP
php 无法加载mysql的module的时候的配置的解决方案引发的思考
Jan 27 PHP
php中stream(流)的用法
Mar 25 PHP
php过滤html标记属性类用法实例
Sep 23 PHP
php密码生成类实例
Sep 24 PHP
php绘制一个扇形的方法
Jan 24 PHP
PHP也能干大事之PHP中的编码解码详解
Apr 20 PHP
php导出中文内容excel文件类实例
Jul 06 PHP
php实现图片以base64显示的方法
Oct 13 PHP
PHP迭代器和迭代的实现与使用方法分析
Apr 19 PHP
PHP小程序支付功能完整版【基于thinkPHP】
Mar 26 PHP
在laravel框架中使用model层的方法
Oct 08 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投票程序源码
2007/03/11 PHP
Codeigniter通过SimpleXML将xml转换成对象的方法
2015/03/19 PHP
Thinkphp3.2简单解决多文件上传只上传一张的问题
2017/09/26 PHP
PHP递归的三种常用方式
2019/02/28 PHP
JQuery EasyUI 数字格式化处理示例
2014/05/05 Javascript
用js格式化金额可设置保留的小数位数
2014/05/09 Javascript
JavaScript操作XML文件之XML读取方法
2015/06/09 Javascript
Javascript原型链的原理详解
2016/01/05 Javascript
Bootstrap+jfinal退出系统弹出确认框的实现方法
2016/05/30 Javascript
基于Vue.js实现数字拼图游戏
2016/08/02 Javascript
AngularJS使用ng-repeat和ng-if实现数据的删选显示效果示例【适用于表单数据的显示】
2016/12/13 Javascript
jQuery实现选项卡功能(两种方法)
2017/03/08 Javascript
vue-cli中的webpack配置详解
2017/09/25 Javascript
AngularJS自定义表单验证功能实例详解
2018/08/24 Javascript
解决vue 子组件修改父组件传来的props值报错问题
2019/11/09 Javascript
Python实现遍历windows所有窗口并输出窗口标题的方法
2015/03/13 Python
新年快乐! python实现绚烂的烟花绽放效果
2019/01/30 Python
python批量爬取下载抖音视频
2019/06/17 Python
Python学习笔记之错误和异常及访问错误消息详解
2019/08/08 Python
python判断变量是否为int、字符串、列表、元组、字典的方法详解
2020/02/13 Python
python pandas移动窗口函数rolling的用法
2020/02/29 Python
python3中sorted函数里cmp参数改变详解
2020/03/12 Python
Python调用Redis的示例代码
2020/11/24 Python
Python中的流程控制详解
2021/02/18 Python
css3实现一个div设置多张背景图片及background-image属性实例演示
2017/08/10 HTML / CSS
美国时尚孕妇装品牌:A Pea in the Pod
2017/07/16 全球购物
物流专业大学生求职信范文
2013/10/28 职场文书
毕业生简历自我评价范文
2014/04/09 职场文书
竞选团支书演讲稿
2014/04/28 职场文书
社区学习党的群众路线教育实践活动心得体会
2014/11/03 职场文书
安阳殷墟导游词
2015/02/10 职场文书
青少年法制教育心得体会
2016/01/14 职场文书
用React Native制作一个简单的游戏引擎
2021/05/27 Javascript
告别网页搜索!教你用python实现一款属于自己的翻译词典软件
2021/06/03 Python
python人工智能human learn绘图可创建机器学习模型
2021/11/23 Python
十大最强火系宝可梦,喷火龙上榜,第一名有双火属性
2022/03/18 日漫