php实现菜单无限极分类

一、数据表结构


CREATE TABLE `t_admin_privilege` (
`f_id` int(11) NOT NULL AUTO_INCREMENT,
`f_name` varchar(50) DEFAULT NULL COMMENT '目录名称',
`f_parent_id` int(11) DEFAULT '0' COMMENT '父级id',
`f_type` tinyint(4) DEFAULT NULL COMMENT '第几级目录',
`f_url` varchar(255) DEFAULT NULL COMMENT '目录的链接地址',
`f_createtime` int(10) DEFAULT NULL COMMENT '创建时间',
`f_is_menu` tinyint(1) DEFAULT '1' COMMENT '1是菜单栏 2不是菜单栏',
`f_icon` varchar(50) DEFAULT NULL COMMENT '小图标',
`f_is_del` tinyint(1) NOT NULL DEFAULT '1' COMMENT '是否删除 1正在使用(未删除) 2删除',
`f_sort` tinyint(5) DEFAULT NULL COMMENT '排序',
PRIMARY KEY (`f_id`)
) ENGINE=InnoDB AUTO_INCREMENT=335 DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT

二、后台取数据(使用Yii框架)

header("content-type:text/html;charset=utf-8");   //避免提示中文乱码
$html = array();
//获取菜单栏所有的数据
$menu_record = T_admin_privilege::model()->findAll();
$EData = new EData();
$html['menu_list'] = $EData->push_info($menu_record);

//1级目录
$criteria_first = new CDbCriteria();
$criteria_first->addCondition("f_type=1 AND f_is_menu=1 AND f_is_del=1");
$criteria_first->order="f_id";

//2级目录
$criteria_second = new CDbCriteria();
$criteria_second->addCondition("f_type=2 AND f_is_menu=1 AND f_is_del=1");
$criteria_second->order="f_id";

//3级目录
$criteria_third = new CDbCriteria();
$criteria_third->addCondition("f_type=3 AND f_is_menu=1 AND f_is_del=1");
$criteria_third->order="f_id";

//4级目录
$criteria_fourth = new CDbCriteria();
$criteria_fourth->addCondition("f_type=4 AND f_is_menu=1 AND f_is_del=1");
$criteria_fourth->order="f_id";

$menu_array = array();
//菜单分为4级
$first_list = T_admin_privilege::model()->findAll($criteria_first);
$html['first_num'] = $first_num = count($first_list);
$second_list = T_admin_privilege::model()->findAll($criteria_second);
$html['second_num'] = $second_num = count($second_list);
$third_list = T_admin_privilege::model()->findAll($criteria_third);
$html['third_num'] = $third_num = count($third_list);
$fourth_list = T_admin_privilege::model()->findAll($criteria_fourth);
$html['fourth_num'] = $third_num = count($fourth_list);

//一级目录
foreach ($first_list as $first)
{
    $menu_array[$first->f_id] = array();
}

//二级目录
foreach ($second_list as $second)
{
    $menu_array[$second->f_parent_id][$second->f_id] = array();
}

//三级目录
foreach ($third_list as $third)
{
    foreach ($menu_array as $first_k => $menu)
    {
        foreach ($menu as $second_k => $next)
        {
            if ($second_k == $third->f_parent_id)
            {
                $menu_array[$first_k][$second_k][$third->f_id] = array();
            }
        }
    }
}

//四级目录
foreach ($fourth_list as $fourth)
{
    foreach ($menu_array as $first_k=>$second_menu)
    {
        foreach ($second_menu as $second_k => $third_menu)
        {
            foreach ($third_menu as $third_k => $firth_menu)
            {
                if ($third_k == $fourth->f_parent_id)
                {
                    $menu_array[$first_k][$second_k][$third_k][$fourth->f_id] = 0;
                }
            }
        }
    }
}

$html['menu_array'] = $menu_array;

//把数据单独放在一个页面,通过ajax加载
$out = array(
    'error' => 0,
    'content' => $this->renderPartial("ajax_get_menu_list_page", $html, true)
);
echo CJSON::encode($out);

三、html页面(ajax_get_menu_list_page页面,在pixed-admin框架下,也可引入jQuery,bootstrap修改样式)

<div class="col-sm-12 menu_list" id="menu_list">
    <!--遍历一级目录 start-->
    <?php foreach ($menu_array as $k=>$first_menu){?>
        <div class="first_menu_list">
            <div class="first_menu menu">
                <?php if(count($first_menu)>0) {?><a href='javascript:;' class="is_show" f_id="<?php echo $menu_list[$k]['f_id'];?>">+</a> <?php }else{?><i style="padding: 0 9px"></i> <?php }?>
                <input type="text" class="first_title title" name="first_title" value="<?php echo $menu_list[$k]['f_name']?>" f_id="<?php echo $menu_list[$k]['f_id'];?>" f_parent_id="0">
                <?php if(count($first_menu)<1) {?><input type="text" placeholder="请填写目录的路径地址" f_id="<?php echo $menu_list[$k]['f_id']?>" value="<?php echo $menu_list[$k]['f_url']?>" class="path_address"/><?php }?>
                <div class="operation">
                   <?php if (empty($menu_list[$k]['f_url']) ){?><a class="btn btn-xs btn-add second_add">添加</a><?php }?>
                   <?php if (count($first_menu)<=1){?><a class="btn btn-xs btn-del del first_del" f_id="<?php echo $menu_list[$k]['f_id']?>">删除</a><?php }?>
                </div>
            </div>
            <!--遍历二级目录 start-->
            <?php if(count($first_menu)>0){foreach ($first_menu as $first_k=>$second_menu){?>
                <div class="second_menu_list <?php echo $menu_list[$first_k]['f_parent_id'];?>">
                    <div class="second_menu menu">
                        <input type="text" class="second_title title" name="second_title" value="<?php echo $menu_list[$first_k]['f_name']?>" f_id="<?php echo $menu_list[$first_k]['f_id'];?>" f_parent_id="<?php echo $menu_list[$first_k]['f_parent_id'];?>">
                        <?php if(count($second_menu)<1) {?><input type="text" placeholder="请填写目录的路径地址" f_id="<?php echo $menu_list[$first_k]['f_id']?>" value="<?php echo $menu_list[$first_k]['f_url']?>" class="path_address"/><?php }?>
                        <div class="operation">
                            <?php if(empty($menu_list[$first_k]['f_url'])) {?><a class="btn btn-xs btn-add third_add">添加</a><?php }?>
                            <?php if (count($second_menu)<=1){?><a class="btn btn-xs btn-del del second_del" f_id="<?php echo $menu_list[$first_k]['f_id']?>">删除</a><?php }?>
                        </div>
                    </div>
                    <!--遍历三级目录  start-->
                    <?php if (count($second_menu)>0){foreach ($second_menu as $second_k=>$third_menu){?>
                        <div class="third_menu_list">
                            <div class="third_menu menu">
                                <input type="text" class="third_title title" name="third_title" value="<?php echo $menu_list[$second_k]['f_name']?>" f_id="<?php echo $menu_list[$second_k]['f_id']?>" f_parent_id="<?php echo $menu_list[$second_k]['f_parent_id']?>"/>
                                <?php if(count($third_menu)<1) {?><input type="text" placeholder="请填写目录的路径地址" f_id="<?php echo $menu_list[$second_k]['f_id']?>" value="<?php echo $menu_list[$second_k]['f_url']?>" class="path_address"/><?php }?>
                                <div class="operation">
                                    <?php if(count($third_menu)>1) {?><a class="btn btn-xs btn-add fourth_add">添加</a><?php }?>
                                    <?php if (count($third_menu)<=1){?><a class="btn btn-xs btn-del del third_del" f_id="<?php echo $menu_list[$second_k]['f_id']?>">删除</a><?php }?>
                                </div>
                            </div>
                            <!--遍历四级目录  start-->
                            <?php if (count($third_menu)>0){foreach ($third_menu as $third_k=>$fourth_menu){?>
                                <div class="fourth_menu menu">
                                    <input type="text" class="fourth_title title" name="fourth_title" value="<?php echo $menu_list[$third_k]['f_name']?>" f_id="<?php echo $menu_list[$third_k]['f_id']?>" f_parent_id="<?php echo $menu_list[$third_k]['f_parent_id']?>"/>
                                    <input type="text" placeholder="请填写目录的路径地址" f_id="<?php echo $menu_list[$third_k]['f_id']?>" value="<?php echo $menu_list[$third_k]['f_url']?>" class="path_address"/>

                                    <div class="operation">
                                        <a class="btn btn-xs btn-del del fourth_del" f_id="<?php echo $menu_list[$third_k]['f_id']?>">删除</a>
                                    </div>
                                </div>
                            <?php }}?>
                            <!--遍历四级目录  end-->
                        </div>
                    <?php }}?>
                    <!--遍历三级目录  end-->
                </div>
            <?php }}?>
            <!--遍历二级目录 end-->
        </div>
    <?php }?>
    <!--遍历一级目录 end-->
</div>

四、html页面(menu_list_page页面,在pixed-admin框架下,也可引入jQuery,bootstrap修改样式)、

<div class="page-body">
      <div class="panel">
          <div class="form-group " id="get_menu_list"></div>
      </div>
</div>

五、css样式

     *{margin: 0;padding: 0;}
        .add {margin-right: 10px;}
        .menu_list { margin:0px 20px 40px 20px;position: relative}
        .menu { height: 25px;}
        .first_menu {font-weight: bolder; font-size: 20px;margin:30px 15px 0px 15px;}
        .second_menu { padding: 25px 45px; font-weight: bold; font-size: 16px;}
        .third_menu { padding: 20px 0px 20px 90px;font-size: 14px;}
        .fourth_menu{padding: 20px 135px;}
        input {padding-left: 10px;border: none;margin-right: 30px;}
        .manual_content { width:450px;}
        .manual_content::after{content: '';}
        .manual_content a{float: right;margin-right: 10px;}
        .manual_content a:active::after{content: '';}
        .ui-accordion-header{border: none;}
        .ui-accordion-header.ui-state-active:after{content:""}
        a{display: inline-block}
        a:link{text-decoration: none}
        a:active{text-decoration: none}
        a:visited{text-decoration: none}
        a:hover{text-decoration: none}
        /*.second_menu_list{display: none}*/
        .is_show{font-size: 30px;}
        .menu_list{padding-right: 60px;}
        .btn-del,.btn-add{margin: -30px 10px 0 10px;}
        .btn-add{position: absolute;  right:35%;}
        .btn-del{position:absolute;right: 30%;}
        .menu .path_address{font-size: 14px;width:400px;margin-left: 30px;font-weight: normal}

六、js

//通过ajax,把数据加载到menu_list_page页面
$.ajax({
       url         :   '/system/ajax_get_menu_list_page',
            type        :   'post',
            async       :   false,
            data        :   {},
            dataType    :   'json',
            success     :   function(res)
            {
                if( res.error == 0)
                {
                    $("#get_menu_list").prepend(res.content);
                }
                else
                {

                }
            }
        });

//添加其他方法动态实现目录的增删改查。或拖动div对目录的显示顺序进行修改。或实现分目录的显示和隐藏
  。。。 。。。
  。。。 。。。

实现效果

原文地址:https://www.cnblogs.com/zwtqf/p/9195648.html