1、先将插件源码进行下载,新建 tableTree.js
文件,将源码放进去
2、将 tableTree.js
文件 配置之后,在需要使用的页面进行引入:
layui. define ( [ "tableTree" ] , function ( exports ) {
var tableTree = layui. tableTree;
var handleList = function ( ) {
let tableData = [ {
"pid" : "0" ,
"title" : "1" ,
"parentTitle" : null ,
"sid" : "1111111111" ,
"children" : null
} ,
{
"pid" : "1111111111" ,
"title" : "1-1" ,
"parentTitle" : "1" ,
"sid" : "2"
} ,
{
"pid" : "1111111111" ,
"title" : "1-2" ,
"parentTitle" : "1" ,
"sid" : "3"
} ,
{
"pid" : "0" ,
"title" : "2" ,
"parentTitle" : null ,
"sid" : "2222222"
} , {
"pid" : "0" ,
"title" : "3" ,
"parentTitle" : null ,
"sid" : "3333333"
} , {
"pid" : "0" ,
"title" : "4" ,
"parentTitle" : null ,
"sid" : "44444"
} , {
"pid" : "0" ,
"title" : "5" ,
"parentTitle" : null ,
"sid" : "5555"
} , {
"pid" : "5555" ,
"title" : "5" ,
"parentTitle" : "5" ,
"sid" : "6"
} ]
renderTable ( tableData)
}
var renderTable = function ( tableData ) {
tableTree. render ( {
id : 'test' ,
tree : {
iconIndex : 3 ,
isPidData : true ,
idName : 'sid' ,
pidName : 'pid' ,
openName : 'open' ,
} ,
elem : '#test' ,
skin : 'line'
, page : false
, limit : 100
, cols : [ [
{ field : 'sid' , hide : true } ,
{ type : 'radio' }
, { field : 'title' , title : '名称' , align : 'left' , width : 200 }
, {
field : 'opt' , title : '操作' , templet :
function ( item ) {
if ( item. sid < 100000 ) {
return ' '
}
return ' '
}
}
] ] ,
data : tableData,
done : function ( ) {
}
, event : true
} )
} ;
tableTree. on ( 'checkbox(LAY-model-manager)' , function ( obj ) {
var data = obj. data;
console. log ( '拿到的当前行的数据' , data)
} ) ;
tableTree. on ( "tool(LAY-model-manager)" , function ( obj ) {
var data = obj. data;
var layEvent = obj. event;
var tr = obj. tr;
if ( "del" === layEvent) {
console. log ( 删除的数据', data)
} else if ( "edit" === layEvent) {
console. log ( 操作的数据', data)
}
} ) ;
var Class = {
init : function ( ) {
handleList ( )
return this ;
} ,
} ;
}
) ;
效果图:
插件源码如下:
layui. define ( [ 'laytpl' , 'form' , 'util' ] , function ( exports ) {
var $ = layui. jquery;
var laytpl = layui. laytpl;
var form = layui. form;
var util = layui. util;
var device = layui. device ( ) ;
var MOD_NAME = 'treeTable' ;
var _instances = { } ;
var defaultOption = {
elem : undefined ,
cols : undefined ,
url : undefined ,
method : undefined ,
where : undefined ,
contentType : undefined ,
headers : undefined ,
parseData : undefined ,
request : { pidName : 'pid' } ,
toolbar : undefined ,
defaultToolbar : undefined ,
width : undefined ,
height : undefined ,
cellMinWidth : 90 ,
done : undefined ,
data : undefined ,
title : undefined ,
skin : undefined ,
even : undefined ,
size : undefined ,
text : {
none : '无数据'
} ,
reqData : undefined ,
useAdmin : false ,
tree : {
idName : 'id' ,
pidName : 'pid' ,
childName : 'children' ,
haveChildName : 'haveChild' ,
openName : 'open' ,
iconIndex : 0 ,
arrowType : undefined ,
onlyIconControl : undefined ,
getIcon : function ( d ) {
var haveChild = d[ this . haveChildName] ;
if ( haveChild !== undefined ) haveChild = haveChild === true || haveChild === 'true' ;
else if ( d[ this . childName] ) haveChild = d[ this . childName] . length > 0 ;
if ( haveChild) return ' ' ;
else return ' ' ;
}
}
} ;
var colDefaultOption = {
field : undefined ,
title : undefined ,
width : undefined ,
minWidth : undefined ,
type : 'normal' ,
fixed : undefined ,
hide : undefined ,
unresize : undefined ,
style : undefined ,
align : undefined ,
colspan : undefined ,
rowspan : undefined ,
templet : undefined ,
toolbar : undefined ,
'class' : undefined ,
singleLine : undefined
} ;
var TreeTable = function ( options ) {
_instances[ options. elem. substring ( 1 ) ] = this ;
this . reload ( options) ;
} ;
TreeTable . prototype. initOptions = function ( opt ) {
var that = this ;
function initCol ( item ) {
if ( ! item. INIT_OK ) item = $. extend ( { INIT_OK : true } , colDefaultOption, item) ;
if ( item. type === 'space' ) {
if ( ! item. width) item. width = 15 ;
item. minWidth = item. width;
} else if ( item. type === 'numbers' ) {
if ( ! item. width) item. width = 40 ;
item. minWidth = item. width;
if ( ! item. singleLine) item. singleLine = false ;
if ( ! item. unresize) item. unresize = true ;
if ( ! item. align) item. align = 'center' ;
} else if ( item. type === 'checkbox' || item. type === 'radio' ) {
if ( ! item. width) item. width = 48 ;
item. minWidth = item. width;
if ( ! item. singleLine) item. singleLine = false ;
if ( ! item. unresize) item. unresize = true ;
if ( ! item. align) item. align = 'center' ;
}
if ( item. toolbar) item. type = 'tool' ;
return item;
}
if ( 'Array' !== isClass ( opt. cols[ 0 ] ) ) opt. cols = [ opt. cols] ;
for ( var m = 0 ; m < opt. cols. length; m++ ) {
for ( var n = 0 ; n < opt. cols[ m] . length; n++ ) {
opt. cols[ m] [ n] . INIT_OK = undefined ;
opt. cols[ m] [ n] . key = undefined ;
opt. cols[ m] [ n] . colGroup = undefined ;
opt. cols[ m] [ n] . HAS_PARENT = undefined ;
opt. cols[ m] [ n] . parentKey = undefined ;
opt. cols[ m] [ n] . PARENT_COL_INDEX = undefined ;
}
}
var colArrays = [ ] , colIndex = 0 ;
for ( var i1 = 0 ; i1 < opt. cols. length; i1++ ) {
var item1 = opt. cols[ i1] ;
for ( var i2 = 0 ; i2 < item1. length; i2++ ) {
var item2 = item1[ i2] ;
if ( ! item2) {
item1. splice ( i2, 1 ) ;
continue ;
}
item2 = initCol ( item2) ;
item2. key = i1 + '-' + i2;
var CHILD_COLS = undefined ;
if ( item2. colGroup || item2. colspan > 1 ) {
item2. colGroup = true ;
item2. type = 'group' ;
CHILD_COLS = [ ] ;
colIndex++ ;
var childIndex = 0 ;
for ( var i22 = 0 ; i22 < opt. cols[ i1 + 1 ] . length; i22++ ) {
var item22 = $. extend ( { INIT_OK : true } , colDefaultOption, opt. cols[ i1 + 1 ] [ i22] ) ;
if ( item22. HAS_PARENT || ( childIndex > 1 && childIndex == item2. colspan) ) {
opt. cols[ i1 + 1 ] [ i22] = item22;
continue ;
}
item22. HAS_PARENT = true ;
item22. parentKey = i1 + '-' + i2;
item22. key = ( i1 + 1 ) + '-' + i22;
item22. PARENT_COL_INDEX = colIndex;
item22 = initCol ( item22) ;
CHILD_COLS . push ( item22) ;
childIndex = childIndex + parseInt ( item22. colspan > 1 ? item22. colspan : 1 ) ;
opt. cols[ i1 + 1 ] [ i22] = item22;
}
}
item2. CHILD_COLS = CHILD_COLS ;
if ( ! item2. PARENT_COL_INDEX ) colArrays. push ( item2) ;
opt. cols[ i1] [ i2] = item2;
}
}
this . options = $. extend ( true , { } , defaultOption, opt) ;
this . options. colArrays = colArrays;
if ( this . options. url) {
this . options. reqData = function ( data, callback ) {
if ( ! that. options. where) that. options. where = { } ;
if ( data) that. options. where[ that. options. request. pidName] = data[ that. options. tree. idName] ;
( that. options. useAdmin ? layui. admin : $) . ajax ( {
url : that. options. url,
data : that. options. contentType && that. options. contentType. indexOf ( 'application/json' ) === 0 ? JSON . stringify ( that. options. where) : that. options. where,
headers : that. options. headers,
type : that. options. method,
dataType : 'json' ,
contentType : that. options. contentType,
success : function ( res ) {
if ( that. options. parseData) res = that. options. parseData ( res) ;
if ( res. code == 0 ) callback ( res. data) ;
else callback ( res. msg || '加载失败' ) ;
} ,
error : function ( xhr ) {
callback ( xhr. status + ' - ' + xhr. statusText) ;
}
} ) ;
} ;
} else if ( this . options. data && this . options. data. length > 0 && this . options. tree. isPidData) {
this . options. data = tt. pidToChildren ( this . options. data, this . options. tree. idName, this . options. tree. pidName, this . options. tree. childName) ;
}
if ( 'default' === this . options. toolbar) {
this . options. toolbar = [
''
,
' ',
' ' ,
'
' ,
' ',
' ' ,
'
' ,
' ',
' ' ,
'
' ,
' '
] . join ( '' ) ;
}
if ( this . options. defaultToolbar === undefined ) this . options. defaultToolbar = [ 'filter' , 'exports' , 'print' ] ;
if ( typeof this . options. tree. getIcon === 'string' ) {
var icon = this . options. tree. getIcon;
this . options. tree. getIcon = function ( d ) {
if ( icon !== 'ew-tree-icon-style2' ) return icon;
var haveChild = d[ this . haveChildName] ;
if ( haveChild !== undefined ) haveChild = haveChild === true || haveChild === 'true' ;
else if ( d[ this . childName] ) haveChild = d[ this . childName] . length > 0 ;
if ( haveChild) return ' ' ;
else return ' ' ;
}
}
} ;
TreeTable . prototype. init = function ( ) {
var options = this . options;
var $elem = $ ( options. elem) ;
var tbFilter = options. elem. substring ( 1 ) ;
$elem. removeAttr ( 'lay-filter' ) ;
if ( $elem. next ( '.ew-tree-table' ) . length === 0 ) {
$elem. css ( 'display' , 'none' ) ;
$elem. after ( [
''
] . join ( '' ) ) ;
}
var components = this . getComponents ( ) ;
if ( options. skin) components. $table. attr ( 'lay-skin' , options. skin) ;
if ( options. size) components. $table. attr ( 'lay-size' , options. size) ;
if ( options. even) components. $table. attr ( 'lay-even' , options. even) ;
components. $toolbar. empty ( ) ;
if ( options. toolbar === false || options. toolbar === undefined ) {
components. $toolbar. hide ( ) ;
} else {
components. $toolbar. show ( ) ;
if ( typeof options. toolbar === 'string' ) {
laytpl ( $ ( options. toolbar) . html ( ) ) . render ( { } , function ( html ) {
components. $toolbar. html ( '' + html + '
' ) ;
} ) ;
}
var tbRights = [ '' ) ;
}
if ( options. width) {
components. $view. css ( 'width' , options. width) ;
components. $tHeadGroup. css ( 'width' , options. width) ;
components. $tBodyGroup. css ( 'width' , options. width) ;
}
var colgroupHtml = this . resize ( true ) ;
var headHtml = '' + this . renderBodyTh ( ) + ' ' ;
components. $tBodyGroup. children ( 'style' ) . remove ( ) ;
if ( options. height) {
components. $tHead. html ( colgroupHtml + headHtml) ;
components. $tBody. html ( colgroupHtml + ' ' ) ;
if ( options. height. indexOf ( 'full-' ) === 0 ) {
var h = parseFloat ( options. height. substring ( 5 ) ) + components. $toolbar. outerHeight ( )
+ components. $tHeadGroup. outerHeight ( ) + 1 ;
components. $tBodyGroup. append ( [
''
] . join ( '' ) ) ;
components. $tBodyGroup. data ( 'full' , h) ;
components. $tBodyGroup. css ( 'height' , '' ) ;
} else {
components. $tBodyGroup. css ( 'height' , options. height) ;
components. $tBodyGroup. data ( 'full' , '' ) ;
}
components. $tHeadGroup. show ( ) ;
} else {
components. $tHeadGroup. hide ( ) ;
var trH = { lg : 50 , sm : 30 , md : 38 } ;
components. $tBodyGroup. append ( [
''
] . join ( '' ) ) ;
components. $tBody. html ( colgroupHtml + headHtml + ' ' ) ;
}
form. render ( 'checkbox' , tbFilter) ;
function patchHide ( $tr ) {
var parentKey = $tr. data ( 'parent' ) , pCol;
if ( ! parentKey) return ;
var $parent = components. $table. children ( 'thead' ) . children ( 'tr' ) . children ( '[data-key="' + parentKey + '"]' ) ;
var colspan = $parent. attr ( 'colspan' ) - 1 ;
$parent. attr ( 'colspan' , colspan) ;
if ( colspan === 0 ) $parent. addClass ( 'layui-hide' ) ;
patchHide ( $parent) ;
}
components. $table. children ( 'thead' ) . children ( 'tr' ) . children ( 'th.layui-hide' ) . each ( function ( ) {
patchHide ( $ ( this ) ) ;
} ) ;
if ( options. reqData) {
this . options. data = undefined ;
this . renderBodyAsync ( ) ;
} else if ( options. data && options. data. length > 0 ) {
this . renderBodyData ( options. data) ;
} else {
components. $loading. hide ( ) ;
components. $empty. show ( ) ;
}
} ;
TreeTable . prototype. bindEvents = function ( ) {
var that = this ;
var options = this . options;
var components = this . getComponents ( ) ;
var $allBody = components. $table. children ( 'tbody' ) ;
var member = function ( ext ) {
var $tr = $ ( this ) ;
if ( ! $tr. is ( 'tr' ) ) {
var $temp = $tr. parent ( 'tr' ) ;
if ( $temp. length > 0 ) $tr = $temp;
else $tr = $tr. parentsUntil ( 'tr' ) . last ( ) . parent ( ) ;
}
var data = that. getDataByTr ( $tr) ;
var obj = {
tr : $tr,
data : data,
del : function ( ) {
var index = $tr. data ( 'index' ) ;
var indent = parseInt ( $tr. data ( 'indent' ) ) ;
$tr. nextAll ( 'tr' ) . each ( function ( ) {
if ( parseInt ( $ ( this ) . data ( 'indent' ) ) <= indent) return false ;
$ ( this ) . remove ( ) ;
} ) ;
var indexLength = ( typeof index === 'number' ? 1 : index. split ( '-' ) . length) ;
$tr. nextAll ( 'tr' ) . each ( function ( ) {
var $this = $ ( this ) ;
if ( parseInt ( $this . data ( 'indent' ) ) < indent) return false ;
var _index = $this . data ( 'index' ) . toString ( ) . split ( '-' ) ;
_index[ indexLength - 1 ] = parseInt ( _index[ indexLength - 1 ] ) - 1 ;
$this . data ( 'index' , _index. join ( '-' ) ) ;
} ) ;
var $pTr = $tr. prevAll ( 'tr' ) ;
that. del ( undefined , index) ;
$tr. remove ( ) ;
that. renderNumberCol ( ) ;
$pTr. each ( function ( ) {
var tInd = parseInt ( $ ( this ) . data ( 'indent' ) ) ;
if ( tInd >= indent) return true ;
that. checkParentCB ( $ ( this ) ) ;
indent = tInd;
} ) ;
that. checkChooseAllCB ( ) ;
if ( options. data. length === 0 ) components. $empty. show ( ) ;
updateFixedTbHead ( components. $view) ;
} ,
update : function ( fields ) {
data = $. extend ( true , data, fields) ;
var indent = parseInt ( $tr. data ( 'indent' ) ) ;
that. renderBodyTr ( data, indent, undefined , $tr) ;
form. render ( null , components. filter) ;
that. renderNumberCol ( ) ;
$tr. prevAll ( 'tr' ) . each ( function ( ) {
var tInd = parseInt ( $ ( this ) . data ( 'indent' ) ) ;
if ( tInd >= indent) return true ;
that. checkParentCB ( $ ( this ) ) ;
indent = tInd;
} ) ;
that. checkChooseAllCB ( ) ;
}
} ;
return $. extend ( obj, ext) ;
} ;
$allBody. off ( 'click.fold' ) . on ( 'click.fold' , '.ew-tree-pack' , function ( e ) {
layui. stope ( e) ;
var $tr = $ ( this ) . parentsUntil ( 'tr' ) . last ( ) . parent ( ) ;
if ( $tr. hasClass ( 'ew-tree-table-loading' ) ) return ;
var haveChild = $tr. data ( 'have-child' ) ;
if ( haveChild !== true && haveChild !== 'true' ) return ;
var open = $tr. hasClass ( 'ew-tree-table-open' ) ;
var data = that. getDataByTr ( $tr) ;
if ( ! open && ! data[ options. tree. childName] ) {
that. renderBodyAsync ( data, $tr) ;
} else {
data[ options. tree. openName] = toggleRow ( $tr) ;
}
} ) ;
$allBody. off ( 'click.tool' ) . on ( 'click.tool' , '*[lay-event]' , function ( e ) {
layui. stope ( e) ;
var $this = $ ( this ) ;
layui. event . call ( this , MOD_NAME , 'tool(' + components. filter + ')' , member . call ( this , {
event : $this . attr ( 'lay-event' )
} ) ) ;
} ) ;
form. on ( 'radio(' + components. radioFilter + ')' , function ( data ) {
var d = that. getDataByTr ( $ ( data. elem) . parentsUntil ( 'tr' ) . last ( ) . parent ( ) ) ;
that. removeAllChecked ( ) ;
d. LAY_CHECKED = true ;
d. LAY_INDETERMINATE = false ;
layui. event . call ( this , MOD_NAME , 'checkbox(' + components. filter + ')' ,
{ checked : true , data : d, type : 'one' } ) ;
} ) ;
form. on ( 'checkbox(' + components. checkboxFilter + ')' , function ( data ) {
var checked = data. elem. checked;
var $cb = $ ( data. elem) ;
var $layCb = $cb. next ( '.layui-form-checkbox' ) ;
if ( ! checked && $cb. hasClass ( 'ew-form-indeterminate' ) ) {
checked = true ;
$cb. prop ( 'checked' , checked) ;
$layCb. addClass ( 'layui-form-checked' ) ;
$cb. removeClass ( 'ew-form-indeterminate' ) ;
}
var $tr = $cb. parentsUntil ( 'tr' ) . last ( ) . parent ( ) ;
var d = that. getDataByTr ( $tr) ;
d. LAY_CHECKED = checked;
d. LAY_INDETERMINATE = false ;
if ( d[ options. tree. childName] && d[ options. tree. childName] . length > 0 ) {
that. checkSubCB ( $tr, checked) ;
}
var indent = parseInt ( $tr. data ( 'indent' ) ) ;
$tr. prevAll ( 'tr' ) . each ( function ( ) {
var tInd = parseInt ( $ ( this ) . data ( 'indent' ) ) ;
if ( tInd < indent) {
that. checkParentCB ( $ ( this ) ) ;
indent = tInd;
}
} ) ;
that. checkChooseAllCB ( ) ;
layui. event . call ( this , MOD_NAME , 'checkbox(' + components. filter + ')' ,
{ checked : checked, data : d, type : 'more' } ) ;
} ) ;
form. on ( 'checkbox(' + components. chooseAllFilter + ')' , function ( data ) {
var checked = data. elem. checked;
var $cb = $ ( data. elem) ;
var $layCb = $cb. next ( '.layui-form-checkbox' ) ;
if ( ! options. data || options. data. length === 0 ) {
$cb. prop ( 'checked' , false ) ;
$layCb. removeClass ( 'layui-form-checked' ) ;
$cb. removeClass ( 'ew-form-indeterminate' ) ;
return ;
}
if ( ! checked && $cb. hasClass ( 'ew-form-indeterminate' ) ) {
checked = true ;
$cb. prop ( 'checked' , checked) ;
$layCb. addClass ( 'layui-form-checked' ) ;
$cb. removeClass ( 'ew-form-indeterminate' ) ;
}
layui. event . call ( this , MOD_NAME , 'checkbox(' + components. filter + ')' , { checked : checked, type : 'all' } ) ;
that. checkSubCB ( components. $tBody. children ( 'tbody' ) , checked) ;
} ) ;
$allBody. off ( 'click.row' ) . on ( 'click.row' , 'tr' , function ( ) {
layui. event . call ( this , MOD_NAME , 'row(' + components. filter + ')' , member . call ( this , { } ) ) ;
} ) ;
$allBody. off ( 'dblclick.rowDouble' ) . on ( 'dblclick.rowDouble' , 'tr' , function ( ) {
layui. event . call ( this , MOD_NAME , 'rowDouble(' + components. filter + ')' , member . call ( this , { } ) ) ;
} ) ;
$allBody. off ( 'click.cell' ) . on ( 'click.cell' , 'td' , function ( e ) {
var $td = $ ( this ) ;
var type = $td. data ( 'type' ) ;
if ( type === 'checkbox' || type === 'radio' ) return layui. stope ( e) ;
var edit = $td. data ( 'edit' ) ;
var field = $td. data ( 'field' ) ;
if ( edit) {
layui. stope ( e) ;
if ( $allBody. find ( '.ew-tree-table-edit' ) . length > 0 ) return ;
var index = $td. data ( 'index' ) ;
var indent = $td. find ( '.ew-tree-table-indent' ) . length;
var d = that. getDataByTr ( $td. parent ( ) ) ;
if ( 'text' === edit || 'number' === edit) {
var $input = $ ( ' + edit + '" class="layui-input ew-tree-table-edit"/>' ) ;
$input[ 0 ] . value = d[ field] ;
$td. append ( $input) ;
$input. focus ( ) ;
$input. blur ( function ( ) {
var value = $ ( this ) . val ( ) ;
if ( value == d[ field] ) return $ ( this ) . remove ( ) ;
var rs = layui. event . call ( this , MOD_NAME , 'edit(' + components. filter + ')' , member . call ( this ,
{ value : value, field : field} ) ) ;
if ( rs === false ) {
$ ( this ) . addClass ( 'layui-form-danger' ) ;
$ ( this ) . focus ( ) ;
} else {
d[ field] = value;
var keys = $td. data ( 'key' ) . split ( '-' ) ;
that. renderBodyTd ( d, indent, index, $td, options. cols[ keys[ 0 ] ] [ keys[ 1 ] ] ) ;
}
} ) ;
} else {
console. error ( '不支持的单元格编辑类型:' + edit) ;
}
} else {
var rs = layui. event . call ( this , MOD_NAME , 'cell(' + components. filter + ')' , member . call ( this ,
{ td : $td, field : field} ) ) ;
if ( rs === false ) layui. stope ( e) ;
}
} ) ;
$allBody. off ( 'dblclick.cellDouble' ) . on ( 'dblclick.cellDouble' , 'td' , function ( e ) {
var $td = $ ( this ) ;
var type = $td. data ( 'type' ) ;
if ( type === 'checkbox' || type === 'radio' ) return layui. stope ( e) ;
var edit = $td. data ( 'edit' ) ;
var field = $td. data ( 'field' ) ;
if ( edit) return layui. stope ( e) ;
var rs = layui. event . call ( this , MOD_NAME , 'cellDouble(' + components. filter + ')' , member . call ( this ,
{ td : $td, field : field} ) ) ;
if ( rs === false ) layui. stope ( e) ;
} ) ;
components. $toolbar. off ( 'click.toolbar' ) . on ( 'click.toolbar' , '*[lay-event]' , function ( e ) {
layui. stope ( e) ;
var $this = $ ( this ) ;
var event = $this . attr ( 'lay-event' ) ;
if ( 'LAYTABLE_COLS' === event) that. toggleCol ( ) ;
else if ( 'LAYTABLE_EXPORT' === event) that. exportData ( 'show' ) ;
else if ( 'LAYTABLE_PRINT' === event) that. printTable ( ) ;
else layui. event . call ( this , MOD_NAME , 'toolbar(' + components. filter + ')' , { event : event, elem : $this } ) ;
} ) ;
components. $tBodyGroup. on ( 'scroll' , function ( ) {
var $this = $ ( this ) ;
components. $tHeadGroup. scrollLeft ( $this . scrollLeft ( ) ) ;
} ) ;
components. $toolbar. off ( 'click.export' ) . on ( 'click.export' , '.layui-table-tool-panel>[data-type]' , function ( ) {
var type = $ ( this ) . data ( 'type' ) ;
if ( 'csv' === type || 'xls' === type) that. exportData ( type) ;
} ) ;
components. $toolbar. off ( 'click.panel' ) . on ( 'click.panel' , '.layui-table-tool-panel' , function ( e ) {
layui. stope ( e) ;
} ) ;
form. on ( 'checkbox(' + components. colsToggleFilter + ')' , function ( data ) {
that. toggleCol ( data. elem. checked, undefined , data. value) ;
} ) ;
} ;
TreeTable . prototype. getComponents = function ( ) {
var $view = $ ( this . options. elem) . next ( '.ew-tree-table' ) ;
var filter = $view. attr ( 'lay-filter' ) ;
var $tHeadGroup = $view. children ( '.ew-tree-table-head' ) ;
var $tBodyGroup = $view. children ( '.ew-tree-table-box' ) ;
return {
$view : $view,
filter : filter,
$tHeadGroup : $tHeadGroup,
$tBodyGroup : $tBodyGroup,
$tHead : $tHeadGroup. children ( '.layui-table' ) ,
$tBody : $tBodyGroup. children ( '.layui-table' ) ,
$table : $view. find ( '.layui-table' ) ,
$toolbar : $view. children ( '.ew-tree-table-tool' ) ,
$empty : $tBodyGroup. children ( '.ew-tree-table-empty' ) ,
$loading : $tBodyGroup. children ( '.ew-tree-table-loading' ) ,
checkboxFilter : 'ew_tb_checkbox_' + filter,
radioFilter : 'ew_tb_radio_' + filter,
chooseAllFilter : 'ew_tb_choose_all_' + filter,
colsToggleFilter : 'ew_tb_toggle_cols' + filter
} ;
} ;
TreeTable . prototype. eachCols = function ( callback, obj ) {
if ( ! obj) obj = this . options. colArrays;
for ( var i = 0 ; i < obj. length; i++ ) {
var item = obj[ i] ;
callback && callback ( i, item) ;
if ( item. CHILD_COLS ) this . eachCols ( callback, item. CHILD_COLS ) ;
}
} ;
TreeTable . prototype. eachData = function ( callback, data ) {
if ( ! data) data = this . options. data;
for ( var i = 0 ; i < data. length; i++ ) {
var item = data[ i] ;
callback && callback ( i, item) ;
if ( item[ this . options. tree. childName] ) this . eachData ( callback, item[ this . options. tree. childName] ) ;
}
} ;
TreeTable . prototype. renderBodyAsync = function ( d, $tr ) {
var that = this ;
var options = this . options;
var components = this . getComponents ( ) ;
if ( $tr) {
$tr. addClass ( 'ew-tree-table-loading' ) ;
$tr. find ( '.ew-tree-pack' ) . children ( '.ew-tree-table-arrow' ) . addClass ( 'layui-anim layui-anim-rotate layui-anim-loop' ) ;
} else {
components. $empty. hide ( ) ;
if ( options. data && options. data. length > 0 ) components. $loading. addClass ( 'ew-loading-float' ) ;
components. $loading. show ( ) ;
}
options. reqData ( d, function ( data ) {
if ( typeof data !== 'string' && data && data. length > 0 && options. tree. isPidData) {
data = tt. pidToChildren ( data, options. tree. idName, options. tree. pidName, options. tree. childName) ;
}
that. renderBodyData ( data, d, $tr) ;
} ) ;
} ;
TreeTable . prototype. renderBodyData = function ( data, d, $tr ) {
var msg;
if ( typeof data === 'string' ) {
msg = data;
data = [ ] ;
}
var that = this ;
var options = this . options;
var components = this . getComponents ( ) ;
if ( d === undefined ) options. data = data;
else d[ options. tree. childName] = data;
var indent;
if ( $tr) {
indent = parseInt ( $tr. data ( 'indent' ) ) + 1 ;
d[ options. tree. openName] = true ;
}
var htmlStr = this . renderBody ( data, indent, d) ;
if ( $tr) {
$tr. nextAll ( 'tr' ) . each ( function ( ) {
if ( parseInt ( $ ( this ) . data ( 'indent' ) ) <= ( indent - 1 ) ) return false ;
$ ( this ) . remove ( ) ;
} ) ;
$tr. after ( htmlStr) . addClass ( 'ew-tree-table-open' ) ;
} else {
components. $tBody. children ( 'tbody' ) . html ( htmlStr) ;
}
form. render ( null , components. filter) ;
this . renderNumberCol ( ) ;
if ( $tr) {
this . checkParentCB ( $tr) ;
$tr. prevAll ( 'tr' ) . each ( function ( ) {
var tInd = parseInt ( $ ( this ) . data ( 'indent' ) ) ;
if ( tInd < ( indent - 1 ) ) {
that. checkParentCB ( $ ( this ) ) ;
indent = tInd + 1 ;
}
} ) ;
$tr. removeClass ( 'ew-tree-table-loading' ) ;
var $arrow = $tr. find ( '.ew-tree-pack' ) . children ( '.ew-tree-table-arrow' ) ;
$arrow. removeClass ( 'layui-anim layui-anim-rotate layui-anim-loop' ) ;
if ( msg) {
$tr. removeClass ( 'ew-tree-table-open' ) ;
} else if ( data && data. length === 0 ) {
d[ options. tree. haveChildName] = false ;
$tr. data ( 'have-child' , false ) ;
$arrow. addClass ( 'ew-tree-table-arrow-hide' ) ;
$arrow. next ( '.ew-tree-icon' ) . after ( options. tree. getIcon ( d) ) . remove ( ) ;
}
} else {
components. $loading. hide ( ) ;
components. $loading. removeClass ( 'ew-loading-float' ) ;
if ( data && data. length > 0 ) {
components. $empty. hide ( ) ;
} else {
components. $empty. show ( ) ;
if ( msg) components. $empty. text ( msg) ;
else components. $empty. html ( options. text. none) ;
}
}
this . checkChooseAllCB ( ) ;
updateFixedTbHead ( components. $view) ;
options. done && options. done ( data) ;
} ;
TreeTable . prototype. renderBody = function ( data, indent, parent, h ) {
var options = this . options;
if ( ! indent) indent = 0 ;
var html = '' ;
if ( ! data || data. length === 0 ) return html;
var hide = parent ? ! parent[ options. tree. openName] : undefined ;
if ( h) hide = h;
for ( var i = 0 ; i < data. length; i++ ) {
var d = data[ i] ;
d. LAY_INDEX = ( parent ? parent. LAY_INDEX + '-' : '' ) + i;
html += this . renderBodyTr ( d, indent, hide) ;
html += this . renderBody ( d[ options. tree. childName] , indent + 1 , d, h) ;
}
return html;
} ;
TreeTable . prototype. renderBodyTr = function ( d, indent, hide, $tr ) {
var that = this ;
var options = this . options;
if ( ! indent) indent = 0 ;
var haveChild = d[ options. tree. haveChildName] ;
if ( haveChild === undefined ) haveChild = d[ options. tree. childName] && d[ options. tree. childName] . length > 0 ;
if ( $tr) {
$tr. data ( 'have-child' , haveChild ? 'true' : 'false' ) ;
$tr. data ( 'indent' , indent) ;
$tr. removeClass ( 'ew-tree-table-loading' ) ;
}
var html = ';
var classNames = '' ;
if ( haveChild && d[ options. tree. openName] ) classNames += 'ew-tree-table-open' ;
if ( hide) classNames += 'ew-tree-tb-hide' ;
html += ( ' class="' + classNames + '"' ) ;
if ( haveChild) html += ( ' data-have-child="' + haveChild + '"' ) ;
html += ( ' data-index="' + d. LAY_INDEX + '"' ) ;
html += ( ' data-indent="' + indent + '">' ) ;
var index = 0 ;
this . eachCols ( function ( i, col ) {
if ( col. colGroup) return ;
html += that. renderBodyTd ( d, indent, index, $tr ? $tr. children ( 'td' ) . eq ( index) : undefined , col) ;
index++ ;
} ) ;
html += ' ' ;
return html;
} ;
TreeTable . prototype. renderBodyTd = function ( d, indent, index, $td, col ) {
if ( ! col|| col. colGroup) return '' ;
var options = this . options;
var components = this . getComponents ( ) ;
if ( ! indent) indent = 0 ;
var content = '' , cell = '' , icon = '' ;
if ( col. type === 'numbers' ) {
content = ' ' ;
} else if ( col. type === 'checkbox' ) {
content = [
', d. LAY_CHECKED ? ' checked="checked"' : '' ,
' lay-filter="' , components. checkboxFilter, '"' ,
' lay-skin="primary" class="ew-tree-table-checkbox' ,
d. LAY_INDETERMINATE ? ' ew-form-indeterminate' : '' , '" />'
] . join ( '' ) ;
} else if ( col. type === 'radio' ) {
content = [
', d. LAY_CHECKED ? ' checked="checked"' : '' ,
' lay-filter="' , components. radioFilter, '"' ,
' name="' , components. radioFilter, '"' ,
' class="ew-tree-table-radio" />'
] . join ( '' ) ;
} else if ( col. templet) {
if ( typeof col. templet === 'function' ) {
content = col. templet ( d) ;
} else if ( typeof col. templet === 'string' ) {
laytpl ( $ ( col. templet) . html ( ) ) . render ( d, function ( html ) {
content = html;
} ) ;
}
} else if ( col. toolbar) {
if ( typeof col. toolbar === 'function' ) {
content = col. toolbar ( d) ;
} else if ( typeof col. toolbar === 'string' ) {
laytpl ( $ ( col. toolbar) . html ( ) ) . render ( d, function ( html ) {
content = html;
} ) ;
}
} else if ( col. field && d[ col. field] !== undefined && d[ col. field] !== null ) {
content = util. escape ( d[ col. field] === 0 ? '0' : d[ col. field] ) ;
}
if ( index === options. tree. iconIndex) {
for ( var i = 0 ; i < indent; i++ ) icon += ' ' ;
icon += '' ;
var haveChild = d[ options. tree. haveChildName] ;
if ( haveChild === undefined ) haveChild = d[ options. tree. childName] && d[ options. tree. childName] . length > 0 ;
icon += ( '+ ( haveChild ? '' : ' ew-tree-table-arrow-hide' ) ) ;
icon += ( ' ' + ( options. tree. arrowType || '' ) + '">' ) ;
icon += options. tree. getIcon ( d) ;
content = '' + content + ' ' ;
if ( options. tree. onlyIconControl) content = icon + ' ' + content;
else content = icon + content + ' ' ;
}
cell = [
', col
. singleLine
=== undefined || col
. singleLine
? ' single-line' : '' , '"' ,
col
. align
? ' align="' + col
. align
+ '"' : '' ,
'>' ,
' ', content, '
' ,
' ' ,
'
' ,
' '
] . join ( '' ) ;
if ( $td) $td. html ( cell) ;
var html = ' ;
if ( col. field) html += ( ' data-field="' + col. field + '"' ) ;
if ( col. edit) html += ( ' data-edit="' + col. edit + '"' ) ;
if ( col. type) html += ( ' data-type="' + col. type + '"' ) ;
if ( col. key) html += ( ' data-key="' + col. key + '"' ) ;
if ( col. style) html += ( ' style="' + col. style + '"' ) ;
if ( col[ 'class' ] ) html += ( ' class="' + col[ 'class' ] + ( col. hide ? ' layui-hide' : '' ) + '"' ) ;
else if ( col. hide) html += ( ' class="layui-hide"' ) ;
html += ( '>' + cell + ' ') ;
return html;
} ;
TreeTable . prototype. renderBodyTh = function ( ) {
var options = this . options;
var components = this . getComponents ( ) ;
var html = [ ] ;
$. each ( options. cols, function ( i1, item1 ) {
html. push ( '') ;
$. each ( item1, function ( i2, item2 ) {
html. push ( ' ) ;
if ( item2. colspan) html. push ( ' colspan="' + item2. colspan + '"' ) ;
if ( item2. rowspan) html. push ( ' rowspan="' + item2. rowspan + '"' ) ;
if ( item2. type) html. push ( ' data-type="' + item2. type + '"' ) ;
if ( item2. key) html. push ( ' data-key="' + item2. key + '"' ) ;
if ( item2. parentKey) html. push ( ' data-parent="' + item2. parentKey + '"' ) ;
if ( item2. hide) html. push ( ' class="layui-hide"' ) ;
html. push ( '>' ) ;
html. push ( '+
( item2
. singleLine
=== undefined || item2
. singleLine
? ' single-line' : '' ) + '"' ) ;
if ( item2
. thAlign
|| item2
. align
) html
. push ( ' align="' + ( item2
. thAlign
|| item2
. align
) + '"' ) ;
html
. push ( '>' ) ;
html
. push ( '') ;
var ca = ' + components. chooseAllFilter + '" lay-skin="primary" class="ew-tree-table-checkbox"/>' ;
if ( item2. type === 'checkbox' ) html. push ( ca) ;
else html. push ( item2. title || '' ) ;
html. push ( '
' ) ;
html
. push ( '
' ) ;
if ( ! item2. colGroup && ! item2. unresize) html. push ( ' ' ) ;
html. push ( ' ') ;
} ) ;
html. push ( ' ' ) ;
} ) ;
return html. join ( '' ) ;
} ;
TreeTable . prototype. resize = function ( returnColgroup ) {
var options = this . options;
var components = this . getComponents ( ) ;
var minWidth = 1 , width = 1 , needSetWidth = true , mwPercent = 0 ;
this . eachCols ( function ( i, item ) {
if ( item. colGroup || item. hide) return ;
if ( item. width) {
width += ( item. width + 1 ) ;
if ( item. minWidth) {
if ( item. width < item. minWidth) item. width = item. minWidth;
} else if ( item. width < options. cellMinWidth) item. width = options. cellMinWidth;
} else needSetWidth = false ;
if ( item. width) minWidth += ( item. width + 1 ) ;
else if ( item. minWidth) {
minWidth += ( item. minWidth + 1 ) ;
mwPercent += item. minWidth;
} else {
minWidth += ( options. cellMinWidth + 1 ) ;
mwPercent += options. cellMinWidth;
}
} ) ;
if ( minWidth) {
components. $tHead. css ( 'min-width' , minWidth) ;
components. $tBody. css ( 'min-width' , minWidth) ;
} else {
components. $tHead. css ( 'min-width' , 'auto' ) ;
components. $tBody. css ( 'min-width' , 'auto' ) ;
}
if ( needSetWidth) {
components. $tHead. css ( 'width' , width) ;
components. $tBody. css ( 'width' , width) ;
} else {
components. $tHead. css ( 'width' , '100%' ) ;
components. $tBody. css ( 'width' , '100%' ) ;
}
var colgroupHtml = [ ] ;
this . eachCols ( function ( i, item ) {
if ( item. colGroup || item. hide) return ;
colgroupHtml. push ( ') ;
if ( item. width) colgroupHtml. push ( ' width="' + item. width + '"' ) ;
else if ( item. minWidth) colgroupHtml. push ( ' width="' + ( item. minWidth / mwPercent * 100 ) . toFixed ( 2 ) + '%"' ) ;
else colgroupHtml. push ( ' width="' + ( options. cellMinWidth / mwPercent * 100 ) . toFixed ( 2 ) + '%"' ) ;
if ( item. type) colgroupHtml. push ( ' data-type="' + item. type + '"' ) ;
if ( item. key) colgroupHtml. push ( ' data-key="' + item. key + '"' ) ;
colgroupHtml. push ( '/>' ) ;
} ) ;
colgroupHtml = colgroupHtml. join ( '' ) ;
if ( returnColgroup) return '' + colgroupHtml + '' ;
components. $table. children ( 'colgroup' ) . html ( colgroupHtml) ;
} ;
TreeTable . prototype. getDataByTr = function ( $tr ) {
var data, index;
if ( typeof $tr !== 'string' && typeof $tr !== 'number' ) {
if ( $tr) index = $tr. data ( 'index' ) ;
} else index = $tr;
if ( index === undefined ) return ;
if ( typeof index === 'number' ) index = [ index] ;
else index = index. split ( '-' ) ;
for ( var i = 0 ; i < index. length; i++ ) {
if ( data) data = data[ this . options. tree. childName] [ index[ i] ] ;
else data = this . options. data[ index[ i] ] ;
}
return data;
} ;
TreeTable . prototype. checkSubCB = function ( $tr, checked ) {
var that = this ;
var components = this . getComponents ( ) ;
var indent = - 1 , $trList;
if ( $tr. is ( 'tbody' ) ) {
$trList = $tr. children ( 'tr' ) ;
} else {
indent = parseInt ( $tr. data ( 'indent' ) ) ;
$trList = $tr. nextAll ( 'tr' ) ;
}
$trList. each ( function ( ) {
if ( parseInt ( $ ( this ) . data ( 'indent' ) ) <= indent) return false ;
var $cb = $ ( this ) . children ( 'td' ) . find ( 'input[lay-filter="' + components. checkboxFilter + '"]' ) ;
$cb. prop ( 'checked' , checked) ;
$cb. removeClass ( 'ew-form-indeterminate' ) ;
if ( checked) $cb. next ( '.layui-form-checkbox' ) . addClass ( 'layui-form-checked' ) ;
else $cb. next ( '.layui-form-checkbox' ) . removeClass ( 'layui-form-checked' ) ;
var d = that. getDataByTr ( $ ( this ) ) ;
d. LAY_CHECKED = checked;
d. LAY_INDETERMINATE = false ;
} ) ;
} ;
TreeTable . prototype. checkParentCB = function ( $tr ) {
var options = this . options;
var components = this . getComponents ( ) ;
var d = this . getDataByTr ( $tr) ;
var ckNum = 0 , unCkNum = 0 ;
if ( d[ options. tree. childName] ) {
function checkNum ( data ) {
for ( var i = 0 ; i < data. length; i++ ) {
if ( data[ i] . LAY_CHECKED ) ckNum++ ;
else unCkNum++ ;
if ( data[ i] [ options. tree. childName] ) checkNum ( data[ i] [ options. tree. childName] ) ;
}
}
checkNum ( d[ options. tree. childName] ) ;
}
var $cb = $tr. children ( 'td' ) . find ( 'input[lay-filter="' + components. checkboxFilter + '"]' ) ;
if ( ckNum > 0 && unCkNum === 0 ) {
$cb. prop ( 'checked' , true ) ;
$cb. removeClass ( 'ew-form-indeterminate' ) ;
$cb. next ( '.layui-form-checkbox' ) . addClass ( 'layui-form-checked' ) ;
d. LAY_CHECKED = true ;
d. LAY_INDETERMINATE = false ;
} else if ( ckNum === 0 && unCkNum > 0 ) {
$cb. prop ( 'checked' , false ) ;
$cb. removeClass ( 'ew-form-indeterminate' ) ;
$cb. next ( '.layui-form-checkbox' ) . removeClass ( 'layui-form-checked' ) ;
d. LAY_CHECKED = false ;
d. LAY_INDETERMINATE = false ;
} else if ( ckNum > 0 && unCkNum > 0 ) {
$cb. prop ( 'checked' , true ) ;
$cb. data ( 'indeterminate' , 'true' ) ;
$cb. addClass ( 'ew-form-indeterminate' ) ;
$cb. next ( '.layui-form-checkbox' ) . addClass ( 'layui-form-checked' ) ;
d. LAY_CHECKED = true ;
d. LAY_INDETERMINATE = true ;
}
} ;
TreeTable . prototype. checkChooseAllCB = function ( ) {
var options = this . options;
var components = this . getComponents ( ) ;
var ckNum = 0 , unCkNum = 0 ;
function checkNum ( data ) {
for ( var i = 0 ; i < data. length; i++ ) {
if ( data[ i] . LAY_CHECKED ) ckNum++ ;
else unCkNum++ ;
if ( data[ i] [ options. tree. childName] ) checkNum ( data[ i] [ options. tree. childName] ) ;
}
}
checkNum ( options. data) ;
var $cb = components. $view. find ( 'input[lay-filter="' + components. chooseAllFilter + '"]' ) ;
if ( ckNum > 0 && unCkNum === 0 ) {
$cb. prop ( 'checked' , true ) ;
$cb. removeClass ( 'ew-form-indeterminate' ) ;
$cb. next ( '.layui-form-checkbox' ) . addClass ( 'layui-form-checked' ) ;
} else if ( ( ckNum === 0 && unCkNum > 0 ) || ( ckNum === 0 && unCkNum === 0 ) ) {
$cb. prop ( 'checked' , false ) ;
$cb. removeClass ( 'ew-form-indeterminate' ) ;
$cb. next ( '.layui-form-checkbox' ) . removeClass ( 'layui-form-checked' ) ;
} else if ( ckNum > 0 && unCkNum > 0 ) {
$cb. prop ( 'checked' , true ) ;
$cb. addClass ( 'ew-form-indeterminate' ) ;
$cb. next ( '.layui-form-checkbox' ) . addClass ( 'layui-form-checked' ) ;
}
} ;
TreeTable . prototype. renderNumberCol = function ( ) {
this . getComponents ( ) . $tBody. children ( 'tbody' ) . children ( 'tr' ) . each ( function ( i ) {
$ ( this ) . children ( 'td' ) . find ( '.ew-tree-table-numbers' ) . text ( i + 1 ) ;
} ) ;
} ;
TreeTable . prototype. getIndexById = function ( id ) {
var options = this . options;
function each ( data, pi ) {
for ( var i = 0 ; i < data. length; i++ ) {
if ( data[ i] [ options. tree. idName] === id) return pi !== undefined ? pi + '-' + i : i;
if ( data[ i] [ options. tree. childName] ) {
var res = each ( data[ i] [ options. tree. childName] , pi !== undefined ? pi + '-' + i : i) ;
if ( res) return res;
}
}
}
return each ( options. data) ;
} ;
TreeTable . prototype. expand = function ( id, cascade ) {
var components = this . getComponents ( ) ;
var $tr = components. $table. children ( 'tbody' ) . children ( 'tr[data-index="' + this . getIndexById ( id) + '"]' ) ;
if ( ! $tr. hasClass ( 'ew-tree-table-open' ) ) $tr. children ( 'td' ) . find ( '.ew-tree-pack' ) . trigger ( 'click' ) ;
if ( cascade === false ) return ;
var indent = parseInt ( $tr. data ( 'indent' ) ) ;
$tr. prevAll ( 'tr' ) . each ( function ( ) {
var tInd = parseInt ( $ ( this ) . data ( 'indent' ) ) ;
if ( tInd < indent) {
if ( ! $ ( this ) . hasClass ( 'ew-tree-table-open' ) ) {
$ ( this ) . children ( 'td' ) . find ( '.ew-tree-pack' ) . trigger ( 'click' ) ;
}
indent = tInd;
}
} ) ;
} ;
TreeTable . prototype. fold = function ( id ) {
var components = this . getComponents ( ) ;
var $tr = components. $table. children ( 'tbody' ) . children ( 'tr[data-index="' + this . getIndexById ( id) + '"]' ) ;
if ( $tr. hasClass ( 'ew-tree-table-open' ) ) $tr. children ( 'td' ) . find ( '.ew-tree-pack' ) . trigger ( 'click' ) ;
} ;
TreeTable . prototype. expandAll = function ( ) {
this . getComponents ( ) . $table. children ( 'tbody' ) . children ( 'tr' ) . each ( function ( ) {
if ( ! $ ( this ) . hasClass ( 'ew-tree-table-open' ) ) $ ( this ) . children ( 'td' ) . find ( '.ew-tree-pack' ) . trigger ( 'click' ) ;
} ) ;
} ;
TreeTable . prototype. foldAll = function ( ) {
this . getComponents ( ) . $table. children ( 'tbody' ) . children ( 'tr' ) . each ( function ( ) {
if ( $ ( this ) . hasClass ( 'ew-tree-table-open' ) ) $ ( this ) . children ( 'td' ) . find ( '.ew-tree-pack' ) . trigger ( 'click' ) ;
} ) ;
} ;
TreeTable . prototype. getData = function ( ) {
return this . options. data;
} ;
TreeTable . prototype. reload = function ( opt ) {
this . initOptions ( this . options ? $. extend ( true , this . options, opt) : opt) ;
this . init ( ) ;
this . bindEvents ( ) ;
} ;
TreeTable . prototype. checkStatus = function ( needIndeterminate ) {
if ( needIndeterminate === undefined ) needIndeterminate = true ;
var list = [ ] ;
this . eachData ( function ( i, item ) {
if ( ( needIndeterminate || ! item. LAY_INDETERMINATE ) && item. LAY_CHECKED )
list. push ( $. extend ( { isIndeterminate : item. LAY_INDETERMINATE } , item) ) ;
} ) ;
return list;
} ;
TreeTable . prototype. setChecked = function ( ids ) {
var that = this ;
var components = this . getComponents ( ) ;
var $radio = components. $table. find ( 'input[lay-filter="' + components. radioFilter + '"]' ) ;
if ( $radio. length > 0 ) {
$radio. each ( function ( ) {
var d = that. getDataByTr ( $ ( this ) . parentsUntil ( 'tr' ) . parent ( ) ) ;
if ( d && ids[ ids. length - 1 ] == d[ that. options. tree. idName] ) {
$ ( this ) . next ( '.layui-form-radio' ) . trigger ( 'click' ) ;
return false ;
}
} ) ;
} else {
components. $table. find ( 'input[lay-filter="' + components. checkboxFilter + '"]' ) . each ( function ( ) {
var $cb = $ ( this ) ;
var $layCb = $cb. next ( '.layui-form-checkbox' ) ;
var checked = $cb. prop ( 'checked' ) ;
var indeterminate = $cb. hasClass ( 'ew-form-indeterminate' ) ;
var d = that. getDataByTr ( $cb. parentsUntil ( 'tr' ) . parent ( ) ) ;
for ( var i = 0 ; i < ids. length; i++ ) {
if ( d && ids[ i] == d[ that. options. tree. idName] ) {
if ( d[ that. options. tree. childName] && d[ that. options. tree. childName] . length > 0 ) continue ;
if ( ! checked || indeterminate) $layCb. trigger ( 'click' ) ;
}
}
} ) ;
}
} ;
TreeTable . prototype. removeAllChecked = function ( ) {
this . checkSubCB ( this . getComponents ( ) . $table. children ( 'tbody' ) , false ) ;
} ;
TreeTable . prototype. exportData = function ( type ) {
var components = this . getComponents ( ) ;
if ( 'show' === type) {
components. $toolbar. find ( '.layui-table-tool-panel' ) . remove ( ) ;
components. $toolbar. find ( '[lay-event="LAYTABLE_EXPORT"]' ) . append ( [
' ,
' 导出到 Csv 文件 ' ,
' 导出到 Excel 文件 ' ,
''
] . join ( '' ) ) ;
} else {
if ( device. ie) return layer. msg ( '不支持ie导出' ) ;
if ( ! type) type = 'xls' ;
var head = [ ] , body = [ ] ;
this . eachCols ( function ( i, item ) {
if ( item. type !== 'normal' || item. hide) return ;
head. push ( item. title || '' ) ;
} ) ;
components. $tBody. children ( 'tbody' ) . children ( 'tr' ) . each ( function ( ) {
var items = [ ] ;
$ ( this ) . children ( 'td' ) . each ( function ( ) {
var $this = $ ( this ) ;
if ( $this . data ( 'type' ) !== 'normal' || $this . hasClass ( 'layui-hide' ) ) return true ;
items. push ( $this . text ( ) . trim ( ) . replace ( / , / g , ',' ) ) ;
} ) ;
body. push ( items. join ( ',' ) ) ;
} ) ;
var alink = document. createElement ( 'a' ) ;
var content = encodeURIComponent ( head. join ( ',' ) + '\r\n' + body. join ( '\r\n' ) ) ;
var contentType = ( { csv : 'text/csv' , xls : 'application/vnd.ms-excel' } ) [ type] ;
alink. href = 'data:' + contentType + ';charset=utf-8,\ufeff' + content;
alink. download = ( this . options. title || 'table' ) + '.' + type;
document. body. appendChild ( alink) ;
alink. click ( ) ;
document. body. removeChild ( alink) ;
}
} ;
TreeTable . prototype. printTable = function ( ) {
var components = this . getComponents ( ) ;
var head = components. $tHead. children ( 'thead' ) . html ( ) ;
if ( ! head) head = components. $tBody. children ( 'thead' ) . html ( ) ;
var body = components. $tBody. children ( 'tbody' ) . html ( ) ;
var colgroup = components. $tBody. children ( 'colgroup' ) . html ( ) ;
var $html = $ ( [
'',
' ' , colgroup, '' ,
' ', head, ' ' ,
' ', body, ' ' ,
'
'
] . join ( '' ) ) ;
$html. find ( 'col[data-type="checkbox"],col[data-type="radio"],col[data-type="tool"]' ) . remove ( ) ;
$html. find ( 'td[data-type="checkbox"],td[data-type="radio"],td[data-type="tool"],.layui-hide' ) . remove ( ) ;
function hideCol ( $temp ) {
var parentKey = $temp. data ( 'parent' ) , pCol;
if ( ! parentKey) return ;
var $parent = $html. children ( 'thead' ) . children ( 'tr' ) . children ( '[data-key="' + parentKey + '"]' ) ;
var colspan = parseInt ( $parent. attr ( 'colspan' ) ) - 1 ;
$parent. attr ( 'colspan' , colspan) ;
if ( colspan === 0 ) $parent. remove ( ) ;
hideCol ( $parent) ;
}
$html. find ( 'th[data-type="checkbox"],th[data-type="radio"],th[data-type="tool"]' ) . each ( function ( ) {
hideCol ( $ ( this ) ) ;
} ) . remove ( ) ;
var style = [
''
] . join ( '' ) ;
var pWindow = window. open ( '' , '_blank' ) ;
pWindow. focus ( ) ;
var pDocument = pWindow. document;
pDocument. open ( ) ;
pDocument. write ( $html[ 0 ] . outerHTML + style) ;
pDocument. close ( ) ;
pWindow. print ( ) ;
pWindow. close ( ) ;
} ;
TreeTable . prototype. toggleCol = function ( show, field, key ) {
var components = this . getComponents ( ) ;
if ( show === undefined ) {
components. $toolbar. find ( '.layui-table-tool-panel' ) . remove ( ) ;
var cols = [ ' ] ;
this . eachCols ( function ( i, item ) {
if ( item. type !== 'normal' ) return ;
cols. push ( ') ;
cols. push ( ' lay-filter="' + components. colsToggleFilter + '"' ) ;
cols. push ( ' value="' + item. key + '" title="' + util. escape ( item. title || '' ) + '"' ) ;
cols. push ( ( item. hide ? '' : ' checked' ) + '> ' ) ;
} ) ;
components. $toolbar. find ( '[lay-event="LAYTABLE_COLS"]' ) . append ( cols. join ( '' ) + '' ) ;
form. render ( 'checkbox' , components. filter) ;
} else {
if ( key) {
var $td = components. $table. children ( 'tbody' ) . children ( 'tr' ) . children ( '[data-key="' + key + '"]' ) ;
var $th = components. $table. children ( 'thead' ) . children ( 'tr' ) . children ( '[data-key="' + key + '"]' ) ;
if ( show) {
$td. removeClass ( 'layui-hide' ) ;
$th. removeClass ( 'layui-hide' ) ;
} else {
$td. addClass ( 'layui-hide' ) ;
$th. addClass ( 'layui-hide' ) ;
}
var ks = key. split ( '-' ) ;
var col = this . options. cols[ ks[ 0 ] ] [ ks[ 1 ] ] ;
col. hide = ! show;
function changeParent ( $temp ) {
var parentKey = $temp. data ( 'parent' ) , pCol;
if ( ! parentKey) return ;
var $parent = components. $table. children ( 'thead' ) . children ( 'tr' ) . children ( '[data-key="' + parentKey + '"]' ) ;
var colspan = $parent. attr ( 'colspan' ) ;
show ? colspan++ : colspan-- ;
$parent. attr ( 'colspan' , colspan) ;
if ( colspan === 0 ) $parent. addClass ( 'layui-hide' ) ;
else $parent. removeClass ( 'layui-hide' ) ;
changeParent ( $parent) ;
}
changeParent ( $th) ;
this . eachCols ( function ( i, item ) {
if ( item. key === key) item. hide = col. hide;
} ) ;
this . resize ( ) ;
}
}
} ;
TreeTable . prototype. filterData = function ( ids ) {
var components = this . getComponents ( ) ;
components. $loading. show ( ) ;
if ( this . options. data. length > 0 ) components. $loading. addClass ( 'ew-loading-float' ) ;
var $trList = components. $table. children ( 'tbody' ) . children ( 'tr' ) ;
var indexList = [ ] ;
if ( typeof ids === 'string' ) {
$trList. each ( function ( ) {
var index = $ ( this ) . data ( 'index' ) ;
$ ( this ) . children ( 'td' ) . each ( function ( ) {
if ( $ ( this ) . text ( ) . indexOf ( ids) !== - 1 ) {
indexList. push ( index) ;
return false ;
}
} ) ;
} ) ;
} else {
for ( var i = 0 ; i < ids. length; i++ ) {
indexList. push ( this . getIndexById ( ids[ i] ) ) ;
}
}
$trList. addClass ( 'ew-tree-table-filter-hide' ) ;
for ( var j = 0 ; j < indexList. length; j++ ) {
var $tr = $trList. filter ( '[data-index="' + indexList[ j] + '"]' ) ;
$tr. removeClass ( 'ew-tree-table-filter-hide' ) ;
var indent = parseInt ( $tr. data ( 'indent' ) ) ;
$tr. nextAll ( 'tr' ) . each ( function ( ) {
if ( parseInt ( $ ( this ) . data ( 'indent' ) ) <= indent) return false ;
$ ( this ) . removeClass ( 'ew-tree-table-filter-hide' ) ;
} ) ;
if ( $tr. hasClass ( 'ew-tree-table-open' ) ) toggleRow ( $tr) ;
$tr. prevAll ( 'tr' ) . each ( function ( ) {
var tInd = parseInt ( $ ( this ) . data ( 'indent' ) ) ;
if ( tInd < indent) {
$ ( this ) . removeClass ( 'ew-tree-table-filter-hide' ) ;
if ( ! $ ( this ) . hasClass ( 'ew-tree-table-open' ) ) toggleRow ( $ ( this ) ) ;
indent = tInd;
}
} ) ;
}
components. $loading. hide ( ) ;
components. $loading. removeClass ( 'ew-loading-float' ) ;
if ( indexList. length === 0 ) components. $empty. show ( ) ;
updateFixedTbHead ( components. $view) ;
} ;
TreeTable . prototype. clearFilter = function ( ) {
var components = this . getComponents ( ) ;
components. $table. children ( 'tbody' ) . children ( 'tr' ) . removeClass ( 'ew-tree-table-filter-hide' ) ;
if ( this . options. data. length > 0 ) components. $empty. hide ( ) ;
updateFixedTbHead ( components. $view) ;
} ;
TreeTable . prototype. refresh = function ( id, data ) {
if ( isClass ( id) === 'Array' ) {
data = id;
id = undefined ;
}
var components = this . getComponents ( ) ;
var d, $tr;
if ( id !== undefined ) {
$tr = components. $table. children ( 'tbody' ) . children ( 'tr[data-index="' + this . getIndexById ( id) + '"]' ) ;
d = this . getDataByTr ( $tr) ;
}
if ( data) {
if ( data. length > 0 ) components. $loading. addClass ( 'ew-loading-float' ) ;
components. $loading. show ( ) ;
if ( data. length > 0 && this . options. tree. isPidData) {
this . renderBodyData ( tt. pidToChildren ( data, this . options. tree. idName, this . options. tree. pidName, this . options. tree. childName) , d, $tr) ;
} else {
this . renderBodyData ( data, d, $tr) ;
}
} else {
this . renderBodyAsync ( d, $tr) ;
}
} ;
TreeTable . prototype. del = function ( id, index ) {
if ( index === undefined ) index = this . getIndexById ( id) ;
var indexList = ( typeof index === 'number' ? [ index] : index. split ( '-' ) ) ;
var d = this . options. data;
if ( indexList. length > 1 ) {
for ( var i = 0 ; i < indexList. length - 1 ; i++ ) {
d = d[ parseInt ( indexList[ i] ) ] [ this . options. tree. childName] ;
}
}
d. splice ( indexList[ indexList. length - 1 ] , 1 ) ;
} ;
TreeTable . prototype. update = function ( id, fields ) {
$. extend ( true , this . getDataByTr ( this . getIndexById ( id) ) , fields) ;
} ;
function toggleRow ( $tr ) {
var indent = parseInt ( $tr. data ( 'indent' ) ) ;
var open = $tr. hasClass ( 'ew-tree-table-open' ) ;
if ( open) {
$tr. removeClass ( 'ew-tree-table-open' ) ;
$tr. nextAll ( 'tr' ) . each ( function ( ) {
if ( parseInt ( $ ( this ) . data ( 'indent' ) ) <= indent) return false ;
$ ( this ) . addClass ( 'ew-tree-tb-hide' ) ;
} ) ;
} else {
$tr. addClass ( 'ew-tree-table-open' ) ;
var hideInd;
$tr. nextAll ( 'tr' ) . each ( function ( ) {
var ind = parseInt ( $ ( this ) . data ( 'indent' ) ) ;
if ( ind <= indent) return false ;
if ( hideInd !== undefined && ind > hideInd) return true ;
$ ( this ) . removeClass ( 'ew-tree-tb-hide' ) ;
if ( ! $ ( this ) . hasClass ( 'ew-tree-table-open' ) ) hideInd = parseInt ( $ ( this ) . data ( 'indent' ) ) ;
else hideInd = undefined ;
} ) ;
}
updateFixedTbHead ( $tr. parentsUntil ( '.ew-tree-table' ) . last ( ) . parent ( ) ) ;
return open;
}
function updateFixedTbHead ( $view ) {
var $headBox = $view. children ( '.ew-tree-table-head' ) ;
var $tbBox = $view. children ( '.ew-tree-table-box' ) ;
var sWidth = $tbBox. width ( ) - $tbBox. prop ( 'clientWidth' ) ;
$headBox. css ( 'border-right' , ( sWidth > 0 ? sWidth : 0 ) + 'px solid #f2f2f2' ) ;
}
$ ( window) . resize ( function ( ) {
$ ( '.ew-tree-table' ) . each ( function ( ) {
updateFixedTbHead ( $ ( this ) ) ;
var $tbBox = $ ( this ) . children ( '.ew-tree-table-box' ) ;
var full = $tbBox. data ( 'full' ) ;
if ( full && device. ie && device. ie < 10 ) {
$tbBox. css ( 'height' , getPageHeight ( ) - full) ;
}
} ) ;
} ) ;
$ ( document) . on ( 'mouseenter' , '.ew-tree-table-cell.single-line' , function ( ) {
var $content = $ ( this ) . children ( '.ew-tree-table-cell-content' ) ;
if ( $content. prop ( 'scrollWidth' ) > $content. outerWidth ( ) ) $ ( this ) . children ( '.layui-table-grid-down' ) . show ( ) ;
} ) . on ( 'mouseleave' , '.ew-tree-table-cell.single-line' , function ( ) {
$ ( this ) . children ( '.layui-table-grid-down' ) . hide ( ) ;
} ) ;
$ ( document) . on ( 'click' , '.ew-tree-table-cell>.layui-table-grid-down' , function ( e ) {
e. stopPropagation ( ) ;
hideAllTdTips ( ) ;
var $cell = $ ( this ) . parent ( ) ;
$cell. addClass ( 'ew-tree-tips-open' ) ;
$cell. children ( '.layui-table-grid-down' ) . hide ( ) ;
var tw = $cell. parent ( ) . outerWidth ( ) + 4 ;
if ( $cell. outerWidth ( ) < tw) $cell. children ( '.ew-tree-table-cell-content' ) . css ( { 'width' : tw, 'max-width' : tw} ) ;
var $box = $cell. parents ( ) . filter ( '.ew-tree-table-box' ) ;
if ( $box. length === 0 ) $box = $cell. parents ( ) . filter ( '.ew-tree-table-head' ) ;
if ( $box. length === 0 ) return ;
if ( ( $cell. outerWidth ( ) + $cell. offset ( ) . left) + 20 > $box. offset ( ) . left + $box. outerWidth ( ) ) {
$cell. addClass ( 'ew-show-left' ) ;
}
if ( ( $cell. outerHeight ( ) + $cell. offset ( ) . top + 10 ) > $box. offset ( ) . top + $box. outerHeight ( ) ) {
$cell. addClass ( 'ew-show-bottom' ) ;
}
} ) ;
$ ( document) . on ( 'click' , '.ew-tree-table-cell>.ew-tree-tips-c' , function ( ) {
hideAllTdTips ( ) ;
} ) ;
$ ( document) . on ( 'click' , function ( ) {
hideAllTdTips ( ) ;
$ ( '.ew-tree-table .layui-table-tool-panel' ) . remove ( ) ;
} ) ;
$ ( document) . on ( 'click' , '.ew-tree-table-cell.ew-tree-tips-open' , function ( e ) {
e. stopPropagation ( ) ;
} ) ;
function hideAllTdTips ( ) {
$ ( '.ew-tree-table-cell' ) . removeClass ( 'ew-tree-tips-open ew-show-left ew-show-bottom' ) ;
$ ( '.ew-tree-table-cell>.ew-tree-table-cell-content' ) . css ( { 'width' : '' , 'max-width' : '' } ) ;
}
$ ( document) . on ( 'mousedown' , '.ew-tb-resize' , function ( e ) {
layui. stope ( e) ;
var $this = $ ( this ) ;
$this . attr ( 'move' , 'true' ) ;
var key = $this . parent ( ) . data ( 'key' ) ;
$this . data ( 'x' , e. clientX) ;
var w = $this . parent ( ) . parent ( ) . parent ( ) . parent ( ) . children ( 'colgroup' ) . children ( 'col[data-key="' + key + '"]' ) . attr ( 'width' ) ;
if ( ! w || w. toString ( ) . indexOf ( '%' ) !== - 1 ) w = $this . parent ( ) . outerWidth ( ) ;
$this . data ( 'width' , w) ;
$ ( 'body' ) . addClass ( 'ew-tree-table-resizing' ) ;
} ) . on ( 'mousemove' , function ( e ) {
var $rs = $ ( '.ew-tree-table .ew-tb-resize[move="true"]' ) ;
if ( $rs. length === 0 ) return ;
layui. stope ( e) ;
var x = $rs. data ( 'x' ) ;
var w = $rs. data ( 'width' ) ;
var nw = parseFloat ( w) + e. clientX - parseFloat ( x) ;
if ( nw <= 0 ) nw = 1 ;
var ins = _instances[ $rs. parentsUntil ( '.ew-tree-table' ) . last ( ) . parent ( ) . attr ( 'lay-filter' ) ] ;
var key = $rs. parent ( ) . data ( 'key' ) ;
var ks = key. split ( '-' ) ;
ins. options. cols[ ks[ 0 ] ] [ ks[ 1 ] ] . width = nw;
ins. eachCols ( function ( i, item ) {
if ( item. key === key) item. width = nw;
} ) ;
ins. resize ( ) ;
} ) . on ( 'mouseup' , function ( e ) {
$ ( '.ew-tree-table .ew-tb-resize[move="true"]' ) . attr ( 'move' , 'false' ) ;
$ ( 'body' ) . removeClass ( 'ew-tree-table-resizing' ) ;
} ) . on ( 'mouseleave' , function ( e ) {
$ ( '.ew-tree-table .ew-tb-resize[move="true"]' ) . attr ( 'move' , 'false' ) ;
$ ( 'body' ) . removeClass ( 'ew-tree-table-resizing' ) ;
} ) ;
function getPids ( data, idName, pidName ) {
var pids = [ ] ;
for ( var i = 0 ; i < data. length; i++ ) {
var hasPid = false ;
for ( var j = 0 ; j < data. length; j++ ) {
if ( data[ i] [ pidName] == data[ j] [ idName] ) {
hasPid = true ;
break ;
}
}
if ( ! hasPid) pids. push ( data[ i] [ pidName] ) ;
}
return pids;
}
function pidEquals ( pId, pIds ) {
if ( isClass ( pIds) === 'Array' ) {
for ( var i = 0 ; i < pIds. length; i++ )
if ( pId == pIds[ i] ) return true ;
}
return pId == pIds;
}
function isClass ( o ) {
if ( o === null ) return 'Null' ;
if ( o === undefined ) return 'Undefined' ;
return Object . prototype. toString . call ( o) . slice ( 8 , - 1 ) ;
}
function getPageHeight ( ) {
return document. documentElement. clientHeight || document. body. clientHeight;
}
var tt = {
render : function ( options ) {
return new TreeTable ( options) ;
} ,
reload : function ( id, opt ) {
_instances[ id] . reload ( opt) ;
} ,
on : function ( events, callback ) {
return layui. onevent . call ( this , MOD_NAME , events, callback) ;
} ,
pidToChildren : function ( data, idName, pidName, childName, pId ) {
if ( ! childName) childName = 'children' ;
var newList = [ ] ;
for ( var i = 0 ; i < data. length; i++ ) {
if ( data[ i] [ idName] == data[ i] [ pidName] )
return console. error ( '第' + i + '条数据的' + idName + '与' + pidName + '相同' , data[ i] ) ;
if ( pId === undefined ) pId = getPids ( data, idName, pidName) ;
if ( pidEquals ( data[ i] [ pidName] , pId) ) {
var children = this . pidToChildren ( data, idName, pidName, childName, data[ i] [ idName] ) ;
if ( children. length > 0 ) data[ i] [ childName] = children;
newList. push ( data[ i] ) ;
}
}
return newList;
}
} ;
$ ( 'head' ) . append ( [
''
] . join ( '' ) ) ;
exports ( 'tableTree' , tt) ;
} ) ;