在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,//form表单
  14. dataValidationName?:string,//设置提交名称,若用此参数提交则提交选中的data,用于菜单提交获取
  15. keyValidationName?:string,//设置提交名称,若用此参数提交则提交选中的key,用于菜单提交获取
  16. notNull?:boolean,//选项不能为空
  17. }
  18.  
  19. export interface State {
  20. keys:string,//选中的标签的key,用','分割
  21. datas:string,//选中的标签的data,用','分割
  22. styleState:number | Array<number>,//选中的下标集
  23. }
  24.  
  25. class TagOpt extends React.Component<Props, State> {
  26. constructor(props: Props) {
  27. super(props);
  28. //验证传入数据的合法性
  29. if(this.props.notNull && !!!this.props.defaultKey){
  30. throw Error('TagOpt选中项为空,设置defaultKey!');
  31. }
  32. if(!!this.props.form && !!!this.props.keyValidationName && !!!this.props.dataValidationName){
  33. throw Error('若要使用form提交,请设置keyValidationName或dataValidationName!');
  34. }
  35. this.state=this.setDefaultVal();
  36. }
  37. //鼠标点击标签事件
  38. TagClick = (tagData:TagDataType,index:number) =>{
  39. if(this.props.click !== undefined && this.props.click){
  40. if(this.props.checkbox){
  41. const optIf = this.optIf(index);
  42. let styleState:Array<number> = new Array();;
  43. if(typeof this.state.styleState === 'object'){
  44. styleState = [...this.state.styleState];
  45. }else{
  46. styleState = [this.state.styleState];
  47. }
  48. if(optIf.state){
  49. //点击已选择
  50. //如果设置不为空且选中选项大于1或者没有设置不为空选项
  51. //则清空
  52. if(this.props.notNull && styleState.length>1 || !!!this.props.notNull){
  53. styleState.splice(optIf.index,1);
  54. this.setState({
  55. keys:this.moveSubString(this.state.keys,tagData.key),
  56. datas:this.moveSubString(this.state.datas,tagData.data),
  57. styleState
  58. },()=>{this.setVal(this.state.datas,'data');this.setVal(this.state.keys,'key')});
  59. }
  60. }else{
  61. //点击未选择
  62. styleState.splice(styleState.length,0,index);
  63. this.setState({
  64. keys:this.addSubString(this.state.keys,tagData.key),
  65. datas:this.addSubString(this.state.datas,tagData.data),
  66. styleState
  67. },()=>{this.setVal(this.state.datas,'data');this.setVal(this.state.keys,'key')});
  68. }
  69. }else{
  70. if(this.state.styleState === index){
  71. //点击已选择
  72. //若设置可以为空
  73. //则清空
  74. if(!!!this.props.notNull){
  75. this.setState({keys:'',datas:'',styleState:this.props.data.length}
  76. ,()=>{this.setVal(this.state.datas,'data');this.setVal(this.state.keys,'key')});
  77. }
  78. }else{
  79. //点击未选择
  80. this.setState({keys:tagData.key,datas:tagData.data,styleState:index}
  81. ,()=>{this.setVal(this.state.datas,'data');this.setVal(this.state.keys,'key')});
  82. }
  83. }
  84. }
  85. }
  86. //返回移出指定子串的字符串,移出所有重复子串
  87. moveSubString = (str:string,subString:string):string => {
  88. let array:Array<string> = str.split(',');
  89. for(let i=0;i<array.length;i++){
  90. if(array[i] === subString){
  91. array.splice(i,1);
  92. }
  93. }
  94. return array.toString();
  95. }
  96. //返回增加子串的字符串,重复则不增加
  97. addSubString = (str:string,subString:string|Array<string>) =>{
  98. if(typeof subString === 'string'){
  99. let comma = str !==''?',':'';
  100. return str +comma+subString;
  101. }else{
  102. let s:string = str;
  103. for(let i=0;i<subString.length;i++){
  104. let comma = s !==''?',':'';
  105. s+=comma+subString[i];
  106. }
  107. return s;
  108. }
  109. }
  110. //选择判断
  111. optIf = (index:number):{state:boolean,index:number} => {
  112. if(typeof this.state.styleState ==='number'){
  113. return {state:this.state.styleState === index,index:0};
  114. }else{
  115. let falg:boolean = false;
  116. const styleState = this.state.styleState;
  117. let i=0;
  118. for(;i<styleState.length;i++){
  119. if(styleState[i] === index){
  120. falg = true;
  121. break;
  122. }
  123. }
  124. return {state:falg,index:i};
  125. }
  126. }
  127. //写入表单
  128. setVal = (data:string,type:string) => {
  129. if(this.props.form != undefined){
  130. let json:object = {}
  131. if(type === 'data'){
  132. if(this.props.dataValidationName !== undefined){
  133. json[this.props.dataValidationName] = data;
  134. this.props.form.setFieldsValue(json);
  135. }
  136. }else if(type === 'key'){
  137. if(this.props.keyValidationName !== undefined){
  138. json[this.props.keyValidationName] = data;
  139. this.props.form.setFieldsValue(json);
  140. }
  141. }
  142. }
  143. }
  144. //默认值转换
  145. setDefaultVal=():State=>{
  146. if(this.props.checkbox){
  147. //多选框,值为1个或数组
  148. let styleState:Array<number> = new Array();
  149. let keys:Array<string> = new Array();
  150. let datas:Array<string> = new Array();
  151. const {defaultKey,data} = this.props;
  152. if(typeof defaultKey === 'object'){
  153. for(let i=0;i<defaultKey.length;i++){
  154. for(let j=0;j<data.length;j++){
  155. if(defaultKey[i] === data[j].key){
  156. styleState.push(i);
  157. keys.push(data[j].key);
  158. datas.push(data[j].data);
  159. }
  160. }
  161. }
  162. return {
  163. keys:this.addSubString('',keys),
  164. datas:this.addSubString('',datas),
  165. styleState
  166. }
  167. }else{
  168. let i:number = 0;
  169. let key:string = '';
  170. let dat:string = '';
  171. for(;i<data.length;i++){
  172. if(data[i].key === defaultKey){
  173. key=data[i].key;
  174. dat=data[i].data;
  175. break;
  176. }
  177. }
  178. return { keys:key,datas:dat,styleState: i };
  179. }
  180. }else if(this.props.checkbox === undefined && typeof this.props.defaultKey ==='string' ||
  181. !this.props.checkbox && typeof this.props.defaultKey ==='string'){
  182. //多选未设置且默认值为1个或单选且默认值为一个
  183. let i:number = 0;
  184. let key:string = '';
  185. let dat:string = '';
  186. if(this.props.defaultKey !== undefined){
  187. const data = this.props.data;
  188. for(;i<data.length;i++){
  189. if(data[i].key === this.props.defaultKey){
  190. key=data[i].key;
  191. dat=data[i].data;
  192. break;
  193. }
  194. }
  195. }
  196. return { keys:key,datas:dat,styleState: i };
  197. }else if(this.props.defaultKey === undefined || this.props.defaultKey === '' || this.props.defaultKey === []){
  198. if(this.props.checkbox){
  199. return { keys:'',datas:'',styleState: [] };
  200. }else{
  201. return { keys:'',datas:'',styleState: this.props.data.length };
  202. }
  203. }else{
  204. return {keys:'',datas:'',styleState: this.props.data.length};
  205. }
  206. }
  207. render() {
  208. const content:any = this.props.data.map((tagData:TagDataType,index:number)=>{
  209. const cursor:any = this.props.click !== undefined && this.props.click ?'pointer':'default';
  210. return(
  211. <Tag color={tagData.color} key={tagData.key} onClick={this.TagClick.bind(this,tagData,index)} style={{cursor}}>
  212. {tagData.data}
  213. {this.optIf(index).state?<Icon type="check" />:undefined}
  214. </Tag>
  215. )
  216. });
  217. return (
  218. <Fragment>
  219. {content}
  220. {
  221. !!this.props.click && !!this.props.form && !!this.props.form.getFieldDecorator && !!this.props.keyValidationName?
  222. this.props.form.getFieldDecorator(this.props.keyValidationName, {
  223. initialValue:this.state.keys,
  224. })(<Input type="hidden"/>)
  225. :undefined
  226. }
  227. {
  228. !!this.props.click && !!this.props.form &&!!this.props.form.getFieldDecorator && !!this.props.dataValidationName
  229. && !!!this.props.keyValidationName?
  230. this.props.form.getFieldDecorator(this.props.dataValidationName, {
  231. initialValue:this.state.datas,
  232. })(<Input type="hidden"/>)
  233. :undefined
  234. }
  235. </Fragment>
  236. );
  237. }
  238. }
  239. export default TagOpt;

效果:

也可以在普通页面中调用:

获取值

效果:

封装一个漂亮的ant design form标签组件的更多相关文章

  1. 2017.11.6 - ant design table等组件的使用,以及 chrome 中 network 的使用

    一.今日主要任务 悉尼小程序后台管理开发: 景点管理页面: 获取已有数据列表,选取部分数据呈现在表格中,根据景点名称.分类过滤出对应的景点.   二.难点 1. 项目技术选取: ant design. ...

  2. 使用Ant Design的select组件时placeholder不生效/不起作用的解决办法

    先来说说使用Ant Design和Element-ui的感觉吧. 公司的项目开发中用的是vue+element-ui,使用了一通下来后,觉得element-ui虽然也有一些问题或坑,但这些小问题或坑凭 ...

  3. react的ant design的UI组件库

    PC官网:https://ant.design/ 移动端网址:https://mobile.ant.design/docs/react/introduce-cn antd-mobile :是 Ant ...

  4. 基于ant design form的二次封装

    // standardForm.js import React, { PureComponent } from 'react'; import PropTypes from 'prop-types'; ...

  5. ant design 的Table组件固定表头时不对齐

    现在有一个表格,里面的列数是不固定的(可以重复写入数据),且列数行数都可能很多,就带来一个问题: 必须要固定表头,但是antd 的表格组件设置了固定表格 scroll={{x:1000,y:300}} ...

  6. Ant Design 日期选择组件RangePicker 选择时间范围后计算范围内的天数。

    /** *需求:同年同月,同年不同月(两个月相减大于1,小于1),不同年(两个年相减大于1(是否为闰年),小于1),起止包含的月份及天 */ //首先引入组件 import { DatePicker} ...

  7. Ant Design of Vue 组件库的使用

    文档里面很清楚 安装步骤    这是全部引入的 1  有的组价涉及到汉化的问题 import moment from 'moment' import '../../../../node_modules ...

  8. 使用Ant Design写一个仿微软ToDo

    实习期的第一份活,自己看Ant Design的官网学习,然后用Ant Design写一个仿微软ToDo. 不做教学目的,只是记录一下. 1.学习 Ant Design 是个组件库,想要会用,至少要知道 ...

  9. 同时使用 Ant Design of React 中 Mention 和 Form

    使用场景,在一个列表中,点击每一行会弹出一个表单,通过修改表单数据并提交来修改这一行的数据,其中某个数据的填写需要通过Mention实现动态提示及自动补全的功能. 具体效果为: 遇到的问题: 1.希望 ...

随机推荐

  1. 二、vim的保存文件和退出命令

    vim的保存文件和退出命令   命令 简单说明 :w 保存编辑后的文件内容,但不退出vim编辑器.这个命令的作用是把内存缓冲区中的数据写到启动vim时指定的文件中. :w! 强制写文件,即强制覆盖原有 ...

  2. 【Unity|C#】基础篇(7)——属性(Property)/ 索引器(Indexer)

    [学习资料] <C#图解教程>(第6章):https://www.cnblogs.com/moonache/p/7687551.html 电子书下载:https://pan.baidu.c ...

  3. ansible笔记(12):变量(一)

    1.定义变量规范 先说说怎样定义变量,变量名应该由字母.数字.下划线组成,变量名需要以字母开头,ansible内置的关键字不能作为变量名. 2.定义变量,使用关键字:vars 定义变量用vars,调用 ...

  4. 压缩包安装mysql8.0

    在使用django的时候遇到一个错误,就是用脚本改变数据库的时候,发现mysql的版本不够,需要的版本应该大于5.8,而我的只有5.5,就很烦,恰好我之前有8.0的压缩包.(mysql重装已经不下十次 ...

  5. LitElement(一)概述

    1.一些感悟 自从踏入编程领域开始,从html,css,JavaScript,jQuery,bootstrap开始接触前端,经常用NodeJS,ejs等模板语言来写个简单的页面,感觉蛮简单的,也不怎么 ...

  6. Request原理

  7. jvm(2):垃圾收集和内存分配

    typora-root-url: ./ 垃圾收集 垃圾收集器关注的是线程共享的这部分内存. jvisualvm用来监控JVM的运行情况,可以用它来查看和浏览Heap Dump.Thread Dump. ...

  8. 三种方法获取 lua时间戳

    ngx.now()    返回:1523174287.735    毫秒级精度的时间戳(获取的是nginx缓存的时间戳,并非实时刷新, 如果希望刷新,可以在获取前一行加上 ngx.update_tim ...

  9. selenium参数化-ddt模块

    DDT介绍: DDT(数据驱动测试)允许您通过使用不同的测试数据运行一个测试用例来使其倍增,并使它显示为多个测试用例.要使用DDT需要安装,安装命令:pip install ddt 使用方法: dd. ...

  10. 【常识】常用RGB颜色对照表

    RGB颜色表 白色:rgb(255,255,255) 黑色:rgb(0,0,0) 红色:rgb(255,0,0) 绿色:rgb(0,255,0) 蓝色:rgb(0,0,255) 青色:rgb(0,25 ...