easyui-treegrid實現節點繫結選擇功能
阿新 • • 發佈:2019-02-01
背景:
使用treegrid,實現一個樹形的職業選擇(多選)。
需求:
1)選中一個最低階的節點,能夠自動選中所有父節點。
2)取消選中某節點下唯一的選中節點,則取消的父節點也一併取消,並且用該規則迭代被取消節點的所有父節點。
3)勾選一個父節點,則子節點全選,同理,反選父節點,子節點也反選。
設計及實踐:
一、頁面部分
頁面部分沒有什麼東西,這裡去掉了一個<th data-options="field:'ck',checkbox=true"></th>因為這個東西會被測試提bug。(後敘)
<table id="occupationGrid" class="easyui-treegrid" style="width:656px;height:426px;"> <thead> <tr> <th data-options="field:'professionId',hidden:true">主鍵</th> <th data-options="field:'customerId',hidden:true">保險公司主鍵</th> <th data-options="field:'name',align:'left'">行業名稱</th> <th data-options="field:'code',align:'left'">行業程式碼</th> <th data-options="field:'type',align:'center'">行業類別</th> </tr> </thead> </table>
二、JavaScript部分
$('#occupationGrid').treegrid({ url:'profession/query.action?customerId='+customerId+'&active=1', idField:'professionId', treeField:'name', singleSelect:false, rownumbers:true, loadMsg:'正在載入資料', onClickRow:function(row){ //獲取所有選中節點並遍歷他們 var select = $('#occupationGrid').treegrid('getSelections'); for(var i=0;i<select.length;i++) { if(select[i].professionId==row.professionId) { // ①選中某個節點,遍歷所有父節點,設定選中 if(row.parentId && row.parentId!=0) { parentOption('select',row.parentId); } // ②同步處理該節點下的子節點 var children = row.children; if(children && children.length>0) { childOperation('select',children) } return; } } //取消選中行的子節點 var children = row.children; if(children && children.length>0) { childOperation('unselect',children); } unselectParents(row); /** * 設定子節點選中/取消選中 * @param method 選:'select'/不選'unselect' * @param children 子節點的資料 */ function childOperation(method,children) { for(var i=0;i<children.length;i++) { var thisRow = children[i]; $('#occupationGrid').treegrid(method,thisRow.professionId); if(children[i].children && children[i].children.length>0) { childOperation(method,children[i].children); } } } /** * 處理所有父節點選中或取消選中 * @param method 選:'select'/不選'unselect' * @param parentId 父節點id */ function parentOption(method,parentId) { if(!parentId) { return; } $('#occupationGrid').treegrid(method,parentId); var thisNode = $('#occupationGrid').treegrid('find',parentId); if(thisNode.parentId && thisNode.parentId!=0) { parentOption(method,thisNode.parentId); } } /** * 取消選中節點的父節點 * 必須是當前節點的兄弟節點都沒有選中的情況下,才去取消父節點,要逐級判斷 * @param row */ function unselectParents(row){ //判斷該行同級節點是否有選中,若都沒有,則取消該節點上級選中 if(row.parentId && row.parentId!=0) { var noCheckChildren = false; var parentNode = $('#occupationGrid').treegrid('find',row.parentId); var childrenNodes = $('#occupationGrid').treegrid('getChildren',row.parentId); for(var i=0;i<childrenNodes.length;i++) { var a = $('tr[node-id='+childrenNodes[i].professionId+']') .hasClass('datagrid-row-checked datagrid-row-selected'); if(a) { noCheckChildren = true; } } if(!noCheckChildren) { $('#occupationGrid').treegrid('unselect',parentNode.professionId); unselectParents(parentNode); } } } }, onLoadSuccess:function(row, data){ professionIds = $('#occupationGrid').treegrid('getSelections'); } });
1)通過onSelect/unSelect事件,只能實現需求三,當選中一個父節點會同時觸發多個需求。因為使用了以下方法來實現選中/不選:
$('#id').treegrid('select',row.id);//這個方法本身會觸發onSelect事件,所以會出現衝突,不能用。
2)找遍了api文件,想盡了辦法得到上面的程式碼。但是由於checkbox的存在,這個獨立於資料區的選項,並不遵循繫結的事件觸發,於是只能將checkbox刪除,免得測試提bug。