Пользовательский интерфейс материала + React Form Hook + несколько флажков + выбран по умолчанию - PullRequest
1 голос
/ 28 апреля 2020

Я пытаюсь создать форму, которая поддерживает несколько «сгруппированных» флажков, используя react-form-hook Material UI.

Флажки создаются асин c из HTTP-запроса.

Я хочу предоставить массив идентификаторов объектов в качестве значений по умолчанию:

defaultValues: { boat_ids: trip?.boats.map(boat => boat.id.toString()) || [] }

Кроме того, когда я выбираю или снимаю флажок, я хочу добавить / удалить Идентификатор объекта со значениями react-hook-form.

ie. (boat_ids: [25, 29, 4])

Как мне этого добиться?

Вот образец , который я пытаюсь воспроизвести.

Бонусное очко , проверка минимально выбранных флажков с использованием Yup

boat_ids: Yup.array() .min(2, "")

Ответы [ 3 ]

3 голосов
/ 01 мая 2020

Вот упрощенный пример, который не требует контроллера. Неконтролируемая рекомендация в документах. По-прежнему рекомендуется, чтобы вы вводили для каждого входа свой собственный name и преобразовывали / фильтровали данные, чтобы удалить непроверенные значения, например, с помощью yup и validatorSchema в последнем примере, но для целей вашего примера использование того же имени приводит к значения, которые будут добавлены в массив, который соответствует вашим требованиям.
https://codesandbox.io/s/practical-dijkstra-f1yox

В любом случае, проблема в том, что ваш defaultValues не соответствует структуре ваших флажков , Это должно быть {[name]: boolean}, где names, как сгенерировано, является литеральной строкой boat_ids[${boat.id}], пока она не пройдет через входы неконтролируемой формы, которые объединяют значения в один массив. Например: form_input1[0] form_input1[1] испускает form_input1 == [value1, value2]

https://codesandbox.io/s/determined-paper-qb0lf

Сборки defaultValues: { "boat_ids[0]": false, "boat_ids[1]": true ... }
Контроллер ожидает логические значения для переключения значений флажков и в качестве значений по умолчанию он будет добавлен к флажкам.

 const { register, handleSubmit, control, getValues, setValue } = useForm({
    validationSchema: schema,
    defaultValues: Object.fromEntries(
      preselectedBoats.map(boat => [`boat_ids[${boat.id}]`, true])
    )
  });

Схема, используемая для validationSchema, которая проверяет, что выбрано как минимум 2, а также преобразует данные в требуемую схему перед отправкой в ​​onSubmit. Он отфильтровывает ложные значения, поэтому вы получаете массив идентификаторов строк:

  const schema = Yup.object().shape({
    boat_ids: Yup.array()
      .transform(function(o, obj) {
        return Object.keys(obj).filter(k => obj[k]);
      })
      .min(2, "")
  });
2 голосов
/ 04 мая 2020

Вот рабочая версия:

import React from "react";
import { useForm, Controller } from "react-hook-form";
import FormControlLabel from "@material-ui/core/FormControlLabel";
import Checkbox from "@material-ui/core/Checkbox";

export default function CheckboxesGroup() {
  const { control, handleSubmit } = useForm({
    defaultValues: {
      bill: "bill",
      luo: ""
    }
  });

  return (
    <form onSubmit={handleSubmit(e => console.log(e))}>
      {["bill", "luo"].map(name => (
        <Controller
          key={name}
          name={name}
          as={
            <FormControlLabel
              control={<Checkbox value={name} />}
              label={name}
            />
          }
          valueName="checked"
          type="checkbox"
          onChange={([e]) => {
            return e.target.checked ? e.target.value : "";
          }}
          control={control}
        />
      ))}
      <button>Submit</button>
    </form>
  );
}

коды и ссылка на ящик: https://codesandbox.io/s/material-demo-65rjy?file= / demo. js: 0-932

Однако я делаю не рекомендуется делать это, потому что флажок в пользовательском интерфейсе материала, вероятно, должен возвращать флажок (булево) вместо (значение).

1 голос
/ 04 мая 2020

Я тоже с этим боролся, вот что сработало для меня.

Заменили логи c в коде @Bill:

import React, { useState } from "react";
import { useForm, Controller } from "react-hook-form";
import FormControlLabel from "@material-ui/core/FormControlLabel";
import Checkbox from "@material-ui/core/Checkbox";

export default function CheckboxesGroup() {
  const defaultNames = ["bill", "Manos"];
  const { control, handleSubmit } = useForm({
    defaultValues: { names: defaultNames }
  });

  const [checkedValues, setCheckedValues] = useState(defaultNames);

  function handleSelect(checkedName) {
    const newNames = checkedValues?.includes(checkedName)
      ? checkedValues?.filter(name => name !== checkedName)
      : [...(checkedValues ?? []), checkedName];
    setCheckedValues(newNames);
    return newNames;
  }

  return (
    <form onSubmit={handleSubmit(e => console.log(e))}>
      {["bill", "luo", "Manos", "user120242"].map(name => (
        <FormControlLabel
          control={
            <Controller
              as={<Checkbox />}
              control={control}
              checked={checkedValues.includes(name)}
              name="names"
              onChange={() => handleSelect(name)}
            />
          }
          key={name}
          label={name}
        />
      ))}
      <button>Submit</button>
    </form>
  );
}

Ссылка Codesandbox: https://codesandbox.io/s/material-demo-639rq?file= / демо. js

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...