react+ant 自定义表单

import React, { useState, useEffect } from "react";

import { Row, Col, Input, Select, DatePicker, Button, Tooltip } from "antd";

import { Const } from "src/utils/const";

 

const { Option } = Select;

const { RangePicker } = DatePicker;

 

interface IFilters {

// 公共筛选组件

label: string; // 筛选名称

key: string; // 筛选的字段

defaultValue?: any; // 默认值

type: string; // 选项的类型:Input-输入框,NumberInput-数字输入框,Select-下拉框,SelectMultiple-下拉框多选,Date-日期,DateRange-日期范围,DateRangeButton-按钮日期

options?: { name: string; value: any }[]; // 下拉框的可选项, 如果是DateRangeButton,value为const中DATE_PICKER_RANGER_HELPER的key

span?: number; // 列宽,总共24

tip?: string; // 文案提示

render?: () => any; // 自定义渲染选项

onChange?: (data: any) => any;

}

 

interface IFilterFormProps {

filterColumns: IFilters[][]; // 一个数组代表一行

onSubmit: (data: any) => any;

onChange?: (data: any) => any;

className?: string;

changeFieldsValue?: any; // 联动字段

}

const FilterForm: React.FunctionComponent<IFilterFormProps> = (props: IFilterFormProps) => {

const { filterColumns } = props;

 

const [filterValues, setFilterValues] = useState();

 

// 初始化

useEffect(() => {

initFilterValues();

}, []);

 

useEffect(() => {

if (props.changeFieldsValue) {

const values = filterValues ? { ...filterValues } : {};

Object.keys(props.changeFieldsValue).map(item => {

values[item] = props.changeFieldsValue[item];

});

setFilterValues(values);

}

}, [props.changeFieldsValue]);

 

const initFilterValues = () => {

const values = {};

filterColumns.map(rows => {

rows.map(item => {

values[item.key] = item.defaultValue;

});

});

setFilterValues(values);

};

 

const onFieldsChange = (filter: IFilters, value: any) => {

const values = { ...filterValues };

const field = filter.key;

// Just because an empty array or string means all.

values[field] = String(value).length ? value : void 0;

setFilterValues(values);

if (filter.onChange) {

filter.onChange(value);

}

if (props.onChange) {

props.onChange(values);

}

};

 

const resetFields = () => {

initFilterValues();

};

 

const renderTooltip = (text: string) => {

return (

<Tooltip placement="topLeft" title={text}>

<Button icon="question-circle" type="link" size="small" />

</Tooltip>

);

};

 

const renderDateRange = (filter: IFilters, text: string, range: any) => {

return (

<Button

key={text}

style={{ marginLeft: 10 }}

onClick={() => {

onFieldsChange(filter, range);

}}

>

{text}

</Button>

);

};

 

// 选项的类型:Input-输入框,NumberInput-数字输入框,Select-下拉框,SelectMultiple-下拉框多选,

// Date-日期,DateRange-日期范围

// 根据需求定义更多类型

const renderForm = (filter: IFilters) => {

const filterItem = {

Input: (

<Input

value={filterValues ? filterValues[filter.key] : undefined}

className="full-width"

placeholder={filter.label}

onChange={e => onFieldsChange(filter, e.target.value)}

/>

),

NumberInput: (

<Input

value={filterValues ? filterValues[filter.key] : undefined}

className="full-width"

placeholder={filter.label}

onChange={e => {

if (!e.target.value) {

onFieldsChange(filter, undefined);

} else if (!Number.isNaN(Number(e.target.value)) && /^\d+$/.test(e.target.value)) {

onFieldsChange(filter, Number(e.target.value));

}

}}

/>

),

Select: (

<Select

value={filterValues ? filterValues[filter.key] : undefined}

className="full-width"

placeholder={filter.label}

allowClear={true}

filterOption={(input: string, option: any) => {

try {

return option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0;

} catch {

return option.props.children.indexOf(input) >= 0;

}

}}

onChange={(value: any) => onFieldsChange(filter, value)}

>

{filter.options

? filter.options.map((item: any) => {

return (

<Option key={item.value} value={item.value}>

{item.name}

</Option>

);

})

: null}

</Select>

),

SelectMultiple: (

<Select

value={filterValues ? filterValues[filter.key] : undefined}

className="full-width"

mode="multiple"

allowClear={true}

placeholder={filter.label}

filterOption={(input: string, option: any) => {

try {

return option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0;

} catch {

return option.props.children.indexOf(input) >= 0;

}

}}

onChange={(value: any) => onFieldsChange(filter, value)}

>

{filter.options

? filter.options.map((item: any) => {

return (

<Option key={item.value} value={item.value}>

{item.name}

</Option>

);

})

: null}

</Select>

),

Date: (

<DatePicker

value={filterValues ? filterValues[filter.key] : undefined}

onChange={value => onFieldsChange(filter, value)}

/>

),

DateRange: (

<RangePicker

value={filterValues ? filterValues[filter.key] : undefined}

onChange={value => onFieldsChange(filter, value)}

/>

),

};

return filterItem[filter.type];

};

 

return (

<div className={props.className}>

{filterColumns.map((rows, index) => (

<Row gutter={8} key={index}>

{rows.map(filter => (

<span key={filter.key}>

<Col span={2} className="form-label">

{filter.label}

{filter.tip ? renderTooltip(filter.tip) : null}:

</Col>

<Col span={filter.span ? filter.span : 4} className="margin-bottom-sm">

{filter.render ? filter.render() : renderForm(filter)}

</Col>

</span>

))}

</Row>

))}

<div className="pull-right">

<Button className="margin-right-sm btn-warning" onClick={() => props.onSubmit(filterValues)}>

查询

</Button>

<Button type="danger" onClick={() => resetFields()}>

重置

</Button>

</div>

</div>

);

};

export default FilterForm;

 

 

// 引用表单测试

import React, { useState } from "react";

import moment from "moment";

import FilterForm from "src/components/public/filter-form";

 

interface ITestFilters {

onFilter: (params: any) => void;

defaultFilters: any;

}

 

const TestFilters: React.FunctionComponent<ITestFilters> = (props: ITestFilters) => {

 

const [changeFieldsValue, setChangeFieldsValue] = useState<any>();

 

const test2=[...];

const changeTest3 = (id: number) => {

...

setChangeFieldsValue({Test3:""})

};

 

const onSubmit = (filters: any) => {

...

}

 

const { StartTime, EndTime } = props.defaultFilters;

const filterColumns: IFilters[][] = [

[

{

label: "Test1",

key: "Test1",

type: "NumberInput"

},

{

label: "Test2",

key: "Test2",

type: "Select",

options: test2.map((item: any) => {

return { name: item.Name, value: item.Id };

}),

},

],

[

{

label: "Test3",

key: "Test3",

type: "Date",

defaultValue: StartTime,

onChange: changeTest3

},

{

label: "Test4",

key: "Test4",

type: "Date",

defaultValue: EndTime,

},

......

]

];

 

return <FilterForm filterColumns={filterColumns} changeFieldsValue={changeFieldsValue} onSubmit={onSubmit} />;

};

export default TestFilters;

 

我这里用的是ts,用js的也差的不多,react是新版的hook,省略了一些代码,思想基本都体现出来了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值