# フィールドとバリデーション

> フィールドを一度定義すれば、Ikiform がすべての送信をサーバーでバリデーションし、わかりやすいメッセージと型付きの値を返します。

フィールドは任意です。フィールドのないフォームは、フォームから送られたデータを何でも受け付けます。フィールドを公開すると、Ikiform はすべての送信をそれに照らしてサーバーでバリデーションし、不正なデータはわかりやすいメッセージで拒否し、整った型付きの値を保存します。

## フィールドを定義する

ダッシュボードでフォームを開き、**Fields** に移動します。ビジュアルエディターでフィールドを追加するか、JSON の定義を直接編集します。各フィールドの `id` が、フォームが送るべき入力欄の `name` です。

`フォームの定義`:

```json
{
  "version": 1,
  "title": "Contact",
  "fields": [
    { "id": "name", "type": "text", "label": "Name", "required": true, "validation": { "max_length": 120 } },
    { "id": "email", "type": "email", "label": "Email", "required": true },
    {
      "id": "topic",
      "type": "select",
      "label": "Topic",
      "options": [
        { "value": "sales", "label": "Sales" },
        { "value": "support", "label": "Support" }
      ]
    },
    { "id": "message", "type": "textarea", "label": "Message", "validation": { "min_length": 10 } }
  ],
  "settings": { "submit_label": "Send", "success_message": "Thanks, we'll reply within a day." }
}
```

### 定義

| キー | 必須 | ルール |
| --- | --- | --- |
| `version` | はい | 常に `1` |
| `title` | はい | 1〜200 文字 |
| `description` | いいえ | 最大 2,000 文字 |
| `fields` | はい | ID が重複しない 1〜100 個のフィールド。選択肢は合計で最大 2,000 個 |
| `settings.submit_label` | いいえ | 1〜100 文字。[shadcn/ui コンポーネント](https://ikiform.com/ja/docs/shadcn.md)などのレンダラーが使います |
| `settings.success_message` | いいえ | 1〜1,000 文字 |
| `settings.redirect_url` | いいえ | 最大 2,048 文字の `http:` または `https:` の URL |
| `$schema` | いいえ | 最大 200 文字の任意の文字列。無視されます |

トップレベルでも各フィールドでも、不明なキーは拒否されるので、`requried` のようなタイプミスは保存時にエラーとして表示されます。

### すべてのフィールドに共通のキー

| キー | 必須 | ルール |
| --- | --- | --- |
| `id` | はい | 小文字の snake_case で、英字で始まり、最大 64 文字。例: `team_size` |
| `type` | はい | 下記の 12 種類のいずれか |
| `label` | はい | 1〜200 文字。エラーページや通知メールで使われます |
| `required` | いいえ | `true` にすると、空の値がエラーになります |
| `placeholder` | いいえ | 最大 200 文字 |
| `help_text` | いいえ | 最大 1,000 文字 |

## プレイグラウンド

このページのインタラクティブなプレイグラウンドでは、フォームの定義とサンプルの JSON ペイロードを編集できます。Ikiform の本物のバリデーターをブラウザーで実行し、サーバーが返す `201` または `422` のレスポンス、型変換されて保存される値、フォームの HTML マークアップを正確に表示します。

## フィールドタイプ

| タイプ | 保存される型 | 受け付ける値 |
| --- | --- | --- |
| `text` | 文字列 | 1 行の任意のテキスト |
| `textarea` | 文字列 | 複数行のテキスト |
| `email` | 文字列。ドメインは小文字に変換 | メールアドレス 1 つ |
| `number` | 数値 | 数値、または HTML フォームからの数字の文字列 |
| `select` | 文字列 | 選択肢にある値 1 つ |
| `radio` | 文字列 | 選択肢にある値 1 つ |
| `multi_select` | string[] | 選択肢にある値。重複は削除 |
| `checkbox` | 真偽値 | `on`、`true`、`1`、`yes`、または値なし |
| `date` | 文字列、`YYYY-MM-DD` | 実在する日付 |
| `url` | 文字列、正規化済み | Web アドレス。なければ `https://` を補完 |
| `phone` | 文字列 | 数字、スペース、`+ ( ) . -` |
| `rating` | 整数 | 1 から `max` までの整数 |

### text

| バリデーション | 値 | デフォルト |
| --- | --- | --- |
| `min_length` | 0〜10,000 | なし |
| `max_length` | 1〜10,000。pattern がある場合は最大 256 | 1,000。pattern がある場合は 256 |
| `pattern` | 値全体と照合される、最大 200 文字の正規表現 | なし |
| `pattern_message` | 1〜200 文字 | `Invalid format` |

パターンは `u` フラグ付きで実行され、値全体に一致する必要があります。保存時に、Ikiform は破滅的なバックトラッキングを起こしうるパターンを拒否します。後方参照、繰り返しや選択を含むグループの繰り返し（`(a+)+`、`(a|b)*`）、深すぎる繰り返しのネストです。

### textarea

| キー | 値 | デフォルト |
| --- | --- | --- |
| `validation.min_length` | 0〜16,000 | なし |
| `validation.max_length` | 1〜16,000 | 10,000 |
| `rows` | 1〜50。レンダラー向けの表示のヒント | なし |

### email

| バリデーション | 値 | デフォルト |
| --- | --- | --- |
| `allowed_domains` | `example.com` のような 1〜100 個のドメイン。完全一致で照合 | すべてのドメイン |

254 文字を超えるアドレスは拒否されます。ドメイン部分は小文字で保存され、`@` より前の部分は送られたとおりに保持されます。

### 数値

| バリデーション | 値 | デフォルト |
| --- | --- | --- |
| `min` | 任意の数値 | なし |
| `max` | `min` 以上の任意の数値 | なし |
| `integer` | `true` にすると小数を拒否 | `false` |

### select、radio、multi_select

| キー | 値 | デフォルト |
| --- | --- | --- |
| `options` | 値が重複しない 1〜500 個の `{ "value", "label" }` オブジェクト。それぞれ 1〜200 文字 | 必須 |
| `validation.min_items` | `multi_select` のみ。0〜500 | 0。必須の場合は 1 |
| `validation.max_items` | `multi_select` のみ。1〜500 | 選択肢の数 |

選択肢にある値だけを受け付けます。`select` と `radio` は値を 1 つ受け取ります。`multi_select` は、繰り返しの名前、`name[]`、JSON の配列のいずれかで送ります。

### checkbox

追加のキーはありません。送られなかったチェックボックスは `false` になります。`required: true` はチェックが必須という意味で、同意のチェックボックスに向いています。`on`、`true`、`1`、`yes`、`off`、`false`、`0`、`no`、空以外の値は拒否されます。

### date

| バリデーション | 値 | デフォルト |
| --- | --- | --- |
| `min` | `YYYY-MM-DD` 形式の日付 | なし |
| `max` | `YYYY-MM-DD` 形式の日付。`min` 以降 | なし |

### url

| バリデーション | 値 | デフォルト |
| --- | --- | --- |
| `https_only` | `true` にすると `http:` を拒否 | `false` |
| `max_length` | 1〜4,096 | 2,048 |

ドット付きのホスト名を持ち、ユーザー名やパスワードを含まない `http:` と `https:` の URL だけを受け付けます。保存される値は正規化された URL です。

### phone

| バリデーション | 値 | デフォルト |
| --- | --- | --- |
| `e164` | `true` にすると国際形式が必須になり、区切り文字なしで保存 | `false` |

`e164` がない場合、電話番号は 6〜15 桁の数字が必要で、送られたとおりに保存されます。`e164` がある場合、`+1 (415) 555-0123` は `+14155550123` として保存されます。

### rating

| バリデーション | 値 | デフォルト |
| --- | --- | --- |
| `max` | 2〜10 | 5 |

## 型変換

HTML フォームはすべてをテキストとして送ります。Ikiform は保存する前に、それを各フィールドが宣言した型に変換します。`name` がテキスト、`email`、`guests` が数値、`newsletter` がチェックボックス、`site` が URL、`phone` が電話番号のフィールドの場合:

`送信内容（urlencoded）`:

```text
name=++Ada+Lovelace++&email=Ada@Example.COM&guests=3&newsletter=on&site=example.com&phone=%2B1%20415%20555%200123
```

`保存内容（phone は e164）`:

```json
{
  "name": "Ada Lovelace",
  "email": "Ada@example.com",
  "guests": 3,
  "newsletter": true,
  "site": "https://example.com/",
  "phone": "+14155550123"
}
```

- 値の前後の空白は削除されます。空文字列は値なしとみなされます。
- 値を 1 つだけ受け取るフィールドは、2 つ以上の要素を持つ配列を拒否します。
- 数値は、`3`、`-2.5`、`1e3` のような、64 文字までの通常の小数表記と指数表記を受け付けます。

## バリデーションエラー

バリデーションに失敗した送信は `422 validation_failed` で拒否され、何も保存されません。`error.fields` は各フィールド ID をそのメッセージに対応づけます。ブラウザーからの送信では、同じメッセージがフィールドのラベル付きで、ホストされたエラーページに表示されます。

`422 Unprocessable Content`:

```json
{
  "ok": false,
  "error": {
    "code": "validation_failed",
    "message": "Some fields are invalid.",
    "fields": {
      "email": ["Enter a valid email address"],
      "website": ["Unknown field \"website\""]
    }
  },
  "request_id": "req_01k7v2c9t3e8m5q4x6z0a1b2c3"
}
```

### 不明なフィールド

フィールドが定義されている場合、定義にないフィールドは `Unknown field "name"` として拒否されます。`_` で始まる予約済みフィールド、ハニーポット、`cf-turnstile-response` は対象外です。定義がない場合は、どんなフィールド名でも受け付けます。

### メッセージ

| 問題 | メッセージ |
| --- | --- |
| 必須の値がない | `This field is required` |
| 必須のチェックボックスにチェックがない | `This box must be checked` |
| 短すぎる、または長すぎる | `Must be at least 10 characters`, `Must be at most 120 characters` |
| パターンに一致しない | `pattern_message` の値、または `Invalid format` |
| メールアドレス | `Enter a valid email address`, `Email must be at one of: example.com` |
| 数値 | `Enter a number`, `Enter a whole number`, `Must be at least 1` |
| 選択肢 | `Choose one of the listed options`, `Choose at least 2 options`, `Choose at most 3 options` |
| 日付 | `Enter a valid date (YYYY-MM-DD)`, `Must be on or after 2026-01-01` |
| URL | `Enter a valid URL`, `Enter a valid https:// URL` |
| 電話番号 | `Enter a valid phone number`, `Use international format, e.g. +14155550123` |
| 評価 | `Choose a rating`, `Rating must be at most 5` |

## ブラウザーでバリデーションする

SDK の `validate` は、12 種類すべてのフィールドタイプでサーバーのルールとメッセージを再現するので、送信前にエラーを表示できます。正とするのはあくまでサーバーです。[validate](https://ikiform.com/ja/docs/sdk.md#validate) を参照してください。
