Как отправить данные в Final Form

Ближайший пример того, что я пытаюсь сделать, - это https://codesandbox.io/s/3x989zl866?file=/src/index.js.

Однако вместо полей, которые люди заполняют, у меня есть 3 кнопки с ценами: 300,500,1000

Когда они нажимают на них, мне нужно установить значение в

 <TextField
                                name="campaignAmount"
                                id="campaignAmount"
                                component="input"
                                type="number"
                                placeholder="Total"
                                
                                />

Я могу установить поле, но оно не отправит значение в окончательную форму.

Мой полный код:

import React,  { useState } from 'react';
import Wizard from '../wrappers/Wizard'
import { Form, Field } from 'react-final-form'
import ExternalModificationDetector from '../wrappers/ExternalModificationDetector';
import BooleanDecay from '../wrappers/BooleanDecay'

import {
    Typography,
    Paper,
    Grid,
    Button,
    ButtonGroup,
    Box,
    CssBaseline,
  } from '@material-ui/core';
import DateFnsUtils from '@date-io/date-fns';

import {
    TextField,
    Radios,
    KeyboardDatePicker,
  } from 'mui-rff';



const onSubmit = async values => {
    const sleep = ms => new Promise(resolve => setTimeout(resolve, ms));
    await sleep(300);
    window.alert(JSON.stringify(values, 0, 2));
  };
 

  
// MAIN FORM AREA
export default function BuildAdStepper(props: MyFormProps) {
 //   const [selectedDate, handleDateChange] = useState(new Date());
    const [txtValue, setTxtValue] = useState({})


    const today = new Date();
    const dateTimeFormat = new Intl.DateTimeFormat('en', { year: 'numeric', month: '2-digit', day: '2-digit' }) 
    const [{ value: month },,{ value: day },,{ value: year }] = dateTimeFormat.formatToParts(today) 
    const nmonth = new Date(today.getFullYear(), today.getMonth()+1,  day);
    const [{ value: nextmonth },,{ value: nextday },,{ value: nextyear }] = dateTimeFormat.formatToParts(nmonth) 


   function schemaTypeSelectionHandle(event) {

         console.log('key: ', event.target.parentNode.value);
        setTxtValue(""+event.target.parentNode.value);

       // console.log('key: ', event.target.attributes.getNamedItem('data-key').value);
      }


      const calculator = createDecorator({
        field: /day\[\d\]/, // when a field matching this pattern changes...
        updates: {
          // ...update the total to the result of this function
          total: (ignoredValue, allValues) =>
            (allValues.day || []).reduce((sum, value) => sum + Number(value || 0), 0)
        }
      })



    return (
        <div style={{ padding: 16, margin: 'auto', maxWidth: 600 }}>
          <CssBaseline />
          
          <Typography variant="h5" align="center" component="h2" gutterBottom>
            Create your campaign
          </Typography>
               <Paper style={{ padding: 16 }}>
               <Form
                onSubmit={onSubmit}
                decorators={[calculator]}
                render={({ handleSubmit, form, submitting, pristine, values }) => (
                <Wizard
                    initialValues={{promoting:"business", startDate:`${day}-${month}-${year }`,endDate:`${nextday}-${nextmonth}-${nextyear }`}}
                    onSubmit={onSubmit}
                    >

                    <Wizard.Page>
                    <Typography variant="h5">What are you Advertising</Typography>
                    <Box m={2}/>
                    <Radios
                    name="promoting"
                    formControlProps={{ margin: 'none' }}
                    radioGroupProps={{ row: true }}
                    data={[
                      { label: 'Business', value: 'business' },
                      { label: 'Community Project', value: 'community' },
                      { label: 'Event', value: 'event' },
                    ]}
                  />

                    <Box m={2}/>
                    
                    </Wizard.Page>
                    <Wizard.Page>
                    <Typography variant="h5">Name Your Campaign</Typography>
                    <Box m={2}/>
                    
                    <TextField
                        name="campaignName"
                        margin="none"
                        fullWidth
                        variant="outlined"
                        required={true}
                        />
                    
                    <Box m={2}/>
                    </Wizard.Page>
                    <Wizard.Page>
                    <Typography variant="h5">Set your schedule and budget</Typography>
                    <Box m={2} />
                    <KeyboardDatePicker label="Start Date" format="dd-MM-yyyy" name="startDate" dateFunsUtils={DateFnsUtils} required={true} value={new Date()} />
                    <Box m={2} />
                    <KeyboardDatePicker label="End Date" format="dd-MM-yyyy" name="endDate" dateFunsUtils={DateFnsUtils} value={new Date(nextyear,nextmonth - 1,nextday)} required={true}/>
                    <Box m={2} />


                    <Typography variant="h5">Your budget will be evenly distributed between start and end dates.</Typography>
                    <Grid container>
                        <Grid item lg={6}>
                    <ButtonGroup color="primary"  onClick={schemaTypeSelectionHandle.bind(this)} aria-label="outlined primary button group">
                        <Button value='300'>$300</Button>
                        <Button value='500'>$500</Button>
                        <Button value='1000'>$1000</Button>
                    </ButtonGroup>
                    </Grid>
                    <Grid item lg={3}>
                    
                        <ExternalModificationDetector name="total">
                        {externallyModified => (
                            <BooleanDecay value={externallyModified} delay={1000}>
                            {highlight => (
                                <TextField
                                name="campaignAmount"
                                id="campaignAmount"
                                component="input"
                                type="number"
                                placeholder="Total"
                                style={{
                                    transition: 'background 500ms ease-in-out',
                                    background: highlight ? 'yellow' : 'none'
                                }}
                                />
                            )}
                            </BooleanDecay>
                        )}
                        </ExternalModificationDetector>
                    </Grid>
                    </Grid>
                    </Wizard.Page>
                    
                    </Wizard>
                 )}
                 />
                  </Paper>
              
        </div>
      );
}

Я загрузил код на codeandbox.io

Но не могу запустить его.

https://codesandbox.io/s/keen-architecture-iu02l?file=/src/core/pages/BuildAd.js


person RussellHarrower    schedule 09.08.2020    source источник


Ответы (1)


Если вы хотите установить значение поля с помощью нескольких кнопок, вы можете сделать следующее:

Добавьте искусственное поле, вызывающее, скажем, budget:

<Field
    name="budget"
    render={({ input }) => (
    <button
        onClick={() => input.onChange(500)}
        type="button"
    >
        500
    </button>
    )}
/>

Это поле отображает кнопку, которая имеет onClick обработчик, который вызывает метод onChange поля и устанавливает соответствующее значение.

Затем, если вы продублируете это поле, как показано ниже:

<Field name="budget" render={({ input }) => (
    <button onClick={() => input.onChange(500)} type="button">500</button>)}
/>

<Field name="budget" render={({ input }) => (
    <button onClick={() => input.onChange(1000)} type="button">1000</button>)}
/>

<Field name="budget" render={({ input }) => (
    <button onClick={() => input.onChange(10000)} type="button">10000</button>)}
/>

у вас будет три кнопки, которые обновят budget на 500, 1000 и 10000 соответственно.

Поскольку у вас есть это значение в состоянии формы, вы можете скопировать его в поле campaignAmount с помощью декоратора final-form-calculate:

const calculator = createDecorator({
    field: "budget",
    updates: {
        total: (_, allValues) => allValues.budget
    }
});

Вот полный список кодов и ящик: https://codesandbox.io/s/httpsstackoverflowcomquestions63323056how-to-send-data-to-final-form-ssoz3?file=/index.js.

person Evgeny Timoshenko    schedule 27.08.2020