Primero necesita instalar el componente
react-validation-boo , supongo que está familiarizado con react y sabe cómo configurarlo.
npm install react-validation-booPara no hablar mucho, inmediatamente daré un pequeño ejemplo de código.
import React, {Component} from 'react'; import {connect, Form, Input, logger} from 'react-validation-boo'; class MyForm extends Component { sendForm = (event) => { event.preventDefault(); if(this.props.vBoo.isValid()) { console.log(' ', this.props.vBoo.getValues()); } else { console.log(' ', this.props.vBoo.getErrors()); } }; getError = (name) => { return this.props.vBoo.hasError(name) ? <div className="error">{this.props.vBoo.getError(name)}</div> : ''; }; render() { return <Form connect={this.props.vBoo.connect}> <div> <Input type="text" name="name" /> {this.getError('name')} </div> <button onClick={this.sendForm}> {this.props.vBoo.isValid() ? ' ': ' !!!'} </button> </Form> } } export default connect({ rules: () => ( [ ['name', 'required'], ] ), middleware: logger })(MyForm);
Analicemos este código.
Comencemos con la función de
conexión , le pasamos nuestras reglas de validación y otros parámetros adicionales. Al llamar a este método, obtenemos una nueva función en la que pasamos nuestro componente (
MyForm ) para que
reciba los métodos necesarios para trabajar con la validación de formularios en
accesorios .
En la función de
representación de nuestro componente, devolvemos el componente de
formulario que conectamos a las reglas de validación
connect = {this.props.connect} . Este es un diseño necesario para que el
Formulario sepa cómo validar componentes anidados.
<Input type = "text" name = "name" /> el campo de entrada que revisaremos, pasamos las reglas de verificación para
conectarnos en la propiedad de
reglas . En nuestro caso, este
nombre no debe estar vacío (
obligatorio ).
También pasamos
middleware: logger para
conectarse para ver cómo funciona la validación en la consola.
En los
accesorios de nuestro componente, tenemos un conjunto de funciones:
- vBoo.isValid () : devuelve verdadero si todos los componentes de entrada han sido validados
- vBoo.hasError (nombre) : devuelve verdadero si el componente con la propiedad de nombre no es válido
- vBoo.getError (nombre) : para un componente con la propiedad de nombre , devuelve el texto de error
Ahora lo complicaremos gradualmente, primero pasaremos el idioma para
conectarnos , de modo que podamos cambiar las reglas de validación según el idioma, y también agregar campos y reglas de validación adicionales.
import React, {Component} from 'react'; import {connect, Form, Input, InputCheckbox} from 'react-validation-boo'; class MyForm extends Component { sendForm = (event) => { event.preventDefault(); if(this.props.vBoo.isValid()) { console.log(' ', this.props.vBoo.getValues()); } else { console.log(' ', this.props.vBoo.getErrors()); } }; getError = (name) => { return this.props.vBoo.hasError(name) ? <div className="error">{this.props.vBoo.getError(name)}</div> : ''; }; render() { return <Form connect={this.props.vBoo.connect}> <div> <label>{this.props.vBoo.getLabel('name')}:</label> <Input type="text" name="name" /> {this.getError('name')} </div> <div> <label>{this.props.vBoo.getLabel('email')}:</label> <Input type="text" name="email" value="default@mail.ru" /> {this.getError('email')} </div> <div> <label>{this.props.vBoo.getLabel('remember')}:</label> <InputCheckbox name="remember" value="yes" /> {this.getError('remember')} </div> <button onClick={this.sendForm}> {this.props.vBoo.isValid() ? ' ': ' !!!'} </button> </Form> } } export default connect({ rules: (lang) => { let rules = [ [ ['name', 'email'], 'required', { error: '%name% ' } ], ['email', 'email'] ]; rules.push(['remember', lang === 'ru' ? 'required': 'valid']); return rules; }, labels: (lang) => ({ name: '', email: ' ', remember: '' }), lang: 'ru' })(MyForm);
En este ejemplo, la casilla de verificación
recordar en ruso debe estar instalada, pero en otros siempre es válida.
También pasamos las
etiquetas de función
(lang) para
conectarse , que devuelve el nombre de los campos en un formato legible.
En los
accesorios de su componente, hay una función
getLabel (nombre) que devuelve el valor pasado a la función de
etiquetas , o si no existe dicho valor, devuelve el
nombre .
Componentes principales de VBoo
Formulario ,
Entrada ,
Radio de entrada ,
EntradaCheckbox ,
Seleccionar ,
Área de texto .
import React, {Component} from 'react'; import {connect, Form, Input, Select, InputRadio, InputCheckbox, Textarea} from 'react-validation-boo'; class MyForm extends Component { sendForm = (event) => { event.preventDefault(); if(this.props.vBoo.isValid()) { console.log(' ', this.props.vBoo.getValues()); } else { console.log(' ', this.props.vBoo.getErrors()); } }; getError = (name) => { return this.props.vBoo.hasError(name) ? <div className="error">{this.props.vBoo.getError(name)}</div> : ''; }; render() { return <Form connect={this.props.vBoo.connect}> <div> <label>{this.props.vBoo.getLabel('name')}:</label> <Input type="text" name="name" /> {this.getError('name')} </div> <div> <label>{this.props.vBoo.getLabel('email')}:</label> <Input type="text" name="email" value="default@mail.ru" /> {this.getError('email')} </div> <div> <label>{this.props.vBoo.getLabel('gender')}:</label> <Select name="gender"> <option disabled> </option> <option value="1"></option> <option value="2"></option> </Select> {this.getError('gender')} </div> <div> <div>{this.props.vBoo.getLabel('familyStatus')}:</div> <div> <InputRadio name="familyStatus" value="1" checked /> <label></label> </div> <div> <InputRadio name="familyStatus" value="2" /> <label></label> </div> <div> <InputRadio name="familyStatus" value="3" /> <label></label> </div> {this.getError('familyStatus')} </div> <div> <label>{this.props.vBoo.getLabel('comment')}:</label> <Textarea name="comment"></Textarea> {this.getError('comment')} </div> <div> <label>{this.props.vBoo.getLabel('remember')}:</label> <InputCheckbox name="remember" value="yes" /> {this.getError('remember')} </div> <button onClick={this.sendForm}> {this.props.vBoo.isValid() ? ' ': ' !!!'} </button> </Form> } } export default connect({ rules: () => ([ [ ['name', 'email'], 'required', { error: '%name% ' } ], ['email', 'email'], [['gender', 'familyStatus', 'comment', 'remember'], 'valid'] ]), labels: () => ({ name: '', email: ' ', gender: '', familyStatus: ' ', comment: '', remember: '' }), lang: 'ru' })(MyForm);
Reglas de validación
Veamos cómo escribir nuestras propias reglas de validación.
Para escribir una regla, debe crear una clase que se heredará de la clase de
validador .
import {validator} from 'react-validation-boo'; class myValidator extends validator { validate(name, value, params) { let lang = this.getLang(); let pattern = /^\d+$/; if(!pattern.test(value)) { let error = params.error || ' %name% %value%'; error = error.replace('%name%', name); error = error.replace('%value%', value); this.addError(error); } } } export default myValidator;
Ahora conecte nuestro validador al formulario.
import myValidator from 'path/myValidator';
Para no registrar todas sus reglas de validación cada vez, cree un archivo separado donde se registrarán y conecte sus
validadores: `` importación 'validación de archivos' ' . Y si hay reglas especiales para este formulario, los
validadores: Object.assign ({}, `import 'file-validation``, {...})Escenarios
Considere los casos en los que necesitamos cambiar las reglas de validación dependiendo de las acciones realizadas en el formulario.
Por defecto, tenemos un script llamado
default , en las reglas que podemos especificar bajo qué escenario llevar a cabo esta validación.
Si no se especifica ningún script, la validación se realizará para todos los escenarios.
rules = () => ([ [ 'name', 'required', { error: '%name% ' } ], [ 'name', 'myValidator', { scenario: ['default', 'scenario1'] } ], [ 'email', 'email', { scenario: 'scenario1' } ] ])
La función se pasa a través de la propiedad de
accesorios de nuestro componente:
- vBoo.setScenario (escenario) : establece el script del escenario, puede ser una cadena o una matriz, si tenemos varios scripts activos a la vez
- vBoo.getScenario () : devuelve el script actual o la matriz de scripts
- vBoo.hasScenario (nombre) : si este script está instalado ahora, nombre cadena
Agreguemos un objeto de
escenarios en nuestro formulario, en el que almacenaremos todos los guiones posibles,
verdadero el guión está activo,
falso no.
Además de las funciones
addScenaries y
deleteScenaries que agregarán y eliminarán scripts.
Si hemos seleccionado "cohabitación" o "matrimonio", entonces agregamos un campo de comentarios y, naturalmente, este campo debe validarse solo en este caso, el
escenario de escenario casado .
Si tenemos activada la casilla de verificación "Avanzado", agregaremos campos adicionales que serán necesarios, el script '
escenario-adición '.
import React, {Component} from 'react'; import {connect, Form, Input, Select, InputRadio, InputCheckbox, Textarea} from 'react-validation-boo'; class MyForm extends Component { constructor() { super(); this.scenaries = { 'scenario-married': false, 'scenario-addition': false } } changeScenaries(addScenaries = [], deleteScenaries = []) { addScenaries.forEach(item => this.scenaries[item] = true); deleteScenaries.forEach(item => this.scenaries[item] = false); let scenario = Object.keys(this.scenaries) .reduce((result, item) => this.scenaries[item]? result.concat(item): result, []); this.props.vBoo.setScenario(scenario); } addScenaries = (m = []) => this.changeScenaries(m, []); deleteScenaries = (m = []) => this.changeScenaries([], m); sendForm = (event) => { event.preventDefault(); if(this.props.vBoo.isValid()) { console.log(' ', this.props.vBoo.getValues()); } else { console.log(' ', this.props.vBoo.getErrors()); } }; getError = (name) => { return this.props.vBoo.hasError(name) ? <div className="error">{this.props.vBoo.getError(name)}</div> : ''; }; changeFamilyStatus = (event) => { let val = event.target.value; if(val !== '1') { this.addScenaries(['scenario-married']) } else { this.deleteScenaries(['scenario-married']); } }; changeAddition = (event) => { let check = event.target.checked; if(check) { this.addScenaries(['scenario-addition']) } else { this.deleteScenaries(['scenario-addition']); } }; getCommentContent() { if(this.props.vBoo.hasScenario('scenario-married')) { return ( <div key="comment-content"> <label>{this.props.vBoo.getLabel('comment')}:</label> <Textarea name="comment"></Textarea> {this.getError('comment')} </div> ); } return ''; } getAdditionContent() { if(this.props.vBoo.hasScenario('scenario-addition')) { return ( <div key="addition-content"> <label>{this.props.vBoo.getLabel('place')}:</label> <Input type="text" name="place" /> {this.getError('place')} </div> ); } return ''; } render() { return <Form connect={this.props.vBoo.connect}> <div> <label>{this.props.vBoo.getLabel('name')}:</label> <Input type="text" name="name" /> {this.getError('name')} </div> <div> <label>{this.props.vBoo.getLabel('email')}:</label> <Input type="text" name="email" value="default@mail.ru" /> {this.getError('email')} </div> <div> <label>{this.props.vBoo.getLabel('gender')}:</label> <Select name="gender"> <option disabled> </option> <option value="1"></option> <option value="2"></option> </Select> {this.getError('gender')} </div> <div> <div>{this.props.vBoo.getLabel('familyStatus')}:</div> <div> <InputRadio name="familyStatus" value="1" checked onChange={this.changeFamilyStatus} /> <label></label> </div> <div> <InputRadio name="familyStatus" value="2" onChange={this.changeFamilyStatus} /> <label></label> </div> <div> <InputRadio name="familyStatus" value="3" onChange={this.changeFamilyStatus} /> <label></label> </div> {this.getError('familyStatus')} </div> {this.getCommentContent()} <div> <label>{this.props.vBoo.getLabel('addition')}:</label> <InputCheckbox name="addition" value="yes" onChange={this.changeAddition} /> {this.getError('addition')} </div> {this.getAdditionContent()} <button onClick={this.sendForm}> {this.props.vBoo.isValid() ? ' ': ' !!!'} </button> </Form> } } export default connect({ rules: () => ([ [ ['name', 'gender', 'familyStatus', 'email'], 'required', { error: '%name% ' } ], ['email', 'email'], [ 'comment', 'required', { scenario: 'scenario-married' } ], ['addition', 'valid'], [ 'place', 'required', { scenario: 'scenario-addition' } ], ]), labels: () => ({ name: '', email: ' ', gender: '', familyStatus: ' ', comment: '', addition: '', place: '' }), lang: 'ru' })(MyForm);
Para no hacer el artículo muy extenso, continuaré en el siguiente, donde escribiré cómo crear mis componentes (por ejemplo, un calendario o inputSearch) y validarlos, cómo asociarlos con redux y más.