feat: 新增排序和全选高阶组件,并增加使用示例

This commit is contained in:
huyueb 2017-09-14 15:45:18 +08:00
parent d8343df513
commit f8a00fe2e8
6 changed files with 464 additions and 119 deletions

76
demo/demolist/Demo13.js Normal file
View File

@ -0,0 +1,76 @@
/**
*
* @title 全选功能
* @description 全选功能
*
*/
import React, { Component } from "react";
import Table from "../../src";
import Checkbox from "bee-checkbox";
import multiTable from "../../src/lib/multiSelectFunc.js";
import sortTable from "../../src/lib/sortFunc.js";
const columns13 = [
{
title: "名字",
dataIndex: "a",
key: "a",
width: 100
},
{
title: "性别",
dataIndex: "b",
key: "b",
width: 100
},
{
title: "年龄",
dataIndex: "c",
key: "c",
width: 200,
sorter: (a, b) => a.c - b.c
},
{
title: "操作",
dataIndex: "",
key: "d",
render() {
return <a href="#">一些操作</a>;
}
}
];
const data13 = [
{ a: "杨过", b: "男", c: 30, key: "2" },
{ a: "令狐冲", b: "男", c: 41, key: "1" },
{ a: "郭靖", b: "男", c: 25, key: "3" }
];
class Demo13 extends Component {
getCheckedObj = () => {
console.log(this.state);
};
setCheckedOjb = (data) =>{
console.log(data)
}
render() {
let multiObj = {
type: "checkbox",
param: "key"
};
let ComplexTable = multiTable(sortTable(Table));
return (
<div>
<ComplexTable
columns={columns13}
data={data13}
multiSelect={multiObj}
prefixCls="bee-table"
getSelectedDataFunc={this.setCheckedOjb}
/>
<button onClick={this.getCheckedObj}>xxxx</button>
</div>
);
}
}
export default Demo13;

View File

@ -5,180 +5,200 @@
* *
*/ */
import Button from "bee-button";
import React, { Component } from "react";
import Button from 'bee-button'; import Table from "../../src";
import React, { Component } from 'react'; import Animate from "bee-animate";
import Table from '../../src';
import Animate from 'bee-animate';
import Icon from "bee-icon"; import Icon from "bee-icon";
import Input from 'bee-form-control'; import Input from "bee-form-control";
import Popconfirm from 'bee-popconfirm'; import Popconfirm from "bee-popconfirm";
class EditableCell extends React.Component { class EditableCell extends React.Component {
state = { state = {
value: this.props.value, value: this.props.value,
editable: false, editable: false
} };
handleChange = (e) => { handleChange = e => {
const value = e.target.value; const value = e.target.value;
this.setState({ value }); this.setState({ value });
} };
check = () => { check = () => {
this.setState({ editable: false }); this.setState({ editable: false });
if (this.props.onChange) { if (this.props.onChange) {
this.props.onChange(this.state.value); this.props.onChange(this.state.value);
} }
} };
edit = () => { edit = () => {
this.setState({ editable: true }); this.setState({ editable: true });
} };
handleKeydown = (event) => { handleKeydown = event => {
console.log(event.keyCode); console.log(event.keyCode);
if(event.keyCode == 13){ if (event.keyCode == 13) {
this.check(); this.check();
} }
};
}
render() { render() {
const { value, editable } = this.state; const { value, editable } = this.state;
return (<div className="editable-cell"> return (
{ <div className="editable-cell">
editable ? {editable ? (
<div className="editable-cell-input-wrapper"> <div className="editable-cell-input-wrapper">
<Input <Input
value={value} value={value}
onChange={this.handleChange} onChange={this.handleChange}
onKeyDown = {this.handleKeydown} onKeyDown={this.handleKeydown}
/> />
<Icon <Icon
type="uf-correct" type="uf-correct"
className="editable-cell-icon-check" className="editable-cell-icon-check"
onClick={this.check} onClick={this.check}
/> />
</div> </div>
: ) : (
<div className="editable-cell-text-wrapper"> <div className="editable-cell-text-wrapper">
{value || ' '} {value || " "}
<Icon <Icon
type="uf-pencil" type="uf-pencil"
className="editable-cell-icon" className="editable-cell-icon"
onClick={this.edit} onClick={this.edit}
/> />
</div> </div>
} )}
</div>); </div>
);
} }
} }
class Demo2 extends React.Component { class Demo2 extends React.Component {
constructor(props) { constructor(props) {
super(props); super(props);
this.columns = [{ this.columns = [
title: '姓名', {
dataIndex: 'name', title: "姓名",
key:'name', dataIndex: "name",
width: '30%', key: "name",
render: (text, record, index) => ( width: "30%",
<EditableCell render: (text, record, index) => (
value={text} <EditableCell
onChange={this.onCellChange(index, 'name')} value={text}
/> onChange={this.onCellChange(index, "name")}
), />
}, { )
title: '年龄',
dataIndex: 'age',
key:'age',
}, {
title: '你懂的',
dataIndex: 'address',
key:'address',
}, {
title: '操作',
dataIndex: 'operation',
key: 'operation',
render: (text, record, index) => {
return (
this.state.dataSource.length > 1 ?
(
<Popconfirm content="确认删除?" id='aa' onClose={this.onDelete(index)}>
<Icon type="uf-del"></Icon>
</Popconfirm>
) : null
);
}, },
}]; {
title: "年龄",
dataIndex: "age",
key: "age"
},
{
title: "你懂的",
dataIndex: "address",
key: "address"
},
{
title: "操作",
dataIndex: "operation",
key: "operation",
render: (text, record, index) => {
return this.state.dataSource.length > 1 ? (
<Popconfirm content="确认删除?" id="aa" onClose={this.onDelete(index)}>
<Icon type="uf-del" />
</Popconfirm>
) : null;
}
}
];
this.state = { this.state = {
dataSource: [{ dataSource: [
key: '0', {
name: '沉鱼', key: "0",
age: '18', name: "沉鱼",
address: '96, 77, 89', age: "18",
}, { address: "96, 77, 89"
key: '1', },
name: '落雁', {
age: '16', key: "1",
address: '90, 70, 80', name: "落雁",
}, { age: "16",
key: '2', address: "90, 70, 80"
name: '闭月', },
age: '17', {
address: '80, 60, 80', key: "2",
}, { name: "闭月",
key: '3', age: "17",
name: '羞花', address: "80, 60, 80"
age: '20', },
address: '120, 60, 90', {
}], key: "3",
count: 4, name: "羞花",
age: "20",
address: "120, 60, 90"
}
],
count: 4
}; };
} }
onCellChange = (index, key) => { onCellChange = (index, key) => {
return (value) => { return value => {
const dataSource = [...this.state.dataSource]; const dataSource = [...this.state.dataSource];
dataSource[index][key] = value; dataSource[index][key] = value;
this.setState({ dataSource }); this.setState({ dataSource });
}; };
} };
onDelete = (index) => { onDelete = index => {
return () => { return () => {
const dataSource = [...this.state.dataSource]; const dataSource = [...this.state.dataSource];
dataSource.splice(index, 1); dataSource.splice(index, 1);
this.setState({ dataSource }); this.setState({ dataSource });
}; };
} };
handleAdd = () => { handleAdd = () => {
const { count, dataSource } = this.state; const { count, dataSource } = this.state;
const newData = { const newData = {
key: count, key: count,
name: `凤姐 ${count}`, name: `凤姐 ${count}`,
age: 32, age: 32,
address: `100 100 100`, address: `100 100 100`
}; };
this.setState({ this.setState({
dataSource: [...dataSource, newData], dataSource: [...dataSource, newData],
count: count + 1, count: count + 1
}); });
} };
getBodyWrapper = (body) => { getBodyWrapper = body => {
return ( return (
<Animate transitionName="move" component="tbody" className={body.props.className}> <Animate
transitionName="move"
component="tbody"
className={body.props.className}
>
{body.props.children} {body.props.children}
</Animate> </Animate>
); );
} };
render() { render() {
const { dataSource } = this.state; const { dataSource } = this.state;
const columns = this.columns; const columns = this.columns;
return (<div> return (
<Button className="editable-add-btn" type="ghost" onClick={this.handleAdd}>添加</Button> <div>
<Table bordered data={dataSource} columns={columns} getBodyWrapper={this.getBodyWrapper} /> <Button
</div>); className="editable-add-btn"
type="ghost"
onClick={this.handleAdd}
>
添加
</Button>
<Table
bordered
data={dataSource}
columns={columns}
getBodyWrapper={this.getBodyWrapper}
/>
</div>
);
} }
} }
export default Demo2; export default Demo2;

File diff suppressed because one or more lines are too long

149
src/lib/multiSelectFunc.js Normal file
View File

@ -0,0 +1,149 @@
import React, { Component } from "react";
import Checkbox from "bee-checkbox";
/**
* multiSelect={
* type--默认值为checkbox
* param--可以设置返回的选中的数据属性默认值null
* }
* getSelectedDataFunc--function能获取到选中的数据
* 使用全选时得注意data中的key值一定要是唯一值
*/
module.exports = function multiTable(Table) {
Array.prototype.indexOf = function(val) {
for (var i = 0; i < this.length; i++) {
if (this[i] == val) return i;
}
return -1;
};
Array.prototype.remove = function(val) {
var index = this.indexOf(val);
if (index > -1) {
this.splice(index, 1);
}
};
return class BookLoader extends Component {
constructor(props) {
super(props);
this.state = {
checkedAll: false,
checkedObj: {},
selIds: [],
data: this.props.data
};
}
onAllCheckChange = () => {
let self = this;
let listData = self.state.data.concat();
let checkedObj = Object.assign({}, self.state.checkedObj);
let data = self.props.data;
let selIds = [];
let id = self.props.multiSelect.param;
for (var i = 0; i < data.length; i++) {
checkedObj[data[i]["key"]] = !self.state.checkedAll;
}
if (self.state.checkedAll) {
selIds = [];
} else {
for (var i = 0; i < listData.length; i++) {
if (id) {
selIds[i] = listData[i][id];
} else {
selIds[i] = listData[i];
}
}
}
self.setState({
checkedAll: !self.state.checkedAll,
checkedObj: checkedObj,
selIds: selIds
});
self.props.getSelectedDataFunc(selIds);
};
onCheckboxChange = (text, record, index) => {
let self = this;
let allFlag = false;
let selIds = self.state.selIds;
let id = self.props.multiSelect.param
? record[self.props.multiSelect.param]
: record;
let checkedObj = Object.assign({}, self.state.checkedObj);
let checkedArray = Object.keys(checkedObj);
if (checkedObj[record["key"]]) {
selIds.remove(id);
} else {
selIds.push(id);
}
checkedObj[record["key"]] = !checkedObj[record["key"]];
for (var i = 0; i < checkedArray.length; i++) {
if (!checkedObj[checkedArray[i]]) {
allFlag = false;
break;
} else {
allFlag = true;
}
}
self.setState({
checkedAll: allFlag,
checkedObj: checkedObj,
selIds: selIds
});
self.props.getSelectedDataFunc(selIds);
};
renderColumnsMultiSelect(columns) {
const { data } = this.state;
let checkedObj = Object.assign({}, this.state.checkedObj);
let checkedArray = Object.keys(checkedObj);
let { multiSelect } = this.props;
let select_column = {};
let indeterminate_bool = false;
if (!multiSelect || !multiSelect.type) {
multiSelect = Object.assign({}, multiSelect, { type: "checkbox" });
}
if (multiSelect && multiSelect.type === "checkbox") {
let i = checkedArray.length;
while (i--) {
if (checkedObj[checkedArray[i]]) {
indeterminate_bool = true;
break;
}
}
let defaultColumns = [
{
title: (
<Checkbox
className="table-checkbox"
checked={this.state.checkedAll}
indeterminate={indeterminate_bool && !this.state.checkedAll}
onChange={this.onAllCheckChange}
/>
),
key: "checkbox",
dataIndex: "checkbox",
width: "5%",
render: (text, record, index) => {
return (
<Checkbox
className="table-checkbox"
checked={checkedObj[record.key]}
onChange={this.onCheckboxChange.bind(
this,
text,
record,
index
)}
/>
);
}
}
];
columns = defaultColumns.concat(columns);
}
return columns;
}
render() {
let { data } = this.props;
let columns = this.renderColumnsMultiSelect(this.props.columns).concat();
return <Table {...this.props} columns={columns} data={data} />;
}
};
};

100
src/lib/sortFunc.js Normal file
View File

@ -0,0 +1,100 @@
import React, { Component } from 'react';
import Icon from 'bee-icon';
/**
* 参数prefixCls默认bee-table,用于设置图标的样式
* @param {*} Table
*/
export default function sortTable(Table) {
return class Demo11 extends Component {
constructor(props) {
super(props);
this.state = {
sortOrder: "",
data: this.props.data
};
}
toggleSortOrder = (order, column) => {
let { sortOrder, data, oldData } = this.state;
let ascend_sort = function (key) {
return function (a, b) {
return a.key - b.key;
};
};
let descend_sort = function (key) {
return function (a, b) {
return b.key - a.key;
};
};
if (sortOrder === order) {
// 切换为未排序状态
order = "";
}
if (!oldData) {
oldData = data.concat();
}
if (order === "ascend") {
data = data.sort(function (a, b) {
return column.sorter(a, b);
});
} else if (order === "descend") {
data = data.sort(function (a, b) {
return column.sorter(b, a);
});
} else {
data = oldData.concat();
}
this.setState({
sortOrder: order,
data: data,
oldData: oldData
});
}
renderColumnsDropdown(columns) {
const { sortOrder } = this.state;
const prefixCls = this.props.prefixCls || 'bee-table';
return columns.map(originColumn => {
let column = Object.assign({}, originColumn);
let sortButton;
if (column.sorter) {
const isAscend = sortOrder === "ascend";
const isDescend = sortOrder === "descend";
sortButton = (
<div className={`${prefixCls}-column-sorter`}>
<span
className={`${prefixCls}-column-sorter-up ${isAscend
? "on"
: "off"}`}
title="↑"
onClick={() => this.toggleSortOrder("ascend", column)}
>
<Icon type="uf-triangle-up" />
</span>
<span
className={`${prefixCls}-column-sorter-down ${isDescend
? "on"
: "off"}`}
title="↓"
onClick={() => this.toggleSortOrder("descend", column)}
>
<Icon type="uf-triangle-down" />
</span>
</div>
);
}
column.title = (
<span>
{column.title}
{sortButton}
</span>
);
return column;
});
}
render() {
let columns = this.renderColumnsDropdown(this.props.columns).concat();
return <Table{...this.props} columns={columns} data={this.state.data}/>;
}
}
}

0
src/lib/util.js Normal file
View File