index.jsx 9.0 KB
Newer Older
A
afc163 已提交
1 2
'use strict';

A
afc163 已提交
3
import React from 'react';
A
afc163 已提交
4
import jQuery from 'jquery';
A
afc163 已提交
5
import Table from 'rc-table';
A
afc163 已提交
6 7
import Menu from 'rc-menu';
import Dropdown from '../dropdown';
8
import Pagination from '../pagination';
A
afc163 已提交
9 10

let AntTable = React.createClass({
A
afc163 已提交
11
  getInitialState() {
12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
    // 支持两种模式
    if (Array.isArray(this.props.dataSource)) {
      this.mode = 'local';
      // 保留原来的数据
      this.originDataSource = this.props.dataSource.slice(0);
    } else {
      this.mode = 'remote';
      this.props.dataSource.resolve =
        this.props.dataSource.resolve || function(data) {
          return data || [];
        };
      this.props.dataSource.getParams =
        this.props.dataSource.getParams || function() {
          return {};
        };
      this.props.dataSource.getPagination =
        this.props.dataSource.getPagination || function() {
          return {};
        };
    }
    var pagination;
    if (this.props.pagination === false) {
      pagination = false;
    } else {
      pagination = this.props.pagination || {};
      pagination.pageSize = pagination.pageSize || 10;
A
afc163 已提交
38
      pagination.total = this.props.dataSource.length || 10;
39
    }
A
afc163 已提交
40
    return {
A
afc163 已提交
41 42
      selectedRowKeys: [],
      loading: false,
43 44
      selectedFilters: [],
      pagination: pagination,
A
afc163 已提交
45
      data: []
A
afc163 已提交
46 47
    };
  },
A
afc163 已提交
48 49
  getDefaultProps() {
    return {
A
afc163 已提交
50
      prefixCls: 'ant-table',
A
afc163 已提交
51
      useFixedHeader: false,
A
afc163 已提交
52 53
      rowSelection: null,
      size: 'normal'
A
afc163 已提交
54 55
    };
  },
A
afc163 已提交
56 57
  renderMenus(items) {
    let menuItems = items.map((item) => {
A
afc163 已提交
58
      return <Menu.Item key={item.value}>{item.text}</Menu.Item>;
A
afc163 已提交
59 60 61 62 63 64 65 66 67
    });
    return menuItems;
  },
  toggleSortOrder(order, column) {
    if (column.sortOrder === order) {
      column.sortOrder = '';
    } else {
      column.sortOrder = order;
    }
68 69 70 71 72 73 74 75 76 77 78 79 80 81
    if (this.mode === 'local') {
      let sorter = function() {
        let result = column.sorter.apply(this, arguments);
        if (column.sortOrder === 'ascend') {
          return result;
        } else if (column.sortOrder === 'descend') {
          return -result;
        }
      };
      if (column.sortOrder) {
        this.props.dataSource = this.props.dataSource.sort(sorter);
      } else {
        this.props.dataSource = this.originDataSource.slice();
      }
A
afc163 已提交
82
    }
83
    this.fetch();
A
afc163 已提交
84
  },
A
afc163 已提交
85
  handleFilter(column) {
86 87 88 89 90 91 92 93 94 95
    this.props.dataSource = this.originDataSource.slice().filter(function(record) {
      if (column.selectedFilters.length === 0) {
        return true;
      }
      return column.selectedFilters.some(function(value) {
        var result = column.onFilter.call(this, value, record);
        return result;
      });
    });
    this.fetch();
A
afc163 已提交
96 97
  },
  handleSelectFilter(column, selected) {
98 99
    column.selectedFilters = column.selectedFilters || [];
    column.selectedFilters.push(selected);
A
afc163 已提交
100
  },
A
afc163 已提交
101
  handleDeselectFilter(column, key) {
102 103
    column.selectedFilters = column.selectedFilters || [];
    var index = column.selectedFilters.indexOf(key);
A
afc163 已提交
104
    if (index !== -1) {
105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134
      column.selectedFilters.splice(index, 1);
    }
  },
  handleSelect(e) {
    let checked = e.currentTarget.checked;
    let currentRowIndex = e.currentTarget.parentElement.parentElement.rowIndex;
    let selectedRow = this.state.data[currentRowIndex - 1];
    if (checked) {
      this.state.selectedRowKeys.push(currentRowIndex);
    } else {
      this.state.selectedRowKeys = this.state.selectedRowKeys.filter(function(i){
        return currentRowIndex !== i;
      });
    }
    this.setState({
      selectedRowKeys: this.state.selectedRowKeys
    });
    if (this.props.rowSelection.onSelect) {
      this.props.rowSelection.onSelect(selectedRow, checked);
    }
  },
  handleSelectAllRow(e) {
    let checked = e.currentTarget.checked;
    this.setState({
      selectedRowKeys: checked ? this.state.data.map(function(item, i) {
        return i + 1;
      }) : []
    });
    if (this.props.rowSelection.onSelectAll) {
      this.props.rowSelection.onSelectAll(checked);
A
afc163 已提交
135
    }
A
afc163 已提交
136
  },
137
  handlePageChange: function(current) {
A
afc163 已提交
138 139
    this.state.pagination.current = current || 1;
    this.fetch();
140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167
  },
  renderSelectionCheckBox(value, record, index) {
    let checked = this.state.selectedRowKeys.indexOf(index + 1) >= 0;
    let checkbox = <input type="checkbox" checked={checked} onChange={this.handleSelect} />;
    return checkbox;
  },
  renderRowSelection() {
    var columns = this.props.columns;
    if (this.props.rowSelection) {
      let checked = this.state.data.every(function(item, i) {
        return this.state.selectedRowKeys.indexOf(i + 1) >= 0;
      }, this);
      let checkboxAll = <input type="checkbox" checked={checked} onChange={this.handleSelectAllRow} />;
      let selectionColumn = {
        key: 'selection-column',
        title: checkboxAll,
        width: 60,
        render: this.renderSelectionCheckBox
      };
      if (columns[0] &&
          columns[0].key === 'selection-column') {
        columns[0] = selectionColumn;
      } else {
        columns.unshift(selectionColumn);
      }
    }
    return columns;
  },
A
afc163 已提交
168
  renderColumnsDropdown() {
169
    return this.props.columns.map((column) => {
A
afc163 已提交
170 171 172 173
      if (!column.originTitle) {
        column.originTitle = column.title;
      }
      let filterDropdown, menus, sortButton;
174
      if (column.filters && column.filters.length > 0) {
A
afc163 已提交
175 176 177 178
        menus = <Menu multiple={true}
          className="ant-table-filter-dropdown"
          onSelect={this.handleSelectFilter.bind(this, column)}
          onDeselect={this.handleDeselectFilter.bind(this, column)}>
179
          {this.renderMenus(column.filters)}
A
afc163 已提交
180 181 182 183 184 185 186 187 188 189
          <Menu.Item disabled>
            <button style={{
                cursor: 'pointer',
                pointerEvents: 'visible'
              }}
              className="ant-btn ant-btn-primary ant-btn-sm"
              onClick={this.handleFilter.bind(this, column)}>
              确 定
            </button>
          </Menu.Item>
A
afc163 已提交
190
        </Menu>;
A
afc163 已提交
191
        let dropdownSelectedClass = '';
192
        if (column.selectedFilters && column.selectedFilters.length > 0) {
A
afc163 已提交
193 194 195 196 197 198
          dropdownSelectedClass = 'ant-table-filter-selected';
        }
        filterDropdown = <Dropdown trigger="click"
          closeOnSelect={false}
          overlay={menus}>
          <i title="筛选" className={'anticon anticon-bars ' + dropdownSelectedClass}></i>
A
afc163 已提交
199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221
        </Dropdown>;
      }
      if (column.sorter) {
        sortButton = <div className="ant-table-column-sorter">
          <span className={'ant-table-column-sorter-up ' +
                           (column.sortOrder === 'ascend' ? 'on' : 'off')}
            title="升序排序"
            onClick={this.toggleSortOrder.bind(this, 'ascend', column)}>
            <i className="anticon anticon-caret-up"></i>
          </span>
          <span className={'ant-table-column-sorter-down ' +
                           (column.sortOrder === 'descend' ? 'on' : 'off')}
            title="降序排序"
            onClick={this.toggleSortOrder.bind(this, 'descend', column)}>
            <i className="anticon anticon-caret-down"></i>
          </span>
        </div>;
      }
      column.title = [
        column.originTitle,
        sortButton,
        filterDropdown
      ];
A
afc163 已提交
222
      return column;
A
afc163 已提交
223 224
    });
  },
225 226 227 228
  renderPagination() {
    // 强制不需要分页
    if (this.state.pagination === false) {
      return '';
A
afc163 已提交
229
    }
230 231 232
    return <Pagination className="ant-table-pagination"
      onChange={this.handlePageChange}
      {...this.state.pagination} />;
A
afc163 已提交
233
  },
234 235 236
  fetch: function() {
    let dataSource = this.props.dataSource;
    if (this.mode === 'remote') {
A
afc163 已提交
237 238 239 240
      this.setState({
        loading: true
      });
      jQuery.ajax({
241 242
        url: dataSource.url,
        params: dataSource.getParams(),
A
afc163 已提交
243 244
        success: (result) => {
          if (this.isMounted()) {
A
afc163 已提交
245 246 247 248
            let pagination = jQuery.extend(
              this.state.pagination,
              dataSource.getPagination.call(this, result)
            );
A
afc163 已提交
249
            this.setState({
250
              data: dataSource.resolve.call(this, result),
A
afc163 已提交
251 252
              pagination: pagination,
              loading: false
A
afc163 已提交
253 254 255
            });
          }
        },
A
afc163 已提交
256
        error: () => {
A
afc163 已提交
257 258 259 260 261
          this.setState({
            loading: false
          });
        }
      });
262
    } else {
A
afc163 已提交
263 264 265 266 267 268 269 270 271 272 273
      let pageSize = this.state.pagination.pageSize;
      let current = this.state.pagination.current;
      this.setState({
        data: this.props.dataSource.filter(function(item, i) {
          if (i >= (current - 1) * pageSize &&
              i < current * pageSize) {
            return item;
          }
        }),
        pagination: this.state.pagination
      });
A
afc163 已提交
274 275 276
    }
  },
  componentDidMount() {
A
afc163 已提交
277
    this.handlePageChange();
A
afc163 已提交
278
  },
A
afc163 已提交
279
  render() {
280 281
    this.props.columns = this.renderRowSelection();

A
afc163 已提交
282 283 284 285 286 287 288
    var classString = '';
    if (this.props.loading) {
      classString += ' ant-table-loading';
    }
    if (this.props.size === 'small') {
      classString += ' ant-table-small';
    }
289 290 291 292

    return <div className="clearfix">
      <Table data={this.state.data}
      columns={this.renderColumnsDropdown()}
A
afc163 已提交
293
      className={classString}
294 295 296
      {...this.props} />
      {this.renderPagination()}
    </div>;
A
afc163 已提交
297 298 299 300
  }
});

export default AntTable;