(1)表的設計
父級的id作爲子級的parentid,也就是說,父子級的關係用parentid這個字段關聯
通訊錄分組表:
通訊錄聯繫人表:
聯繫人 存儲分組id,因爲需求,設計了部門字段,以最低部門選擇的分組id,作爲該條記錄的groupid
(02)實現樹形展示的方式一 jsTree樹形插件
這個插件是基於jQuery的,通訊錄,分組需要添加,修改,刪除。可以滿足需求,並有較好的體驗、美觀
jsTree: https://www.jstree.com/
引入css
<link rel="stylesheet" href="dist/themes/default/style.min.css" />
引入js
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.1/jquery.min.js"></script>
<script src="dist/jstree.min.js"></script>
前端html:
<!--通訊錄內容 start--> <div class="box-body"> <div class="tab-content"> <div class="row"> <div class="col-md-8" id="container"></div>//樹形結構容器 <div class="col-md-4"> <h4 id="curr_op_title">新增</h4> <hr/> <form role="form" id="objform" method="post" action="{buildurl('contacts_group_save','index','contacts')}"> <div class="form-group"> <label class="control-label">分組名稱</label> <input type="text" name="name" id="curr_op_name" placeholder="請輸入分組名稱" class="form-control"/> </div> <div class="form-group" style="text-align: right;"> <button class="btn btn-info" type="button" id="save">全部保存</button> </div> </form> </div> </div> </div> </div> <!--通訊錄內容 end-->
編輯區的作用是,修改當前操作的節點名稱。Form表單中隱藏着相應的節點操作數據,每點擊了節點。就會生成,並記錄。
類似:
type:是指定 節點之前的圖標樣式
var op_obj = '';//標記當前操作的對象 //生成結構樹 $('#container').jstree({ 'core': { 'check_callback': true,'data':jstreelist,multiple:false }, 'plugins': ['types','dnd','contextmenu'], 'types': { 'default': { 'icon': 'fa fa-folder' }, 'show': { 'icon': 'fa fa-eye-slash text-muted' } }, 'contextmenu' : { 'items' : function(o, cb) { var items = { createAfter: {"label": "插入節點","action": function (data) {createNode(data, 'after');}}, createChildren: {"label": "插入子節點","action": function (data) {createNode(data, 'last');}}, deleteItem: {"label": "刪除節點","action": function (data) {deleteNode(data);}} }; return items; } } }).bind("select_node.jstree", function (event, node) { $('#objform').find('input[name=name]').focus(); //點擊已有節點。。編輯 var currnode = node.node; $('#curr_op_name').val(currnode.text); //添加隱藏域和記錄當前操作的對象 if(currnode.id.indexOf('new')=='-1'){ $('#curr_op_title').text('編輯'); //添加隱藏域,用於記錄修改的分組名 if($("#update_"+currnode.id).length==0){ $('#objform').append('<input type="hidden" name="update['+currnode.id+'][name]" id="update_'+currnode.id+'" value="'+currnode.text+'" />'); } //記錄當前操作的對象 op_obj = $("#update_"+currnode.id); }else{ //新增節點編輯 //記錄當前操作的對象 $('#curr_op_title').text('新增'); op_obj = $("#add_"+currnode.id); } }); //監聽修改的分組名,寫入隱藏域 $('#curr_op_name').on('input',function () { var value = $.trim($(this).val()); var ref = $('#container').jstree(true); var sel = ref.get_selected(); //有選中節點 纔去更新數據 if(sel.length!=0){ //同步更新隱藏域和節點的文本值 op_obj.val(value); ref.set_text(sel, value); } }); //插入節點或插入子節點 var newId = 1; function createNode(data, pos) { var inst = $.jstree.reference(data.reference); var obj = inst.get_node(data.reference);//獲取當前樹節點 obj.data.type = 'default'; var pid= pos=='after' ? obj.parent : obj.id; var data={}; data.id='new'+(newId++); data.name='自定義分組'; data.parentid=pid; //把以上數據寫入表單 $('#objform').append('<input type="hidden" name="add['+data.id+'][name]" id="add_'+data.id+'" value="'+data.name+'" /><input type="hidden" name="add['+data.id+'][parentid]" value="'+pid+'" id="add_pid_'+data.id +'"/>'); inst.create_node(obj, { id:data.id, text: data.name, data: { data:data,jstree:{type: "show"}}, }, pos, function (new_node) { inst.deselect_all(); inst.select_node(new_node, true); inst.select_node(new_node); } ); $('#objform').find('input[name=name]').focus(); } //刪除節點 function deleteNode(data) { var inst = $.jstree.reference(data.reference), obj = inst.get_node(data.reference); //當前刪除節點的id var id = obj.id; //刪除表單中的隱藏域 if(id.indexOf('new')=='-1'){ //原節點 $('#update_'+id).remove(); }else{ //新增的節點 $('#add_'+id).remove(); $('#add_pid_'+id).remove(); } //在表單中添加隱藏域,標記刪除的節點 $('#objform').append('<input type="hidden" name="del['+id+']" value="'+id+'" />'); inst.delete_node(obj); //編輯框的值清除 $('#curr_op_name').val(''); } //表單提交驗證,所有修改或新增的分組名不能爲空 $('#save').click(function () { $flag = true;//標記是否通過驗證 $('#objform input:hidden').each(function (key,obj) { if(!$(obj).val()){ alert('所有分組名稱不能爲空!'); return false; $flag = false; } }); if($flag){ alert('此操作將對所有變更做保存,包括刪除節點,您確認要進行此操作?') $('#objform').submit(); } });
後臺就可以針對傳過來的數據,變更通訊錄分組
/** * @todo 通訊錄保存,包含新增、修改、刪除 */ public function contacts_group_save(){ $userid = param::get_cookie('_userid'); //獲取當前用戶編號 $data = $_POST; if(!$data['update'] && !$data['add'] && !$data['del']){ showmessage('數據沒有任何修改', buildurl('contacts_group_list', 'index', 'contacts')); } //操作 if($data['update']){ //修改,驗證數據 foreach ($data['update'] as $key=>$value){ if(empty($value['name'])){ showmessage('分組名稱不能爲空!', buildurl('contacts_group_list', 'index', 'contacts')); } $info = $this->group_db->get_one(['id'=>$key]); if(!$info){ showmessage('分組信息不存在!', buildurl('contacts_group_list', 'index', 'contacts')); } //當要修改的的分組名,和原組名一致,不進行修改 $is_update = $this->group_db->get_one(['id'=>$key,'name'=>$value['name']]); if(!$is_update){ //修改時,需要驗證,同級別(parentid相同) 組名不能重複 $is_update_again = $this->group_db->get_one(['parentid'=>$info['parentid'],'name'=>$value['name']]); if($is_update_again){ showmessage('同級部門已存在相同分組名稱!', buildurl('contacts_group_list', 'index', 'contacts')); } $flag = $this->group_db->update(['name'=>$value['name'],'time'=>date('Y-m-d H:i:s',time())],['id'=>$key]); }else{ $flag = true; //標記修改,實際未修改,爲了顯示修改成功 } } } if($data['add']){ //添加 驗證數據 foreach ($data['add'] as $key=>$value){ if(empty($value['name'])){ showmessage('分組名稱不能爲空!', buildurl('contacts_group_list', 'index', 'contacts')); } $is_add = $this->group_db->get_one(['name'=>$value['name'],'parentid'=>$value['parentid']]); if($is_add){ showmessage('同級部門已存在相同分組名稱!', buildurl('contacts_group_list', 'index', 'contacts')); } $data = array( 'uid'=> $userid, 'name'=>$value['name'], 'time'=>date('Y-m-d H:i:s',time()), 'parentid'=>$value['parentid'], ); $flag = $this->group_db->insert($data); } } if($data['del']){ //刪除 軟刪除 foreach ($data['del'] as $key=>$value){ $flag = $this->group_db->update(['is_del'=>1,'time'=>date('Y-m-d H:i:s',time())],['id'=>$value]); } } if($flag){ showmessage('用戶分組更新成功!', buildurl('contacts_group_list', 'index', 'contacts')); }else{ showmessage('用戶分組更新失敗!', buildurl('contacts_group_list', 'index', 'contacts')); } }