UNPKG

@piscium2010/v-form

Version:

This is not a form, instead it is only a form shell of which the single responsibility is validating and providing error messages. Capable of definding flexiable rules and validating multi fields at a time.

109 lines (99 loc) 4.04 kB
import React, { useState } from 'react' import { makeStyles } from '@material-ui/core/styles' import Button from '@material-ui/core/Button' import TextField from '@material-ui/core/TextField' import Select from '@material-ui/core/Select' import MenuItem from '@material-ui/core/MenuItem' import InputLabel from '@material-ui/core/InputLabel' import { MuiPickersUtilsProvider, KeyboardDatePicker } from '@material-ui/pickers' import DateFnsUtils from '@date-io/date-fns' import VForm, { v } from 'v-form' const useStyles = makeStyles(theme => ({ textField: { width: 300, marginBottom: 5 }, select: { width: 300, marginBottom: 5 }, picker: { width: 300, marginBottom: 5 } })) const Field = VForm.fieldFactory(({ name, message, children }) => { const { Children, cloneElement } = React const hasError = message ? true : false const errorStyle = { color: '#f44336', fontSize: 12, marginBottom: 15 } return ( <div> {Children.map(children, c => cloneElement(c, { error: hasError }))} <div style={errorStyle}>{message}</div> </div> ) }) const validation = v.create({ email: v.expect('Required').expect('Should be email', c => v.isEmail(c.email)), marriage: v.expect('Required'), birth_date: v.expect('Required') .expect( 'Seriouly? Just born?', c => c.birth_date.getFullYear() < new Date().getFullYear() ) }) export default function Form() { const [values, setValues] = useState({ email: '', marriage: '', birth_date: new Date() }) const update = value => { validation.test(value, values/* context */) setValues({ ...values, ...value }) } const onSubmit = () => { const result = validation.testAllRules(values) if (result.pass) { window.alert('pass') } } const classes = useStyles(); const style = { margin: 'auto', width: 380 } return ( <MuiPickersUtilsProvider utils={DateFnsUtils}> <div style={style}> <p>Validation rules as:</p> <ul> <li>Email is required with correct format</li> <li>Marriage is required</li> <li>Birth date year can not be current year</li> </ul> <VForm validation={validation}> <InputLabel>Email</InputLabel> <Field name='email'> <TextField className={classes.textField} onChange={evt => update({ email: evt.target.value })} /> </Field> <InputLabel>Marriage</InputLabel> <Field name='marriage'> <Select className={classes.select} value={values.marriage} onChange={evt => update({ marriage: evt.target.value })} > <MenuItem value={'single'}>Single</MenuItem> <MenuItem value={'married'}>Married</MenuItem> </Select> </Field> <InputLabel>Birth Date</InputLabel> <Field name='birth_date'> <KeyboardDatePicker className={classes.picker} format="MM/dd/yyyy" value={values.birth_date} onChange={d => update({ birth_date: d })} /> </Field> <Button variant="contained" color="primary" className={classes.button} onClick={onSubmit} > Submit </Button> </VForm> </div> </MuiPickersUtilsProvider> ) }