1 | import React from 'react';
|
2 | import Column from './Column';
|
3 | import ColumnGroup from './ColumnGroup';
|
4 | import Icon from 'bee-icon';
|
5 |
|
6 |
|
7 | export default class ColumnManager {
|
8 | _cached = {}
|
9 |
|
10 | constructor(columns, elements,originWidth,rowDraggAble,showRowNum) {
|
11 | columns = this.addDragHandleColumn(columns,rowDraggAble);
|
12 | columns = this.addOrderColumn(columns,showRowNum);
|
13 | columns = this.deleteColumnNotShow(columns);
|
14 | this.columns = columns || this.normalize(elements);
|
15 |
|
16 | this.originWidth = originWidth;
|
17 | }
|
18 |
|
19 |
|
20 | addDragHandleColumn = (columns, rowDraggAble) => {
|
21 | if(!rowDraggAble){
|
22 | return columns
|
23 | }
|
24 | let dragHandleColumn =[{
|
25 | className: "drag-handle-column",
|
26 | title: "",
|
27 | key: "dragHandle",
|
28 | dataIndex: "dragHandle",
|
29 | width: 49,
|
30 | draggable: true,
|
31 | render: () => {
|
32 | return <Icon type="uf-navmenu" />
|
33 | }
|
34 | }]
|
35 | columns = dragHandleColumn.concat(columns);
|
36 | return columns;
|
37 | }
|
38 |
|
39 | // delete the column which does not show
|
40 | deleteColumnNotShow = (columns) => {
|
41 | let len = columns.length;
|
42 | for(let i=0; i < len; i++) {
|
43 | if(columns && columns[i] && columns[i].isShow === false){
|
44 | columns.splice(i,1);
|
45 | i--;
|
46 | }
|
47 | }
|
48 | return columns;
|
49 | }
|
50 |
|
51 | // 向数据列中添加一列:序号
|
52 | addOrderColumn = (columns, showRowNum) => {
|
53 | if(!showRowNum){
|
54 | return columns
|
55 | }
|
56 | let { key, fixed, width, name, type, base } = showRowNum;
|
57 | let order = {
|
58 | dataIndex: key || '_index',
|
59 | key:'_index',
|
60 | fixed:fixed || 'left',
|
61 | width:width || 50,
|
62 | title: name || '序号',
|
63 | render:(text, record, index)=>{
|
64 | switch( type ){
|
65 | case 'ascii':{
|
66 | return (String.fromCharCode((base || 'a').charCodeAt() + index));
|
67 | }
|
68 | case 'number':
|
69 | default:{
|
70 | return ( (base || 0) + index);
|
71 | }
|
72 | }
|
73 | }
|
74 | }
|
75 | if(columns.length > 0 && columns[0].dataIndex !== 'checkbox' && columns[0].dataIndex !== 'radio'){ // 多选表格/单选表格时放在第二列,其他情况放到第一列
|
76 | columns = [order].concat(columns);
|
77 | }
|
78 | else{
|
79 | columns.splice(1,0,order); // splice方法改变原数组,返回切割出的数组,此处为[]
|
80 | }
|
81 | return columns;
|
82 | }
|
83 |
|
84 | isAnyColumnsFixed() {
|
85 | return this._cache('isAnyColumnsFixed', () => {
|
86 | return this.columns.some(column => !!column.fixed);
|
87 | });
|
88 | }
|
89 |
|
90 | isAnyColumnsLeftFixed() {
|
91 | return this._cache('isAnyColumnsLeftFixed', () => {
|
92 | return this.columns.some(
|
93 | column => column.fixed === 'left' || column.fixed === true
|
94 | );
|
95 | });
|
96 | }
|
97 |
|
98 | isAnyColumnsRightFixed() {
|
99 | return this._cache('isAnyColumnsRightFixed', () => {
|
100 | return this.columns.some(
|
101 | column => column.fixed === 'right'
|
102 | );
|
103 | });
|
104 | }
|
105 |
|
106 | leftColumns() {
|
107 | return this._cache('leftColumns', () => {
|
108 | return this.groupedColumns().filter(
|
109 | column => column.fixed === 'left' || column.fixed === true
|
110 | );
|
111 | });
|
112 | }
|
113 |
|
114 | rightColumns() {
|
115 | return this._cache('rightColumns', () => {
|
116 | return this.groupedColumns().filter(
|
117 | column => column.fixed === 'right'
|
118 | );
|
119 | });
|
120 | }
|
121 |
|
122 | centerColumns() {
|
123 | return this._cache('centerColumns', () => {
|
124 | return this.groupedColumns().filter(
|
125 | column => !column.fixed
|
126 | );
|
127 | });
|
128 | }
|
129 |
|
130 | leafColumns() {
|
131 | return this._cache('leafColumns', () =>
|
132 | this._leafColumns(this.columns)
|
133 | );
|
134 | }
|
135 |
|
136 | leftLeafColumns() {
|
137 | return this._cache('leftLeafColumns', () =>
|
138 | this._leafColumns(this.leftColumns())
|
139 | );
|
140 | }
|
141 |
|
142 | rightLeafColumns() {
|
143 | return this._cache('rightLeafColumns', () =>
|
144 | this._leafColumns(this.rightColumns())
|
145 | );
|
146 | }
|
147 | centerLeafColumns() {
|
148 | return this._cache('centerLeafColumns', () =>
|
149 | this._leafColumns(this.centerColumns())
|
150 | );
|
151 | }
|
152 |
|
153 | // add appropriate rowspan and colspan to column
|
154 | groupedColumns(type) {
|
155 | return this._cache('groupedColumns', () => {
|
156 | const _groupColumns = (columns, currentRow = 0, parentColumn = {}, rows = []) => {
|
157 | // track how many rows we got
|
158 | rows[currentRow] = rows[currentRow] || [];
|
159 | const grouped = [];
|
160 | const setRowSpan = column => {
|
161 | const rowSpan = rows.length - currentRow;
|
162 | if (column &&
|
163 | !column.children && // parent columns are supposed to be one row
|
164 | rowSpan > 1 &&
|
165 | (!column.rowSpan || column.rowSpan < rowSpan)
|
166 | ) {
|
167 | column.rowSpan = rowSpan;
|
168 | }
|
169 | };
|
170 | columns.forEach((column, index) => {
|
171 | let defaultOpt= {
|
172 | ifshow:true
|
173 | }
|
174 | if(!this.originWidth){
|
175 | defaultOpt.width = 200
|
176 | }
|
177 | //获取非固定列
|
178 | if(type=='nofixed' && column.fixed){
|
179 | return false;
|
180 | }
|
181 | const newColumn = { ...defaultOpt,...column };
|
182 | rows[currentRow].push(newColumn);
|
183 | parentColumn.colSpan = parentColumn.colSpan || 0;
|
184 | if (newColumn.children && newColumn.children.length > 0) {
|
185 | newColumn.children = _groupColumns(newColumn.children, currentRow + 1, newColumn, rows);
|
186 | parentColumn.colSpan = parentColumn.colSpan + newColumn.colSpan;
|
187 | } else {
|
188 | parentColumn.colSpan++;
|
189 | }
|
190 | // update rowspan to all same row columns
|
191 | for (let i = 0; i < rows[currentRow].length - 1; ++i) {
|
192 | setRowSpan(rows[currentRow][i]);
|
193 | }
|
194 | // last column, update rowspan immediately
|
195 | if (index + 1 === columns.length) {
|
196 | setRowSpan(newColumn);
|
197 | }
|
198 | grouped.push(newColumn);
|
199 | });
|
200 | return grouped;
|
201 | };
|
202 | return _groupColumns(this.columns);
|
203 | });
|
204 | }
|
205 |
|
206 | normalize(elements) {
|
207 | const columns = [];
|
208 | React.Children.forEach(elements, element => {
|
209 | if (!this.isColumnElement(element)) return;
|
210 | const column = { ...element.props };
|
211 | if (element.key) {
|
212 | column.key = element.key;
|
213 | }
|
214 | if (element.type === ColumnGroup) {
|
215 | column.children = this.normalize(column.children);
|
216 | }
|
217 | columns.push(column);
|
218 | });
|
219 | return columns;
|
220 | }
|
221 |
|
222 | isColumnElement(element) {
|
223 | return element && (element.type === Column || element.type === ColumnGroup);
|
224 | }
|
225 |
|
226 | reset(columns, elements, showRowNum, rowDraggAble) {
|
227 | columns = this.addDragHandleColumn(columns,rowDraggAble);
|
228 | columns = this.addOrderColumn(columns,showRowNum);
|
229 | columns = this.deleteColumnNotShow(columns);
|
230 | this.columns = columns || this.normalize(elements);
|
231 | this._cached = {};
|
232 | }
|
233 | getColumnWidth(contentWidth){
|
234 | let columns = this.leafColumns();
|
235 | let res={computeWidth:0,lastShowIndex:-1};
|
236 | columns.forEach((col,index)=>{
|
237 | //如果列显示
|
238 | if(col.ifshow){
|
239 | let width = col.width;
|
240 | if(typeof(width) == 'string' && width.includes('%') ){
|
241 | width = contentWidth * parseInt(col.width) /100;
|
242 | }
|
243 | res.computeWidth += parseInt(width);
|
244 | if(!col.fixed){
|
245 | res.lastShowIndex = index;
|
246 | }
|
247 | }
|
248 | })
|
249 | return res;
|
250 | }
|
251 |
|
252 | getLeftColumnsWidth(contentWidth=1) {
|
253 | return this._cache('leftColumnsWidth', () => {
|
254 | let leftColumnsWidth =0;
|
255 | this.groupedColumns().forEach(column =>{
|
256 | if (column.fixed === 'left' || column.fixed === true){
|
257 | let width = column.width;
|
258 | if(typeof(width) == 'string' && width.includes('%') ){
|
259 | width = contentWidth * parseInt(column.width) /100;
|
260 | }
|
261 | leftColumnsWidth += parseInt(width)
|
262 | }
|
263 | });
|
264 | return leftColumnsWidth;
|
265 | });
|
266 | }
|
267 |
|
268 | getRightColumnsWidth(contentWidth=1) {
|
269 | return this._cache('rightColumnsWidth', () => {
|
270 | let rightColumnsWidth =0;
|
271 | this.groupedColumns().forEach(column =>{
|
272 | if (column.fixed === 'right'){
|
273 | let width = column.width;
|
274 | if(typeof(width) == 'string' && width.includes('%') ){
|
275 | width = contentWidth * parseInt(column.width) /100;
|
276 | }
|
277 | rightColumnsWidth += parseInt(width)
|
278 | }
|
279 | });
|
280 | return rightColumnsWidth;
|
281 | });
|
282 | }
|
283 |
|
284 | _cache(name, fn) {
|
285 | if (name in this._cached) {
|
286 | return this._cached[name];
|
287 | }
|
288 | this._cached[name] = fn();
|
289 | return this._cached[name];
|
290 | }
|
291 |
|
292 | //todo 含有children的宽度计算
|
293 | _leafColumns(columns) {
|
294 | const leafColumns = [];
|
295 |
|
296 | columns.forEach(column => {
|
297 | if (!column.children) {
|
298 |
|
299 | let defaultOpt= {
|
300 | ifshow:true
|
301 | }
|
302 | if(!this.originWidth){
|
303 | defaultOpt.width = 200
|
304 | }
|
305 | const newColumn = { ...defaultOpt,...column };
|
306 | leafColumns.push(newColumn);
|
307 | } else {
|
308 | leafColumns.push(...this._leafColumns(column.children));
|
309 | }
|
310 | });
|
311 | return leafColumns;
|
312 | }
|
313 | }
|
314 |
|
\ | No newline at end of file |