首页 > 解决方案 > React Formik Material-UI 自动完成:如何在提交时提交多个选定的值

问题描述

我试图弄清楚如何将 Material-UI Autocomplete 与 Formik 一起使用。

在这里,我创建了一个表单,每页显示 3 个问题字段,效果很好。

由于我对此很陌生并且不太了解Formik,因此我在使用这种类型的输入时遇到了麻烦。

所以我在这里做的是首先有一个条件,你选择(是或否)取决于你是否想回答这个问题。之后有自动完成下拉菜单,您可以从中选择多个选项。我遇到问题的部分是我不知道如何提交多个选定的选项。您从自动完成下拉列表中选择的选项将进入补救措施数组。

最后它应该返回如下内容:

question11: {
    agree: 'Yes',
    remedies: ['option you selected', 'another selected option']
}

所以我希望能够从自动完成中选择多个值并将它们填充到补救措施中:[] 数组。

FormikControl 是我做的另一件事,它只是一堆 switch 语句,它们根据传递的条件呈现某种类型的 Input。在这种情况下,它返回我在下面发布的输入组件。

表格:

import React, { useState } from 'react';
import { Link } from 'react-router-dom';
import { Formik, Form } from 'formik';
import * as yup from 'yup';
import FormikControl from './FormikControl';
import SurveyFormLayout from '../surveyForm/SurveyFormLayout';
import PrimaryBtn from '../../../components/buttons/PrimaryBtn';

const data = [
    {
        type: 'radioWithDropdown',
        question: 'Do you take any natural remedies? (Vitamins, minerals, amino acids, 
        herbs etc.)',
        name: 'question11',
        conditions: [ { key: 'yes', value: 'Yes' }, { key: 'no', value: 'No' } ],
        options: [
            { key: 'Option 11', value: 'word' },
            { key: 'Option 12', value: 'another word' },
            { key: 'Option 13', value: 'some other' },
            { key: 'Option 14', value: 'random' }
        ]
    }
]

const InputAssesment = () => {

    const initialValues = {
        question11: {
            agree: '',
            remedies: []
        }
    };

    const validationSchema = yup.object({
        question11: yup.object().shape({
            agree: yup.string(),
            remedies: yup.array()
        })
    });

    return (
        <SurveyFormLayout>
            
            <div className="survey-form__container">
                <FormikStepper 
                    initialValues={initialValues} 
                    validationSchema={validationSchema} 
                    onSubmit={() => {}}
                >
                    <FormikStep>
                        <FormikControl
                            control="conditionWithSelectMultiple"
                            label={data[9].question}
                            name="question11.remedies"
                            options={data[9].options}
                            conditionName="question11.agree"
                            conditionOptions={data[9].conditions}
                        />
                    </FormikStep>
                </FormikStepper>
            </div>

        </SurveyFormLayout>
    )
}

export function FormikStep({ children }) {
    return <div className="formik-step">{children}</div>;
}

export function FormikStepper({ children, ...props }) {
    const childrenArray = React.Children.toArray(children);
    const [ step, setStep ] = useState(0);
    const currentChild = childrenArray[step];

    function isLastStep() {
        return step === childrenArray.length - 1;
    }

    return (
        <Formik
            {...props}
            onSubmit={async (values, helpers) => {
                if (isLastStep()) {
                    await props.onSubmit(values, helpers);
                } else {
                    setStep((s) => s + 1);
                }
                console.log(values);
            }}
        >
            <Form autoComplete="off" className="formik-form">
                {currentChild}
                <div className="survey-btns-container">
                    {step > 0 ? (
                        <button
                            className="btn-secondary survey-back-btn"
                            type="button"
                            onClick={() => setStep((s) => s - 1)}
                        >
                            Back
                        </button>
                    ) : null}
                    <PrimaryBtn text={isLastStep() ? 'Submit' : 'Next'} type="submit" />
                </div>
            </Form>
        </Formik>
    );
}

输入组件:

import React from 'react';
import { Field } from 'formik';

import Checkbox from '@material-ui/core/Checkbox';
import TextField from '@material-ui/core/TextField';

import { Autocomplete } from 'formik-material-ui-lab';
import CheckBoxOutlineBlankIcon from '@material-ui/icons/CheckBoxOutlineBlank';
import CheckBoxIcon from '@material-ui/icons/CheckBox';

const icon = <CheckBoxOutlineBlankIcon fontSize="small" />;
const checkedIcon = <CheckBoxIcon fontSize="small" />;

const ConditionWithSelectMultiple = (props) => {
    const { label, name, options, conditionName, conditionOptions, ...rest } = props;

    return (
        <div className="question-field">
            <label className="survey-question-h">{label}</label>

            <div className="radio-options-container">
                <Field name={conditionName} {...rest}>
                    {({ field }) => {
                        return conditionOptions.map((option) => {
                            return (
                                <div key={option.key} className="radio-button-option">
                                    <input
                                        className="radio-button"
                                        type="radio"
                                        id={option.value}
                                        {...field}
                                        value={option.value}
                                        checked={field.value === option.value}
                                    />
                                    <div className="radio-button-gap" />
                                    <label htmlFor={option.value} className="radio-button-option-label">
                                        {option.value}
                                    </label>
                                </div>
                            );
                        });
                    }}
                </Field>
            </div>

            <Field
                name="name"
                component={Autocomplete}
                multiple
                options={options}
                disableCloseOnSelect
                getOptionLabel={(option) => option.key}
                renderOption={(option, { selected }) => (
                    <React.Fragment>
                        <Checkbox icon={icon} checkedIcon={checkedIcon} style={{ marginRight: 8 }} checked={selected} />
                        {option.key}
                    </React.Fragment>
                )}
                style={{ width: 500 }}
                renderInput={(params) => <TextField {...params} variant="outlined" placeholder="Select" />}
            />
        </div>
    );
};

export default ConditionWithSelectMultiple;

任何帮助都非常受欢迎

标签: reactjsmaterial-uiformikformik-material-ui

解决方案


推荐阅读