表格展示无限级分类(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 相关文章推荐
一个更简单的无限级分类菜单代码
Jan 16 PHP
PHP 作用域解析运算符(::)
Jul 27 PHP
让PHP以ROOT权限执行系统命令的方法
Feb 10 PHP
php中http_build_query 的一个问题
Mar 25 PHP
PHP中加密解密函数与DES加密解密实例
Oct 17 PHP
thinkphp3.2.2前后台公用类架构问题分析
Nov 25 PHP
PHP获取文件夹内文件数的方法
Mar 12 PHP
php把数组值转换成键的方法
Jul 13 PHP
PHP上传文件参考配置大文件上传
Dec 16 PHP
php 输出json及显示json中的中文汉字详解及实例
Nov 09 PHP
使用phpQuery获取数组的实例
Mar 13 PHP
[原创]php使用strpos判断字符串中数字类型子字符串出错的解决方法
Apr 01 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防CC攻击实现代码
2011/12/29 PHP
浅谈web上存漏洞及原理分析、防范方法(安全文件上存方法)
2013/06/29 PHP
PHP5.3安装Zend Guard Loader图文教程
2014/09/29 PHP
php简单图像创建入门实例
2015/06/10 PHP
php实现爬取和分析知乎用户数据
2016/01/26 PHP
Laravel中任务调度console使用方法小结
2017/05/07 PHP
PHP校验15位和18位身份证号的类封装
2018/11/07 PHP
JavaScript中的排序算法代码
2011/02/22 Javascript
javascript实现日期按月份加减
2015/05/15 Javascript
在ASP.NET MVC项目中使用RequireJS库的用法示例
2016/02/15 Javascript
Angular 路由route实例代码
2016/07/12 Javascript
jquery动态遍历Json对象的属性和值的方法
2016/07/27 Javascript
JS继承之借用构造函数继承和组合继承
2016/09/07 Javascript
jQuery中用on绑定事件时需注意的事项
2017/03/19 Javascript
jquery+css实现下拉列表功能
2017/09/03 jQuery
详解angularjs popup-table 弹出框表格指令
2017/09/20 Javascript
写gulp遇到的ES6问题详解
2018/12/03 Javascript
JS使用JSON.parse(),JSON.stringify()实现对对象的深拷贝功能分析
2019/03/06 Javascript
使用easyui从servlet传递json数据到前端页面的两种方法
2019/09/05 Javascript
Jquery让form表单异步提交代码实现
2019/11/14 jQuery
javascript如何使用函数random来实现课堂随机点名方法详解
2020/07/28 Javascript
再也不怕 JavaScript 报错了,怎么看怎么处理都在这儿
2020/12/09 Javascript
[01:03:47]VP vs NewBee Supermajor 胜者组 BO3 第一场 6.5
2018/06/06 DOTA
[42:06]2019国际邀请赛全明星赛 8.23
2019/09/05 DOTA
Django中更新多个对象数据与删除对象的方法
2015/07/17 Python
Python的SQLalchemy模块连接与操作MySQL的基础示例
2016/07/11 Python
python将unicode转为str的方法
2017/06/21 Python
在Python中COM口的调用方法
2019/07/03 Python
如何使用Flask-Migrate拓展数据库表结构
2019/07/24 Python
Python pip 安装与使用(安装、更新、删除)
2019/10/06 Python
你需要学会的8个Python列表技巧
2020/06/24 Python
css3 box-shadow阴影(外阴影与外发光)图示讲解
2017/08/11 HTML / CSS
Jogun Shop中文官网:韩国知名时尚男装网站
2016/10/12 全球购物
品牌推广策划方案
2014/05/28 职场文书
人大调研汇报材料
2014/08/14 职场文书
协会周年庆活动方案
2014/08/26 职场文书