yii框架分类树扩展示例

提供两种方式的分类树格式,表格和下拉框形式的树形结构
可以自定义表格和下拉框的样式,自定义以哪一列的参数为格式化数据,自定义层级关系参数,自定义表格列名称,也可以设置时间的格式化。

调用方式

表格方式:


代码如下:

<?php $this->widget('ext.tree.widgets.TreeWidget',array(
        'dataProvider'  => $dataProvider,           // 传递数据
        'pid'           => 'pid',                   // 设置层级关系id
        'tableClass'    => 'items table table-striped table-bordered table-condensed',  // 表格样式
        'formatParam'   => 'name',                  // 设置格式化字段   
        'formatTime'    => array(                   // 设置格式化的时间参数
            'created'
        ),              
        'tableHead'     => array(                   // 设置表格列头信息
                '分类ID',
                '频道',
                '中文名',
                '英文名',
                '首字母',
                '排序',
                '分类级别',
                '父ID',
                '创建时间',
        ),   
    )); ?>

下拉框方式


代码如下:

<?php $this->widget('ext.tree.widgets.TreeWidget',array(
            'dataProvider'  => $cate,           // 传递数据
            'pid'           => 'pid',                   // 设置父ID           
            'formatParam'   => 'name',                  // 设置格式化字段
            'treeType'      => false,                   // 输出树格式
            'selectClass'  => 'class="span11"',         // 设置下拉框样式
             'defaultSelectValue' => array(             // 设置下拉框的默认值和选项
                    0 , '≡ 作为一级栏目 ≡'
             ),
        )); ?>

TreeWidget.php

代码如下:

<?php

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/**
 * Description of Tree
 *
 * @author 汪嘉诚
 * @email 819434425@qq.com
 * 
 * 表格方式调用
    <?php $this->widget('ext.tree.widgets.TreeWidget',array(
        'dataProvider'  => $dataProvider,           // 传递数据
        'pid'           => 'pid',                   // 设置层级关系id
        'tableClass'    => 'items table table-striped table-bordered table-condensed',  // 表格样式
        'formatParam'   => 'name',                  // 设置格式化字段   
        'formatTime'    => array(                   // 设置格式化的时间参数
            'created'
        ),              
        'tableHead'     => array(                   // 设置表格列头信息
                '分类ID',
                '频道',
                '中文名',
                '英文名',
                '首字母',
                '排序',
                '分类级别',
                '父ID',
                '创建时间',
        ),   
    )); ?>
 *
 * 下拉框方式调用
 * <?php $this->widget('ext.tree.widgets.TreeWidget',array(
            'dataProvider'  => $cate,           // 传递数据
            'pid'           => 'pid',                   // 设置父ID           
            'formatParam'   => 'name',                  // 设置格式化字段
            'treeType'      => false,                   // 输出树格式
            'selectClass'  => 'class="span11"',         // 设置下拉框样式
             'defaultSelectValue' => array(             // 设置下拉框的默认值和选项
                    0 , '≡ 作为一级栏目 ≡'
             ),
        )); ?>
 */
class TreeWidget extends Widget {
    /**
     * CArrayDataProvider 数据对象或数组数据
     * 组件数据接收参数
     * @var Object || array
     */
    public $dataProvider;

/**
     * 赋值接收数据
     * @var type
     */
    public $arrAll = array();

/**
     * 按_ID作键名的多维关系
     * @var type
     */
    public $arrIdRelation = array();

/**
     * 按_ID作键名的多维关系的简化,用来输出树状图
     * @var type
     */
    public $arrIdRelationSimple = array();

/**
     * 将原始数据转化成的_ID作键名的数组
     * @var type
     */
    public $arrIdAll = array();

/**
     * 所有的父子关系
     * @var type
     */
    public $arrIdSon = array();

/**
     * 叶子节点的_ID
     * @var type
     */
    public $arrIdLeaf = array();

/**
     * 根节点的_ID
     * @var type
     */
    public $arrIdRoot = array();

/**
     * 每个节点下的子孙后代_ID
     * @var type
     */
    public $arrIdChildren = array();

/**
     * 每个节点回逆到根
     * @var type
     */
    public $arrIdBackPath = array();

/**
     * 输出树的结构
     * @var type
     */
    public $strItem = '<br />{$strSep}{$name}';

/**
     * 设置表格样式
     * @var type
     */
    public $tableClass  = 'items table table-striped table-bordered table-condensed';

/**
     * 数据字段参数数组
     * @var type
     */
    public $dataKey   = array();

/**
     * 指定需要格式化的字段
     * @var type
     */
    public $formatParam = 'name';

/**
     * 表格列名称
     * @var type
     */
    public $tableHead   = array();

/**
     * 父ID
     * @var type
     */
    public $pid = 'pid';

/**
     * 指定树的类型
     * true 表格类型树
     * false 下拉框类型树
     * @var type
     */
    public $treeType = true;

/**
     * 绑定下拉框value值
     * @var type
     */
    public $optionValue = 'id';

/**
     * 格式化时间
     * @var type
     */
    public $formatTime = array();

/**
     * 下拉框样式
     * @var type
     */
    public $selectClass = 'class="span3"';

/**
     * 设置下拉框的默认值和选项
     * @var type
     */
    public $defaultSelectValue = array(
        0,'≡ 作为一级栏目 ≡',
    );

/**
     * 设置下拉框是否多选
     * true 多选
     * false 单选
     * @var type
     */
    public $isMultiple = false;

/**
     * 绑定到下拉框的默认值
     * @var type
     */
    public $bindSelectValue = 0;

/**
     * 运行
     */
    public function run() {               
            if (is_array($this->dataProvider) && count($this->dataProvider) > 0)
                    $data = $this->_run($this->dataProvider);
            else if (is_object($this->dataProvider) && count($this->dataProvider->rawData) > 0)
                    $data = $this->_run($this->dataProvider->rawData);

$this->render('tree' , array('data'=>$data));
    }

/**
     *
     * @return type
     */
    private function _run($datas){           
            foreach ($datas as $data)
                    $this->arrAll[] = $data;
                    $this->dataKey = array_keys($data);

$this->processData();
            if ($this->treeType === true)
                    $data = $this->getTable();
            else
                    $data = $this->getSelect($this->pid, $this->bindSelectValue, $this->isMultiple, $this->selectClass, $this->defaultSelectValue);

return $data;
    }

/**
     * 获得html
     * @return type
     */
    public function getHtml() {
            return $this->genHtml();
    }

/**
     * 设置分层字段
     * 表格类型
     * @return string
     */
    public function getItemName(){           
            $html = '<tr>';
            foreach($this->dataKey as $v) {                   
                    if ($this->formatParam == $v)
                            $str = '{$strSep}';
                    else
                            $str = '';

$html .= '<td>'.$str.'{$'.$v.'}</td>';
            }
            $html .= '</tr>';
            return $html;
    }

/**
     * 获取表格列名称
     * @return string
     */
    public function getTableHead(){
            $html = '<tr>';
            foreach($this->tableHead as $v)
                    $html .= '<th>'.$v.'</th>';

$html .= '</tr>';
            return $html;
    }

/**
     * 获得表格形式的树
     * @return string
     */
    public function getTable() {                   
            $this->strItem = $this->getItemName();
            $strRe = '<table class="'.$this->tableClass.'">';
            $strRe .= '<thead>'.$this->getTableHead().'</thead><tbody>';
            $strRe .= $this->genHtml();
            $strRe .= '</tbody></table>';
            return $strRe;
    }

/**
     * 获取下拉框形式的树
     * @param type $strName
     * @param array $arrValue
     * @param type $blmMulti
     * @param type $strExt
     * @param type $arrFirst
     * @return string
     */
    public function getSelect($strName = 'tree', $arrValue = array(), $blmMulti = false, $strExt = '', $arrFirst = null) {
            !is_array($arrValue) && $arrValue = array($arrValue);
            foreach ($this->arrIdAll as $strTemp => $arrTemp) {
                    $this->arrIdAll[$strTemp]['selected'] = '';

if (in_array($arrTemp['id'], $arrValue)) {
                            $this->arrIdAll[$strTemp]['selected'] = ' selected="selected"';
                    }
            }
            $this->strItem = '<option value=\"{$'.$this->optionValue.'}\"{$selected} title=\"{$'.$this->formatParam.'}\">{$strSep}{$'.$this->formatParam.'}</option>';
            $strRe = '<select id="id_' . $strName . '" name="' . $strName . ($blmMulti ? '[]' : '') . '"';
            $strRe .= ($blmMulti ? ' multiple="multiple"' : '') . (empty($strExt) ? '' : ' ' . $strExt) . '>';

if (is_array($arrFirst) && count($arrFirst) == 2) {
                    $strRe .= '<option value="' . $arrFirst[0] . '">' . $arrFirst[1] . '</option>';
            }

$strRe .= $this->getHtml() . '</select>';           
            return $strRe;
    }

/**
     * 数据处理
     * @param type $arrData
     * @return type
     */
    private function helpForGetRelation($arrData) {
            $arrRe = array();
            foreach ($arrData as $strTemp => $arrTemp) {
                    $arrRe[$strTemp] = $arrTemp;
                    if (isset($this->arrIdRelation[$strTemp])) {
                            $arrRe[$strTemp] = $this->arrIdRelation[$strTemp];
                    }
                    if (count($arrRe[$strTemp]) > 0) {
                            $arrRe[$strTemp] = $this->helpForGetRelation($arrRe[$strTemp]);
                    } else {
                            array_push($this->arrIdLeaf, $strTemp);
                    }
            }
            return $arrRe;
    }

/**
     * 数据处理
     * @param type $arrData
     * @return type
     */
    private function helpForGetChildren($arrData) {
            $arrRe = array_keys($arrData);
            foreach ($arrData as $arrTemp) {
                    $arrRe = array_merge($arrRe, $this->helpForGetChildren($arrTemp));
            }
            return $arrRe;
    }

/**
     * 数据处理
     * @param type $str
     * @return type
     */
    private function helpForGetBackPath($str) {
            $arrRe = array();
            $intTemp = $this->arrIdAll[$str][$this->pid];
            if ($intTemp > 0) {
                    $intTemp = '_' . $intTemp;
                    array_push($arrRe, $intTemp);
                    $arrRe = array_merge($arrRe, $this->helpForGetBackPath($intTemp));
            }
            return $arrRe;
    }

/**
     * 数据处理
     */
    private function processData() {
            $count = count($this->arrAll);
            foreach ($this->arrAll as $arrTemp) {           
                    $strTemp = '_' . $arrTemp['id'];
                    $this->arrIdAll[$strTemp] = $arrTemp;
                    if ($arrTemp[$this->pid] > 0 && $count > 1) {
                            $strTemp_ = '_' . $arrTemp[$this->pid];
                            !isset($this->arrIdRelation[$strTemp_]) && $this->arrIdRelation[$strTemp_] = array();
                            $this->arrIdRelation[$strTemp_][$strTemp] = array();
                            !isset($this->arrIdSon[$strTemp_]) && $this->arrIdSon[$strTemp_] = array();
                            array_push($this->arrIdSon[$strTemp_], $strTemp);
                    } else {
                            !isset($this->arrIdRelation[$strTemp]) && $this->arrIdRelation[$strTemp] = array();
                            array_push($this->arrIdRoot, $strTemp);
                    }
            }

$this->arrIdRelation = $this->helpForGetRelation($this->arrIdRelation);
            $this->arrIdLeaf = array_unique($this->arrIdLeaf);
            foreach ($this->arrIdRelation as $strTemp => $arrTemp) {
                    $this->arrIdChildren[$strTemp] = $this->helpForGetChildren($arrTemp);
                    in_array($strTemp, $this->arrIdRoot) && $this->arrIdRelationSimple[$strTemp] = $arrTemp;
            }
            $arrTemp = array_keys($this->arrIdAll);
            foreach ($arrTemp as $strTemp) {
                    $this->arrIdBackPath[$strTemp] = $this->helpForGetBackPath($strTemp);
            }
    }

/**
     * 数据处理
     * @param type $intLen
     * @return string
     */
    private function genSeparator($intLen) {
            $strRe = '';
            $i = 0;
            while ($i < $intLen) {
                    $strRe .= ' ' . (($i + 1 == $intLen) ? '├' : '│');
                    $i++;
            }

!empty($strRe) && $strRe .= '─';
            return $strRe;
    }

/**
     * 数据处理
     * @param type $arrRelation
     * @param type $intSep
     * @return type
     */
    private function genHtml($arrRelation = null, $intSep = 0) {
            $strRe = '';
            null === $arrRelation && $arrRelation = $this->arrIdRelationSimple;
            foreach ($arrRelation as $strKey => $arrTemp) {
                    if (count($this->arrIdAll[$strKey]) > 0) {
                            if (!empty($this->formatTime) && count($this->formatTime) > 0) {
                                    foreach($this->formatTime as $formatTime) {
                                            if ($this->arrIdAll[$strKey][$formatTime] > 0) {
                                                    $this->arrIdAll[$strKey][$formatTime] = date('Y-m-d H:i:s' , $this->arrIdAll[$strKey][$formatTime]);
                                            }
                                    }                                   
                            }

$strSep = $this->genSeparator($intSep);                       
                            extract($this->arrIdAll[$strKey]);
                            eval('$strRe .= "' . $this->strItem . '";');                                               
                            count($arrTemp) > 0 && $strRe .= $this->genHtml($arrTemp, ($intSep + 1));
                    }
            }           
            return $strRe;
    }
}
?>

tree.php

代码如下:

<?php  if (!empty($data)): ?>
<?php echo $data;  ?>
<?php else:  ?>
<tr><td colspan="4" class="empty"><span class="empty">没有找到数据.</span></td></tr>
<?php endif; ?>

(0)

相关推荐

  • YII CLinkPager分页类扩展增加显示共多少页

    yii的分页类CLinkPager默认是不支持显示共x页的,那么现在需求来了,要在分页的后面显示共多少页,怎么办喃?我们来看解决办法 1.默认的CLinkPager显示的效果 上面这里写了css的样式哈,我们来看pager代码: <div class="page-link"> <?php $this->widget('CLinkPager',array( 'header' => '', 'firstPageLabel' => '首页', 'lastP

  • Yii中CGridView禁止列排序的设置方法

    本文实例讲述了Yii中CGridView禁止列排序的设置方法.分享给大家供大家参考,具体如下: Yii中CGridView的功能是用来显示的数据列表.它支持排序,分页,和AJAX数据请求. 下面的代码演示了CGridView禁止列排序的设置方法: 'columns' => array ( array ( 'class' => 'CCheckBoxColumn', 'selectableRows' => '2', 'value' => '$data->id', 'id' =&g

  • YII视图整合kindeditor扩展的方法

    本文实例讲述了YII视图整合kindeditor扩展的方法.分享给大家供大家参考,具体如下: 比较喜欢用kindeditor,YII上的版本比较旧,所以自己重新整了个扩展 先在protected\extensions下创建KEditor文件夹用来放文件,keSource里放kindeditor的源文件,然后建三个类KEditor.KEditorManage和KEditorUpload,KEditor是扩展的主文件,KEditorManage是用来浏览服务器文件的,KEditorUpload是用来

  • Yii把CGridView文本框换成下拉框的方法

    本文实例讲述了Yii把CGridView文本框换成下拉框的方法.分享给大家供大家参考.具体实现方法如下: 使用yii的朋友都知道Yii中的CGridView默认显示提文本框了,那么我们要怎么把它转换成下拉框呢?本文就此分析一下解决方法. 默认情况下CGridView会生成一个文本框,但是这并不友好,用户往往希望知道有什么可选的,特别是数据库里存的是数字id的时候,我们希望将数字转换为可读的文本,这时候只需要修改一下表头的"filter"属性就行了,比如: 复制代码 代码如下: <

  • Yii CGridView用法实例详解

    本文实例讲述了Yii CGridView用法.分享给大家供大家参考,具体如下: CGridView的功能是用来显示的数据列表.它支持排序,分页,和AJAX数据请求. CGridView最好使用 data provider,最好是 CActiveDataProvider . 简单代码如下: $dataProvider=new CActiveDataProvider('Post'); $this->widget('zii.widgets.grid.CGridView', array( 'dataPr

  • Yii视图CGridView列表用法实例分析

    本文实例讲述了Yii视图CGridView列表用法.分享给大家供大家参考,具体如下: CGridView列表实例 <!-- 列表 --> <?php $this->widget('zii.widgets.grid.CGridView', array( 'id'=>'words-grid', 'dataProvider'=>$model->search(),//数据源 'filter'=>$model,//设置过滤器,筛选输入框 'columns'=>a

  • PHP的Yii框架中YiiBase入口类的扩展写法示例

    通过yiic.php自动创建一个应用后,入口文件初始代码如下: <?php // change the following paths if necessary $yii=dirname(__FILE__).'/../yii/framework/yii.php'; $config=dirname(__FILE__).'/protected/config/main.php'; // remove the following lines when in production mode defined

  • Yii视图CGridView实现操作按钮定义地址示例

    本文实例讲述了Yii视图CGridView实现操作按钮定义地址的方法.分享给大家供大家参考,具体如下: <?php $this->widget('zii.widgets.grid.CGridView', array( 'id'=>'mem-sub-grid', 'dataProvider'=>$model, 'columns'=>array( 'zpc_catname', array('name'=>'inputtime', 'value'=>'date(&quo

  • Yii框架扩展CGridView增加导出CSV功能的方法

    本文实例讲述了Yii框架扩展CGridView增加导出CSV功能的方法.分享给大家供大家参考,具体如下: Yii提供的CGridView组件没有内置数据导出功能,不过我们可以通过扩展该组件来添加该功能. 具体方法如下: 1.首先派生一个子类,添加一个action成员,在该视图的init函数中判断是浏览动作还是数据导出动作,如果是浏览动作者则保持默认行为,否则输出csv文件. public function init() { if($this->action == 'export') { pare

  • Yii2分页的使用及其扩展方法详解

    前言: 说明下我们本篇文章都要讲哪些内容 分页的使用,一步一步的教你怎么做 分页类LinkPager和Pagination都可以自定义哪些属性 分页类LinkPager如何扩展成我们所需要的 第一步,我们来看看yii2自带的分页类该如何去使用? 1.controller action use yii\data\Pagination; $query = Article::find()->where(['status' => 1]); $countQuery = clone $query; $pa

  • Yii中CGridView实现批量删除的方法

    本文实例讲述了Yii中CGridView实现批量删除的方法.分享给大家供大家参考,具体如下: 1. CGridView中的columns添加 array( 'selectableRows' => 2, 'footer' => '<button type="button" onclick="GetCheckbox();" style="width:76px">批量删除</button>', 'class' =&g

  • Yii中CGridView关联表搜索排序方法实例详解

    本文实例讲述了Yii中CGridView关联表搜索排序方法.分享给大家供大家参考.具体实现方法如下: 在Yii CGridView 关联表搜索排序实现方法有点复杂,今天看了一老外写的了篇游戏,下面我整理一下与各位朋友分享一下,相信会对大家Yii框架的学习有所帮助. 首先,检查你的blog demo里的protectedmodelsComment.php,确保Comment模型有一个search的方法,如果没有,就用gii生成一个,我下载到的blog demo里倒是没有. 然后,写代码的时间到了,

随机推荐