cjd-parkball
Version:
> 中后台业务组件库,中后台就像公园,进入需要买门票(登录),所以以 Parkball(公园球) 命名,公园内必定捕获!作为一个组件库,提供使用方法文档,方便开发者的调用
275 lines (256 loc) • 7.53 kB
JavaScript
import React, { Component } from 'react'
import ReactDom from 'react-dom'
import PropTypes from 'prop-types'
import { Row, Col, Button, Form, Icon, Dropdown, Menu } from 'antd'
import classnames from 'classnames'
import moment from 'moment'
import store from 'store2'
import Arrange from '../arrange'
import { formatParams, customStoreKey } from '../utils'
import './index.scss'
const FormItem = Form.Item
function calcRowByItems (children = [], column) {
const rowLength = Math.ceil([].concat(children).length / column)
const rows = Array.from(new Array(rowLength), (val, index) => index)
return rows
}
@Form.create()
export default class extends Component {
state = {
more: false,
}
static defaultProps = {
column: 3,
changeHistory: true,
className: '',
operation: () => null,
onSubmit: () => null,
onReset: false,
custom: true,
moreText: '更多搜索条件',
}
static propTypes = {
column: PropTypes.number,
changeHistory: PropTypes.bool,
className: PropTypes.string,
operation: PropTypes.func,
onSubmit: PropTypes.func,
onReset: PropTypes.oneOfType([
PropTypes.bool,
PropTypes.func,
]),
moreText: PropTypes.string,
custom: PropTypes.bool,
}
static Item (props) {
const {
label,
name,
children,
form: { getFieldDecorator },
defaultValue,
labelCol,
wrapperCol,
key,
className,
...attrs
} = props
return (
<FormItem
className={className}
label={label}
labelCol={labelCol || { span: 7 }}
wrapperCol={wrapperCol || { span: 17 }}
key={key}
>
{getFieldDecorator(name, {
initialValue: defaultValue,
...attrs,
})(children)}
</FormItem>
)
}
reset () {
const {
form: { resetFields }, onSubmit, changeHistory, onReset,
} = this.props
const { origin, pathname } = window.location
resetFields()
onReset && onReset(this.getFields())
changeHistory && window.history.pushState(null, null, `${origin}${pathname}`)
!onReset && onSubmit()
}
search = (event) => {
event.preventDefault()
const { form: { validateFieldsAndScroll }, onSubmit, changeHistory } = this.props
validateFieldsAndScroll((error, values) => {
if (!error) {
const { origin, pathname } = window.location
const result = onSubmit(values)
changeHistory && window.history.pushState(null, null, `${origin}${pathname}?${formatParams(result || values)}`)
}
})
}
filterHideChild = (children) => {
return [].concat(children).filter(child => !child.props.hide)
}
defaultFields () {
return this.filterHideChild(this.props.children).slice(0, 2)
}
otherFields () {
return this.filterHideChild(this.props.children).slice(2)
}
isNeedMore () {
return this.filterHideChild(this.props.children).length > 2
}
expandMoreFilter () {
this.setState({
more: !this.state.more,
})
}
attachNode = (node) => {
this._form = ReactDom.findDOMNode(node)
}
moreFields () {
const { form, column = 3 } = this.props
return (<div className="pk-filter-block" style={{ display: this.state.more ? 'block' : 'none' }}>
{calcRowByItems(this.otherFields(), column).map((row, rowIndex) => (
<Row key={rowIndex}>
{
this.otherFields().map((child, index) => {
if (index >= rowIndex * column && index < (rowIndex + 1) * column) {
return (
<Col span={8} key={index} style={{ paddingRight: '10px' }}>
{
React.cloneElement(child, {
form,
key: index,
})
}
</Col>
)
}
return null
})
}
</Row>))
}
</div>)
}
onUseShortCut = (item) => {
const { form: { validateFieldsAndScroll, setFieldsValue }, onSubmit } = this.props
const key = customStoreKey({ compKey: 'pk-filter', ...this.props })
if (item.key === '1') {
validateFieldsAndScroll((error, values) => {
onSubmit(values)
const newValues = {}
Object.keys(values).forEach((name) => {
if (values[name] && ((Array.isArray(values[name]) && values[name].every(val => val.isValid)) || values[name].isValid)) {
newValues[name] = {
type: 'date',
value: values[name],
}
} else {
newValues[name] = {
type: 'orgin',
value: values[name],
}
}
})
store.set(key, newValues)
})
} else {
const values = store.get(key) || {}
const newValues = {}
Object.keys(values).forEach((name) => {
if (values[name] && values[name].type === 'date') {
if (Array.isArray(values[name].value)) {
newValues[name] = values[name].value.map(val => moment(val))
} else {
newValues[name] = moment(values[name].value)
}
} else {
newValues[name] = values[name].value
}
})
setFieldsValue(newValues)
}
return 0
}
render () {
const {
form,
className,
operation = () => null,
moreText,
custom,
} = this.props
let { children } = this.props
const menu = (
<Menu onClick={this.onUseShortCut}>
<Menu.Item key="1">设为常用筛选</Menu.Item>
<Menu.Item key="2">使用常用筛选</Menu.Item>
</Menu>
)
if (!Array.isArray(children)) {
children = [children]
}
return (
<Form
layout="horizontal"
className={classnames('pk-filter', className)}
onSubmit={e => this.search(e)}
ref={this.attachNode}
>
<Row gutter={16}>
{
this.defaultFields().map((child, index) => {
return (
<Col key={index} span={6}>
{
React.cloneElement(child, {
form,
key: index,
})
}
</Col>
)
})
}
{
children.length > 2 ?
<Col span={6} className="pk-filter-more">
<span className={`pk-filter-span ${this.state.more ? 'expand' : ''}`} onClick={() => this.expandMoreFilter()}>
{moreText}<Icon type="down" />
</span>
</Col> : null
}
<Col span={6} className="pk-filter-submit">
<Arrange middle={8}>
<React.Fragment key="operation">{operation(this.props.form)}</React.Fragment>
<Button key="reset" onClick={this.reset.bind(this)}>重置</Button>
{
custom ? <Dropdown.Button
overlay={menu}
key="query"
type="secondary"
onClick={this.search}
>
筛选
</Dropdown.Button>
: <Button
key="query"
type="secondary"
htmlType="submit"
>
筛选
</Button>
}
</Arrange>
</Col>
</Row>
{this.moreFields()}
</Form>
)
}
}