はじめに
この記事はアソビュー! Advent Calendar 2024 の13日目(裏面)です。
こんにちは、アソビューでフロントエンドエンジニアをしている村井です。皆さんは、1つのフォームの中で2つの送信ボタンを扱ったことはありますか?
複数の送信ボタン配置時に押されたボタンを判別したい
私が担当する開発において、同じ入力項目を使って「検索」と「CSVダウンロード」の2つの機能を実装することで、ユーザーが手間なく必要な情報を取得できるようにする必要がありました。
しかし、1つのフォームに複数の送信ボタンを配置すると、どのボタンが押下されたのかを判別する必要があります。 ボタンの区別ができなければ、適切な処理を実行することができず、ユーザーに混乱を招く可能性があります。
本記事では、この課題をどのように解決したのか、実装時のポイントを交えながらご紹介していきたいと思います。
解決策
JavaScriptのsubmitter
プロパティを活用することで、押下された送信ボタンを特定する方法を見つけました。submitter
プロパティは、フォームの送信イベント(SubmitEvent
)から取得でき、押下したボタン要素の情報を取得することができます。この特性を活用することで、フォーム内の複数の送信ボタンを区別して処理することができます。
実装の詳細
では、具体的にどのように実装するのか、実際のコードを示しながら説明していきます。
以下が実際の実装コードです。フォームの管理にはreact-hook-form
を使用しています。
type FieldValue = { keyword: string; }; type RequestType = 'search' | 'download'; export const SearchForm = () => { const { register, handleSubmit } = useForm<FieldValue>(); return ( <form onSubmit={handleSubmit(async (data, event) => { const nativeEvent = event?.nativeEvent as SubmitEvent; const submitter = nativeEvent.submitter; const requestType = submitter?.id || ('search' as RequestType); if (requestType === 'download') { await download(data); } else { await search(data); } })} > <input type="text" {...register('keyword')} /> <button type="submit" id="search"> 検索 </button> <button type="submit" id="download"> CSVダウンロード </button> </form> ); };
各送信ボタンに id
属性(search
と download
)を設定し、handleSubmit
関数内で event.nativeEvent.submitter.id
を使用することで、フォーム送信時にどのボタンが押下されたかを特定しています。取得した type
(ボタンの id
)に応じて、onPreSubmit
関数内で処理を分岐させ、requestType
が search
の場合は検索処理を、download
の場合は CSV ダウンロード処理を実行します。
まとめ
submitter
プロパティを活用することで、1つのフォーム内で複数の送信ボタンを効果的に扱うことができました。この実装により、ユーザーは同じ入力データを使って「検索」や「CSV ダウンロード」といった異なる操作をスムーズに行うことができ、UXの向上につながりました。
We're hiring!
アソビューでは、より良いプロダクトを世の中に届けるため、共に挑戦していただけるエンジニアを募集しています。カジュアル面談も実施していますので、興味を持たれた方はぜひエントリーをお願いいたします!
技術情報を発信する公式アカウントもございます。ぜひフォローをお願いします! https://twitter.com/Asoview_dev