【问题标题】:Auto Calculate Input Fields自动计算输入字段
【发布时间】:2020-11-12 20:08:01
【问题描述】:

请有人帮忙回答这个问题:

我有 2 个 NumberInput 控件,一个输入,另一个被禁用。我需要在第一个输入字段中输入数字,禁用字段以显示此数字/100。这两个 NumberInput 将具有源字段,这些字段将保存到 simpleform 中的当前记录。

如何在 react-admin 中执行此操作

谢谢

【问题讨论】:

    标签: react-admin


    【解决方案1】:

    最简单的方法是使用Linking two inputs部分下的文档中描述的方法

    本质上:您可以创建自己的输入组件,您可以在其中通过钩子useFormState 访问表单值。然后只需按照您想要的方式分配所需的值,例如除以 100。

    编辑

    找到了一种更简洁的方法 - 使用 final-form-calculate 创建装饰器并将其传递给 <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]}
    />
    

    看看这个code sandbox

    【讨论】:

      【解决方案2】:

      使用 FormDataConsumer

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

      使用 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"/>
      

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

      动态

      您需要使用 react-final-formuseForm 挂钩来使您的输入动态化:

      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"/>
      

      【讨论】:

      • 感谢@Striped 和 Kia Kaha 的努力。我已经尝试过 FormDataConsumer,它做了我想要的,除了 second_input 中的结果仅在我第一次在 first_input 中输入值时得到结果。我认为这是因为使用了 defaultValue 属性。我可以在 second_input 中使用什么其他属性,只要我在 first_input 中输入值,就会显示结果。谢谢
      • 欢迎您 :) 我更新了我的评论,试试useForm 钩子。
      • 嗨条纹,再次感谢。我收到此错误错误:useForm 必须在
        组件内使用
        。我实际上使用的是 SimpleForm——我没有使用自定义表单。还有什么是获取表单字段的最佳方法,因为我使用的是数组输入记录(salesoutdet)。从下面的 json 中,应该从 unitprice 和数量计算 total { "salesdate": "2020-11-23", "distributorid": 1, "salesrep": 4, "salesoutdet": [ { "unitprice": 10, “数量”:5,“总数”:50}]}
      • 你做得很好。但由于useForm 需要在inside 表单中调用,因此您需要将组件一分为二,一次使用SimpleForm,另一次使用它的子组件,您可以在其中实际调用useForm,因为它被包裹SimpleForm中。
      • 或者你只是创建你自己的输入包装你NumberInput就像在这里描述marmelab.com/react-admin/…。这也可以让您同时使用 useFormuseFormState 钩子。
      【解决方案3】:

      我对这个问题有一个更简短的解决方案: 我所做的只是在 FormDataConsumer 中进行计算。现在,我可以得到计算值,它会更新数组中的正确记录。

      谢谢

      <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')} />
            )
          }            
        }} 
      

      【讨论】:

        猜你喜欢
        • 2023-03-04
        • 1970-01-01
        • 1970-01-01
        • 2011-08-29
        • 1970-01-01
        • 2015-08-05
        • 2023-03-10
        • 1970-01-01
        • 2013-06-02
        相关资源
        最近更新 更多