import React from 'react' import { Upload, Input, Button,Select,Icon, Row, Col, message,Tag, Tooltip, Card, Divider, Switch, InputNumber, Form } from 'antd'; import AceEditor from "react-ace"; import "brace/mode/javascript"; import UUID from 'react-native-uuid'; const FormItem = Form.Item const Option=Select.Option const types={ "string": "字符", "number": "数字", "boolean":"布尔值", "method": "公式", "regexp":"正则表达式", "integer": "整数", "float":"浮点数", "array": "列表", "object": "对象", "enum": "枚举", "date": "日期", "url":"超链接", "hex": "16进制数", "email": "邮箱", "any": "任意" } class Enums extends React.Component{ state = { inputVisible: false, inputValue: '', }; handleClose = removedTag => { const tags = this.props.value.filter(tag => tag !== removedTag); this.props.onChange(tags) }; showInput = () => { this.setState({ inputVisible: true }, () => this.input.focus()); }; handleInputChange = e => { this.setState({ inputValue: e.target.value }); }; handleInputConfirm = () => { const { inputValue } = this.state; let tags = this.props.value; if (inputValue && tags.indexOf(inputValue) === -1) { tags = [...tags, inputValue]; } this.setState({ inputVisible: false, inputValue: '', }); this.props.onChange(tags) }; saveInputRef = input => (this.input = input); render() { const { inputVisible, inputValue } = this.state; const tags= this.props.value return ( <div> {tags.map((tag, index) => { const isLongTag = tag.length > 20; const tagElem = ( <Tag key={tag} 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' }}> <Icon type="plus" /> New Tag </Tag> )} </div> ); } } export default class Validator extends React.Component { constructor(props) { super(props) const value = props.value || []; this.state = { rules: value } } triggerChange = (changedValue) => { // Should provide an event to pass value to Form. const onChange = this.props.onChange; if (onChange) { onChange(changedValue); } } componentWillReceiveProps(nextProps) { // Should be a controlled component. if ('value' in nextProps) { const value = nextProps.value; this.setState(value); } } change = (i, t, e) => { const { rules } = this.state if (t == "message"||t == "pattern") { rules[i][t] = e.target.value } else { rules[i][t] = e if(t=="type"&&e=="date"){ rules[i].validatorFunc="var errors = [];if (!( typeof value.getTime === 'function' &&typeof value.getMonth === 'function' &&typeof value.getYear === 'function')) {errors.push(new Error('请输入日期!', rule.field));} callback(errors);" } } if (!('value' in this.props)) { this.setState({ rules }); } this.triggerChange(rules); } add = () => { const { rules } = this.state rules.push({ id: UUID.v4() ,message:"请输入"}) if (!('value' in this.props)) { this.setState({ rules }); } this.triggerChange(rules); } delete = (i) => { const { rules } = this.state rules.splice(i, 1) if (!('value' in this.props)) { this.setState({ rules }); } this.triggerChange(rules); } render() { const { rules } = this.state return ( <div> <Button size="small" type="primary" style={{ margin: "auto" }} onClick={this.add}>新增</Button> <div style={{ minHeight: 10 }}> {rules.map((r, i) => <div key={r.id}> <FormItem label="类型" labelCol={{ span: 8 }} wrapperCol={{ span: 16 }}> <Select style={{width:150}} onChange={this.change.bind(this, i, "type")} value={r.type} > {Object.keys(types).map((ty)=><Option key={ty} value={ty}>{types[ty]}</Option>)} </Select> </FormItem> <FormItem label="是否必填" labelCol={{ span: 8 }} wrapperCol={{ span: 16 }}> <Switch onChange={this.change.bind(this, i, "required")} checked={r.required} /> </FormItem> <FormItem label="正则表达式" labelCol={{ span: 8 }} wrapperCol={{ span: 16 }}> <Input onChange={this.change.bind(this, i, "pattern")} value={r.pattern} /> </FormItem> <FormItem label="最小值" labelCol={{ span: 8 }} wrapperCol={{ span: 16 }}> <InputNumber onChange={this.change.bind(this, i, "min")} value={r.min} /> </FormItem> <FormItem label="最大值" labelCol={{ span: 8 }} wrapperCol={{ span: 16 }}> <InputNumber onChange={this.change.bind(this, i, "max")} value={r.max} /> </FormItem> <FormItem label="长度" labelCol={{ span: 8 }} wrapperCol={{ span: 16 }}> <InputNumber onChange={this.change.bind(this, i, "len")} value={r.len} /> </FormItem> <FormItem label={<span><span style={{color:"red"}}> * </span>错误提示</span>} labelCol={{ span: 8 }} wrapperCol={{ span: 16 }}> <Input onChange={this.change.bind(this, i, "message")} value={r.message} /> </FormItem> <FormItem label="枚举" labelCol={{ span: 8 }} wrapperCol={{ span: 16 }}> <Enums onChange={this.change.bind(this, i, "enum")} value={r.enum||[]}/> </FormItem> <FormItem label="自定义验证" labelCol={{ span: 24 }} wrapperCol={{ span: 24 }}> <AceEditor height={300} width="100%" onChange={this.change.bind(this, i, "validatorFunc")} placeholder="var errors = [];\n if (value == 'xxx') { errors.push(new Error('请输入正确值!', rule.field)); } callback(errors); " mode={"javascript"} theme={"textmate"} fontSize={12} showPrintMargin={true} showGutter={true} highlightActiveLine={true} value={r.validatorFunc} name="UNIQUE_ID_OF_DIV" // keyboardHandler="vim" setOptions={{ enableBasicAutocompletion: true, enableLiveAutocompletion: true, enableSnippets: true, showLineNumbers: true, tabSize: 2, }} editorProps={{ $blockScrolling: true }} /> </FormItem> <Button type="danger" style={{ margin: "auto" }} size="small" onClick={this.delete.bind(this, i)}>删除</Button> </div>) }</div> </div> ) } }