Vous devez d'abord installer le composant
react-validation-boo , je suppose que vous êtes familier avec react et savez comment le configurer.
npm installer react-validation-booAfin de ne pas trop parler, je vais immédiatement donner un petit exemple de code.
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);
Analysons ce code.
Commençons par la fonction
connect , nous lui passons nos règles de validation et d'autres paramètres supplémentaires. En appelant cette méthode, nous obtenons une nouvelle fonction dans laquelle nous transmettons notre composant (
MyForm ) afin qu'il
reçoive les méthodes nécessaires pour travailler avec la validation de formulaire dans les
accessoires .
Dans la fonction de
rendu de notre composant, nous
renvoyons le composant
Form que nous connectons aux règles de validation
connect = {this.props.connect} . Il s'agit d'une conception nécessaire pour que
Form sache comment valider les composants imbriqués.
<Input type = "text" name = "name" /> le champ de saisie que nous allons vérifier, nous avons passé les règles de vérification pour se
connecter dans la propriété
rules . Dans notre cas, ce
nom ne doit pas être vide (
obligatoire ).
Nous avons également passé le
middleware: logger pour se
connecter afin de voir comment fonctionne la validation dans la console.
Dans les
accessoires de notre composant, nous avons obtenu un ensemble de fonctions:
- vBoo.isValid () - retourne vrai si tous les composants d'entrée ont été validés
- vBoo.hasError (name) - renvoie true si le composant avec la propriété name n'est pas valide
- vBoo.getError (nom) - pour un composant avec la propriété name , retourne le texte d'erreur
Maintenant, nous allons le compliquer progressivement, nous allons d'abord passer la langue pour se
connecter , afin que nous puissions changer les règles de validation en fonction de la langue, et également ajouter des champs supplémentaires et des règles de validation.
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);
Dans cet exemple, la case à cocher se
souvenir en russe doit être installée
obligatoire , mais dans d'autres elle est toujours valide.
Nous avons également passé les
étiquettes de fonction
(lang) pour se
connecter , qui renvoie le nom des champs sous une forme lisible.
Dans les
accessoires de votre composant, il y a une fonction
getLabel (nom) qui retourne la valeur passée à la fonction
labels , ou s'il n'y a pas une telle valeur, elle retourne le
nom .
Composants principaux de VBoo
Form ,
Input ,
InputRadio ,
InputCheckbox ,
Select ,
Textarea .
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);
Règles de validation
Voyons comment écrire nos propres règles de validation.
Pour écrire une règle, vous devez créer une classe qui sera héritée de la classe de
validateur .
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;
Connectez maintenant notre validateur au formulaire.
import myValidator from 'path/myValidator';
Afin de ne pas enregistrer toutes vos règles de validation à chaque fois, créez un fichier séparé où elles seront enregistrées et connectez ses
valideurs: `` import '' file-validation`` . Et s'il existe des règles spéciales pour ce formulaire, alors les
validateurs: Object.assign ({}, `import 'file-validation``, {...})Scénarios
Considérez les cas où nous devons modifier les règles de validation en fonction des actions effectuées sur le formulaire.
Par défaut, nous avons un script appelé
default , dans les règles nous pouvons spécifier sous quel scénario effectuer cette validation.
Si aucun script n'est spécifié, la validation sera effectuée pour tous les scénarios.
rules = () => ([ [ 'name', 'required', { error: '%name% ' } ], [ 'name', 'myValidator', { scenario: ['default', 'scenario1'] } ], [ 'email', 'email', { scenario: 'scenario1' } ] ])
La fonction est passée à travers la propriété
props de notre composant:
- vBoo.setScenario (scenario) - définit le script de scénario , il peut s'agir d'une chaîne ou d'un tableau, si nous avons plusieurs scripts actifs à la fois
- vBoo.getScenario () - retourne le script ou le tableau de scripts en cours
- vBoo.hasScenario (nom) - si ce script est installé maintenant, chaîne de nom
Ajoutons un objet
scenaries dans notre formulaire, dans lequel nous allons stocker tous les scripts possibles,
true le script est actif,
false ne l'
est pas.
Ainsi que les fonctions
addScenaries et
deleteScenaries qui ajouteront et supprimeront des scripts.
Si nous avons sélectionné «cohabitation» ou «mariage», nous ajoutons un champ de commentaire et naturellement ce champ ne doit être validé que dans ce cas, le
scénario marié .
Si nous avons la case à cocher "Avancé", alors nous ajoutons des champs supplémentaires qui seront requis, le script '
scenario-addition '.
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);
Afin de ne pas rendre l'article très volumineux, je continuerai dans le suivant, où j'écrirai comment créer mes composants (par exemple, un calendrier ou inputSearch) et les valider, comment les associer à redux et plus encore.