はじめに
表題通り、プルダウンの一覧にない項目を追加できるようにしていきます。
プルダウンの一覧にある場合は一覧から選択し、ない場合は新規で作れるようにするのが本実装の目的です。
成果物
src/FreeSolo.tsx
import React, { useState } from "react";
import { useForm, Controller } from "react-hook-form";
import { Autocomplete, TextField } from "@mui/material";
type FormValues = {
country: string;
};
const defaultOptions = [
"アメリカ",
"イギリス",
"カナダ",
"日本",
"アメリカ合衆国",
];
export default function MyAutoCompleteForm() {
const { control, handleSubmit } = useForm<FormValues>();
const [options, setOptions] = useState(defaultOptions); // 初期の選択肢
const [inputValue, setInputValue] = useState("");
const onSubmit = (data: FormValues) => {
alert(`選択した国: ${data.country}`);
};
return (
<form onSubmit={handleSubmit(onSubmit)}>
<Controller
name="country"
control={control}
defaultValue=""
render={({ field }) => (
<Autocomplete
sx={{ width: 300 }}
{...field}
freeSolo // 自由入力を許可
options={options}
inputValue={inputValue}
onInputChange={(_, newInputValue) => {
setInputValue(newInputValue); // 検索バーの入力値を更新
if (!options.includes(newInputValue) && newInputValue !== "") {
// 新しいラベルを追加して表示
setOptions([...defaultOptions, `"${newInputValue}" を追加`]);
} else {
setOptions(defaultOptions); // 既存の選択肢にリセット
}
}}
onChange={(_, newValue) => {
// 新しい値が選択されたときの処理
if (typeof newValue === "string" && newValue.startsWith('"')) {
// "新しいラベル" を選択した場合、新しい値を設定
const addedValue = newValue.replace(/"| を追加/g, ""); // エスケープを削除
field.onChange(addedValue);
} else {
field.onChange(newValue);
}
}}
renderInput={(params) => <TextField {...params} label="国" />}
/>
)}
/>
<button type="submit">送信</button>
</form>
);
}
freeSoloを入れるだけで良いんですね😊
意外と簡単!!ReactHookFormは扱いやすくて良いですね!!!
終わりに
思ったより簡単な実装ですね。