index.jsx 8.7 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 38
    // 支持两种模式
    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 已提交
39
    return {
A
afc163 已提交
40 41
      selectedRowKeys: [],
      loading: false,
42 43
      selectedFilters: [],
      pagination: pagination,
A
afc163 已提交
44
      data: []
A
afc163 已提交
45 46
    };
  },
A
afc163 已提交
47 48
  getDefaultProps() {
    return {
A
afc163 已提交
49
      prefixCls: 'ant-table',
A
afc163 已提交
50
      useFixedHeader: false,
A
afc163 已提交
51 52
      rowSelection: null,
      size: 'normal'
A
afc163 已提交
53 54
    };
  },
A
afc163 已提交
55 56
  renderMenus(items) {
    let menuItems = items.map((item) => {
A
afc163 已提交
57
      return <Menu.Item key={item.value}>{item.text}</Menu.Item>;
A
afc163 已提交
58 59 60 61 62 63 64 65 66
    });
    return menuItems;
  },
  toggleSortOrder(order, column) {
    if (column.sortOrder === order) {
      column.sortOrder = '';
    } else {
      column.sortOrder = order;
    }
67 68 69 70 71 72 73 74 75 76 77 78 79 80
    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 已提交
81
    }
82
    this.fetch();
A
afc163 已提交
83
  },
A
afc163 已提交
84
  handleFilter(column) {
85 86 87 88 89 90 91 92 93 94
    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 已提交
95 96
  },
  handleSelectFilter(column, selected) {
97 98
    column.selectedFilters = column.selectedFilters || [];
    column.selectedFilters.push(selected);
A
afc163 已提交
99
  },
A
afc163 已提交
100
  handleDeselectFilter(column, key) {
101 102
    column.selectedFilters = column.selectedFilters || [];
    var index = column.selectedFilters.indexOf(key);
A
afc163 已提交
103
    if (index !== -1) {
104 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
      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 已提交
134
    }
A
afc163 已提交
135
  },
136
  handlePageChange: function(current) {
A
afc163 已提交
137 138
    console.log(current);
    current = current || 1;
139 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 168 169 170 171 172 173 174 175
    let pageSize = this.state.pagination.pageSize;
    this.setState({
      data: this.props.dataSource.filter(function(item, i) {
        if (i >= (current - 1) * pageSize &&
            i < current * pageSize) {
          return item;
        }
      })
    });
  },
  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 已提交
176
  renderColumnsDropdown() {
177
    return this.props.columns.map((column) => {
A
afc163 已提交
178 179 180 181
      if (!column.originTitle) {
        column.originTitle = column.title;
      }
      let filterDropdown, menus, sortButton;
182
      if (column.filters && column.filters.length > 0) {
A
afc163 已提交
183 184 185 186
        menus = <Menu multiple={true}
          className="ant-table-filter-dropdown"
          onSelect={this.handleSelectFilter.bind(this, column)}
          onDeselect={this.handleDeselectFilter.bind(this, column)}>
187
          {this.renderMenus(column.filters)}
A
afc163 已提交
188 189 190 191 192 193 194 195 196 197
          <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 已提交
198
        </Menu>;
A
afc163 已提交
199
        let dropdownSelectedClass = '';
200
        if (column.selectedFilters && column.selectedFilters.length > 0) {
A
afc163 已提交
201 202 203 204 205 206
          dropdownSelectedClass = 'ant-table-filter-selected';
        }
        filterDropdown = <Dropdown trigger="click"
          closeOnSelect={false}
          overlay={menus}>
          <i title="筛选" className={'anticon anticon-bars ' + dropdownSelectedClass}></i>
A
afc163 已提交
207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229
        </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 已提交
230
      return column;
A
afc163 已提交
231 232
    });
  },
233 234 235 236
  renderPagination() {
    // 强制不需要分页
    if (this.state.pagination === false) {
      return '';
A
afc163 已提交
237
    }
238 239 240
    return <Pagination className="ant-table-pagination"
      onChange={this.handlePageChange}
      {...this.state.pagination} />;
A
afc163 已提交
241
  },
242 243 244
  fetch: function() {
    let dataSource = this.props.dataSource;
    if (this.mode === 'remote') {
A
afc163 已提交
245 246 247 248
      this.setState({
        loading: true
      });
      jQuery.ajax({
249 250
        url: dataSource.url,
        params: dataSource.getParams(),
A
afc163 已提交
251 252 253
        success: (result) => {
          if (this.isMounted()) {
            this.setState({
254 255
              data: dataSource.resolve.call(this, result),
              pagination: dataSource.getPagination.call(this, result)
A
afc163 已提交
256 257 258 259 260 261 262 263 264
            });
          }
        },
        complete: () => {
          this.setState({
            loading: false
          });
        }
      });
265 266
    } else {
      this.handlePageChange(this.state.pagination.current);
A
afc163 已提交
267 268 269
    }
  },
  componentDidMount() {
A
afc163 已提交
270
    this.fetch();
A
afc163 已提交
271
  },
A
afc163 已提交
272
  render() {
273 274
    this.props.columns = this.renderRowSelection();

A
afc163 已提交
275 276 277 278 279 280 281
    var classString = '';
    if (this.props.loading) {
      classString += ' ant-table-loading';
    }
    if (this.props.size === 'small') {
      classString += ' ant-table-small';
    }
282 283 284 285

    return <div className="clearfix">
      <Table data={this.state.data}
      columns={this.renderColumnsDropdown()}
A
afc163 已提交
286
      className={classString}
287 288 289
      {...this.props} />
      {this.renderPagination()}
    </div>;
A
afc163 已提交
290 291 292 293
  }
});

export default AntTable;