在保存之前,如何验证我的自定义输入字段?

发布于 2025-01-31 06:45:19 字数 5753 浏览 2 评论 0原文

“ react-admin”:“^3.7.1”

import {
  Create,
  SimpleForm,
  TextInput,
  SelectInput,
  NumberInput,
  required,
} from "react-admin";
import { getChoices } from "../../utils";

import RichTextInput from "ra-input-rich-text";
import { makeStyles } from "@material-ui/core/styles";
import Button from "@material-ui/core/Button";
import CloudUploadIcon from "@material-ui/icons/CloudUpload";
import EditIcon from "@material-ui/icons/Edit";
import CropperModal from "./Modal";
import GoodForField from "./goodForField";

export const MEASUREMENT_UNITS = {
  GM: "GM",
  PIECE: "Piece",
  GLASS: "Glass",
  KATORI: "Katori",
  CUP: "Cup",
  BOWL: "Bowl",
};
export const RECIPE_PREPARATION_COMPLEXITY = {
  EASY: "EASY",
  MEDIUM: "MEDIUM",
  HARD: "HARD",
};

const useStyles = makeStyles((theme) => ({
  paper: {
    position: "absolute",
    backgroundColor: theme.palette.background.paper,
    border: "2px solid #000",
    boxShadow: theme.shadows[5],
    padding: theme.spacing(2, 4, 3),
  },
  root: {
    margin: "10px 0",
  },
  input: {
    display: "none",
  },
}));

const RecipeCreate = (props) => {
  const classes = useStyles();
  const [open, setOpen] = React.useState(false);
  const [file, setFile] = React.useState("");
  const [imageLink, setImageLink] = React.useState("");
  const [goodForIds, setGoodForIds] = React.useState([]);
  const imageRef = React.useRef();
  imageRef.current = imageLink;
  const goodForRef = React.useRef();
  goodForRef.current = goodForIds;
  const transform = (data) => {
    console.log({ imageRef });
    return {
      ...data,
      image_url: imageRef.current,
      good_for: goodForRef.current,
    };
  };

  const handleOpen = () => {
    setOpen(true);
  };

  const handleClose = () => {
    setOpen(false);
  };

  const handleChangeFileInput = (e) => {
    setFile(e.target.files[0]);
    handleOpen();
  };
  const handleClickEdit = () => {
    setFile(imageLink);
    handleOpen();
  };

  return (
    <>
      <CropperModal
        open={open}
        handleClose={handleClose}
        file={file}
        handleImageLink={setImageLink}
        handleVisibility={setOpen}
      />
      <Create transform={transform} {...props}>
        <SimpleForm redirect={false}>
          {imageLink && (
            <div
              style={{
                display: "flex",
                width: "100px",
                height: "100px",
                marginBottom: "20px",
                position: "relative",
              }}
            >
              <img
                src={imageLink}
                alt="dish"
                style={{
                  width: "100px",
                  height: "100px",
                  border: "5px solid #c9c5c5",
                  cursor: "pointer",
                }}
                onClick={handleClickEdit}
              />
              <EditIcon
                onClick={handleClickEdit}
                style={{
                  position: "absolute",
                  cursor: "pointer",
                  right: "-10px",
                  bottom: "-10px",
                  backgroundColor: "#c9c5c5",
                  fontSize: "1.2rem",
                }}
              />
            </div>
          )}
          <div className={classes.root}>
            <input
              accept=".png, .jpg, .jpeg"
              className={classes.input}
              id="contained-button-file"
              multiple
              type="file"
              onChange={handleChangeFileInput}
            />
            <label htmlFor="contained-button-file">
              <Button
                style={{ textTransform: "none" }}
                startIcon={<CloudUploadIcon />}
                variant="contained"
                color="primary"
                component="span"
              >
                {imageLink ? "Upload new" : "Upload picture"}
              </Button>
            </label>
          </div>
          <TextInput source="name" validate={required()} />
          <SelectInput
            source="measurement_unit"
            lable="Measurement Unit"
            choices={getChoices(MEASUREMENT_UNITS)}
            validate={required()}
          />
          <TextInput validate={required()} source="description" multiline />
          <RichTextInput source="recipe" validate={required()} />
          <TextInput
            validate={required()}
            source="preparation_time"
            lable="Preparation time"
          />

          <SelectInput
            validate={required()}
            source="preparation_complexity"
            label="Preparation Complexity"
            choices={getChoices(RECIPE_PREPARATION_COMPLEXITY)}
          />
          <GoodForField goodForIds={goodForIds} setGoodForIds={setGoodForIds} />
          <NumberInput validate={required()} source="calories" />
          <NumberInput validate={required()} source="carbs" />
          <NumberInput validate={required()} source="protein" />
          <NumberInput validate={required()} source="fats" />
          <NumberInput validate={required()} source="fibre" />
          <TextInput source="preparation_video_link" label="Video url" />
        </SimpleForm>
      </Create>
    </>
  );
};

我正在使用React-Admin的创建组件来创建配方资源。我也有一个图像搜索,通过该搜索,我将图像上传到云存储中,然后通过URL来创建通过转换函数。 croppermodal 是用于裁剪图像并将图像上传到云stoarge的组件。提交表单后,我将图像URL传递给请求主体,借助转换功能。我的问题是如何在保存之前验证此自定义字段?

注意: croppermodal 纯粹是一种自定义组件,不使用任何反应 - 辅助实用程序。

"react-admin": "^3.7.1"

import {
  Create,
  SimpleForm,
  TextInput,
  SelectInput,
  NumberInput,
  required,
} from "react-admin";
import { getChoices } from "../../utils";

import RichTextInput from "ra-input-rich-text";
import { makeStyles } from "@material-ui/core/styles";
import Button from "@material-ui/core/Button";
import CloudUploadIcon from "@material-ui/icons/CloudUpload";
import EditIcon from "@material-ui/icons/Edit";
import CropperModal from "./Modal";
import GoodForField from "./goodForField";

export const MEASUREMENT_UNITS = {
  GM: "GM",
  PIECE: "Piece",
  GLASS: "Glass",
  KATORI: "Katori",
  CUP: "Cup",
  BOWL: "Bowl",
};
export const RECIPE_PREPARATION_COMPLEXITY = {
  EASY: "EASY",
  MEDIUM: "MEDIUM",
  HARD: "HARD",
};

const useStyles = makeStyles((theme) => ({
  paper: {
    position: "absolute",
    backgroundColor: theme.palette.background.paper,
    border: "2px solid #000",
    boxShadow: theme.shadows[5],
    padding: theme.spacing(2, 4, 3),
  },
  root: {
    margin: "10px 0",
  },
  input: {
    display: "none",
  },
}));

const RecipeCreate = (props) => {
  const classes = useStyles();
  const [open, setOpen] = React.useState(false);
  const [file, setFile] = React.useState("");
  const [imageLink, setImageLink] = React.useState("");
  const [goodForIds, setGoodForIds] = React.useState([]);
  const imageRef = React.useRef();
  imageRef.current = imageLink;
  const goodForRef = React.useRef();
  goodForRef.current = goodForIds;
  const transform = (data) => {
    console.log({ imageRef });
    return {
      ...data,
      image_url: imageRef.current,
      good_for: goodForRef.current,
    };
  };

  const handleOpen = () => {
    setOpen(true);
  };

  const handleClose = () => {
    setOpen(false);
  };

  const handleChangeFileInput = (e) => {
    setFile(e.target.files[0]);
    handleOpen();
  };
  const handleClickEdit = () => {
    setFile(imageLink);
    handleOpen();
  };

  return (
    <>
      <CropperModal
        open={open}
        handleClose={handleClose}
        file={file}
        handleImageLink={setImageLink}
        handleVisibility={setOpen}
      />
      <Create transform={transform} {...props}>
        <SimpleForm redirect={false}>
          {imageLink && (
            <div
              style={{
                display: "flex",
                width: "100px",
                height: "100px",
                marginBottom: "20px",
                position: "relative",
              }}
            >
              <img
                src={imageLink}
                alt="dish"
                style={{
                  width: "100px",
                  height: "100px",
                  border: "5px solid #c9c5c5",
                  cursor: "pointer",
                }}
                onClick={handleClickEdit}
              />
              <EditIcon
                onClick={handleClickEdit}
                style={{
                  position: "absolute",
                  cursor: "pointer",
                  right: "-10px",
                  bottom: "-10px",
                  backgroundColor: "#c9c5c5",
                  fontSize: "1.2rem",
                }}
              />
            </div>
          )}
          <div className={classes.root}>
            <input
              accept=".png, .jpg, .jpeg"
              className={classes.input}
              id="contained-button-file"
              multiple
              type="file"
              onChange={handleChangeFileInput}
            />
            <label htmlFor="contained-button-file">
              <Button
                style={{ textTransform: "none" }}
                startIcon={<CloudUploadIcon />}
                variant="contained"
                color="primary"
                component="span"
              >
                {imageLink ? "Upload new" : "Upload picture"}
              </Button>
            </label>
          </div>
          <TextInput source="name" validate={required()} />
          <SelectInput
            source="measurement_unit"
            lable="Measurement Unit"
            choices={getChoices(MEASUREMENT_UNITS)}
            validate={required()}
          />
          <TextInput validate={required()} source="description" multiline />
          <RichTextInput source="recipe" validate={required()} />
          <TextInput
            validate={required()}
            source="preparation_time"
            lable="Preparation time"
          />

          <SelectInput
            validate={required()}
            source="preparation_complexity"
            label="Preparation Complexity"
            choices={getChoices(RECIPE_PREPARATION_COMPLEXITY)}
          />
          <GoodForField goodForIds={goodForIds} setGoodForIds={setGoodForIds} />
          <NumberInput validate={required()} source="calories" />
          <NumberInput validate={required()} source="carbs" />
          <NumberInput validate={required()} source="protein" />
          <NumberInput validate={required()} source="fats" />
          <NumberInput validate={required()} source="fibre" />
          <TextInput source="preparation_video_link" label="Video url" />
        </SimpleForm>
      </Create>
    </>
  );
};

I am using Create component of react-admin to create the recipe resource. I also have an image scource through which I am uploading the image to cloud storage and later passing the url to create throught transform function.
CropperModal is a component that is used to crop the image and upload the image to cloud stoarge. When the form is submitted I am passing the image URL to the request body with the help of transform function. My problem is how can I validate this custom field before save ?

Note: CropperModal is purely a custom component, not using any of the react-admin utilities.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文