无限极分类,几乎在每个网站上都会用到的,因此而重要。

先来对数据表进行分析

parent_id:表示当前分类的父id,他是实现无限级分类的关键

无限级分类,主要从两个方面进行考虑的。

1.数据库的设计,表中的parent_id字段。

2.在程序的层面上,来完成,使用递归。

我们只要理解下面这张图即可了解无限极分类的大部份了

上面的这三表是否可以变成下面这一张表呢?

这样的话关联起来是不是更加方便呢?

说白了也就是PID就是他的老爸的ID一直到PID为0这就到了顶级分类

添加分类,首先是要载入添加的表单,确保表单的name和字段一致,首先在view里面创建一个category文件夹在里面将模版放进去,我们先来写add.html的文件

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>SHOP 管理中心 - 添加分类 </title>
<meta name="robots" content="noindex, nofollow">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<link href="__ADMIN__/styles/general.css" rel="stylesheet" type="text/css" />
<link href="__ADMIN__/styles/main.css" rel="stylesheet" type="text/css" />
</head>
<body><h1>
<span class="action-span"><a href="index.php?p=admin&c=category&a=index">商品分类</a></span>
<span class="action-span1"><a href="index.php?act=main">SHOP 管理中心</a> </span><span id="search_id" class="action-span1"> - 添加分类 </span>
<div style="clear:both"></div>
</h1>
<!-- start add new category form -->
<div class="main-div"><form action="" method="post" name="theForm" enctype="multipart/form-data" onsubmit="return validate()"><table width="100%" id="general-table"><tbody><tr><td class="label">分类名称:</td><td><input type="text" name="cat_name" maxlength="20" value="" size="27"> <font color="red">*</font></td></tr><tr><td class="label">上级分类:</td><td><select name="parent_id"><option value="0">顶级分类</option><volist name="cats" id='vo'><option value="{$vo['cat_id']}">{$vo['cat_name']}</option></volist></select></td></tr><tr id="measure_unit"><td class="label">数量单位:</td><td><input type="text" name="unit" value="" size="12"></td></tr><tr><td class="label">排序:</td><td><input type="text" name="sort_order" value="50" size="15"></td></tr><tr><td class="label">是否显示:</td><td><input type="radio" name="is_show" value="1" checked="true"> 是<input type="radio" name="is_show" value="0"> 否  </td></tr><tr><td class="label">分类描述:</td><td><textarea name="cat_desc" rows="6" cols="48"></textarea></td></tr></tbody></table><div class="button-div"><input type="submit" value=" 确定 "><input type="reset" value=" 重置 "></div></form>
</div><div id="footer">版权所有 &copy; 2014-2016 夺命雷公狗 - 技术总结 -
</div></div></body>
</html>

这里完成了后,下一步就是开始写CategoryController.class.php控制器里面的add方法了

public function add(){if(IS_POST){//分类信息入库$data['cat_name'] = I('cat_name');$data['parent_id'] = I('parent_id',0,'int');//parent_id通常是整型,所以做个小处理$data['cat_desc'] = I('cat_desc');$data['unit'] = I('unit');//数量$data['is_show'] = I('is_show');$data['sort_order'] = I('sort_order');$categoryModel = D('category');if($categoryModel->create($data)){//验证通过if($categoryModel->add()){//插入成功$this -> success('分类信息添加成功',U('index'),1);}else{//插入失败$this -> error('分类信息添加失败');}}else{//验证失败$this -> error($categoryModel->getError());}return;}//载入添加分类页面//获取所有的分类$cats = M('category')->select();$this -> assign('cats',$cats);$this -> display();}

在这的验证是通过model层里面进行验证的,那么我们下一步就是在model文件夹里创建一个CategoryModel.class.php的文件,代码如下所示

<?php//商品分类模型
    namespace Admin\Model;use Think\Model;class CategoryModel extends Model{//自动验证protected $_validate = array(array('cat_name','require','商品名称不能为空'),);}

好像是完成了噢,不过一测试,发现里面的无限极分类效果是出来了,但是实在不好看,什么都逼在同个水平线下,那么我们的解决方案是通过树状方式来进行解决问题

我们做目录树的时候要玩到递归,递归说白了就是让他重复干事情的,给定一个pid,找他的后代节点,找到保存起来。

条件pid等于给定的id。

最终目的要成为这样:

先在model层里面开干,

<?php//商品分类模型
    namespace Admin\Model;use Think\Model;class CategoryModel extends Model{//自动验证protected $_validate = array(array('cat_name','require','商品名称不能为空'),);//定义一个方法,获取树状的分类信息public function catTree(){$cats = $this->select();return $this->tree($cats);}//定义一个方法,对给定的数组,递归形成树public function tree($arr,$pid=0,$level=0){static $tree = array();foreach($arr as $v){if($v['parent_id']==$pid){//说明找到,保存$v['level'] = $level;$tree[] = $v;//继续找$this -> tree($arr,$v['cat_id'],$level+1);}}return $tree;}}

然后在控制器下改下他的查询方式,代码如下:

public function add(){if(IS_POST){//分类信息入库$data['cat_name'] = I('cat_name');$data['parent_id'] = I('parent_id',0,'int');//parent_id通常是整型,所以做个小处理$data['cat_desc'] = I('cat_desc');$data['unit'] = I('unit');//数量$data['is_show'] = I('is_show');$data['sort_order'] = I('sort_order');$categoryModel = D('category');if($categoryModel->create($data)){//验证通过if($categoryModel->add()){//插入成功$this -> success('分类信息添加成功',U('index'),1);}else{//插入失败$this -> error('分类信息添加失败');}}else{//验证失败$this -> error($categoryModel->getError());}return;}//载入添加分类页面//获取所有的分类$cats = D('category')->catTree();$this -> assign('cats',$cats);$this -> display();}

最后在add.html模版下修改下即可

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>SHOP 管理中心 - 添加分类 </title>
<meta name="robots" content="noindex, nofollow">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<link href="__ADMIN__/styles/general.css" rel="stylesheet" type="text/css" />
<link href="__ADMIN__/styles/main.css" rel="stylesheet" type="text/css" />
</head>
<body><h1>
<span class="action-span"><a href="index.php?p=admin&c=category&a=index">商品分类</a></span>
<span class="action-span1"><a href="index.php?act=main">SHOP 管理中心</a> </span><span id="search_id" class="action-span1"> - 添加分类 </span>
<div style="clear:both"></div>
</h1>
<!-- start add new category form -->
<div class="main-div"><form action="" method="post" name="theForm" enctype="multipart/form-data" onsubmit="return validate()"><table width="100%" id="general-table"><tbody><tr><td class="label">分类名称:</td><td><input type="text" name="cat_name" maxlength="20" value="" size="27"> <font color="red">*</font></td></tr><tr><td class="label">上级分类:</td><td><select name="parent_id"><option value="0">顶级分类</option><volist name="cats" id='vo'><option value="{$vo['cat_id']}">{$vo['level']|str_repeat="&nbsp;&nbsp;&nbsp;",###}{$vo['cat_name']}</option></volist></select></td></tr><tr id="measure_unit"><td class="label">数量单位:</td><td><input type="text" name="unit" value="" size="12"></td></tr><tr><td class="label">排序:</td><td><input type="text" name="sort_order" value="50" size="15"></td></tr><tr><td class="label">是否显示:</td><td><input type="radio" name="is_show" value="1" checked="true"> 是<input type="radio" name="is_show" value="0"> 否  </td></tr><tr><td class="label">分类描述:</td><td><textarea name="cat_desc" rows="6" cols="48"></textarea></td></tr></tbody></table><div class="button-div"><input type="submit" value=" 确定 "><input type="reset" value=" 重置 "></div></form>
</div><div id="footer">版权所有 &copy; 2014-2016 夺命雷公狗 - 技术总结 -
</div></div></body>
</html>

添加页完事,那么下一步就是列表显示页了,先写index方法因为直接赋值刚才那个过来即可

//显示分类public function index(){$cats = D('category')->catTree();$this -> assign('cats',$cats);$this -> display();}

然后在view下的index.html模版里进行遍历

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>SHOP 管理中心 - 商品分类 </title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<link href="__ADMIN__/styles/general.css" rel="stylesheet" type="text/css" />
<link href="__ADMIN__/styles/main.css" rel="stylesheet" type="text/css" />
</head>
<body><h1>
<span class="action-span"><a href="__MODULE__/category/add">添加分类</a></span>
<span class="action-span1"><a href="index.php?p=admin&c=index&a=index">SHOP 管理中心</a> </span><span id="search_id" class="action-span1"> - 商品分类 </span>
<div style="clear:both"></div>
</h1><form method="post" action="" name="listForm">
<!-- start ad position list --><div class="list-div" id="listDiv"><table width="100%" cellspacing="1" cellpadding="2" id="list-table"><tbody><tr><th>分类名称</th><th>商品数量</th><th>数量单位</th><th>导航栏</th><th>是否显示</th><th>价格分级</th><th>排序</th><th>操作</th></tr><volist name="cats" id="vo"><tr align="center" class="0" id="0_1"><td align="left" class="first-cell">{$vo['level']|str_repeat="&nbsp;&nbsp;&nbsp;&nbsp;",###}<img src="__ADMIN__/images/menu_minus.gif" id="icon_0_1" width="9" height="9" border="0" style="margin-left:0em" onclick="rowClicked(this)"><span><a href="goods.php?act=list&amp;cat_id=1">{$vo['cat_name']}</a></span></td><td width="10%">0</td><td width="10%"><span onclick="listTable.edit(this, 'edit_measure_unit', 1)" title="点击修改内容" style="">{$vo['unit']}</span></td><td width="10%"><img src="__ADMIN__/images/no.gif" onclick="listTable.toggle(this, 'toggle_show_in_nav', 1)"></td><td width="10%"><img src="<if condition="$vo['is_show'] eq 1">__ADMIN__/images/yes.gif"<else />__ADMIN__/images/no.gif"</if>οnclick="listTable.toggle(this, 'toggle_is_show', 1)"></td><td><span onclick="listTable.edit(this, 'edit_grade', 1)" title="点击修改内容" style="">5</span></td><td width="10%" align="right"><span onclick="listTable.edit(this, 'edit_sort_order', 1)" title="点击修改内容" style="">{$vo['sort_order']}</span></td><td width="24%" align="center"><a href="category.php?act=move&amp;cat_id=1">转移商品</a> |<a href="__CONTROLLER__/edit/id/{$vo['cat_id']}">编辑</a> |<a href="__CONTROLLER__/del/id/{$vo['cat_id']}" onclick="return confirm('您是否真的删除这个品牌呢?')" title="移除">移除</a></td></tr></volist></tbody></table>
</div>
</form></table>
</div>
</form><div id="footer">版权所有 &copy; 2014-2016 夺命雷公狗 - 技术总结 - </div>
</div><script>/*** 折叠分类列表*/
var imgPlus = new Image();
imgPlus.src = "application/views/admin/images/menu_plus.gif";function rowClicked(obj)
{// 当前图像
  img = obj;// 取得上二级tr>td>img对象
  obj = obj.parentNode.parentNode;// 整个分类列表表格var tbl = document.getElementById("list-table");// 当前分类级别var lvl = parseInt(obj.className);// 是否找到元素var fnd = false;var sub_display = img.src.indexOf('menu_minus.gif') > 0 ? 'none' : 'table-row' ;// 遍历所有的分类for (i = 0; i < tbl.rows.length; i++){var row = tbl.rows[i];if (row == obj){// 找到当前行
          fnd = true;//document.getElementById('result').innerHTML += 'Find row at ' + i +"<br/>";
      }else{if (fnd == true){var cur = parseInt(row.className);var icon = 'icon_' + row.id;if (cur > lvl){row.style.display = sub_display;if (sub_display != 'none'){var iconimg = document.getElementById(icon);iconimg.src = iconimg.src.replace('plus.gif', 'minus.gif');}}else{fnd = false;break;}}}}for (i = 0; i < obj.cells[0].childNodes.length; i++){var imgObj = obj.cells[0].childNodes[i];if (imgObj.tagName == "IMG" && imgObj.src != 'application/views/admin/images/menu_arrow.gif'){imgObj.src = (imgObj.src == imgPlus.src) ? 'application/views/admin/images/menu_minus.gif' : imgPlus.src;}}
}
</script>
</body>
</html>

效果如下图所示:

显示列表也有了,那么下一步就开始写更新页了

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>SHOP 管理中心 - 添加分类 </title>
<meta name="robots" content="noindex, nofollow">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<link href="__ADMIN__/styles/general.css" rel="stylesheet" type="text/css" />
<link href="__ADMIN__/styles/main.css" rel="stylesheet" type="text/css" />
</head>
<body><h1>
<span class="action-span"><a href="index.php?p=admin&c=category&a=index">商品分类</a></span>
<span class="action-span1"><a href="index.php?act=main">SHOP 管理中心</a> </span><span id="search_id" class="action-span1"> - 添加分类 </span>
<div style="clear:both"></div>
</h1>
<!-- start add new category form -->
<div class="main-div"><form action="category.php" method="post" name="theForm" enctype="multipart/form-data" onsubmit="return validate()"><table width="100%" id="general-table"><tbody><tr><td class="label">分类名称:</td><td><input type="text" name="cat_name" maxlength="20" value="{$cat['cat_name']}" size="27"> <font color="red">*</font></td></tr><tr><td class="label">上级分类:</td><td><select name="parent_id"><option value="0">顶级分类</option><volist name="cats" id='vo'><option value="{$vo['cat_id']}"<if condition="$vo['cat_id'] eq $cat['parent_id']" >selected="selected"</if>>{$vo['level']|str_repeat="&nbsp;&nbsp;&nbsp;",###}{$vo['cat_name']}</option></volist>     </select></td></tr><tr id="measure_unit"><td class="label">数量单位:</td><td><input type="text" name="unit" value="{$cat['unit']}" size="12"></td></tr><tr><td class="label">排序:</td><td><input type="text" name="sort_order" value="{$cat['sort_order']}" size="15"></td></tr><tr><td class="label">是否显示:</td><td><input type="radio" name="is_show" value="1" checked="true"<if condition="$cat['is_show'] eq 1">checked="checked"</if>> 是<input type="radio" name="is_show" value="0"<if condition="$cat['is_show'] eq 0">checked="checked"</if>> 否  </td></tr><tr><td class="label">是否显示在导航栏:</td><td><input type="radio" name="show_in_nav" value="1"> 是  <input type="radio" name="show_in_nav" value="0" checked="true"> 否    </td></tr><tr><td class="label">设置为首页推荐:</td><td><input type="checkbox" name="cat_recommend[]" value="1"> 精品          <input type="checkbox" name="cat_recommend[]" value="2"> 最新          <input type="checkbox" name="cat_recommend[]" value="3"> 热门       </td></tr><tr><td class="label">分类描述:</td><td><textarea name="cat_desc" rows="6" cols="48">{$cat['cat_desc']}</textarea></td></tr></tbody></table><div class="button-div"><input type="submit" value=" 确定 "><input type="reset" value=" 重置 "></div><input type="hidden" name="cat_id" value="{$cat['cat_id']}" /></form>
</div><div id="footer">版权所有 &copy; 2014-2016 夺命雷公狗 - 技术总结 -
</div></div></body>
</html>

要注意,在编辑的表单中一定要传cat_id,否则更新会失败

 <input type="hidden" name="cat_id" value="{$cat['cat_id']}" />

注意:在更新的时候,如果把当前分类或则其子分类作为上级分类,就会出现逻辑错误..

所以我们要先到model里面定义一个方法,让他不能随便让他的当前分类或者子分类作为上级分类,否则就会出现逻辑上的错误。。

在CategoryModel.class.php里面定义一个方法,代码如下所示:

//给定一个分类,找其后代分类的cat_id,包括他自己public function getSubIds($cat_id){$cats = $this -> select();$list = $this -> tree($cats,$cat_id);$res = array();foreach($list as $v){$res[] = $v['cat_id'];}//把cat_id追加到数组$res[] = $cat_id;return $res;}

让后会控制器下定义edit方法,代码如下所示:

//修改分类public function edit(){$cat_id = I('id');if(IS_POST){//更新分类$data['cat_name'] = I('cat_name');$data['parent_id'] = I('parent_id',0,'int');//parent_id通常是整型,所以做个小处理$data['cat_desc'] = I('cat_desc');$data['unit'] = I('unit');//数量$data['is_show'] = I('is_show');$data['sort_order'] = I('sort_order');$data['cat_id'] = I('cat_id');$categoryModel = D('category');$ids = $categoryModel->getSubIds($data['cat_id']);if(in_array($data['parent_id'],$ids)){$this -> error('抱歉,不能把当前分类及其子分类作为其上级分类');}if($categoryModel->create($data)){//验证通过if($categoryModel->save()){//插入成功$this -> success('分类信息修改成功',U('index'),1);}else{//插入失败$this -> error('分类信息修改失败');}}else{//验证失败$this -> error($categoryModel->getError());}return;}$cat = M('category')->find($cat_id);$cats = D('category')->catTree();$this -> assign('cats',$cats);$this -> assign('cat',$cat);$this -> display();}

修改也好了,那么就差最后一步了,还差删除分类的了,代码如下所示:

//删除分类public function del(){$cat_id = I('id',0,'int');$categoryModel = D('category');$ids = $categoryModel->getSubIds($cat_id);//这里的目的就是查下有没有子类if(count($ids)>1){$this ->error("该分类下面还存在子分类,请处理好了再来");}if(M('category')->delete($cat_id)){$this -> success('删除成功',U('index'),1);}else{$this ->error('删除失败');}}

转载于:https://www.cnblogs.com/leigood/p/4946324.html

夺命雷公狗ThinkPHP项目之----商城9商品后台无限极分类相关推荐

  1. 夺命雷公狗ThinkPHP项目之----商城10商品属性管理

    我们一般做项目前就要分析业务逻辑先,这次也不例外. attr_type:是指属性的类型,有唯一,单选和多选之分 唯一属性,是指用户在购买商品时,可以看到的扩展属性如下图所示: 单选属性,是指用户在购买 ...

  2. 夺命雷公狗ThinkPHP项目之----商城1项目整体架构

    夺命雷公狗项目之---商城 本人准备更新套基于tp下开发的商城的项目,为啥呢?原因和简单,本人没使用过框架开发商城,准备用一些时间来开发套B2C的商城系统.. 项目规划: 1:项目整体架构 用户部分 ...

  3. 夺命雷公狗ThinkPHP项目之----商城6数据库设计和完成后台首页

    废话步多说,我们开工, 数据库设计如下所示: SQL语句如下: #创建数据库 create database shopp charset utf8;#选择数据库 use shopp;/*------- ...

  4. 夺命雷公狗ThinkPHP项目之----企业网站2之数据库的快速设计

    我们在一个项目的时候,花费最多事件的估计还是数据库的时间了,我们的数据库暂时就这样设计好了: 暂时我们的数据库就这样设计好了用下先,建好后如下所示: 转载于:https://www.cnblogs.c ...

  5. 夺命雷公狗ThinkPHP项目之----企业网站13之文章列表页的实现(主要是分页的实现)...

    列表页这个其实是比较简单的一个,直接遍历除数据即可: public function lists(){//$mod = M("Article")->select();//$t ...

  6. 夺命雷公狗ThinkPHP项目之----企业网站25之网站前台面包屑导航URL的完善

    如果想取出面包屑导航的url那么就必须在model层里面进行多取一个了: <?phpnamespace Home\Model;use Think\Model;class CategoryMode ...

  7. 夺命雷公狗TP3.2.3商城2-----后台模版引入和后台控制器的创建

    首先我们来到D:\phpStudy\WWW\shop\WEB  目录下,将Home目录进行复制一份,并且改名为Admin,如下所示: 然后将我们准备好的后台首页模版放入   D:\phpStudy\W ...

  8. 夺命雷公狗TP3.2.3商城的搭建开篇1

    这里是最后次是最后一次写TP323框架的项目类教程了,大家请见谅,毕竟tp5都出来这么长时间了,我看是时候去研究一下了, 首先我们还是老规矩先在index.php里面进行修改一下: <?php/ ...

  9. 夺命雷公狗TP3.2.3商城5-----管理员的列表页和分页

    列表也其实也很简单,说白了直接在数据库取出数据,然后直接遍历到模版即可,首先来修改Admin控制器的add方法: 然后到add模板页里使用volist进行遍历: 然后测试下看看数据是否成功被取出: 然 ...

最新文章

  1. JS-DOM Element方法和属性
  2. mysql高级查询面试_高级MySQL数据库面试问题 附答案
  3. (function($){...})(jQuery)是什么意思 ——jQuery插件
  4. Tips--TensorFlow报错:tensorflow:Early stopping conditioned on metric `val_loss` which is not available
  5. 小米平板5系列共三款机型:全系搭载2K/120Hz屏幕
  6. 基于JAVA+Servlet+JSP+MYSQL的校园门户信息管理系统
  7. finding the way
  8. MySQL把一个大表拆分多个表后,如何解决跨表查询效率问题
  9. 用MySQL语言创建视图_mysql 创建视图
  10. PostGIS批量导入导出shapefile文件
  11. 端午节谋定顺应自然-农业大健康·万祥军:根植古代农耕文化
  12. 【文献阅读】Cost-Sensitive Portfolio Selection via Deep Reinforcement Learning
  13. html css jsp 数据库,html、css、js、jsp的区别是什么?
  14. 学习java可以做什么?
  15. 当你的Stream遇上Lambda就爱上了,超级无敌酷酷 - 第418篇
  16. poi excel 导出设置边框,自定义背景色,自定义字体
  17. logstash的lumberjack协议解析
  18. 发送打印命令后打印机没反应,重启打印机之后才能打印
  19. 我TM吹爆 VIM - 安装入门,部署
  20. 剑指offer面试题(41-50)——java实现

热门文章

  1. qemu虚拟机模拟固件环境搭建
  2. XshellFoxyProxy 代理访问机房内网配置方法
  3. 如何提升抖音直播间人气热度?首先做好直播封面丨国仁网络资讯
  4. Java学习笔记(未完)
  5. setTimeout函数
  6. QTP11使用DOM XPath以及CSS识别元素对象
  7. 广告投放引擎哪些事儿
  8. vulkan.h_SteamOS已使用Linux内核4.1更新,Nvidia添加了Vulkan支持等
  9. 执行ipconfig -renew命令时出错: 系统找不到指定的文件?
  10. 【WAF剖析】——SQL注入之安全狗bypass深度剖析