自写一个漂亮的ant design form提交标签
程序员文章站
2022-05-29 08:14:46
在ant design 的form组件中 能用于提交的组件比较少,所以我在这写了一个可以单选、多选标签提交的组件,调用非常简单。 代码: 1 import React,{Fragment} from 'react'; 2 import { Tag,Icon,Input } from 'antd'; ......
在ant design 的form组件中 能用于提交的组件比较少,所以我在这写了一个可以单选、多选标签提交的组件,调用非常简单。
代码:
1 import react,{fragment} from 'react'; 2 import { tag,icon,input } from 'antd'; 3 export interface tagdatatype{ 4 data:string, 5 color:string, 6 key:string 7 } 8 export interface props { 9 data:array<tagdatatype>, 10 click?:boolean,//是否可点击 11 defaultkey?:string | array<string>,//默认选择tag的key 12 checkbox?:boolean,//多选 13 form?:any,//菜单验证方法 14 datavalidationname?:string,//设置提交名称,若用此参数提交则提交选中的data,用于菜单提交获取 15 keyvalidationname?:string,//设置提交名称,若用此参数提交则提交选中的key,用于菜单提交获取 16 notnull?:boolean,//选项不能为空 17 } 18 19 export interface state { 20 //tagdata:tagdatatype | undefined, 21 keys:string, 22 datas:string, 23 stylestate:number | array<number>, 24 } 25 26 class tagopt extends react.component<props, state> { 27 constructor(props: props) { 28 super(props); 29 //验证传入数据的合法性 30 if(this.props.notnull && !!!this.props.defaultkey){ 31 throw error('tagopt选中项为空,设置defaultkey!'); 32 } 33 if(!!this.props.form && !!!this.props.keyvalidationname && !!!this.props.datavalidationname){ 34 throw error('若要使用form提交,请设置keyvalidationname或datavalidationname!'); 35 } 36 this.state=this.setdefaultval(); 37 } 38 //鼠标点击标签事件 39 tagclick = (tagdata:tagdatatype,index:number) =>{ 40 if(this.props.click !== undefined && this.props.click){ 41 if(this.props.checkbox){ 42 const optif = this.optif(index); 43 let stylestate:array<number> = new array();; 44 if(typeof this.state.stylestate === 'object'){ 45 stylestate = [...this.state.stylestate]; 46 }else{ 47 stylestate = [this.state.stylestate]; 48 } 49 if(optif.state){ 50 //点击已选择 51 //如果设置不为空且选中选项大于1或者没有设置不为空选项 52 //则清空 53 if(this.props.notnull && stylestate.length>1 || !!!this.props.notnull){ 54 stylestate.splice(optif.index,1); 55 this.setstate({ 56 keys:this.movesubstring(this.state.keys,tagdata.key), 57 datas:this.movesubstring(this.state.datas,tagdata.data), 58 stylestate 59 },()=>{this.setval(this.state.datas,'data');this.setval(this.state.keys,'key')}); 60 } 61 }else{ 62 //点击未选择 63 stylestate.splice(stylestate.length,0,index); 64 this.setstate({ 65 keys:this.addsubstring(this.state.keys,tagdata.key), 66 datas:this.addsubstring(this.state.datas,tagdata.data), 67 stylestate 68 },()=>{this.setval(this.state.datas,'data');this.setval(this.state.keys,'key')}); 69 } 70 }else{ 71 if(this.state.stylestate === index){ 72 //点击已选择 73 //若设置可以为空 74 //则清空 75 if(!!!this.props.notnull){ 76 this.setstate({keys:'',datas:'',stylestate:this.props.data.length} 77 ,()=>{this.setval(this.state.datas,'data');this.setval(this.state.keys,'key')}); 78 } 79 }else{ 80 //点击未选择 81 this.setstate({keys:tagdata.key,datas:tagdata.data,stylestate:index} 82 ,()=>{this.setval(this.state.datas,'data');this.setval(this.state.keys,'key')}); 83 } 84 } 85 } 86 } 87 //返回移出指定子串的字符串,移出所有重复子串 88 movesubstring = (str:string,substring:string):string => { 89 let array:array<string> = str.split(','); 90 for(let i=0;i<array.length;i++){ 91 if(array[i] === substring){ 92 array.splice(i,1); 93 } 94 } 95 return array.tostring(); 96 } 97 //返回增加子串的字符串,重复则不增加 98 addsubstring = (str:string,substring:string|array<string>) =>{ 99 if(typeof substring === 'string'){ 100 let comma = str !==''?',':''; 101 return str +comma+substring; 102 }else{ 103 let s:string = str; 104 for(let i=0;i<substring.length;i++){ 105 let comma = s !==''?',':''; 106 s+=comma+substring[i]; 107 } 108 return s; 109 } 110 } 111 //选择判断 112 optif = (index:number):{state:boolean,index:number} => { 113 if(typeof this.state.stylestate ==='number'){ 114 return {state:this.state.stylestate === index,index:0}; 115 }else{ 116 let falg:boolean = false; 117 const stylestate = this.state.stylestate; 118 let i=0; 119 for(;i<stylestate.length;i++){ 120 if(stylestate[i] === index){ 121 falg = true; 122 break; 123 } 124 } 125 return {state:falg,index:i}; 126 } 127 } 128 //写入表单 129 setval = (data:string,type:string) => { 130 if(this.props.form != undefined){ 131 let json:object = {} 132 if(type === 'data'){ 133 if(this.props.datavalidationname !== undefined){ 134 json[this.props.datavalidationname] = data; 135 this.props.form.setfieldsvalue(json); 136 } 137 }else if(type === 'key'){ 138 if(this.props.keyvalidationname !== undefined){ 139 json[this.props.keyvalidationname] = data; 140 this.props.form.setfieldsvalue(json); 141 } 142 } 143 } 144 } 145 //默认值转换 146 setdefaultval=():state=>{ 147 if(this.props.checkbox){ 148 //多选框,值为1个或数组 149 let stylestate:array<number> = new array(); 150 let keys:array<string> = new array(); 151 let datas:array<string> = new array(); 152 const {defaultkey,data} = this.props; 153 if(typeof defaultkey === 'object'){ 154 for(let i=0;i<defaultkey.length;i++){ 155 for(let j=0;j<data.length;j++){ 156 if(defaultkey[i] === data[j].key){ 157 stylestate.push(i); 158 keys.push(data[j].key); 159 datas.push(data[j].data); 160 } 161 } 162 } 163 return { 164 keys:this.addsubstring('',keys), 165 datas:this.addsubstring('',datas), 166 stylestate 167 } 168 }else{ 169 let i:number = 0; 170 let key:string = ''; 171 let dat:string = ''; 172 for(;i<data.length;i++){ 173 if(data[i].key === defaultkey){ 174 key=data[i].key; 175 dat=data[i].data; 176 break; 177 } 178 } 179 return { keys:key,datas:dat,stylestate: i }; 180 } 181 }else if(this.props.checkbox === undefined && typeof this.props.defaultkey ==='string' || 182 !this.props.checkbox && typeof this.props.defaultkey ==='string'){ 183 //多选未设置且默认值为1个或单选且默认值为一个 184 let i:number = 0; 185 let key:string = ''; 186 let dat:string = ''; 187 if(this.props.defaultkey !== undefined){ 188 const data = this.props.data; 189 for(;i<data.length;i++){ 190 if(data[i].key === this.props.defaultkey){ 191 key=data[i].key; 192 dat=data[i].data; 193 break; 194 } 195 } 196 } 197 return { keys:key,datas:dat,stylestate: i }; 198 }else if(this.props.defaultkey === undefined || this.props.defaultkey === '' || this.props.defaultkey === []){ 199 if(this.props.checkbox){ 200 return { keys:'',datas:'',stylestate: [] }; 201 }else{ 202 return { keys:'',datas:'',stylestate: this.props.data.length }; 203 } 204 }else{ 205 return {keys:'',datas:'',stylestate: this.props.data.length}; 206 } 207 } 208 render() { 209 const content:any = this.props.data.map((tagdata:tagdatatype,index:number)=>{ 210 const cursor:any = this.props.click !== undefined && this.props.click ?'pointer':'default'; 211 return( 212 <tag color={tagdata.color} key={tagdata.key} onclick={this.tagclick.bind(this,tagdata,index)} style={{cursor}}> 213 {tagdata.data} 214 {this.optif(index).state?<icon type="check" />:undefined} 215 </tag> 216 ) 217 }); 218 return ( 219 <fragment> 220 {content} 221 { 222 !!this.props.click && !!this.props.form && !!this.props.form.getfielddecorator && !!this.props.keyvalidationname? 223 this.props.form.getfielddecorator(this.props.keyvalidationname, { 224 initialvalue:this.state.keys, 225 })(<input type="hidden"/>) 226 :undefined 227 } 228 { 229 !!this.props.click && !!this.props.form &&!!this.props.form.getfielddecorator && !!this.props.datavalidationname 230 && !!!this.props.keyvalidationname? 231 this.props.form.getfielddecorator(this.props.datavalidationname, { 232 initialvalue:this.state.datas, 233 })(<input type="hidden"/>) 234 :undefined 235 } 236 </fragment> 237 ); 238 } 239 } 240 export default tagopt;
效果: