J'essaie de construire un formulaire avec des champs conditionnels à partir d'un schéma JSON en utilisant react-jsonschema-form y react-jsonschem-formalités conditionnelles .
Les composants que je rends sont un FormWithConditionals
et un FormModelInspector
. Ce dernier est un composant très simple qui montre le modèle de formulaire.
Le code source correspondant est le suivant :
import React from 'react';
import PropTypes from 'prop-types';
import Engine from "json-rules-engine-simplified";
import Form from "react-jsonschema-form";
import applyRules from "react-jsonschema-form-conditionals";
function FormModelInspector (props) {
return (
<div>
<div className="checkbox">
<label>
<input type="checkbox" onChange={props.onChange} checked={props.showModel}/>
Show Form Model
</label>
</div>
{
props.showModel && <pre>{JSON.stringify(props.formData, null, 2)}</pre>
}
</div>
)
}
class ConditionalForm extends React.Component {
constructor (props) {
super(props);
this.state = {
formData: {},
showModel: true
};
this.handleFormDataChange = this.handleFormDataChange.bind(this);
this.handleShowModelChange = this.handleShowModelChange.bind(this);
}
handleShowModelChange (event) {
this.setState({showModel: event.target.checked});
}
handleFormDataChange ({formData}) {
this.setState({formData});
}
render () {
const schema = {
type: "object",
title: "User form",
properties: {
nameHider: {
type: 'boolean',
title: 'Hide name'
},
name: {
type: 'string',
title: 'Name'
}
}
};
const uiSchema = {};
const rules = [{
conditions: {
nameHider: {is: true}
},
event: {
type: "remove",
params: {
field: "name"
}
}
}];
const FormWithConditionals = applyRules(schema, uiSchema, rules, Engine)(Form);
return (
<div className="row">
<div className="col-md-6">
<FormWithConditionals schema={schema}
uiSchema={uiSchema}
formData={this.state.formData}
onChange={this.handleFormDataChange}
noHtml5Validate={true}>
</FormWithConditionals>
</div>
<div className="col-md-6">
<FormModelInspector formData={this.state.formData}
showModel={this.state.showModel}
onChange={this.handleShowModelChange}/>
</div>
</div>
);
}
}
ConditionalForm.propTypes = {
schema: PropTypes.object.isRequired,
uiSchema: PropTypes.object.isRequired,
rules: PropTypes.array.isRequired
};
ConditionalForm.defaultProps = {
uiSchema: {},
rules: []
};
Cependant, chaque fois que je modifie la valeur d'un champ, celui-ci perd le focus. Je soupçonne que la cause du problème est quelque chose dans le fichier react-jsonschema-form-conditionals
car si je remplace <FormWithConditionals>
con <Form>
le problème ne se pose pas.
Si je supprime le gestionnaire onChange={this.handleFormDataChange}
le champ de saisie ne perd plus le focus lorsque sa valeur change (mais la suppression de ce gestionnaire interrompt le fonctionnement de l'application FormModelInspector
).
A l'écart
Dans le code ci-dessus, si je supprime le gestionnaire onChange={this.handleFormDataChange}
, le <FormModelInspector>
n'est pas mis à jour lorsque les données du formulaire sont modifiées. Je ne comprends pas pourquoi ce gestionnaire est nécessaire car la fonction <FormModelInspector>
reçoit une référence aux données du formulaire par l'intermédiaire de la fonction formData
attribut. Peut-être est-ce dû au fait que chaque modification des données du formulaire entraîne la construction d'un nouvel objet, plutôt qu'une modification du même objet ?