はじめに
本記事は、
「フロントエンドの開発効率を向上するヒントを教え合おう!」イベントの参加記事です。
前回、Reactの環境構築からAnt Designを適用させるところまで行いました。
今回はそこからお問合せフォームを簡単に作成していきたいと思います。
要件を決める
とりあえずお問合せフォームの例として、
「名前」、「性別」、「年齢」、「メールアドレス」、「都道府県」、「お問合せ内容」
これらを作成したいと思います。
以下のようなお問合せフォームを目指します。
お問合せフォームを実装する
前回と同じようにApp.tsxの中身を書き換えていきます。
それでは、細かい実装について順番に解説をしていきます。
※一番最後に完成版のソースコードを載せておきますので良くわからなくなったら、
そちらを見ていただいても良いかと思います。
まずはFormタグでお問合せフォームの大枠を作っていきます。
このタグで送信ボタンを押した時のonFinishと、フォームでのバリデーション時に表示するvalidateMessagesを渡しています。また、スプレット構文のlayoutで、labelとwrapperのサイズの指定も行っています。
function App() {
const layout = {
labelCol: {
span: 8,
},
wrapperCol: {
span: 8,
},
};
const validateMessages = {
required: '${label}は必須です。',
types: {
email: '${label}を正しい形式で入力してください。',
},
number: {
range: '${label}は${min}から${max}の間で入力してください。',
},
};
const onFinish = (item: string) => {
console.log(item);
};
return (
<Form {...layout} name="nest-messages" onFinish={onFinish} validateMessages={validateMessages}>
次にフォーム内の項目についてですが、
FormタグのItemで作っていきます。
labelは項目名で、
rulesのrequiredは、そのままですが必須チェックの有無となります。
入力欄に関してはInputタグを用います。
<Form.Item
name={['user', 'name']}
label="お名前"
rules={[
{
required: true,
},
]}
>
<Input />
</Form.Item>
nameの指定を配列にすると、一つ目の要素は大枠のkeyとなり、
二つ目の要素に入力された値のkeyとなります。
以下がonFinishされた時のパラメータなのですが、
実際に確認すると分かりやすいですね。
{
"user": {
"name": "田中 太郎",
"gender": 1,
"age": 30,
"email": "test@gmail.com",
"prefecture": "東京都",
"introduction": "これはテスト"
}
}
requiredがtrueなので、入力がない場合はvalidateMessagesで定義したメッセージが適用され
以下のような形で表示されます。
labelの定義がそのまま当てはまるので便利ですね。
続いてラジオボタンの実装をしていきます。
Form.ItemタグのinitialValueで初期値を定義しています。
ラジオボタンは、Radio.Groupタグの内部にRadioタグを増やして実装していきます。
<Form.Item
name={['user', 'gender']}
label="性別"
initialValue={1}
>
<Radio.Group name="radiogroup">
<Radio value={1}>男性</Radio>
<Radio value={2}>女性</Radio>
<Radio value={3}>その他</Radio>
</Radio.Group>
</Form.Item>
ちなみに初期値の定義としてRadio.Groupタグで
defaultValueを指定するというやり方もあるのですが…
<Radio.Group name="radiogroup" defaultValue={2}>
以下のメッセージのように推奨はされていないので、
初期値はinitialValueを使うようにしましょう。
arning: [antd: Form.Item] `defaultValue` will not work on controlled Field. You should use `initialValues` of Form instead.
次は年齢の入力です。
年齢入力に関しては、カレンダーや西暦で入力させた方が良いかとは思いますが、
今回は例なのでInputNumberを使っていきます。
これも見たままですが、
rulesでtypeにnumberを指定し、最小値と最大値を決めています。
<Form.Item
name={['user', 'age']}
label="年齢"
rules={[
{
type: 'number',
min: 0,
max: 150,
},
]}
>
<InputNumber />
</Form.Item>
エラーメッセージも以下のように表示されます。
こういう場合、そもそも期待値以外は入力できないようにするのがベターかと思いますが、
今回は例なので、悪しからず。
メールアドレスに関しては、typeにemailを指定しています。
あとは他とほぼ変わりません。
<Form.Item
name={['user', 'email']}
label="メールアドレス"
rules={[
{
type: 'email',
},
]}
>
<Input />
</Form.Item>
こちらもメールアドレスの形式に沿っていないと、
以下のようにエラーメッセージで怒られました。
入力項目の最後のお問合せ内容ですが、
こちらは文字をたくさん入力できるようにしたいので、InputタグのTextAreaを指定します。
これにより可変式のTextAreaが実装できます。
<Form.Item name={['user', 'introduction']} label="お問合せ内容">
<Input.TextArea />
</Form.Item>
最後にボタンですが、antdのButtonタグを使用して、
typeにprimary、htmlTypeはsubmitを指定します。
wrapperは先ほど定義したlayoutと合わせて8としています。
<Form.Item
wrapperCol={{
...layout.wrapperCol,
offset: 8,
}}
>
<Button type="primary" htmlType="submit">
送信
</Button>
</Form.Item>
完成
こちらが完成したソースコードになります。
import React from 'react';
import { Button, Form, Input, InputNumber, Radio } from 'antd';
import 'antd/dist/antd.css';
import Title from 'antd/lib/typography/Title';
function App() {
const layout = {
labelCol: {
span: 8,
},
wrapperCol: {
span: 8,
},
};
const validateMessages = {
required: '${label}は必須です。',
types: {
email: '${label}!を正しい形式で入力してください。',
},
number: {
range: '${label}は${min}から${max}の間で入力してください。',
},
};
const onFinish = (item: string) => {
console.log(item);
};
return (
<div style={{margin: "50px"}}>
<div style={{textAlign: "center"}}>
<Title>お問合せフォーム</Title>
</div>
<Form {...layout} name="nest-messages" onFinish={onFinish} validateMessages={validateMessages}>
<Form.Item
name={['user', 'name']}
label="お名前"
rules={[
{
required: true,
},
]}
>
<Input />
</Form.Item>
<Form.Item
name={['user', 'gender']}
label="性別"
initialValue={1}
>
<Radio.Group name="radiogroup">
<Radio value={1}>男性</Radio>
<Radio value={2}>女性</Radio>
<Radio value={3}>その他</Radio>
</Radio.Group>
</Form.Item>
<Form.Item
name={['user', 'age']}
label="年齢"
rules={[
{
type: 'number',
min: 0,
max: 150,
},
]}
>
<InputNumber />
</Form.Item>
<Form.Item
name={['user', 'email']}
label="メールアドレス"
rules={[
{
type: 'email',
},
]}
>
<Input />
</Form.Item>
<Form.Item name={['user', 'prefecture']} label="都道府県">
<Input />
</Form.Item>
<Form.Item name={['user', 'introduction']} label="お問合せ内容">
<Input.TextArea />
</Form.Item>
<Form.Item
wrapperCol={{
...layout.wrapperCol,
offset: 8,
}}
>
<Button type="primary" htmlType="submit">
送信
</Button>
</Form.Item>
</Form>
</div>
);
}
export default App;
まとめ
長くなりましたが、今回も簡単にお問合せフォームを実装できました。
ちなみに例えばですが、rulesのtypeは、Ant Design内のinterface.d.tsにて
RuleTypeで定義されたものが使用できるので詳しく知りたい方は、
定義の中身を読んでみてもいいかも知れません。
現状、Ant Designは日本語文献があまりないので、海外文献の翻訳か、
中身のコードを読まざるを得ないところは結構あります。(むしろ公式がサンプル集みたいな感じです)
ただ割と直感的に実装はできるので、
良かったら試してみてください。
参考