提供兩種方式的分類樹格式,表格和下拉框形式的樹形結構
可以自定義表格和下拉框的樣式,自定義以哪一列的參數為格式化數據,自定義層級關系參數,自定義表格列名稱,也可以設置時間的格式化。
調用方式
表格方式:
代碼如下:
<?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 [email protected]
*
* 表格方式調用
<?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; ?>