Commit 9058763f authored by k1350's avatar k1350
Browse files

[update] リンクを useFieldArray を使用するよう変更

parent b36bafe0
import { useState, useEffect } from "react";
import { useFormContext } from "react-hook-form";
import { useFieldArray, useFormContext } from "react-hook-form";
import {
FormErrorMessage,
FormLabel,
......@@ -22,6 +22,7 @@ import { GetBlogQuery } from "../../api/generated";
import { CheckIcon, CloseIcon } from "@chakra-ui/icons";
import { CONSTANT } from "../../constants";
import { PasswordInput } from "./PasswordInput";
import { LinkInput } from "./LinkInput";
export function BlogEditForm(props: {
blogId: string;
......@@ -37,6 +38,9 @@ export function BlogEditForm(props: {
watch,
formState: { errors, isSubmitting },
} = useFormContext();
const { fields, update } = useFieldArray({
name: "links",
});
const watchPublishOption = watch("publishOption");
const [showPasswordInput, setShowPasswordInput] = useState(false);
......@@ -61,8 +65,10 @@ export function BlogEditForm(props: {
break;
}
for (let i = 0; i < CONSTANT.MAX_LINKS; i++) {
setValue(`links${i}_name`, defaultData.links?.[i]?.name ?? "");
setValue(`links${i}_url`, defaultData.links?.[i]?.url ?? "");
update(i, {
name: defaultData.links?.[i]?.name ?? "",
url: defaultData.links?.[i]?.url ?? "",
});
}
}
if (!isInitialized) {
......@@ -73,60 +79,7 @@ export function BlogEditForm(props: {
} else {
setShowPasswordInput(false);
}
}, [isInitialized, watchPublishOption]);
const linksInput = (i: number) => {
const { [`links${i}_name`]: nameError } = errors;
const { [`links${i}_url`]: urlError } = errors;
return (
<div key={`new-${i}`}>
<FormControl isInvalid={Boolean(nameError)} mb={2}>
<FormLabel htmlFor={`link-name-${i}`} mr={2}>
<Text fontWeight="bold">リンクタイトル</Text>
</FormLabel>
<Input
id={`link-name-${i}`}
{...register(`links${i}_name`, {
maxLength: {
value: 255,
message: CONSTANT.ERROR_MESSAGE.MAX_LENGTH(255),
},
})}
></Input>
{nameError ? (
<FormErrorMessage>{nameError.message?.toString()}</FormErrorMessage>
) : (
<></>
)}
</FormControl>
<FormControl isInvalid={Boolean(urlError)} mb={4}>
<FormLabel htmlFor={`link-url-${i}`} mr={2}>
<Text fontWeight="bold">URL</Text>
</FormLabel>
<Input
id={`link-url-${i}`}
{...register(`links${i}_url`, {
maxLength: {
value: 3000,
message: CONSTANT.ERROR_MESSAGE.MAX_LENGTH(3000),
},
validate: (value: string) => {
if (watch(`links${i}_name`) !== "" && value === "") {
return CONSTANT.ERROR_MESSAGE.LINK_URL_REQUIRED;
}
},
})}
></Input>
{urlError ? (
<FormErrorMessage>{urlError.message?.toString()}</FormErrorMessage>
) : (
<></>
)}
</FormControl>
{i !== CONSTANT.MAX_LINKS - 1 ? <Divider mb={2} /> : <></>}
</div>
);
};
}, [data, isInitialized, watchPublishOption]);
return (
<>
......@@ -273,7 +226,11 @@ export function BlogEditForm(props: {
isLargerThan600={isLargerThan600}
gridTemplate={gridTemplate}
register={register("password", {
required: CONSTANT.ERROR_MESSAGE.REQUIRED,
validate: (value: string) => {
if (showPasswordInput && value === "") {
return CONSTANT.ERROR_MESSAGE.REQUIRED;
}
},
pattern: {
value: /^[a-zA-Z\d!@#%\^&\*]+$/i,
message: CONSTANT.ERROR_MESSAGE.PASSWORD,
......@@ -298,7 +255,40 @@ export function BlogEditForm(props: {
<FormLabel>
<Text fontWeight="bold">リンク</Text>
</FormLabel>
<Box>{[0, 1, 2].map((value) => linksInput(value))}</Box>
<Box>
{fields.map((field, index) => (
<div key={field.id}>
<LinkInput
id={`links.${index}.name`}
label="リンクタイトル"
register={register(`links.${index}.name`, {
maxLength: {
value: 255,
message: CONSTANT.ERROR_MESSAGE.MAX_LENGTH(255),
},
})}
errors={errors.links?.[index]?.name}
></LinkInput>
<LinkInput
id={`links.${index}.url`}
label="URL"
register={register(`links.${index}.url`, {
maxLength: {
value: 3000,
message: CONSTANT.ERROR_MESSAGE.MAX_LENGTH(3000),
},
validate: (value: string) => {
if (watch(`links.${index}.name`) !== "" && value === "") {
return CONSTANT.ERROR_MESSAGE.LINK_URL_REQUIRED;
}
},
})}
errors={errors.links?.[index]?.url}
></LinkInput>
{index !== CONSTANT.MAX_LINKS - 1 ? <Divider mb={2} /> : <></>}
</div>
))}
</Box>
<span></span>
<FormHelperText ml={4}>
<ul>
......
......@@ -3,11 +3,18 @@ import { FormProvider, useForm } from "react-hook-form";
import { Heading, Spinner } from "@chakra-ui/react";
import { useGetBlogQuery } from "../../api/generated";
import { BlogEditForm } from "./BlogEditForm";
import { CONSTANT } from "../../constants";
export function Index() {
const { blogId } = useMatch().params;
const { status, data, error, isFetching } = useGetBlogQuery({ id: blogId });
const methods = useForm({ mode: "all" });
const linksDefaultValues = [...Array(CONSTANT.MAX_LINKS)].map(() => {
return { name: "", url: "" };
});
const methods = useForm({
mode: "all",
defaultValues: { links: linksDefaultValues },
});
const onSubmit = (data: any) => {
console.log(data);
};
......
import {
FormErrorMessage,
FormLabel,
FormControl,
Text,
Input,
} from "@chakra-ui/react";
import {
FieldError,
FieldErrors,
Merge,
UseFormRegisterReturn,
} from "react-hook-form";
export function LinkInput(props: {
id: string;
label: string;
register: UseFormRegisterReturn;
errors: FieldError | Merge<FieldError, FieldErrors<any>> | undefined;
}) {
const { id, label, register, errors } = props;
return (
<FormControl isInvalid={Boolean(errors)} mb={2}>
<FormLabel htmlFor={id} mr={2}>
<Text fontWeight="bold">{label}</Text>
</FormLabel>
<Input id={id} {...register}></Input>
{errors && errors.message ? (
<FormErrorMessage>{errors.message.toString()}</FormErrorMessage>
) : (
<></>
)}
</FormControl>
);
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment