1
votes

Calculer automatiquement les champs de saisie

Quelqu'un pourrait-il aider à répondre à ceci:

J'ai 2 contrôles NumberInput, une entrée et l'autre est désactivée. Je dois entrer le numéro dans le premier champ de saisie, le champ désactivé pour afficher ce nombre / 100. Les deux NumberInput auront des champs source qui seront enregistrés dans l'enregistrement actuel dans le formulaire simple.

Comment faire cela dans react-admin

Merci


0 commentaires

3 Réponses :


1
votes

Le moyen le plus simple est d'utiliser la méthode décrite dans la documentation sous la sectionLier deux entrées

En substance: vous pouvez créer votre propre composant d'entrée où vous pouvez accéder aux valeurs du formulaire via le hook useFormState . Ensuite, attribuez simplement la valeur souhaitée transformée comme vous le souhaitez, par exemple divisée par 100.

Éditer

<FormWithRedirect /> trouvé une autre manière encore plus propre - en utilisant le final-form-Calculate pour créer un décorateur et le transmettre au composant <FormWithRedirect /> comme <FormWithRedirect /> :

import createDecorator from 'final-form-calculate'

const calculator = createDecorator(
  // Calculations:
{
   field: 'number1', // when the value of foo changes...
   updates: {
     number2: (fooValue, allValues) => allValues["number1"] * 2
   }
})

...

<FormWithRedirect
   ...
   decorators={[calculator]}
/>

Découvrez ce bac à sable de code


0 commentaires

0
votes

Utilisation de FormDataConsumer
import { useForm, useFormState } from 'react-final-form';

...

const {change} = useForm();
const { values: { my_first_input }} = useFormState({ subscription: { values: true } });


useEffect(() => {
  change('my_second_input', my_first_input / 100);
}, [change, my_first_input]);

...


<NumberInput defaultValue={my_first_input / 100} source="second_input"/>

Utilisation du hook useFormState

import { useFormState } from 'react-final-form';

...

const { values: { my_first_input }} = useFormState({ subscription: { values: true } });

...

<NumberInput defaultValue={my_first_input / 100} source="second_input"/>

Source:https://marmelab.com/react-admin/Inputs.html#linking-two-inputs

Dynamique

Vous devez utiliser le hook useForm -final-form pour rendre votre saisie dynamique:

<FormDataConsumer>
  {({ formData }) => (
    <NumberInput defaultValue={formData.my_first_input / 100} source="second_input"/>
  )}
</FormDataConsumer>

17 commentaires

Merci @Striped et Kia Kaha pour vos efforts. J'ai essayé le FormDataConsumer , il fait ce que je veux sauf que le résultat dans le second_input n'obtient le résultat que la première fois que j'entre la valeur dans first_input. Je pense que la raison en est la propriété defaultValue utilisée. Quelle autre propriété puis-je utiliser dans le second_input qui affichera le résultat à chaque fois que j'entre une valeur dans le first_input. Merci


Vous êtes les bienvenus :) J'ai mis à jour mon commentaire, essayez avec le hook useForm .


Salut Striped, merci encore. J'ai eu cette erreur Erreur: useForm doit être utilisé à l'intérieur d'un composant <Form> . J'utilise actuellement SimpleForm - je n'utilise pas de formulaire personnalisé. Quelle est également la meilleure façon d'obtenir le champ de formulaire parce que j'utilise l'enregistrement arrayinput (salesoutdet). À partir du json ci-dessous, le total doit être calculé à partir du prix unitaire et de la quantité {"salesdate": "2020-11-23", "Distributeurid": 1, "salesrep": 4, "salesoutdet": [{"unitprice": 10, "quantité": 5, "total": 50}]}


Tu as bien fait. Mais comme useForm doit être appelé dans un formulaire, vous devez vous diviser en deux composants, une fois avec le SimpleForm et un second avec son enfant où vous pouvez appeler useForm parce qu'il est enveloppé dans la SimpleForm .


Ou vous créez simplement votre propre entrée en enveloppant votre NumberInput comme décrit ici marmelab.com/react-admin/… . Cela peut également vous permettre d'utiliser à la fois les useForm et useFormState .


Salut rayé. Je suis nouveau sur React-Admin. Je vais essayer de vous le faire savoir. En attendant, où sera le useEffect lorsque j'en aurai déplacé d'autres? Merci


Ce sera là où vous serez également autorisé à appeler le hook useForm , donc dans votre wrapper enfant ou votre wrapper d'entrée personnalisé, je suppose.


Salut rayé. Merci beaucoup. J'ai finalement réussi à le faire fonctionner. Tu es une étoile!


Merci, heureux de vous aider :) n'oubliez pas de marquer la réponse comme acceptée si vous considérez que c'est la bonne.


Salut Striped.Thx 4 ystdy.Il y a un petit problème à résoudre b4 Je certifie que ce message est correct.Il fonctionne bien lorsque les entrées d sont sur l'en-tête de mon json.Lorsque les entrées sont sur le détail, il met à jour le 1er enregistrement du détails.Par exemple: voir ce json ci-dessous: j'ai besoin de trouver le total sur chacun des salesoutdet .Il ne fonctionne que sur le premier enregistrement, il échoue 4d 2nd {"id": 1 "salesoutdet": [{"unitprice": 10, "quantité": 5, "total": 50}, {"prix unitaire": 2, "quantité": 1, "total": 2}]}


Je pense que le problème est de savoir comment dire à useFormState avec quel enregistrement du tableau passé à travailler: voir mon FormDataConsumer : Le TotalField est inclus dans le DataConsumer <FormDataConsumer> {({formData, scopedFormData, getSource, ... reste}) => {retourne scopedFormData? <TotalField source = {getSource ('total')} {... reste} />: null; }} </FormDataConsumer>


Il s'agit d'un autre problème lié à l'utilisation de <ArrayInput> et SimpleFornIterator . Je vais vous laisser chercher de cette façon.


Salut rayé. Pls avez-vous une idée. J'ai cherché .. personne ne semble avoir posé la question ou savoir comment résoudre cela. Je pense que ce que j'ai besoin de savoir, c'est comment obtenir le numéro d'enregistrement réel du tableau avec lequel je travaille en ce moment. Si je peux l'obtenir, je pourrai le transmettre à useFormState pour mettre à jour le total réel


Cela dépend principalement de la manière dont vous l'avez implémenté. Comme je l'ai dit, c'est une nouvelle question que vous pouvez poser sur SO. Je ne peux pas vous aider avec si peu d'informations.


Merci rayé. Vous avez très bien fait


Salut Strped, j'ai résolu le problème que j'avais. Je l'ai fait d'une autre manière sans utiliser les hooks useForm. Voir ma réponse ci-dessus. Merci


Bon travail! Félicitations :)



0
votes

J'ai obtenu une solution plus courte à cette question: tout ce que j'ai fait était de faire le calcul dans FormDataConsumer . Maintenant, je suis en mesure d'obtenir la valeur calculée et il met à jour l'enregistrement correct dans le tableau.

Merci

<FormDataConsumer>
  {({
    formData, // The whole form data
    scopedFormData, // The data for this item of the ArrayInput
    getSource, // A function to get the valid source inside an ArrayInput
    ...rest
  }) => {
    if (typeof scopedFormData !== 'undefined') {
      scopedFormData.total = scopedFormData.quantity * scopedFormData.unitprice;
      return (
        <NumberInput disabled defaultValue={scopedFormData.total} label="Total" source={getSource('total')} />
      )
    } else {
      return(
        <NumberInput disabled label="Total" source={getSource('total')} />
      )
    }            
  }} 


0 commentaires