夺命雷公狗ThinkPHP项目之----商城9商品后台无限极分类
無限極分類,幾乎在每個網站上都會用到的,因此而重要。
?
先來對數據表進行分析
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">版權所有 © 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=" ",###}{$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">版權所有 © 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=" ",###}<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&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&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">版權所有 © 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=" ",###}{$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">版權所有 © 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商品后台无限极分类的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 常用代码参考模板
- 下一篇: 用于页面访问,心跳监测的方法