treegrid添加複選框, 附帶級聯事件(自用, 非法調用方式不做處理)

引入treegridEvent.js

/**
 * 自定義樹型表格事件及方法(級聯時用)
 * 針對手動加的複選框, 相關的事件及方法
 */
var treegridEvent = {
		cascade : true,		//是否級聯
		linkage : false,	//行選中與複選框勾選是否聯動
		gridId : "domain_treegrid",	//表格id
		//複選框選中事件
		onChecked : function(nodeId, isChecked){
			//阻止冒泡, 目的是點擊複選框時, 不觸表格的click事件, 而是手動加樣式
			event.stopPropagation();
			//獲取樹圖jquery對象以及真實表格的table對象
			var linkage = this.linkage,
				$treegrid = $("#"+this.gridId),
				$table = $treegrid.prev(".datagrid-view2")
								.children(".datagrid-body")
								.children(".datagrid-btable");
			if(linkage){
				//根據isChecked, 設置當前行選中或不選中
				if(isChecked){
					$treegrid.treegrid("select", nodeId);
				}else{
					$treegrid.treegrid("unselect", nodeId);
				}//if
			}
			if(!this.cascade){
				return;		//如果不級聯, 就此結束
			}
			
			/**
			 * 級聯共有四種情況
			 * 父選中, 父取消, 子選中, 子取消
			 * 下面對四種情況做處理
			 */
			
			//父選中或取消, 子一定隨之而動
			var children = $treegrid.treegrid("getChildren", nodeId);//該方法可跨代獲取
			for(var i=0,len=children.length; i<len; i++){
				var child = children[i],
					childId= child.CODE;
				$table.find('input[name="treegrid_box"][value="'+childId+'"]').attr("checked", isChecked);
				if(linkage){
					//根據isChecked, 設置當前行選中或不選中
					if(isChecked){
						$treegrid.treegrid("select", childId);
					}else{
						$treegrid.treegrid("unselect", childId);
					}//if
				}
			}//for
			
			if(isChecked){
				/* 子級選中後, 對父級的處理, 調用遞歸 */
				treegridEvent.onChildChecked(nodeId);
			}else{
				/* 子取消選中, 父也一定取消 */
				//先遞歸獲取所有父節點
				var parentIds = this.recurGetParents(nodeId);
				//遍歷父節點, 一一做處理
				for(var i=0,len=parentIds.length; i<len; i++){
					var parentId = parentIds[i];
					$table.find('input[name="treegrid_box"][value="'+parentId+'"]').attr("checked", false);
					if(linkage){
						$treegrid.treegrid("unselect", parentId);	//取消勾選後, 設置行取消選中
					}
				}
			}
		},
		//子級選中後, 對父級的處理, 因爲遞歸, 所以提出來寫成方法
		onChildChecked : function(nodeId){
			var linkage = treegridEvent.linkage,
				$treegrid = $("#"+treegridEvent.gridId),
				$table = $treegrid.prev(".datagrid-view2")
								.children(".datagrid-body")
								.children(".datagrid-btable");
			/**
			 * 子選中, 如果其他兄弟都選中, 那麼父也選中
			 * 總共分五步
			 */
			//第一步, 先獲取父級
			var parent = $treegrid.treegrid("getParent", nodeId);
			if(!parent){	//避免父級爲null情況
				return;
			}
			var parentId = parent.CODE,
				flag = true;	//開關默認爲true
			//第二步, 獲取父級的所有子級
			var children = $treegrid.treegrid("getChildren", parent.CODE);
			for(var i=0,len=children.length; i<len; i++){
				var child = children[i];
				/*
				 * 過濾出節點的兄弟級
				 * 因爲插件的getChildren方法, 獲取的是所有後代, 也就是跨代獲取
				 * 所以要根據子級的父id, 與原始父id對比
				 * 如果相同, 則是兄弟級, 否則不是
				 */
				if(child.PARENT_CODE == parentId){
					//第三步, 獲取兄弟的checked屬性
					var chiIsChecked = 
						$table.find('input[name="treegrid_box"][value="'+child.CODE+'"]').attr("checked");
					/* 如果有一個兄弟沒被選中, 那麼開關設置爲false */
					if(!chiIsChecked){
						flag = false;
						break;	//之後的也沒必要判斷了, 直接break
					}
				}
			}
			//第四步, 根據之前得出的開關flag, 設置父級是否選中
			if(flag){
				$table.find('input[name="treegrid_box"][value="'+parentId+'"]').attr("checked", true);
				if(linkage){
					$treegrid.treegrid("select", parentId);	//勾選後, 設置行選中
				}
				//第五步, 如果父級選中了, 那麼要找到父級的兄弟級, 繼續做同樣判斷, 可用遞歸
				treegridEvent.onChildChecked(parentId);
			}
		},
		//遞歸獲取所有父節點, (子級取消選中時用)
		recurGetParents : function(nodeId){
			var $treegrid = $("#"+treegridEvent.gridId),
				parent = $treegrid.treegrid("getParent", nodeId);
			if(parent){
				var parentId = parent.CODE;
				var parentIds = treegridEvent.recurGetParents(parentId);
				parentIds.push(parentId);
				return parentIds;
			}else{
				return [];
			}
		},
		//獲取選中的checkbox
		getCheckedBoxes : function(){
			var boxArr = $("#"+this.gridId)
							.prev(".datagrid-view2")
							.children(".datagrid-body")
							.children(".datagrid-btable")
							.find("input[name='treegrid_box']:checked");
			return boxArr;
		}
};

之後正常初始化treegrid, 需要注意onClickRow事件中的寫法(其實是判斷複選框的勾選與行選中是否聯動), 參考如下:

init : function(){
	$("#domain_treegrid").treegrid({
		idField: "CODE",
		treeField: "NAME",
		columns:[[
			{field:'NAME',title:'專業名稱',width:100,align:"left",
				formatter: function(val, rowData, index){
					var html = ''
						+'<input type="checkbox" name="treegrid_box" '
						+	'style="margin-left:5px;" '
						+	'value="'+rowData.CODE+'" ' 
						+	'οnclick="treegridEvent.onChecked(this.value, this.checked);" />'
						+ val;    //非級聯時,不加onclick事件
					return html;
				}},
			{field:'REMARK',title:'備註',width:300,align:"center"},
			{field:'PARENT_CODE',title:'父節點',width:100,align:"center",hidden:true}
		]],
		animate: true,
		fitColumns: true,
		singleSelect: true,
		data: [],
		onClickRow : function(row){
			if(treegridEvent.linkage){
				var nodeId = row.CODE,
					$tr = $("#domain_treegrid")
						.prev(".datagrid-view2")
						.children(".datagrid-body")
						.children(".datagrid-btable")
						.children("tbody")
						.find('tr[node-id="'+nodeId+'"]'),
					//找到當前行的dom, 根據是否有特定class判斷是否選中
					isChecked = $tr.hasClass("datagrid-row-selected");
				//根據isChecked, 爲複選框設置狀態
				$tr.find('input[type="checkbox"][name="treegrid_box"]').attr("checked", isChecked);
				//之後調用onChecked事件
				treegridEvent.onChecked(nodeId, isChecked);
			}
		}
	});
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章