ant design 封装可填写Tag标签的input框
如图,input框可填写多个值,每个值以Tag标签的形式展示,每个标签可以新增和删除,自动过滤重复的标签。还能结合from表单,做必填值的验证。
如果没有值,提交表单的时候,会提示错误。
话不多说,直接上代码:
这个是selfTag.js:
import {Input, Tag, Tooltip} from 'antd'; import React, { Component } from 'react'; class newTag extends Component { constructor(props) { super(props); this.state = { inputVisible: false, inputValue: '', // gorTagArr:["未处理","上线"], // gorTag:[ // { // id:1, // name:"未处理", // }, // { // id:2, // name:"上线", // } // ] gorTagArr:[], gorTag:[] }; }; componentDidMount() { const {gorTagArr}=this.props; const newVal=gorTagArr.map((item,index)=>({id:index,name:item})); this.setState({ gorTagArr:gorTagArr, gorTag:newVal }) }; handleClose = removedTag => { const { gorTag,gorTagArr } = this.state; const { onOk } = this.props; const gorNameArr = gorTag.map(item => item.name); const inde = gorNameArr.indexOf(removedTag); this.setState({ gorTagArr:gorTagArr.filter(i=>i!==removedTag), gorTag:gorTag.filter(i=>i.id!==inde), }); onOk(gorTagArr.filter(i=>i!==removedTag)); }; saveInputRef = input => (this.input = input); handleInputChange = e => { this.setState({ inputValue: e.target.value }); }; showInput = () => { this.setState({ inputVisible: true }, () => this.input.focus()); }; handleInputConfirm = () => { const { onOk } = this.props; const { gorTag,gorTagArr,inputValue } = this.state; const gorNameArr = gorTag.map(item => item.name); const gorIdArr = gorTag.map(item => item.id); if (inputValue && gorNameArr.indexOf(inputValue) === -1) { const maxId = gorIdArr.length === 0 ? 0 : Math.max(...gorIdArr); onOk([...gorTagArr,inputValue]); this.setState({ inputVisible: false, inputValue: '', gorTagArr:[...gorTagArr,inputValue], gorTag:[...gorTag,{id: maxId + 1, name: inputValue}] }); }else{ this.setState({ inputVisible: false, inputValue: '', }); } }; render() { const {inputVisible, inputValue,gorTagArr}=this.state; return ( <div style={{ border: '1px solid rgb(216,216,216)', borderRadius: 2, width: '100%', padding: '5px 10px', marginTop: 0, display:"inline-block" }} > {gorTagArr.map((tag, index) => { const isLongTag = tag.length > 20; const tagElem = ( <Tag key={tag} closable={index > -1} onClose={() => this.handleClose(tag)}> {isLongTag ? `${tag.slice(0, 20)}...` : tag} </Tag> ); return isLongTag ? ( <Tooltip title={tag} key={tag}> {tagElem} </Tooltip> ) : ( tagElem ); })} {inputVisible && ( <Input ref={this.saveInputRef} type="text" size="small" style={{ width: 78 }} value={inputValue} onChange={this.handleInputChange} onBlur={this.handleInputConfirm} onPressEnter={this.handleInputConfirm} /> )} {!inputVisible && ( <Tag onClick={this.showInput} style={{ background: '#fff', borderStyle: 'dashed' }}> +新增 </Tag> )} </div> ); } } export default newTag;
这是使用这个组件的代码:
import {Card, Col, Row, Form, Table, Button, Input, Tag,} from 'antd'; import React, { Component, Fragment } from 'react'; import { connect } from 'dva'; import SelfTag from "./selfTag"; const FormItem = Form.Item; @connect(({ portrait,loading }) => ({ portrait, listLoading: loading.effects['portrait/fetchBlockIpList'], })) class blockIp extends Component { constructor(props) { super(props); this.state = { page:1, size:15, text:"", val:{}, flog:true, data:{}, stat:"" }; }; componentDidMount() { }; handleTableChange = pagination => { const { current, pageSize } = pagination; const {dispatch} = this.props; const {val}=this.state; this.setState({page:current,size:pageSize}) }; handleSearch = (values) => { const { dispatch } = this.props; dispatch({ type: 'portrait/fetchPortraitCommon', payload: { ...values, }, }); this.setState({val:values}) }; handleOk=(vale)=>{ if(vale.length>0){ this.searchForm.setFieldsValue({"targetUidList":vale}) }else{ this.searchForm.setFieldsValue({"targetUidList":undefined}) } } // 模糊查询表单 renderSearchForm() { const formItemLayout = { labelCol: { span: 8 }, wrapperCol: { span: 16 }, }; return ( <div style={{ marginBottom: 12 }}> <Form {...formItemLayout} onFinish={this.handleSearch} ref={(c)=>{this.searchForm=c}} > <Row> <Col span={8}> <FormItem label="源uid" name="sourceUid" rules={[{ required: true, message: '请输入' }]} > <Input placeholder="请输入" /> </FormItem> </Col> <Col span={8}> <FormItem label="目的uid" name="targetUidList" rules={[{ required: true, message: '请输入' }]} > <SelfTag onOk={this.handleOk} gorTagArr={[]} /> </FormItem> </Col> <Col span={8}> <FormItem style={{ textAlign: 'right' }}> <Button type="primary" htmlType="submit" > 查询 </Button> <Button onClick={() => {this.searchForm.resetFields()}} htmlType="button"> 重置 </Button> </FormItem> </Col> </Row> </Form> </div> ); } render() { const { portrait: { commonList}, listLoading } = this.props; const {page,size,}=this.state; const columns = [ { title: 'uid', dataIndex: 'uid', align:"center", }, { title: "存在的关系", dataIndex: 'relation', align:"center", render:(relation)=><div> {relation.map((i)=><Tag key={i}>{i}</Tag>)} </div> }, ]; return ( <Card bordered={false}> {this.renderSearchForm()} <Table columns={columns} dataSource={commonList} loading={listLoading} bordered rowKey="uid" onChange={this.handleTableChange} /> </Card> ); } } export default blockIp;