This commit is contained in:
wanghaoo 2018-09-25 14:37:25 +08:00
commit ec825b944c
14 changed files with 14753 additions and 13822 deletions

BIN
demo/.DS_Store vendored

Binary file not shown.

Binary file not shown.

106
demo/demolist/Demo26.js Normal file
View File

@ -0,0 +1,106 @@
/**
*
* @title 按条件和值过滤
* @description 可以根据输入项目以及判断条件对表格内的数据进行过滤
*
*/
import React, { Component } from 'react';
import Table from '../../src';
const columns26 = [
{ title: "姓名", width: 180, dataIndex: "name", key: "name", filterType: "text", filterDropdown: "show" },
{ title: "年龄", width: 120, dataIndex: "age", key: "age", filterType: "dropdown" },
{ title: "日期", width: 200, dataIndex: "date", key: "date", filterType: "date" },
{ title: "居住地址", width: 120, dataIndex: "address", key: "address", filterType: "dropdown" },
{ title: "备注", dataIndex: "mark", key: "mark" }
];
const data26 = [
{
key: "1",
name: "John Brown",
age: 32,
date: "2018-09-18 09:46:44",
address: "朝阳区",
mark: "无"
},
{
key: "2",
name: "Jim Green",
age: 40,
date: "2018-09-18 09:46:44",
address: "朝阳区",
mark: "无"
},
{
key: "3",
name: "Jim Green",
age: 40,
date: "2018-09-18 09:46:44",
address: "东城区",
mark: "无"
},
{
key: "4",
name: "Jim Green",
age: 40,
date: "2018-09-18 09:46:44",
address: "东城区",
mark: "无"
}, {
key: "5",
name: "John Brown",
age: 32,
date: "2018-09-18 09:46:44",
address: "海淀区",
mark: "无"
},
{
key: "6",
name: "Jim Green",
age: 48,
date: "2018-09-18 09:46:44",
address: "海淀区",
mark: "无"
},
{
key: "7",
name: "Jim Green",
age: 40,
date: "2018-09-18 09:46:44",
address: "海淀区",
mark: "无"
},
{
key: "8",
name: "Jim Green",
age: 38,
date: "2018-09-18 09:46:44",
address: "海淀区",
mark: "无"
}
];
class Demo26 extends Component {
handlerFilterRowsChange = (key, val) => {
console.log('准备构建AJAX请求接收参数key=', key, ' value=', val);
}
handlerFilterRowsDropChange = (key, val) => {
console.log('过滤条件类型:', key, val);
}
render() {
return <Table
onFilterRowsDropChange={this.handlerFilterRowsDropChange}//下拉条件的回调(key,val)=>()
onFilterRowsChange={this.handlerFilterRowsChange}//触发输入操作以及其他的回调(key,val)=>()
filterDelay={500}//输入文本多少ms触发回调函数默认300ms
filterable={true}//是否开启过滤数据功能
bordered
columns={columns26}
data={data26} />;
}
}
export default Demo26;

File diff suppressed because one or more lines are too long

5
dist/demo.css vendored
View File

@ -8543,6 +8543,11 @@ ul {
pointer-events: none; } pointer-events: none; }
.u-table-scroll-position-right .u-table-fixed-right { .u-table-scroll-position-right .u-table-fixed-right {
box-shadow: none; } box-shadow: none; }
.u-table-thead .filter-text, .u-table-thead .filter-dropdown, .u-table-thead .filter-date {
font-weight: normal; }
.u-table-thead .filter-wrap {
display: -ms-flexbox;
display: flex; }
.u-table-thead th { .u-table-thead th {
background: #f7f7f7; background: #f7f7f7;
overflow: hidden; overflow: hidden;

2
dist/demo.css.map vendored

File diff suppressed because one or more lines are too long

27275
dist/demo.js vendored

File diff suppressed because one or more lines are too long

2
dist/demo.js.map vendored

File diff suppressed because one or more lines are too long

View File

@ -47,13 +47,16 @@
}, },
"dependencies": { "dependencies": {
"bee-dnd": "^1.0.2", "bee-dnd": "^1.0.2",
"bee-dropdown": "^1.0.1",
"bee-loading": "^1.0.3", "bee-loading": "^1.0.3",
"bee-menus": "^1.0.7",
"bee-popover": "^1.0.2", "bee-popover": "^1.0.2",
"bee-select": "^1.0.8", "bee-select": "^1.0.8",
"classnames": "^2.2.5", "classnames": "^2.2.5",
"lodash.clonedeep": "^4.5.0", "lodash.clonedeep": "^4.5.0",
"object-path": "^0.11.3", "object-path": "^0.11.3",
"shallowequal": "^1.0.2", "shallowequal": "^1.0.2",
"throttle-debounce": "^2.0.1",
"tinper-bee-core": "latest", "tinper-bee-core": "latest",
"warning": "^3.0.0" "warning": "^3.0.0"
}, },

35
src/FilterDropDown.js Normal file
View File

@ -0,0 +1,35 @@
import React, { Component } from 'react';
import Dropdown from 'bee-dropdown';
import Menu from 'bee-menus';
import Button from 'bee-button';
import Icon from 'bee-icon';
const { Item } = Menu;
class FilterDropDown extends Component {
render() {
let dropmenu = (
<Menu
onSelect={this.props.onSelectDropdown}
>
<Item key="1">等于</Item>
<Item key="2">包含</Item>
<Item key="3">以结尾</Item>
<Item key="4"></Item>
<Item key="5">不等于</Item>
<Item key="6">不包含</Item>
<Item key="7">以开始</Item>
</Menu>
);
return (
<Dropdown
trigger={['click']}
overlay={dropmenu}
animation="slide-up"
>
<Button shape="border" style={{ marginLeft: "5px", minWidth: "0px", width: "38px", padding: 0 }}><Icon style={{ padding: 0 }} type="uf-navmenu" /></Button>
</Dropdown>
);
}
}
export default FilterDropDown;

57
src/FilterType.js Normal file
View File

@ -0,0 +1,57 @@
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import FormControl from 'bee-form-control';
import Select from 'bee-select';
import DatePicker from 'bee-datepicker';
import FilterDropDown from './FilterDropDown';
const propTypes = {
filterDropdown: PropTypes.string
};
class FilterType extends Component {
renderControl = (rendertype) => {
let { filterDropdown, className, onChange, onSelectDropdown, clsPrefix } = this.props;
switch (rendertype) {
case 'text':
return <div className={`${clsPrefix} filter-wrap`}><FormControl
className={className}
onChange={onChange}
/>
{filterDropdown == 'show' && <FilterDropDown
onSelectDropdown={onSelectDropdown}
>
</FilterDropDown>}
</div>
case 'dropdown':
return <div className={`${clsPrefix} filter-wrap`}><Select
{...this.props}
/>{filterDropdown == 'show' && <FilterDropDown
onSelectDropdown={onSelectDropdown}
>
</FilterDropDown>}</div>
case 'date':
return <div className={`${clsPrefix} filter-wrap`}><DatePicker
{...this.props}
/>{filterDropdown == 'show' && <FilterDropDown
onSelectDropdown={onSelectDropdown}
>
</FilterDropDown>}
</div>
default:
break;
}
}
render() {
let { rendertype } = this.props;
return (
this.renderControl(rendertype)
);
}
}
FilterType.propTypes = propTypes;
FilterType.defaultProps = {
filterDropdown: 'show'
}
export default FilterType;

View File

@ -202,8 +202,8 @@ class Table extends Component{
this.contentWidth = this.computeWidth; this.contentWidth = this.computeWidth;
this.setState({contentWidth:this.contentWidth});//重新渲染,为了显示滚动条 this.setState({contentWidth:this.contentWidth});//重新渲染,为了显示滚动条
} }
} }
onExpandedRowsChange(expandedRowKeys) { onExpandedRowsChange(expandedRowKeys) {
if (!this.props.expandedRowKeys) { if (!this.props.expandedRowKeys) {
this.setState({ expandedRowKeys }); this.setState({ expandedRowKeys });
@ -259,7 +259,7 @@ class Table extends Component{
} }
getHeader(columns, fixed) { getHeader(columns, fixed) {
const { showHeader, expandIconAsCell, clsPrefix ,onDragStart,onDragEnter,onDragOver,onDrop,draggable, const { filterDelay, onFilterRowsDropChange, onFilterRowsChange, filterable, showHeader, expandIconAsCell, clsPrefix, onDragStart, onDragEnter, onDragOver, onDrop, draggable,
onMouseDown, onMouseMove, onMouseUp, dragborder, onThMouseMove, dragborderKey, minColumnWidth, headerHeight } = this.props; onMouseDown, onMouseMove, onMouseUp, dragborder, onThMouseMove, dragborderKey, minColumnWidth, headerHeight } = this.props;
const rows = this.getHeaderRows(columns); const rows = this.getHeaderRows(columns);
if (expandIconAsCell && fixed !== 'right') { if (expandIconAsCell && fixed !== 'right') {
@ -291,11 +291,16 @@ class Table extends Component{
contentTable={this.contentTable} contentTable={this.contentTable}
rowStyle={trStyle} rowStyle={trStyle}
fixed={fixed} fixed={fixed}
filterable={filterable}
onFilterRowsChange={onFilterRowsChange}
onFilterRowsDropChange={onFilterRowsDropChange}
filterDelay={filterDelay}
/> />
) : null; ) : null;
} }
getHeaderRows(columns, currentRow = 0, rows) { getHeaderRows(columns, currentRow = 0, rows) {
let filterCol = [];
rows = rows || []; rows = rows || [];
rows[currentRow] = rows[currentRow] || []; rows[currentRow] = rows[currentRow] || [];
@ -328,7 +333,23 @@ class Table extends Component{
if (cell.colSpan !== 0) { if (cell.colSpan !== 0) {
rows[currentRow].push(cell); rows[currentRow].push(cell);
} }
//判断是否启用过滤
if (this.props.filterable) {
//组装Filter需要的Col
filterCol.push({
key: column.key,
children: "过滤渲染",
width: column.width,
filtertype: column.filterType,
dataindex: column.dataIndex,
datasource: this.props.data,
filterdropdown: column.filterDropdown
}); });
}
});
if (this.props.filterable) {
rows.push(filterCol);
}
return rows.filter(row => row.length > 0); return rows.filter(row => row.length > 0);
} }

View File

@ -272,7 +272,12 @@ $table-move-in-color: $bg-color-base;
} }
&-thead{ &-thead{
.filter-text,.filter-dropdown,.filter-date {
font-weight: normal;
}
.filter-wrap{
display: flex;
}
th{ th{
background: $table-head-background-color; background: $table-head-background-color;
overflow: hidden; overflow: hidden;

View File

@ -1,7 +1,9 @@
import React, { Component } from 'react'; import React, { Component } from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import shallowequal from 'shallowequal'; import shallowequal from 'shallowequal';
import { throttle, debounce } from 'throttle-debounce';
import { tryParseInt, ObjectAssign } from './utils'; import { tryParseInt, ObjectAssign } from './utils';
import FilterType from './FilterType';
const propTypes = { const propTypes = {
clsPrefix: PropTypes.string, clsPrefix: PropTypes.string,
@ -199,12 +201,80 @@ class TableHeader extends Component{
//4、设置overflow属性 //4、设置overflow属性
} }
}
/**
* @description 过滤输入后的回调函数
*/
handlerFilterTextChange = (key, val) => {
let { onFilterRowsChange } = this.props;
if (onFilterRowsChange) {
onFilterRowsChange(key, val);
}
}
/**
* @description 过滤输入后的回调函数
*/
handlerFilterDropChange = (key, val) => {
let { onFilterRowsDropChange } = this.props;
if (onFilterRowsDropChange) {
onFilterRowsDropChange(key, val.key);
}
}
/**
* @description 过滤渲染的组件类型
*/
filterRenderType = (type, dataIndex, index) => {
const { clsPrefix, rows, filterDelay } = this.props;
switch (type) {
//文本输入
case 'text':
return <FilterType
rendertype={type}
clsPrefix={clsPrefix}
className={`${clsPrefix} filter-text`}
onChange={debounce(filterDelay || 300, this.handlerFilterTextChange.bind(this, dataIndex))}
onSelectDropdown={this.handlerFilterDropChange.bind(this, dataIndex)}
filterDropdown={rows[1][index]['filterdropdown']}
/>
//下拉框选择
case 'dropdown':
let selectDataSource = [];
if (rows.length > 0) {
let hash = {};
//处理下拉重复对象组装dropdown
selectDataSource = Array.from(rows[1][0].datasource, x => ({ key: x[dataIndex], value: x[dataIndex] }));
selectDataSource = selectDataSource.reduceRight((item, next) => {
hash[next.key] ? '' : hash[next.key] = true && item.push(next);
return item
}, []);
}
return <FilterType
rendertype={type}
className={`${clsPrefix} filter-dropdown`}
data={selectDataSource}
onChange={this.handlerFilterTextChange.bind(this, dataIndex)}
onSelectDropdown={this.handlerFilterDropChange.bind(this, dataIndex)}
filterDropdown={rows[1][index]['filterdropdown']}
/>
//日期
case 'date':
return <FilterType
rendertype={type}
className={`${clsPrefix} filter-date`}
onClick={() => { }}
onChange={this.handlerFilterTextChange.bind(this, dataIndex)}
onSelectDropdown={this.handlerFilterDropChange.bind(this, dataIndex)}
filterDropdown={rows[1][index]['filterdropdown']}
/>
default:
//不匹配类型默认文本输入
return <div></div>
}
} }
render() { render() {
const { clsPrefix, rowStyle ,onDragStart,onDragOver,onDrop,draggable,rows, const { clsPrefix, rowStyle, onDragStart, onDragOver, onDrop, draggable, rows, filterable, onFilterRowsChange,
onMouseDown, onMouseMove, onMouseUp, dragborder, onMouseOut, contentWidthDiff, fixed, lastShowIndex onMouseDown, onMouseMove, onMouseUp, dragborder, onMouseOut, contentWidthDiff, fixed, lastShowIndex
} = this.props; } = this.props;
let attr = dragborder ? { id: `u-table-drag-thead-${this.theadKey}` } : {} let attr = dragborder ? { id: `u-table-drag-thead-${this.theadKey}` } : {}
@ -250,7 +320,13 @@ class TableHeader extends Component{
className={`${clsPrefix}-thead-th-drag-gap `}></div> className={`${clsPrefix}-thead-th-drag-gap `}></div>
</th>) </th>)
} else { } else {
let th = da.onClick?(<th {...da} className={` ${fixedStyle}`} key={i} onClick={(event)=>{da.onClick(da,event)}}/>):(<th {...da} key={i} className={` ${fixedStyle}`} />); let th;
if (filterable && index == rows.length - 1) {
da.children = this.filterRenderType(da['filtertype'], da.dataindex, i);
th = <th {...da} key={i} className={` ${fixedStyle}`} />;
} else {
th = da.onClick ? (<th {...da} className={` ${fixedStyle}`} key={i} onClick={(event) => { da.onClick(da, event) }} />) : (<th {...da} key={i} className={` ${fixedStyle}`} />);
}
return (th); return (th);
} }
})} })}