2016-10-25 13:35:41 +00:00
import ElCheckbox from 'element-ui/packages/checkbox' ;
import ElTag from 'element-ui/packages/tag' ;
2016-11-04 10:44:19 +00:00
import objectAssign from 'element-ui/src/utils/merge' ;
2017-10-25 07:35:12 +00:00
import { getPropByPath } from 'element-ui/src/utils/util' ;
2016-08-16 08:07:18 +00:00
let columnIdSeed = 1 ;
const defaults = {
default : {
2016-10-27 17:24:13 +00:00
order : ''
2016-08-16 08:07:18 +00:00
} ,
selection : {
width : 48 ,
minWidth : 48 ,
realWidth : 48 ,
2016-12-09 06:44:00 +00:00
order : '' ,
className : 'el-table-column--selection'
2016-08-16 08:07:18 +00:00
} ,
2016-11-12 15:08:17 +00:00
expand : {
width : 48 ,
minWidth : 48 ,
realWidth : 48 ,
order : ''
} ,
2016-08-16 08:07:18 +00:00
index : {
width : 48 ,
minWidth : 48 ,
realWidth : 48 ,
2016-10-27 17:24:13 +00:00
order : ''
2016-08-16 08:07:18 +00:00
}
} ;
const forced = {
selection : {
2018-01-30 02:36:36 +00:00
renderHeader : function ( h , { store } ) {
2016-10-27 13:45:21 +00:00
return < el - checkbox
2018-01-30 04:02:20 +00:00
disabled = { store . states . data && store . states . data . length === 0 }
2018-01-30 02:36:36 +00:00
indeterminate = { store . states . selection . length > 0 && ! this . isAllSelected }
2016-10-12 11:18:34 +00:00
nativeOn - click = { this . toggleAllSelection }
2017-04-28 06:03:42 +00:00
value = { this . isAllSelected } / > ;
2016-10-12 11:18:34 +00:00
} ,
2016-11-04 23:30:23 +00:00
renderCell : function ( h , { row , column , store , $index } ) {
2016-10-12 11:18:34 +00:00
return < el - checkbox
2018-01-26 03:13:47 +00:00
nativeOn - click = { ( event ) => event . stopPropagation ( ) }
2017-04-28 06:03:42 +00:00
value = { store . isSelected ( row ) }
2016-10-12 11:18:34 +00:00
disabled = { column . selectable ? ! column . selectable . call ( null , row , $index ) : false }
2016-11-04 23:30:23 +00:00
on - input = { ( ) => { store . commit ( 'rowSelectedChanged' , row ) ; } } / > ;
2016-10-12 11:18:34 +00:00
} ,
2016-08-16 08:07:18 +00:00
sortable : false ,
resizable : false
} ,
index : {
2016-11-04 23:30:23 +00:00
renderHeader : function ( h , { column } ) {
return column . label || '#' ;
2016-10-12 11:18:34 +00:00
} ,
2017-10-25 07:35:12 +00:00
renderCell : function ( h , { $index , column } ) {
let i = $index + 1 ;
const index = column . index ;
if ( typeof index === 'number' ) {
i = $index + index ;
} else if ( typeof index === 'function' ) {
i = index ( $index ) ;
}
return < div > { i } < / d i v > ;
2016-10-12 11:18:34 +00:00
} ,
2016-08-16 08:07:18 +00:00
sortable : false
2016-11-12 15:08:17 +00:00
} ,
expand : {
2017-11-27 10:14:27 +00:00
renderHeader : function ( h , { column } ) {
return column . label || '' ;
2016-11-12 15:08:17 +00:00
} ,
renderCell : function ( h , { row , store } , proxy ) {
const expanded = store . states . expandRows . indexOf ( row ) > - 1 ;
return < div class = { 'el-table__expand-icon ' + ( expanded ? 'el-table__expand-icon--expanded' : '' ) }
2018-02-04 07:25:04 +00:00
on - click = { e => proxy . handleExpandClick ( row , e ) } >
2016-11-12 15:08:17 +00:00
< i class = 'el-icon el-icon-arrow-right' > < / i >
< / d i v > ;
} ,
sortable : false ,
resizable : false ,
className : 'el-table__expand-column'
2016-08-16 08:07:18 +00:00
}
} ;
const getDefaultColumn = function ( type , options ) {
const column = { } ;
objectAssign ( column , defaults [ type || 'default' ] ) ;
for ( let name in options ) {
if ( options . hasOwnProperty ( name ) ) {
const value = options [ name ] ;
if ( typeof value !== 'undefined' ) {
column [ name ] = value ;
}
}
}
2016-10-12 11:18:34 +00:00
if ( ! column . minWidth ) {
column . minWidth = 80 ;
}
2017-12-17 10:20:00 +00:00
column . realWidth = column . width === undefined ? column . minWidth : column . width ;
2016-10-12 11:18:34 +00:00
2016-08-16 08:07:18 +00:00
return column ;
} ;
2018-04-10 08:15:09 +00:00
const DEFAULT _RENDER _CELL = function ( h , { row , column , $index } ) {
2016-11-23 10:24:32 +00:00
const property = column . property ;
2017-10-25 07:35:12 +00:00
const value = property && getPropByPath ( row , property ) . v ;
2016-11-23 10:24:32 +00:00
if ( column && column . formatter ) {
2018-04-10 08:15:09 +00:00
return column . formatter ( row , column , value , $index ) ;
2016-11-23 10:24:32 +00:00
}
2017-07-15 09:00:36 +00:00
return value ;
2016-11-04 23:30:23 +00:00
} ;
2018-01-30 12:37:23 +00:00
const parseWidth = ( width ) => {
if ( width !== undefined ) {
width = parseInt ( width , 10 ) ;
if ( isNaN ( width ) ) {
width = null ;
}
}
return width ;
} ;
const parseMinWidth = ( minWidth ) => {
if ( minWidth !== undefined ) {
minWidth = parseInt ( minWidth , 10 ) ;
if ( isNaN ( minWidth ) ) {
minWidth = 80 ;
}
}
return minWidth ;
} ;
2016-08-16 08:07:18 +00:00
export default {
2016-12-31 15:33:51 +00:00
name : 'ElTableColumn' ,
2016-08-16 08:07:18 +00:00
props : {
type : {
type : String ,
default : 'default'
} ,
label : String ,
2016-11-13 06:39:24 +00:00
className : String ,
2017-03-08 11:14:36 +00:00
labelClassName : String ,
2016-08-16 08:07:18 +00:00
property : String ,
2016-10-12 11:18:34 +00:00
prop : String ,
2016-08-16 08:07:18 +00:00
width : { } ,
minWidth : { } ,
2016-11-04 23:30:23 +00:00
renderHeader : Function ,
2016-08-16 08:07:18 +00:00
sortable : {
2016-12-30 03:11:20 +00:00
type : [ String , Boolean ] ,
2016-08-16 08:07:18 +00:00
default : false
} ,
2016-10-27 17:24:13 +00:00
sortMethod : Function ,
2017-10-30 02:26:25 +00:00
sortBy : [ String , Function , Array ] ,
2016-08-16 08:07:18 +00:00
resizable : {
type : Boolean ,
default : true
} ,
2016-11-18 07:00:22 +00:00
context : { } ,
2016-12-20 10:21:15 +00:00
columnKey : String ,
2016-09-20 22:20:36 +00:00
align : String ,
2016-12-21 03:03:22 +00:00
headerAlign : String ,
2016-11-04 08:27:51 +00:00
showTooltipWhenOverflow : Boolean ,
showOverflowTooltip : Boolean ,
2016-10-12 11:18:34 +00:00
fixed : [ Boolean , String ] ,
formatter : Function ,
2016-10-19 10:53:31 +00:00
selectable : Function ,
2016-10-27 13:45:21 +00:00
reserveSelection : Boolean ,
filterMethod : Function ,
2017-01-13 06:53:58 +00:00
filteredValue : Array ,
2016-10-27 13:45:21 +00:00
filters : Array ,
2017-04-27 06:08:59 +00:00
filterPlacement : String ,
2016-10-27 13:45:21 +00:00
filterMultiple : {
type : Boolean ,
default : true
2017-10-25 07:35:12 +00:00
} ,
2018-05-22 10:20:04 +00:00
index : [ Number , Function ] ,
sortOrders : {
type : Array ,
default ( ) {
return [ 'ascending' , 'descending' , null ] ;
} ,
validator ( val ) {
return val . every ( order => [ 'ascending' , 'descending' , null ] . indexOf ( order ) > - 1 ) ;
}
}
2016-08-16 08:07:18 +00:00
} ,
data ( ) {
return {
2016-11-23 12:32:23 +00:00
isSubColumn : false ,
2016-08-30 07:36:21 +00:00
columns : [ ]
2016-08-16 08:07:18 +00:00
} ;
} ,
2016-08-30 07:36:21 +00:00
beforeCreate ( ) {
this . row = { } ;
this . column = { } ;
this . $index = 0 ;
} ,
2016-08-16 08:07:18 +00:00
components : {
ElCheckbox ,
ElTag
} ,
2016-10-12 11:18:34 +00:00
computed : {
owner ( ) {
let parent = this . $parent ;
while ( parent && ! parent . tableId ) {
parent = parent . $parent ;
}
return parent ;
2017-11-27 06:59:21 +00:00
} ,
columnOrTableParent ( ) {
let parent = this . $parent ;
while ( parent && ! parent . tableId && ! parent . columnId ) {
parent = parent . $parent ;
}
return parent ;
2016-10-12 11:18:34 +00:00
}
} ,
2016-08-16 08:07:18 +00:00
created ( ) {
2016-09-02 11:12:00 +00:00
this . customRender = this . $options . render ;
2017-10-19 09:29:13 +00:00
this . $options . render = h => h ( 'div' , this . $slots . default ) ;
2016-08-16 08:07:18 +00:00
2017-11-27 06:59:21 +00:00
let parent = this . columnOrTableParent ;
2016-10-12 11:18:34 +00:00
let owner = this . owner ;
2016-11-23 12:32:23 +00:00
this . isSubColumn = owner !== parent ;
2018-01-30 12:37:23 +00:00
this . columnId = ( parent . tableId || parent . columnId ) + '_column_' + columnIdSeed ++ ;
2016-08-16 08:07:18 +00:00
let type = this . type ;
2018-01-30 12:37:23 +00:00
const width = parseWidth ( this . width ) ;
const minWidth = parseMinWidth ( this . minWidth ) ;
2016-08-16 08:07:18 +00:00
let isColumnGroup = false ;
let column = getDefaultColumn ( type , {
2017-01-17 09:59:00 +00:00
id : this . columnId ,
columnKey : this . columnKey ,
2016-08-16 08:07:18 +00:00
label : this . label ,
2016-11-13 06:39:24 +00:00
className : this . className ,
2017-03-08 11:14:36 +00:00
labelClassName : this . labelClassName ,
2016-11-04 23:30:23 +00:00
property : this . prop || this . property ,
2016-08-16 08:07:18 +00:00
type ,
2016-11-23 10:24:32 +00:00
renderCell : null ,
2016-11-04 23:30:23 +00:00
renderHeader : this . renderHeader ,
2016-08-16 08:07:18 +00:00
minWidth ,
width ,
isColumnGroup ,
2016-11-18 07:00:22 +00:00
context : this . context ,
2016-09-20 22:20:36 +00:00
align : this . align ? 'is-' + this . align : null ,
2016-12-21 03:03:22 +00:00
headerAlign : this . headerAlign ? 'is-' + this . headerAlign : ( this . align ? 'is-' + this . align : null ) ,
2016-12-30 03:11:20 +00:00
sortable : this . sortable === '' ? true : this . sortable ,
2016-10-27 17:24:13 +00:00
sortMethod : this . sortMethod ,
2017-10-30 02:26:25 +00:00
sortBy : this . sortBy ,
2016-08-16 08:07:18 +00:00
resizable : this . resizable ,
2016-11-04 08:27:51 +00:00
showOverflowTooltip : this . showOverflowTooltip || this . showTooltipWhenOverflow ,
2016-10-12 11:18:34 +00:00
formatter : this . formatter ,
selectable : this . selectable ,
2016-10-19 10:53:31 +00:00
reserveSelection : this . reserveSelection ,
2016-12-30 03:11:20 +00:00
fixed : this . fixed === '' ? true : this . fixed ,
2016-10-27 13:45:21 +00:00
filterMethod : this . filterMethod ,
filters : this . filters ,
2018-08-29 10:45:56 +00:00
filterable : this . filters || this . filterMethod ,
2016-10-27 13:45:21 +00:00
filterMultiple : this . filterMultiple ,
filterOpened : false ,
2017-04-27 06:08:59 +00:00
filteredValue : this . filteredValue || [ ] ,
2017-10-25 07:35:12 +00:00
filterPlacement : this . filterPlacement || '' ,
2018-05-22 10:20:04 +00:00
index : this . index ,
sortOrders : this . sortOrders
2016-08-16 08:07:18 +00:00
} ) ;
2018-07-16 09:10:43 +00:00
let source = forced [ type ] || { } ;
2018-09-28 09:44:54 +00:00
Object . keys ( source ) . forEach ( ( prop ) => {
let value = source [ prop ] ;
if ( value !== undefined ) {
if ( prop === 'renderHeader' ) {
if ( type === 'selection' && column [ prop ] ) {
console . warn ( '[Element Warn][TableColumn]Selection column doesn\'t allow to set render-header function.' ) ;
} else {
value = column [ prop ] || value ;
}
2018-07-16 09:10:43 +00:00
}
2018-09-28 09:44:54 +00:00
column [ prop ] = prop === 'className' ? ` ${ column [ prop ] } ${ value } ` : value ;
2018-07-16 09:10:43 +00:00
}
2018-09-28 09:44:54 +00:00
} ) ;
2016-08-16 08:07:18 +00:00
2018-10-26 03:16:56 +00:00
// Deprecation warning for renderHeader property
if ( this . renderHeader ) {
2018-10-26 03:59:02 +00:00
console . warn ( '[Element Warn][TableColumn]Comparing to render-header, scoped-slot header is easier to use. We recommend users to use scoped-slot header.' ) ;
2018-10-26 03:16:56 +00:00
}
2016-11-12 15:08:17 +00:00
this . columnConfig = column ;
2016-11-04 23:30:23 +00:00
let renderCell = column . renderCell ;
2016-08-16 08:07:18 +00:00
let _self = this ;
2016-08-30 07:36:21 +00:00
2016-11-12 15:08:17 +00:00
if ( type === 'expand' ) {
owner . renderExpanded = function ( h , data ) {
2016-12-28 10:11:25 +00:00
return _self . $scopedSlots . default
? _self . $scopedSlots . default ( data )
: _self . $slots . default ;
2016-11-12 15:08:17 +00:00
} ;
column . renderCell = function ( h , data ) {
return < div class = "cell" > { renderCell ( h , data , this . _renderProxy ) } < / d i v > ;
} ;
return ;
}
2016-11-04 23:30:23 +00:00
column . renderCell = function ( h , data ) {
2017-09-25 11:16:16 +00:00
if ( _self . $scopedSlots . default ) {
2016-12-20 02:47:16 +00:00
renderCell = ( ) => _self . $scopedSlots . default ( data ) ;
2016-10-12 11:18:34 +00:00
}
2016-08-16 08:07:18 +00:00
2016-11-23 10:24:32 +00:00
if ( ! renderCell ) {
renderCell = DEFAULT _RENDER _CELL ;
}
2019-03-27 08:13:21 +00:00
const children = [
_self . renderTreeCell ( data ) ,
renderCell ( h , data )
] ;
2016-11-23 10:24:32 +00:00
2016-11-04 08:27:51 +00:00
return _self . showOverflowTooltip || _self . showTooltipWhenOverflow
2019-03-27 08:13:21 +00:00
? < div class = "cell el-tooltip" style = { { width : ( data . column . realWidth || data . column . width ) - 1 + 'px' } } > { children } < / d i v >
: ( < div class = "cell" >
{ children }
< / d i v > ) ;
2016-08-16 08:07:18 +00:00
} ;
} ,
destroyed ( ) {
2016-10-12 11:18:34 +00:00
if ( ! this . $parent ) return ;
2018-01-22 06:51:08 +00:00
const parent = this . $parent ;
this . owner . store . commit ( 'removeColumn' , this . columnConfig , this . isSubColumn ? parent . columnConfig : null ) ;
2016-08-16 08:07:18 +00:00
} ,
watch : {
label ( newVal ) {
if ( this . columnConfig ) {
this . columnConfig . label = newVal ;
}
} ,
2016-10-12 11:18:34 +00:00
prop ( newVal ) {
if ( this . columnConfig ) {
this . columnConfig . property = newVal ;
}
} ,
2016-08-16 08:07:18 +00:00
property ( newVal ) {
if ( this . columnConfig ) {
this . columnConfig . property = newVal ;
}
2016-11-04 08:27:51 +00:00
} ,
filters ( newVal ) {
if ( this . columnConfig ) {
this . columnConfig . filters = newVal ;
}
} ,
filterMultiple ( newVal ) {
if ( this . columnConfig ) {
this . columnConfig . filterMultiple = newVal ;
}
} ,
align ( newVal ) {
if ( this . columnConfig ) {
2016-11-24 10:34:02 +00:00
this . columnConfig . align = newVal ? 'is-' + newVal : null ;
2017-01-06 02:28:01 +00:00
if ( ! this . headerAlign ) {
this . columnConfig . headerAlign = newVal ? 'is-' + newVal : null ;
}
2016-11-04 08:27:51 +00:00
}
} ,
2016-12-21 03:03:22 +00:00
headerAlign ( newVal ) {
if ( this . columnConfig ) {
2017-01-06 02:28:01 +00:00
this . columnConfig . headerAlign = 'is-' + ( newVal ? newVal : this . align ) ;
2016-12-21 03:03:22 +00:00
}
} ,
2016-11-04 08:27:51 +00:00
width ( newVal ) {
if ( this . columnConfig ) {
2018-01-30 12:37:23 +00:00
this . columnConfig . width = parseWidth ( newVal ) ;
2016-11-23 22:54:32 +00:00
this . owner . store . scheduleLayout ( ) ;
2016-11-04 08:27:51 +00:00
}
} ,
minWidth ( newVal ) {
if ( this . columnConfig ) {
2018-01-30 12:37:23 +00:00
this . columnConfig . minWidth = parseMinWidth ( newVal ) ;
2016-11-23 22:54:32 +00:00
this . owner . store . scheduleLayout ( ) ;
2016-11-04 08:27:51 +00:00
}
} ,
fixed ( newVal ) {
if ( this . columnConfig ) {
this . columnConfig . fixed = newVal ;
2018-01-30 12:37:23 +00:00
this . owner . store . scheduleLayout ( true ) ;
2016-11-04 08:27:51 +00:00
}
2017-04-28 07:53:39 +00:00
} ,
sortable ( newVal ) {
if ( this . columnConfig ) {
this . columnConfig . sortable = newVal ;
}
2017-10-25 07:35:12 +00:00
} ,
index ( newVal ) {
if ( this . columnConfig ) {
this . columnConfig . index = newVal ;
}
2018-03-16 03:04:44 +00:00
} ,
formatter ( newVal ) {
if ( this . columnConfig ) {
this . columnConfig . formatter = newVal ;
}
2018-06-14 09:07:00 +00:00
} ,
className ( newVal ) {
if ( this . columnConfig ) {
this . columnConfig . className = newVal ;
}
} ,
labelClassName ( newVal ) {
if ( this . columnConfig ) {
this . columnConfig . labelClassName = newVal ;
}
2016-08-16 08:07:18 +00:00
}
} ,
2019-03-27 08:13:21 +00:00
methods : {
renderTreeCell ( data ) {
if ( ! data . treeNode ) return null ;
const ele = [ ] ;
ele . push ( < span class = "el-table__indent" style = { { 'padding-left' : data . treeNode . indent + 'px' } } > < / s p a n > ) ;
if ( data . treeNode . hasChildren ) {
ele . push ( < div class = { [ 'el-table__expand-icon' , data . treeNode . expanded ? 'el-table__expand-icon--expanded' : '' ] }
on - click = { this . handleTreeExpandIconClick . bind ( this , data ) } >
< i class = 'el-icon el-icon-arrow-right' > < / i >
< / d i v > ) ;
} else {
ele . push ( < span class = "el-table__placeholder" > < / s p a n > ) ;
}
return ele ;
} ,
handleTreeExpandIconClick ( data , e ) {
e . stopPropagation ( ) ;
if ( data . store . states . lazy && ! data . treeNode . loaded ) {
data . store . loadData ( data . row , data . treeNode ) ;
} else {
data . store . toggleTreeExpansion ( data . treeNode . rowKey ) ;
}
}
} ,
2016-08-16 08:07:18 +00:00
mounted ( ) {
2016-10-12 11:18:34 +00:00
const owner = this . owner ;
2017-11-27 06:59:21 +00:00
const parent = this . columnOrTableParent ;
2016-08-16 08:07:18 +00:00
let columnIndex ;
2016-11-23 12:32:23 +00:00
if ( ! this . isSubColumn ) {
2016-08-16 08:07:18 +00:00
columnIndex = [ ] . indexOf . call ( parent . $refs . hiddenColumns . children , this . $el ) ;
} else {
columnIndex = [ ] . indexOf . call ( parent . $el . children , this . $el ) ;
}
2018-10-26 03:16:56 +00:00
if ( this . $scopedSlots . header ) {
if ( this . type === 'selection' ) {
2018-10-26 03:59:02 +00:00
console . warn ( '[Element Warn][TableColumn]Selection column doesn\'t allow to set scoped-slot header.' ) ;
2018-10-26 03:16:56 +00:00
} else {
2018-11-01 07:23:55 +00:00
this . columnConfig . renderHeader = ( h , scope ) => this . $scopedSlots . header ( scope ) ;
2018-10-26 03:16:56 +00:00
}
}
2016-11-23 12:32:23 +00:00
owner . store . commit ( 'insertColumn' , this . columnConfig , columnIndex , this . isSubColumn ? parent . columnConfig : null ) ;
2016-08-16 08:07:18 +00:00
}
} ;