index.jsx 21.2 KB
Newer Older
A
afc163 已提交
1
import React from 'react';
2
import RcTable from 'rc-table';
A
afc163 已提交
3
import Checkbox from '../checkbox';
R
RaoHai 已提交
4
import Radio from '../radio';
A
afc163 已提交
5
import FilterDropdown from './filterDropdown';
6
import Pagination from '../pagination';
A
afc163 已提交
7
import Icon from '../icon';
K
KgTong 已提交
8
import Spin from '../spin';
A
afc163 已提交
9
import classNames from 'classnames';
A
afc163 已提交
10
import { flatArray } from './util';
A
afc163 已提交
11

Y
yiminghe 已提交
12 13
function noop() {
}
14

B
Benjy Cui 已提交
15 16 17
const defaultLocale = {
  filterTitle: '筛选',
  filterConfirm: '确定',
A
afc163 已提交
18 19
  filterReset: '重置',
  emptyText: '暂无数据',
B
Benjy Cui 已提交
20 21
};

22 23 24 25 26 27 28
const defaultPagination = {
  pageSize: 10,
  current: 1,
  onChange: noop,
  onShowSizeChange: noop,
};

A
afc163 已提交
29
const Table = React.createClass({
Y
yiminghe 已提交
30
  getInitialState() {
A
afc163 已提交
31
    return {
Y
yiminghe 已提交
32
      // 减少状态
33
      selectedRowKeys: this.props.selectedRowKeys || [],
A
afc163 已提交
34
      filters: this.getFiltersFromColumns(),
A
afc163 已提交
35
      selectionDirty: false,
A
afc163 已提交
36
      ...this.getSortStateFromColumns(),
R
RaoHai 已提交
37
      radioIndex: null,
38
      pagination: this.hasPagination() ?
B
Benjy Cui 已提交
39 40 41 42 43
      {
        size: this.props.size,
        ...defaultPagination,
        ...this.props.pagination,
      } : {},
A
afc163 已提交
44 45
    };
  },
Y
yiminghe 已提交
46

A
afc163 已提交
47 48
  getDefaultProps() {
    return {
A
afc163 已提交
49
      dataSource: [],
A
afc163 已提交
50
      prefixCls: 'ant-table',
A
afc163 已提交
51
      useFixedHeader: false,
A
afc163 已提交
52
      rowSelection: null,
Y
yiminghe 已提交
53
      className: '',
A
afc163 已提交
54
      size: 'large',
A
afc163 已提交
55
      loading: false,
A
afc163 已提交
56
      bordered: false,
A
afc163 已提交
57
      indentSize: 20,
B
Benjy Cui 已提交
58 59
      onChange: noop,
      locale: {}
A
afc163 已提交
60 61
    };
  },
Y
yiminghe 已提交
62

A
afc163 已提交
63
  propTypes: {
A
afc163 已提交
64
    dataSource: React.PropTypes.array,
A
afc163 已提交
65 66 67 68 69 70 71 72 73
    prefixCls: React.PropTypes.string,
    useFixedHeader: React.PropTypes.bool,
    rowSelection: React.PropTypes.object,
    className: React.PropTypes.string,
    size: React.PropTypes.string,
    loading: React.PropTypes.bool,
    bordered: React.PropTypes.bool,
    onChange: React.PropTypes.func,
    locale: React.PropTypes.object,
A
afc163 已提交
74 75
  },

A
afc163 已提交
76
  contextTypes: {
A
afc163 已提交
77
    antLocale: React.PropTypes.object,
A
afc163 已提交
78 79
  },

R
RaoHai 已提交
80
  getDefaultSelection() {
81 82
    if (!this.props.rowSelection || !this.props.rowSelection.getCheckboxProps) {
      return [];
R
RaoHai 已提交
83
    }
A
afc163 已提交
84
    return this.getFlatCurrentPageData()
85 86
      .filter(item => this.props.rowSelection.getCheckboxProps(item).defaultChecked)
      .map((record, rowIndex) => this.getRecordKey(record, rowIndex));
R
RaoHai 已提交
87 88
  },

A
afc163 已提交
89 90
  getLocale() {
    let locale = {};
A
afc163 已提交
91 92
    if (this.context.antLocale && this.context.antLocale.Table) {
      locale = this.context.antLocale.Table;
A
afc163 已提交
93
    }
B
Benjy Cui 已提交
94
    return { ...defaultLocale, ...locale, ...this.props.locale };
A
afc163 已提交
95 96
  },

A
afc163 已提交
97
  componentWillReceiveProps(nextProps) {
Y
yiminghe 已提交
98
    if (('pagination' in nextProps) && nextProps.pagination !== false) {
99
      this.setState({
B
Benjy Cui 已提交
100
        pagination: { ...defaultPagination, ...this.state.pagination, ...nextProps.pagination },
101
      });
A
afc163 已提交
102
    }
103
    // dataSource 的变化会清空选中项
104
    if ('dataSource' in nextProps &&
A
afc163 已提交
105
        nextProps.dataSource !== this.props.dataSource) {
106
      this.setState({
A
afc163 已提交
107
        selectionDirty: false,
A
afc163 已提交
108
      });
109 110 111 112 113 114 115
    }
    if (nextProps.rowSelection &&
        'selectedRowKeys' in nextProps.rowSelection) {
      this.setState({
        selectedRowKeys: nextProps.rowSelection.selectedRowKeys || [],
      });
    }
A
afc163 已提交
116
    if (this.hasSortOrderInColumns(nextProps.columns)) {
A
afc163 已提交
117
      const sortState = this.getSortStateFromColumns(nextProps.columns);
A
afc163 已提交
118 119
      if (sortState.sortColumn !== this.state.sortColumn ||
          sortState.sortOrder !== this.state.sortOrder) {
A
afc163 已提交
120 121 122
        this.setState(sortState);
      }
    }
A
afc163 已提交
123 124 125 126 127 128
    if (this.hasFilteredValueInColumns(nextProps.columns)) {
      const filters = this.getFiltersFromColumns(nextProps.columns);
      if (this.isFiltersChanged(filters)) {
        this.setState({ filters });
      }
    }
129 130 131 132 133 134 135 136
  },

  setSelectedRowKeys(selectedRowKeys) {
    if (this.props.rowSelection &&
        !('selectedRowKeys' in this.props.rowSelection)) {
      this.setState({ selectedRowKeys });
    }
    if (this.props.rowSelection && this.props.rowSelection.onChange) {
A
afc163 已提交
137
      const data = this.getFlatCurrentPageData();
138 139 140
      const selectedRows = data.filter(
        (row, i) => selectedRowKeys.indexOf(this.getRecordKey(row, i)) >= 0
      );
A
afc163 已提交
141
      this.props.rowSelection.onChange(selectedRowKeys, selectedRows);
A
afc163 已提交
142
    }
A
afc163 已提交
143
  },
A
afc163 已提交
144

A
afc163 已提交
145
  hasPagination() {
A
afc163 已提交
146
    return this.props.pagination !== false;
A
afc163 已提交
147
  },
A
afc163 已提交
148

A
afc163 已提交
149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180
  isFiltersChanged(filters) {
    let filtersChanged = false;
    if (Object.keys(filters).length !== Object.keys(this.state.filters).length) {
      filtersChanged = true;
    } else {
      Object.keys(filters).forEach(columnKey => {
        if (filters[columnKey] !== this.state.filters[columnKey]) {
          filtersChanged = true;
        }
      });
    }
    return filtersChanged;
  },

  hasSortOrderInColumns(columns) {
    return (columns || this.props.columns).some(column => 'sortOrder' in column);
  },

  hasFilteredValueInColumns(columns) {
    return (columns || this.props.columns).some(column => 'filteredValue' in column);
  },

  getFiltersFromColumns(columns) {
    let filters = {};
    (columns || this.props.columns).forEach(col => {
      if (col.filteredValue) {
        filters[this.getColumnKey(col)] = col.filteredValue;
      }
    });
    return filters;
  },

A
afc163 已提交
181
  getSortedColumn(columns) {
A
afc163 已提交
182
    return (columns || this.props.columns).filter(col => col.sortOrder)[0];
A
afc163 已提交
183 184
  },

A
afc163 已提交
185
  getSortStateFromColumns(columns) {
A
afc163 已提交
186 187 188 189
    const sortedColumn = this.getSortedColumn(columns);
    if (sortedColumn) {
      return {
        sortColumn: sortedColumn,
A
afc163 已提交
190
        sortOrder: sortedColumn.sortOrder,
A
afc163 已提交
191 192
      };
    }
A
afc163 已提交
193 194 195 196
    return {
      sortColumn: null,
      sortOrder: null,
    };
A
afc163 已提交
197 198
  },

A
afc163 已提交
199 200
  getSorterFn() {
    const { sortOrder, sortColumn } = this.state;
A
afc163 已提交
201 202
    if (!sortOrder || !sortColumn ||
        typeof sortColumn.sorter !== 'function') {
A
afc163 已提交
203 204 205 206 207 208 209 210 211 212 213
      return () => {};
    }
    return (a, b) => {
      let result = sortColumn.sorter(a, b);
      if (result !== 0) {
        return (sortOrder === 'descend') ? -result : result;
      }
      return a.index - b.index;
    };
  },

A
afc163 已提交
214
  toggleSortOrder(order, column) {
A
afc163 已提交
215
    let { sortColumn, sortOrder } = this.state;
A
afc163 已提交
216 217 218 219 220 221 222 223 224 225 226 227 228
    // 只同时允许一列进行排序,否则会导致排序顺序的逻辑问题
    let isSortColumn = this.isSortColumn(column);
    if (!isSortColumn) {  // 当前列未排序
      sortOrder = order;
      sortColumn = column;
    } else {                      // 当前列已排序
      if (sortOrder === order) {  // 切换为未排序状态
        sortOrder = '';
        sortColumn = null;
      } else {                    // 切换为排序状态
        sortOrder = order;
      }
    }
A
afc163 已提交
229 230 231 232
    const newState = {
      sortOrder,
      sortColumn,
    };
A
afc163 已提交
233
    // Controlled
A
afc163 已提交
234
    if (!this.hasSortOrderInColumns()) {
A
afc163 已提交
235 236
      this.setState(newState);
    }
A
afc163 已提交
237
    this.props.onChange(...this.prepareParamsArguments({ ...this.state, ...newState }));
A
afc163 已提交
238
  },
A
afc163 已提交
239

240
  handleFilter(column, nextFilters) {
B
Benjy Cui 已提交
241 242
    const filters = {
      ...this.state.filters,
A
afc163 已提交
243
      [this.getColumnKey(column)]: nextFilters,
B
Benjy Cui 已提交
244
    };
245 246 247 248 249 250 251
    // Remove filters not in current columns
    const currentColumnKeys = this.props.columns.map(c => this.getColumnKey(c));
    Object.keys(filters).forEach((columnKey) => {
      if (currentColumnKeys.indexOf(columnKey) < 0) {
        delete filters[columnKey];
      }
    });
A
afc163 已提交
252
    const newState = {
A
afc163 已提交
253
      selectionDirty: false,
A
afc163 已提交
254
      filters,
A
afc163 已提交
255
    };
A
afc163 已提交
256 257 258 259
    // Controlled
    if (!this.hasFilteredValueInColumns()) {
      this.setState(newState);
    }
A
afc163 已提交
260
    this.props.onChange(...this.prepareParamsArguments({ ...this.state, ...newState }));
A
afc163 已提交
261
  },
A
afc163 已提交
262

Y
yiminghe 已提交
263
  handleSelect(record, rowIndex, e) {
264 265
    const checked = e.target.checked;
    const defaultSelection = this.state.selectionDirty ? [] : this.getDefaultSelection();
R
RaoHai 已提交
266
    let selectedRowKeys = this.state.selectedRowKeys.concat(defaultSelection);
Y
yiminghe 已提交
267
    let key = this.getRecordKey(record, rowIndex);
268
    if (checked) {
Y
yiminghe 已提交
269
      selectedRowKeys.push(this.getRecordKey(record, rowIndex));
270
    } else {
Y
yiminghe 已提交
271 272
      selectedRowKeys = selectedRowKeys.filter((i) => {
        return key !== i;
273 274 275
      });
    }
    this.setState({
276
      selectionDirty: true,
R
RaoHai 已提交
277
    });
278
    this.setSelectedRowKeys(selectedRowKeys);
R
RaoHai 已提交
279
    if (this.props.rowSelection.onSelect) {
A
afc163 已提交
280
      let data = this.getFlatCurrentPageData();
R
RaoHai 已提交
281 282 283 284 285 286 287
      let selectedRows = data.filter((row, i) => {
        return selectedRowKeys.indexOf(this.getRecordKey(row, i)) >= 0;
      });
      this.props.rowSelection.onSelect(record, checked, selectedRows);
    }
  },

288
  handleRadioSelect(record, rowIndex, e) {
289 290
    const checked = e.target.checked;
    const defaultSelection = this.state.selectionDirty ? [] : this.getDefaultSelection();
R
RaoHai 已提交
291 292 293 294
    let selectedRowKeys = this.state.selectedRowKeys.concat(defaultSelection);
    let key = this.getRecordKey(record, rowIndex);
    selectedRowKeys = [key];
    this.setState({
295
      radioIndex: key,
296
      selectionDirty: true,
297
    });
298
    this.setSelectedRowKeys(selectedRowKeys);
299
    if (this.props.rowSelection.onSelect) {
A
afc163 已提交
300
      let data = this.getFlatCurrentPageData();
Y
yiminghe 已提交
301 302
      let selectedRows = data.filter((row, i) => {
        return selectedRowKeys.indexOf(this.getRecordKey(row, i)) >= 0;
A
afc163 已提交
303
      });
Y
yiminghe 已提交
304
      this.props.rowSelection.onSelect(record, checked, selectedRows);
305 306
    }
  },
A
afc163 已提交
307

A
afc163 已提交
308
  handleSelectAllRow(e) {
309
    const checked = e.target.checked;
A
afc163 已提交
310
    const data = this.getFlatCurrentPageData();
311 312 313 314 315 316
    const defaultSelection = this.state.selectionDirty ? [] : this.getDefaultSelection();
    const selectedRowKeys = this.state.selectedRowKeys.concat(defaultSelection);
    const changableRowKeys = data.filter(item =>
      !this.props.rowSelection.getCheckboxProps ||
      !this.props.rowSelection.getCheckboxProps(item).disabled
    ).map((item, i) => this.getRecordKey(item, i));
317 318 319

    // 记录变化的列
    const changeRowKeys = [];
320 321 322 323
    if (checked) {
      changableRowKeys.forEach(key => {
        if (selectedRowKeys.indexOf(key) < 0) {
          selectedRowKeys.push(key);
324
          changeRowKeys.push(key);
325 326 327 328 329 330
        }
      });
    } else {
      changableRowKeys.forEach(key => {
        if (selectedRowKeys.indexOf(key) >= 0) {
          selectedRowKeys.splice(selectedRowKeys.indexOf(key), 1);
331
          changeRowKeys.push(key);
332 333 334
        }
      });
    }
A
afc163 已提交
335
    this.setState({
336
      selectionDirty: true,
337
    });
338
    this.setSelectedRowKeys(selectedRowKeys);
339
    if (this.props.rowSelection.onSelectAll) {
340 341 342 343 344
      const selectedRows = data.filter((row, i) =>
        selectedRowKeys.indexOf(this.getRecordKey(row, i)) >= 0);
      const changeRows = data.filter((row, i) =>
        changeRowKeys.indexOf(this.getRecordKey(row, i)) >= 0);
      this.props.rowSelection.onSelectAll(checked, selectedRows, changeRows);
A
afc163 已提交
345
    }
A
afc163 已提交
346
  },
A
afc163 已提交
347

348
  handlePageChange(current) {
B
Benjy Cui 已提交
349
    let pagination = { ...this.state.pagination };
350 351 352 353 354
    if (current) {
      pagination.current = current;
    } else {
      pagination.current = pagination.current || 1;
    }
355 356
    pagination.onChange(pagination.current);

A
afc163 已提交
357
    const newState = {
A
afc163 已提交
358
      selectionDirty: false,
A
afc163 已提交
359 360
      pagination
    };
A
afc163 已提交
361
    this.setState(newState);
A
afc163 已提交
362
    this.props.onChange(...this.prepareParamsArguments({ ...this.state, ...newState }));
363
  },
A
afc163 已提交
364

365
  onRadioChange(ev) {
R
RaoHai 已提交
366 367
    this.setState({
      radioIndex: ev.target.value
Y
yiminghe 已提交
368
    });
369
  },
A
afc163 已提交
370

R
RaoHai 已提交
371 372 373 374 375 376
  renderSelectionRadio(value, record, index) {
    let rowIndex = this.getRecordKey(record, index); // 从 1 开始
    let props = {};
    if (this.props.rowSelection.getCheckboxProps) {
      props = this.props.rowSelection.getCheckboxProps.call(this, record);
    }
A
afc163 已提交
377 378
    let checked;
    if (this.state.selectionDirty) {
379
      checked = this.state.radioIndex === rowIndex;
A
afc163 已提交
380
    } else {
381
      checked = (this.state.radioIndex === rowIndex ||
A
afc163 已提交
382 383
                 this.getDefaultSelection().indexOf(rowIndex) >= 0);
    }
384
    return (
385 386
      <Radio disabled={props.disabled}
        onChange={this.handleRadioSelect.bind(this, record, rowIndex)}
387
        value={rowIndex} checked={checked} />
388
    );
R
RaoHai 已提交
389 390
  },

391
  renderSelectionCheckBox(value, record, index) {
Y
yiminghe 已提交
392
    let rowIndex = this.getRecordKey(record, index); // 从 1 开始
A
afc163 已提交
393 394 395 396 397 398 399
    let checked;
    if (this.state.selectionDirty) {
      checked = this.state.selectedRowKeys.indexOf(rowIndex) >= 0;
    } else {
      checked = (this.state.selectedRowKeys.indexOf(rowIndex) >= 0 ||
                 this.getDefaultSelection().indexOf(rowIndex) >= 0);
    }
R
RaoHai 已提交
400 401 402 403
    let props = {};
    if (this.props.rowSelection.getCheckboxProps) {
      props = this.props.rowSelection.getCheckboxProps.call(this, record);
    }
404 405
    return (
      <Checkbox checked={checked} disabled={props.disabled}
406
        onChange={this.handleSelect.bind(this, record, rowIndex)} />
407
    );
Y
yiminghe 已提交
408
  },
A
afc163 已提交
409 410

  getRecordKey(record, index) {
411 412 413
    if (this.props.rowKey) {
      return this.props.rowKey(record, index);
    }
Y
yiminghe 已提交
414
    return record.key || index;
415
  },
A
afc163 已提交
416

417
  renderRowSelection() {
Y
yiminghe 已提交
418
    let columns = this.props.columns.concat();
419
    if (this.props.rowSelection) {
A
afc163 已提交
420
      let data = this.getFlatCurrentPageData().filter((item) => {
421 422 423 424 425
        if (this.props.rowSelection.getCheckboxProps) {
          return !this.props.rowSelection.getCheckboxProps(item).disabled;
        }
        return true;
      });
Y
yiminghe 已提交
426 427 428 429
      let checked;
      if (!data.length) {
        checked = false;
      } else {
A
afc163 已提交
430 431 432
        checked = this.state.selectionDirty
          ? data.every((item, i) =>
              this.state.selectedRowKeys.indexOf(this.getRecordKey(item, i)) >= 0)
A
afc163 已提交
433 434 435 436
          : (
            data.every((item, i) =>
              this.state.selectedRowKeys.indexOf(this.getRecordKey(item, i)) >= 0) ||
            data.every((item) =>
A
afc163 已提交
437
              this.props.rowSelection.getCheckboxProps &&
A
afc163 已提交
438 439
              this.props.rowSelection.getCheckboxProps(item).defaultChecked)
          );
Y
yiminghe 已提交
440
      }
R
RaoHai 已提交
441 442 443 444 445 446 447 448
      let selectionColumn;
      if (this.props.rowSelection.type === 'radio') {
        selectionColumn = {
          key: 'selection-column',
          render: this.renderSelectionRadio,
          className: 'ant-table-selection-column'
        };
      } else {
449 450 451 452 453
        const checkboxAllDisabled = data.every(item =>
          this.props.rowSelection.getCheckboxProps &&
          this.props.rowSelection.getCheckboxProps(item).disabled);
        const checkboxAll = (
            <Checkbox checked={checked}
454 455
              disabled={checkboxAllDisabled}
              onChange={this.handleSelectAllRow} />
456
        );
R
RaoHai 已提交
457 458 459 460 461 462 463
        selectionColumn = {
          key: 'selection-column',
          title: checkboxAll,
          render: this.renderSelectionCheckBox,
          className: 'ant-table-selection-column'
        };
      }
A
afc163 已提交
464
      if (columns[0] && columns[0].key === 'selection-column') {
465 466 467 468 469 470 471
        columns[0] = selectionColumn;
      } else {
        columns.unshift(selectionColumn);
      }
    }
    return columns;
  },
Y
yiminghe 已提交
472

A
afc163 已提交
473 474 475 476 477
  getColumnKey(column, index) {
    return column.key || column.dataIndex || index;
  },

  isSortColumn(column) {
A
afc163 已提交
478 479
    const { sortColumn } = this.state;
    if (!column || !sortColumn) {
A
afc163 已提交
480 481
      return false;
    }
A
afc163 已提交
482
    return this.getColumnKey(sortColumn) === this.getColumnKey(column);
Y
yiminghe 已提交
483 484 485
  },

  renderColumnsDropdown(columns) {
A
afc163 已提交
486
    const { sortOrder } = this.state;
A
afc163 已提交
487
    const locale = this.getLocale();
488
    return columns.map((originColumn, i) => {
B
Benjy Cui 已提交
489
      let column = { ...originColumn };
A
afc163 已提交
490
      let key = this.getColumnKey(column, i);
491 492
      let filterDropdown;
      let sortButton;
493
      if (column.filters && column.filters.length > 0) {
Y
yiminghe 已提交
494
        let colFilters = this.state.filters[key] || [];
495
        filterDropdown = (
B
Benjy Cui 已提交
496
          <FilterDropdown locale={locale} column={column}
497
            selectedKeys={colFilters}
498
            confirmFilter={this.handleFilter} />
499
        );
A
afc163 已提交
500 501
      }
      if (column.sorter) {
A
afc163 已提交
502
        let isSortColumn = this.isSortColumn(column);
Y
yiminghe 已提交
503 504
        if (isSortColumn) {
          column.className = column.className || '';
A
afc163 已提交
505
          if (sortOrder) {
A
afc163 已提交
506 507
            column.className += ' ant-table-column-sort';
          }
Y
yiminghe 已提交
508
        }
A
afc163 已提交
509 510
        const isAscend = isSortColumn && sortOrder === 'ascend';
        const isDescend = isSortColumn && sortOrder === 'descend';
511 512
        sortButton = (
          <div className="ant-table-column-sorter">
513
            <span className={`ant-table-column-sorter-up ${isAscend ? 'on' : 'off'}`}
514 515
              title="↑"
              onClick={this.toggleSortOrder.bind(this, 'ascend', column)}>
516
              <Icon type="caret-up" />
517
            </span>
518
            <span className={`ant-table-column-sorter-down ${isDescend ? 'on' : 'off'}`}
519 520
              title="↓"
              onClick={this.toggleSortOrder.bind(this, 'descend', column)}>
521
              <Icon type="caret-down" />
522 523 524
            </span>
          </div>
        );
A
afc163 已提交
525
      }
526
      column.title = (
527
        <span>
528 529 530
          {column.title}
          {sortButton}
          {filterDropdown}
531
        </span>
532
      );
A
afc163 已提交
533
      return column;
A
afc163 已提交
534 535
    });
  },
A
afc163 已提交
536

537
  handleShowSizeChange(current, pageSize) {
B
Benjy Cui 已提交
538
    const pagination = this.state.pagination;
539
    pagination.onShowSizeChange(current, pageSize);
540
    const nextPagination = { ...pagination, pageSize, current };
B
Benjy Cui 已提交
541
    this.setState({ pagination: nextPagination });
A
afc163 已提交
542
    this.props.onChange(...this.prepareParamsArguments({
543 544 545
      ...this.state,
      pagination: nextPagination,
    }));
546 547
  },

548 549
  renderPagination() {
    // 强制不需要分页
Y
yiminghe 已提交
550 551
    if (!this.hasPagination()) {
      return null;
A
afc163 已提交
552
    }
A
afc163 已提交
553 554
    let classString = classNames({
      'ant-table-pagination': true,
555
      mini: this.props.size === 'middle' || this.props.size === 'small',
A
afc163 已提交
556
    });
A
afc163 已提交
557
    let total = this.state.pagination.total || this.getLocalData().length;
Y
yiminghe 已提交
558
    const pageSize = this.state.pagination.pageSize;
A
afc163 已提交
559
    return (total > 0) ?
B
Benjy Cui 已提交
560
      <Pagination {...this.state.pagination}
561 562 563 564 565
        className={classString}
        onChange={this.handlePageChange}
        total={total}
        pageSize={pageSize}
        onShowSizeChange={this.handleShowSizeChange} /> : null;
A
afc163 已提交
566
  },
A
afc163 已提交
567

Y
yiminghe 已提交
568
  prepareParamsArguments(state) {
569
    // 准备筛选、排序、分页的参数
570 571 572
    const pagination = state.pagination;
    const filters = state.filters;
    const sorter = {};
A
afc163 已提交
573 574 575 576
    if (state.sortColumn && state.sortOrder) {
      sorter.column = state.sortColumn;
      sorter.order = state.sortOrder;
      sorter.field = state.sortColumn.dataIndex;
A
afc163 已提交
577
      sorter.columnKey = this.getColumnKey(state.sortColumn);
A
afc163 已提交
578 579
    }
    return [pagination, filters, sorter];
580
  },
Y
yiminghe 已提交
581

A
afc163 已提交
582
  findColumn(myKey) {
A
afc163 已提交
583
    return this.props.columns.filter(c => this.getColumnKey(c) === myKey)[0];
Y
yiminghe 已提交
584 585
  },

A
afc163 已提交
586 587
  getCurrentPageData() {
    let data = this.getLocalData();
588 589
    let current;
    let pageSize;
Y
yiminghe 已提交
590 591 592 593 594
    let state = this.state;
    // 如果没有分页的话,默认全部展示
    if (!this.hasPagination()) {
      pageSize = Number.MAX_VALUE;
      current = 1;
595
    } else {
Y
yiminghe 已提交
596 597 598 599 600
      pageSize = state.pagination.pageSize;
      current = state.pagination.current;
    }
    // 分页
    // ---
A
afc163 已提交
601
    // 当数据量少于等于每页数量时,直接设置数据
Y
yiminghe 已提交
602 603 604
    // 否则进行读取分页数据
    if (data.length > pageSize || pageSize === Number.MAX_VALUE) {
      data = data.filter((item, i) => {
605
        return i >= (current - 1) * pageSize && i < current * pageSize;
Y
yiminghe 已提交
606 607 608 609 610
      });
    }
    return data;
  },

A
afc163 已提交
611 612 613 614 615
  getFlatCurrentPageData() {
    return flatArray(this.getCurrentPageData());
  },

  getLocalData() {
A
afc163 已提交
616
    const state = this.state;
A
afc163 已提交
617
    let data = this.props.dataSource || [];
Y
yiminghe 已提交
618
    // 排序
A
afc163 已提交
619 620 621
    data = data.slice(0);
    for (let i = 0; i < data.length; i++) {
      data[i].index = i;
Y
yiminghe 已提交
622
    }
A
afc163 已提交
623
    data = data.sort(this.getSorterFn());
Y
yiminghe 已提交
624 625 626 627
    // 筛选
    if (state.filters) {
      Object.keys(state.filters).forEach((columnKey) => {
        let col = this.findColumn(columnKey);
628 629 630
        if (!col) {
          return;
        }
Y
yiminghe 已提交
631
        let values = state.filters[columnKey] || [];
A
afc163 已提交
632 633 634
        if (values.length === 0) {
          return;
        }
A
afc163 已提交
635 636 637
        data = col.onFilter ? data.filter(record => {
          return values.some(v => col.onFilter(v, record));
        }) : data;
A
afc163 已提交
638
      });
A
afc163 已提交
639
    }
Y
yiminghe 已提交
640
    return data;
A
afc163 已提交
641
  },
Y
yiminghe 已提交
642 643

  render() {
A
afc163 已提交
644
    const data = this.getCurrentPageData();
Y
yiminghe 已提交
645
    let columns = this.renderRowSelection();
A
afc163 已提交
646
    const expandIconAsCell = this.props.expandedRowRender && this.props.expandIconAsCell !== false;
A
afc163 已提交
647
    const locale = this.getLocale();
A
afc163 已提交
648

A
afc163 已提交
649
    const classString = classNames({
A
afc163 已提交
650 651 652 653 654
      [`ant-table-${this.props.size}`]: true,
      'ant-table-bordered': this.props.bordered,
      [this.props.className]: !!this.props.className,
    });

Y
yiminghe 已提交
655
    columns = this.renderColumnsDropdown(columns);
A
afc163 已提交
656
    columns = columns.map((column, i) => {
B
Benjy Cui 已提交
657
      const newColumn = { ...column };
658 659
      newColumn.key = newColumn.key || newColumn.dataIndex || i;
      return newColumn;
A
afc163 已提交
660
    });
A
afc163 已提交
661
    let emptyText;
662
    let emptyClass = '';
A
afc163 已提交
663
    if (!data || data.length === 0) {
664 665
      emptyText = (
        <div className="ant-table-placeholder">
666
          <Icon type="frown" />{locale.emptyText}
667 668
        </div>
      );
669
      emptyClass = ' ant-table-empty';
A
afc163 已提交
670
    }
A
afc163 已提交
671

672 673
    let table = (
      <div>
674
        <RcTable {...this.props}
675 676 677
          data={data}
          columns={columns}
          className={classString}
A
afc163 已提交
678
          expandIconColumnIndex={(columns[0] && columns[0].key === 'selection-column') ? 1 : 0}
679
          expandIconAsCell={expandIconAsCell} />
680 681 682
          {emptyText}
      </div>
    );
A
afc163 已提交
683
    if (this.props.loading) {
684 685
      // if there is no pagination or no data,
      // the height of spin should decrease by half of pagination
A
afc163 已提交
686
      const paginationPatchClass = (this.hasPagination() && data && data.length !== 0)
K
KgTong 已提交
687 688
              ? 'ant-table-with-pagination'
              : 'ant-table-without-pagination';
A
afc163 已提交
689
      const spinClassName = `${paginationPatchClass} ant-table-spin-holder`;
690
      table = <Spin className={spinClassName}>{table}</Spin>;
A
afc163 已提交
691
    }
692
    return (
693
      <div className={`clearfix${emptyClass}`}>
694 695 696 697
        {table}
        {this.renderPagination()}
      </div>
    );
A
afc163 已提交
698 699
  }
});
700

701
export default Table;