我在PHP中建立了一个树菜单,使用递归函数,它工作正常。我的菜单结构是这样的:
根
——Categ1
——Categ11
——Categ111
——Categ112
——Categ12
——Categ121
——Categ122
——Categ2
——Categ3
——Categ4
我正在使用bootstrap。
我只需要显示活动节点和顶层子节点。对于我的例子,我需要菜单像这样打开(我点击了类别112和类别12的子类别隐藏):
根
——Categ1
——Categ11
——Categ111
——Categ112
——Categ12
——Categ2
——Categ3
——Categ4
/** show all subcategs of the selected category
* @param $iCategIDSelected
* @param null $arrCategs
* @param bool $bIsOnTheLeaf
* @return string
*/
static function getHTMLCategsForMenuBySelected($iCategIDSelected, $arrCategs=null, $arrAllParents=null){
$bIsVisible = false;
if($arrCategs == null){
$oController = new ShopcategoriesController();
$arrCategs = $oController->getShopCategories(0);
}
//find if we make the current node visible or not
//if the current node id is on the parent's of the selected node then make it visible
//take all nodes starting with root until the selected node
if($arrAllParents==null){
$arrAllParents = ShopcategoriesController::getParentsBySelectedCategID($iCategIDSelected,$arrCategs);
}
$sHTML = '<ul class="nav nav-pills nav-stacked">';
foreach($arrCategs as $oneCateg){
//find if is active or not
$bActiveClass = '';
if(in_array($oneCateg['id'],$arrAllParents)){$bActiveClass = 'active';}
$sHTML .= '<li class="'.$bActiveClass.'">';
$sHTML .= '<a href="'.URL::to('showcategory/'.$oneCateg['id']).'" class="list-group-item">'.ucfirst($oneCateg['name']).'</a>';
if(count($oneCateg['subCategories'])>0){
$sHTML .= ShopcategoriesController::getHTMLCategsForMenuBySelected($iCategIDSelected, $oneCateg['subCategories'],$arrAllParents);
$sHTML .= '</li>';
}else{
$sHTML .= '';
}
}
$sHTML .= '</ul>';
return $sHTML;
}
html结构为:
ul.nav > li > a{
padding-left: 30px;
}
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" rel="stylesheet"/>
<div id="menuCateg">
<ul class="nav nav-pills nav-stacked">
<li class="active">
<a class="list-group-item" href="http://localhost:8000/showcategory/1">Categ1</a>
<ul class="nav nav-pills nav-stacked">
<li class="active">
<a class="list-group-item" href="http://localhost:8000/showcategory/2">Categ11 </a>
<ul class="nav nav-pills nav-stacked">
<li class=""><a class="list-group-item" href="http://localhost:8000/showcategory/3">Categ111</a></li>
<li class="active"><a class="list-group-item" href="http://localhost:8000/showcategory/4">Categ112</a></li>
</ul>
</li>
<li class=""><a class="list-group-item" href="http://localhost:8000/showcategory/18">Categ12</a></li>
</ul>
</li>
<li class="">
<a class="list-group-item" href="http://localhost:8000/showcategory/6">Categ2</a>
<ul class="nav nav-pills nav-stacked">
<li class=""><a class="list-group-item" href="http://localhost:8000/showcategory/3">Categ121</a></li>
<li class=""><a class="list-group-item" href="http://localhost:8000/showcategory/4">Categ122</a></li>
</ul>
</li>
<li class=""><a class="list-group-item" href="http://localhost:8000/showcategory/8">Categ3</a>
<li class=""><a class="list-group-item" href="http://localhost:8000/showcategory/8">Categ4</a>
</ul>
</div>
我找到了解决方案,以便生成具有多级子类别的菜单树,并仅显示已选择的级别(不包括树中的所有子级别)。
诀窍是:
if( //if the current subcateg parentid is on the parent that must be active then show his children's otherwise do not
( in_array($oneCateg['parentid'],$arrAllParents) && in_array($oneCateg['id'],$arrAllParents))
)
谢谢你的帮助!
/** show all subcategs of the selected category
* @param $iCategIDSelected
* @param null $arrCategs
* @param bool $bIsOnTheLeaf
* @return string
*/
static function getHTMLCategsForMenuBySelected($iCategIDSelected, $arrCategs=null, $arrAllParents=null, $iLevel=0){
$bIsVisible = false;
if($arrCategs == null){
$oController = new ShopcategoriesController();
$arrCategs = $oController->getShopCategories(0);
}
//find if we make the current node visible or not
//if the current node id is on the parent's of the selected node then make it visible
//take all nodes starting with root until the selected node
if($arrAllParents==null){
$arrAllParents = ShopcategoriesController::getParentsBySelectedCategID($iCategIDSelected,$arrCategs);
$arrAllParents[]=0;
}
$iLevel++;
$sHTML = '<ul class="nav nav-pills nav-stacked level_'.$iLevel.'">';
foreach($arrCategs as $oneCateg){
//find if is active or not
$bActiveClass = '';
if(in_array($oneCateg['id'],$arrAllParents)){$bActiveClass = 'active';}
$sHTML .= '<li class="'.$bActiveClass.'">';
$sHTML .= '<a href="'.URL::to('showcategory/'.$oneCateg['id']).'" class="list-group-item">'.ucfirst($oneCateg['name']).'</a>';
if(count($oneCateg['subCategories'])>0){
if( //if the current subcateg parentid is on the parent that must be active then show his children's otherwise do not
( in_array($oneCateg['parentid'],$arrAllParents) && in_array($oneCateg['id'],$arrAllParents))
) {
$sHTML .= ShopcategoriesController::getHTMLCategsForMenuBySelected($iCategIDSelected, $oneCateg['subCategories'], $arrAllParents, $iLevel);
$sHTML .= '</li>';
}
}else{
$sHTML .= '';
}
}
$sHTML .= '</ul>';
return $sHTML;
}
你应该添加一个类,当它不活动,如.not-active
.not-active{
display: none;
}
编辑
我不确定是否正确理解了你的观点,但这样说吧:
foreach($arrCategs as $oneCateg){
//find if is active or not
$bActiveClass = '';
if(in_array($oneCateg['id'],$arrAllParents)){ //modified
$bActiveClass = 'active';
}else{
$bActiveClass = 'not-active';
}
$sHTML .= '<li class="'.$bActiveClass.'">';
$sHTML .= '<a href="'.URL::to('showcategory/'.$oneCateg['id']).'" class="list-group-item">'.ucfirst($oneCateg['name']).'</a>';
if(count($oneCateg['subCategories'])>0){
$sHTML .= ShopcategoriesController::getHTMLCategsForMenuBySelected($iCategIDSelected, $oneCateg['subCategories'],$arrAllParents);
$sHTML .= '</li>';
}else{
$sHTML .= '';
}
}