mirror of
https://gitee.com/ant-design/ant-design.git
synced 2024-12-01 11:39:28 +08:00
Table 列选择模式重构
+ 表格 `rowSelection` 支持多选 + 表格可配置某行数据默认选中、不能选中。该配置对 ajax 载入的数据有效。 示例: ``` getCheckboxProps: function (value) { return { defaultValue: value.name === '胡彦祖ajax2', // 配置默认勾选的列 disabled: value.name === '李大嘴ajax3' // 配置无法勾选的列 } }, ```
This commit is contained in:
parent
c98c3eef57
commit
2c1fda70d6
117
components/table/demo/ajax-props.md
Normal file
117
components/table/demo/ajax-props.md
Normal file
@ -0,0 +1,117 @@
|
||||
# 配置动态加载数据
|
||||
|
||||
- order: 7
|
||||
|
||||
远程读取的表格是**更为常见的模式**,下面的表格使用了 `dataSource` 对象和远程数据源绑定和适配,并具有筛选、排序等功能以及页面 loading 效果。
|
||||
|
||||
**注意,此示例是静态数据模拟,数据并不准确,请打开网络面板查看请求。**
|
||||
|
||||
---
|
||||
|
||||
````jsx
|
||||
var Table = antd.Table;
|
||||
|
||||
var columns = [{
|
||||
title: '姓名',
|
||||
dataIndex: 'name',
|
||||
filters: [{
|
||||
text: '姓李的',
|
||||
value: '李'
|
||||
}, {
|
||||
text: '姓胡的',
|
||||
value: '胡'
|
||||
}]
|
||||
}, {
|
||||
title: '年龄',
|
||||
dataIndex: 'age',
|
||||
sorter: true
|
||||
}, {
|
||||
title: '住址',
|
||||
dataIndex: 'address'
|
||||
}];
|
||||
|
||||
var dataSource = new Table.DataSource({
|
||||
url: "/components/table/demo/data.json",
|
||||
resolve: function(result) {
|
||||
return result.data;
|
||||
},
|
||||
data: {},
|
||||
// 和后台接口返回的分页数据进行适配
|
||||
getPagination: function(result) {
|
||||
return {
|
||||
total: result.totalCount,
|
||||
pageSize: result.pageSize
|
||||
}
|
||||
},
|
||||
// 和后台接口接收的参数进行适配
|
||||
// 参数里提供了分页、筛选、排序的信息
|
||||
getParams: function(pagination, filters, sorter) {
|
||||
console.log('getParams 的参数是:', pagination, filters, sorter);
|
||||
var params = {
|
||||
pageSize: pagination.pageSize,
|
||||
currentPage: pagination.current,
|
||||
sortField: sorter.field,
|
||||
sortOrder: sorter.order
|
||||
};
|
||||
for (var key in filters) {
|
||||
params[key] = filters[key];
|
||||
}
|
||||
console.log('请求参数:', params);
|
||||
return params;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
var rowSelection = {
|
||||
getCheckboxProps: function (value) {
|
||||
return {
|
||||
defaultValue: value.name === '胡彦祖ajax2', // 配置默认勾选的列
|
||||
disabled: value.name === '李大嘴ajax3' // 配置无法勾选的列
|
||||
}
|
||||
},
|
||||
onSelect: function(record, selected, selectedRows) {
|
||||
console.log(record, selected, selectedRows);
|
||||
},
|
||||
onSelectAll: function(selected, selectedRows) {
|
||||
console.log(selected, selectedRows);
|
||||
}
|
||||
};
|
||||
|
||||
var Test = React.createClass({
|
||||
getInitialState() {
|
||||
return {
|
||||
dataSource: dataSource
|
||||
};
|
||||
},
|
||||
refresh() {
|
||||
this.setState({
|
||||
dataSource: dataSource.clone()
|
||||
});
|
||||
},
|
||||
changeAndRefresh() {
|
||||
// 可以修改原来的 dataSource 再发请求
|
||||
this.setState({
|
||||
dataSource: dataSource.clone({
|
||||
data: {
|
||||
city: 'hz'
|
||||
}
|
||||
})
|
||||
});
|
||||
},
|
||||
render() {
|
||||
return <div>
|
||||
<Table rowSelection={rowSelection} columns={columns} dataSource={this.state.dataSource} />
|
||||
<button className="ant-btn ant-btn-primary" onClick={this.refresh}>
|
||||
重新加载数据
|
||||
</button>
|
||||
|
||||
<button className="ant-btn" onClick={this.changeAndRefresh}>
|
||||
加载 city=hz 的数据
|
||||
</button>
|
||||
</div>;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
React.render(<Test />, document.getElementById('components-table-demo-ajax-props'));
|
||||
````
|
@ -1,6 +1,6 @@
|
||||
# 动态加载数据
|
||||
|
||||
- order: 4
|
||||
- order: 7
|
||||
|
||||
远程读取的表格是**更为常见的模式**,下面的表格使用了 `dataSource` 对象和远程数据源绑定和适配,并具有筛选、排序等功能以及页面 loading 效果。
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
# 边框
|
||||
|
||||
- order: 7
|
||||
- order: 10
|
||||
|
||||
添加表格边框线,`bordered={true}`。
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
# 可展开
|
||||
|
||||
- order: 9
|
||||
- order: 12
|
||||
|
||||
当表格内容较多不能一次性完全展示时。
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
# 筛选和排序
|
||||
|
||||
- order: 3
|
||||
- order: 6
|
||||
|
||||
对某一列数据进行筛选,使用列的 `filter` 属性来指定筛选的列表。
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
# 外界控制数据
|
||||
|
||||
- order: 8
|
||||
- order: 11
|
||||
|
||||
由父元素控制自身数据展示。
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
# 不显示分页
|
||||
|
||||
- order: 5
|
||||
- order: 8
|
||||
|
||||
传入 pagination 为 false 即可。
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
# 分页
|
||||
|
||||
- order: 2
|
||||
- order: 5
|
||||
|
||||
数据项较多时显示分页。
|
||||
|
||||
|
59
components/table/demo/row-selection-props.md
Normal file
59
components/table/demo/row-selection-props.md
Normal file
@ -0,0 +1,59 @@
|
||||
# 配置
|
||||
|
||||
- order: 2
|
||||
|
||||
配置选择框的默认属性。
|
||||
|
||||
---
|
||||
|
||||
````jsx
|
||||
var Table = antd.Table;
|
||||
var columns = [{
|
||||
title: '姓名',
|
||||
dataIndex: 'name',
|
||||
render: function(text) {
|
||||
return <a href="javascript:;">{text}</a>;
|
||||
}
|
||||
}, {
|
||||
title: '年龄',
|
||||
dataIndex: 'age'
|
||||
}, {
|
||||
title: '住址',
|
||||
dataIndex: 'address'
|
||||
}];
|
||||
var data = [{
|
||||
key: '1',
|
||||
name: '胡彦斌',
|
||||
age: 32,
|
||||
address: '西湖区湖底公园1号'
|
||||
}, {
|
||||
key: '2',
|
||||
name: '胡彦祖',
|
||||
age: 42,
|
||||
address: '西湖区湖底公园1号'
|
||||
}, {
|
||||
key: '3',
|
||||
name: '李大嘴',
|
||||
age: 32,
|
||||
address: '西湖区湖底公园1号'
|
||||
}];
|
||||
|
||||
// 通过 rowSelection 对象表明需要行选择
|
||||
var rowSelection = {
|
||||
getCheckboxProps: function (value) {
|
||||
return {
|
||||
defaultValue: value.name === '李大嘴', // 配置默认勾选的列
|
||||
disabled: value.name === '胡彦祖' // 配置无法勾选的列
|
||||
}
|
||||
},
|
||||
onSelect: function(record, selected, selectedRows) {
|
||||
console.log(record, selected, selectedRows);
|
||||
},
|
||||
onSelectAll: function(selected, selectedRows) {
|
||||
console.log(selected, selectedRows);
|
||||
}
|
||||
};
|
||||
|
||||
React.render(<Table rowSelection={rowSelection} columns={columns} dataSource={data} />
|
||||
, document.getElementById('components-table-demo-row-selection-props'));
|
||||
````
|
60
components/table/demo/row-selection-radio-props.md
Normal file
60
components/table/demo/row-selection-radio-props.md
Normal file
@ -0,0 +1,60 @@
|
||||
# 单选配置
|
||||
|
||||
- order: 4
|
||||
|
||||
配置单选框的默认属性。
|
||||
|
||||
---
|
||||
|
||||
````jsx
|
||||
var Table = antd.Table;
|
||||
var columns = [{
|
||||
title: '姓名',
|
||||
dataIndex: 'name',
|
||||
render: function(text) {
|
||||
return <a href="javascript:;">{text}</a>;
|
||||
}
|
||||
}, {
|
||||
title: '年龄',
|
||||
dataIndex: 'age'
|
||||
}, {
|
||||
title: '住址',
|
||||
dataIndex: 'address'
|
||||
}];
|
||||
var data = [{
|
||||
key: '1',
|
||||
name: '胡彦斌',
|
||||
age: 32,
|
||||
address: '西湖区湖底公园1号'
|
||||
}, {
|
||||
key: '2',
|
||||
name: '胡彦祖',
|
||||
age: 42,
|
||||
address: '西湖区湖底公园1号'
|
||||
}, {
|
||||
key: '3',
|
||||
name: '李大嘴',
|
||||
age: 32,
|
||||
address: '西湖区湖底公园1号'
|
||||
}];
|
||||
|
||||
// 通过 rowSelection 对象表明需要行选择
|
||||
var rowSelection = {
|
||||
type: 'radio',
|
||||
getCheckboxProps: function (value) {
|
||||
return {
|
||||
defaultValue: value.name === '李大嘴', // 配置默认勾选的列
|
||||
disabled: value.name === '胡彦祖' // 配置无法勾选的列
|
||||
}
|
||||
},
|
||||
onSelect: function(record, selected, selectedRows) {
|
||||
console.log(record, selected, selectedRows);
|
||||
},
|
||||
onSelectAll: function(selected, selectedRows) {
|
||||
console.log(selected, selectedRows);
|
||||
}
|
||||
};
|
||||
|
||||
React.render(<Table rowSelection={rowSelection} columns={columns} dataSource={data} />
|
||||
, document.getElementById('components-table-demo-row-selection-radio-props'));
|
||||
````
|
54
components/table/demo/row-selection-radio.md
Normal file
54
components/table/demo/row-selection-radio.md
Normal file
@ -0,0 +1,54 @@
|
||||
# 单选
|
||||
|
||||
- order: 3
|
||||
|
||||
第一列是联动的单选框。
|
||||
|
||||
---
|
||||
|
||||
````jsx
|
||||
var Table = antd.Table;
|
||||
var columns = [{
|
||||
title: '姓名',
|
||||
dataIndex: 'name',
|
||||
render: function(text) {
|
||||
return <a href="javascript:;">{text}</a>;
|
||||
}
|
||||
}, {
|
||||
title: '年龄',
|
||||
dataIndex: 'age'
|
||||
}, {
|
||||
title: '住址',
|
||||
dataIndex: 'address'
|
||||
}];
|
||||
var data = [{
|
||||
key: '1',
|
||||
name: '胡彦斌',
|
||||
age: 32,
|
||||
address: '西湖区湖底公园1号'
|
||||
}, {
|
||||
key: '2',
|
||||
name: '胡彦祖',
|
||||
age: 42,
|
||||
address: '西湖区湖底公园1号'
|
||||
}, {
|
||||
key: '3',
|
||||
name: '李大嘴',
|
||||
age: 32,
|
||||
address: '西湖区湖底公园1号'
|
||||
}];
|
||||
|
||||
// 通过 rowSelection 对象表明需要行选择
|
||||
var rowSelection = {
|
||||
type: 'radio',
|
||||
onSelect: function(record, selected, selectedRows) {
|
||||
console.log(record, selected, selectedRows);
|
||||
},
|
||||
onSelectAll: function(selected, selectedRows) {
|
||||
console.log(selected, selectedRows);
|
||||
}
|
||||
};
|
||||
|
||||
React.render(<Table rowSelection={rowSelection} columns={columns} dataSource={data} />
|
||||
, document.getElementById('components-table-demo-row-selection-radio'));
|
||||
````
|
@ -1,6 +1,6 @@
|
||||
# 小型列表
|
||||
|
||||
- order: 6
|
||||
- order: 9
|
||||
|
||||
`size="small"`, 用在对话框等空间较小的地方。
|
||||
|
||||
|
@ -2,6 +2,7 @@ import React from 'react';
|
||||
import reqwest from 'reqwest-without-xhr2';
|
||||
import Table from 'rc-table';
|
||||
import Checkbox from '../checkbox';
|
||||
import Radio from '../radio';
|
||||
import FilterDropdown from './filterDropdown';
|
||||
import Pagination from '../pagination';
|
||||
import objectAssign from 'object-assign';
|
||||
@ -44,10 +45,12 @@ let AntTable = React.createClass({
|
||||
data: [],
|
||||
dataSource: this.props.dataSource,
|
||||
filters: {},
|
||||
dirty: false,
|
||||
loading: false,
|
||||
sortColumn: '',
|
||||
sortOrder: '',
|
||||
sorter: null,
|
||||
radioIndex: null,
|
||||
pagination: this.hasPagination() ? objectAssign({
|
||||
pageSize: 10,
|
||||
current: 1
|
||||
@ -69,6 +72,22 @@ let AntTable = React.createClass({
|
||||
dataSource: React.PropTypes.oneOfType([React.PropTypes.array, React.PropTypes.instanceOf(DataSource)])
|
||||
},
|
||||
|
||||
getDefaultSelection() {
|
||||
let selectedRowKeys = [];
|
||||
if (this.props.rowSelection && this.props.rowSelection.getCheckboxProps) {
|
||||
let data = this.getCurrentPageData();
|
||||
data.filter((item) => {
|
||||
if (this.props.rowSelection.getCheckboxProps) {
|
||||
return this.props.rowSelection.getCheckboxProps(item).defaultValue;
|
||||
}
|
||||
return true;
|
||||
}).map((record, rowIndex) => {
|
||||
selectedRowKeys.push(this.getRecordKey(record, rowIndex));
|
||||
});
|
||||
}
|
||||
return selectedRowKeys;
|
||||
},
|
||||
|
||||
componentWillReceiveProps(nextProps) {
|
||||
if (('pagination' in nextProps) && nextProps.pagination !== false) {
|
||||
this.setState({
|
||||
@ -152,7 +171,11 @@ let AntTable = React.createClass({
|
||||
|
||||
handleSelect(record, rowIndex, e) {
|
||||
let checked = e.target.checked;
|
||||
let selectedRowKeys = this.state.selectedRowKeys.concat();
|
||||
let defaultSelection = [];
|
||||
if (!this.state.dirty) {
|
||||
defaultSelection = this.getDefaultSelection();
|
||||
}
|
||||
let selectedRowKeys = this.state.selectedRowKeys.concat(defaultSelection);
|
||||
let key = this.getRecordKey(record, rowIndex);
|
||||
if (checked) {
|
||||
selectedRowKeys.push(this.getRecordKey(record, rowIndex));
|
||||
@ -162,7 +185,31 @@ let AntTable = React.createClass({
|
||||
});
|
||||
}
|
||||
this.setState({
|
||||
selectedRowKeys: selectedRowKeys
|
||||
selectedRowKeys: selectedRowKeys,
|
||||
dirty: true
|
||||
});
|
||||
if (this.props.rowSelection.onSelect) {
|
||||
let data = this.getCurrentPageData();
|
||||
let selectedRows = data.filter((row, i) => {
|
||||
return selectedRowKeys.indexOf(this.getRecordKey(row, i)) >= 0;
|
||||
});
|
||||
this.props.rowSelection.onSelect(record, checked, selectedRows);
|
||||
}
|
||||
},
|
||||
|
||||
handleRadioSelect: function (record, rowIndex, e) {
|
||||
let checked = e.target.checked;
|
||||
let defaultSelection = [];
|
||||
if (!this.state.dirty) {
|
||||
defaultSelection = this.getDefaultSelection();
|
||||
}
|
||||
let selectedRowKeys = this.state.selectedRowKeys.concat(defaultSelection);
|
||||
let key = this.getRecordKey(record, rowIndex);
|
||||
selectedRowKeys = [key];
|
||||
this.setState({
|
||||
selectedRowKeys: selectedRowKeys,
|
||||
radioIndex: record.key,
|
||||
dirty: true
|
||||
});
|
||||
if (this.props.rowSelection.onSelect) {
|
||||
let data = this.getCurrentPageData();
|
||||
@ -176,11 +223,17 @@ let AntTable = React.createClass({
|
||||
handleSelectAllRow(e) {
|
||||
let checked = e.target.checked;
|
||||
let data = this.getCurrentPageData();
|
||||
let selectedRowKeys = checked ? data.map((item, i) => {
|
||||
let selectedRowKeys = checked ? data.filter((item) => {
|
||||
if (this.props.rowSelection.getCheckboxProps) {
|
||||
return !this.props.rowSelection.getCheckboxProps(item).disabled;
|
||||
}
|
||||
return true;
|
||||
}).map((item, i) => {
|
||||
return this.getRecordKey(item, i);
|
||||
}) : [];
|
||||
this.setState({
|
||||
selectedRowKeys: selectedRowKeys
|
||||
selectedRowKeys: selectedRowKeys,
|
||||
dirty: true
|
||||
});
|
||||
if (this.props.rowSelection.onSelectAll) {
|
||||
let selectedRows = data.filter((row, i) => {
|
||||
@ -204,10 +257,30 @@ let AntTable = React.createClass({
|
||||
});
|
||||
},
|
||||
|
||||
onRadioChange: function (ev) {
|
||||
this.setState({
|
||||
radioIndex: ev.target.value
|
||||
});
|
||||
},
|
||||
|
||||
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);
|
||||
}
|
||||
const checked = this.state.dirty ? this.state.radioIndex === record.key : this.getDefaultSelection().indexOf(rowIndex) >= 0;
|
||||
return <Radio disabled={props.disabled} onChange={this.handleRadioSelect.bind(this, record, rowIndex)} value={record.key} checked={checked} />;
|
||||
},
|
||||
|
||||
renderSelectionCheckBox(value, record, index) {
|
||||
let rowIndex = this.getRecordKey(record, index); // 从 1 开始
|
||||
let checked = this.state.selectedRowKeys.indexOf(rowIndex) >= 0;
|
||||
return <Checkbox checked={checked} onChange={this.handleSelect.bind(this, record, rowIndex)}/>;
|
||||
let checked = this.state.dirty ? this.state.selectedRowKeys.indexOf(rowIndex) >= 0 : this.getDefaultSelection().indexOf(rowIndex) >= 0;
|
||||
let props = {};
|
||||
if (this.props.rowSelection.getCheckboxProps) {
|
||||
props = this.props.rowSelection.getCheckboxProps.call(this, record);
|
||||
}
|
||||
return <Checkbox checked={checked} disabled={props.disabled} onChange={this.handleSelect.bind(this, record, rowIndex)}/>;
|
||||
},
|
||||
|
||||
getRecordKey(record, index) {
|
||||
@ -222,19 +295,34 @@ let AntTable = React.createClass({
|
||||
if (!data.length) {
|
||||
checked = false;
|
||||
} else {
|
||||
checked = data.every((item, i) => {
|
||||
checked = data.filter((item) => {
|
||||
if (this.props.rowSelection.getCheckboxProps) {
|
||||
return !this.props.rowSelection.getCheckboxProps(item).disabled;
|
||||
}
|
||||
return true;
|
||||
}).every((item, i) => {
|
||||
let key = this.getRecordKey(item, i);
|
||||
return this.state.selectedRowKeys.indexOf(key) >= 0;
|
||||
});
|
||||
}
|
||||
let checkboxAll = <Checkbox checked={checked} onChange={this.handleSelectAllRow}/>;
|
||||
let selectionColumn = {
|
||||
key: 'selection-column',
|
||||
title: checkboxAll,
|
||||
width: 60,
|
||||
render: this.renderSelectionCheckBox,
|
||||
className: 'ant-table-selection-column'
|
||||
};
|
||||
let selectionColumn;
|
||||
if (this.props.rowSelection.type === 'radio') {
|
||||
selectionColumn = {
|
||||
key: 'selection-column',
|
||||
width: 60,
|
||||
render: this.renderSelectionRadio,
|
||||
className: 'ant-table-selection-column'
|
||||
};
|
||||
} else {
|
||||
let checkboxAll = <Checkbox checked={checked} onChange={this.handleSelectAllRow}/>;
|
||||
selectionColumn = {
|
||||
key: 'selection-column',
|
||||
title: checkboxAll,
|
||||
width: 60,
|
||||
render: this.renderSelectionCheckBox,
|
||||
className: 'ant-table-selection-column'
|
||||
};
|
||||
}
|
||||
if (columns[0] &&
|
||||
columns[0].key === 'selection-column') {
|
||||
columns[0] = selectionColumn;
|
||||
@ -383,6 +471,7 @@ let AntTable = React.createClass({
|
||||
dataSource.getPagination.call(this, result)
|
||||
);
|
||||
this.setState({
|
||||
dirty: false,
|
||||
loading: false,
|
||||
data: dataSource.resolve.call(this, result),
|
||||
pagination: pagination
|
||||
|
@ -32,6 +32,7 @@
|
||||
],
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"react": "~0.13.3",
|
||||
"css-animation": "~1.1.0",
|
||||
"enter-animation": "~0.5.0",
|
||||
"gregorian-calendar": "~3.0.0",
|
||||
|
Loading…
Reference in New Issue
Block a user