Form
-
class Cake\View\Helper\FormHelper(View $view, array $config = [])
FormHelper は、フォーム作成時の力作業のほとんどを代行してくれます。
FormHelper は、フォームを素早く作成し、検証、再配置、レイアウトを効率化します。
FormHelper は、柔軟でもあります。通常は規約に沿ってほとんどのことをやってくれますが、
特定のメソッドを使って必要な機能だけを使うこともできます。
フォームの開始
-
Cake\View\Helper\FormHelper::create(mixed $context = null, array $options = [])
FormHelper を活用するために最初に使うメソッドは create()
です。
このメソッドは、フォームの開始タグを出力します。
パラメーターはすべてオプションです。 create()
が、パラメーターなしで呼ばれた場合、
現在の URL を元に現在のコントローラーに送信するためのフォームを作ろうとしているものとみなします。
フォーム送信のためのデフォルトのメソッドは POST です。 UsersController::add()
のビューの中で
create()
を呼んだ場合、描画されたビューの中で次のような出力が表示されます。
<form method="post" action="/users/add">
$context
引数は、フォームの「コンテキスト」として使用されます。
いくつかの組み込みフォームのコンテキストがあり、独自に追加することができます。次のセクションで説明します。
組み込みのプロバイダーは、 $context
の次の値とマップします。
Entity
インスタンスまたはイテレーターは、
EntityContext
にマップされます。このコンテキストは、FormHelper が組み込みの ORM の結果を処理できるようにします。
schema
キーを含む配列は、
ArrayContext
にマップされます。これは単純なデータ構造を作成してフォームを構築することができます。
null
と false
は、
NullContext
にマップされます。
このコンテキストクラスは、FormHelper が必要とするインターフェイスを単に満たすだけです。
このコンテキストは、ORM の永続性を必要としない短いフォームを作成したい場合に便利です。
すべてのコンテキストクラスは、リクエストデータにアクセスできるため、フォームを簡単に作成できます。
コンテキストを持ったフォームが作成されると、作成したすべてのコントロールはアクティブなコンテキストを使用します。
ORM バックエンドフォームの場合、FormHelper は関連データ、検証エラー、およびスキーマメタデータに
アクセスできます。 end()
メソッドを使用したり、再度 create()
を呼び出すことによって、
アクティブなコンテキストを閉じることができます。
エンティティーのフォームを作成するには、次の手順を実行します。
// /articles/add において
// $article は、空の Article エンティティーである必要があります。
echo $this->Form->create($article);
出力結果:
<form method="post" action="/articles/add">
これは ArticlesController の add()
アクションにフォームデータを POST します。
また、編集フォームを作成するために、同じロジックを使用することができます。
FormHelper は、 追加 または 編集 のフォームを作成するかどうかを自動的に検出するために、
Entity
オブジェクトを使用します。
提供されたエンティティーが「新しくない」場合は、 編集 フォームとして作成されます。
例えば、 http://example.org/articles/edit/5 を閲覧すると、次のことができます。
// src/Controller/ArticlesController.php:
public function edit($id = null)
{
if (empty($id)) {
throw new NotFoundException;
}
$article = $this->Articles->get($id);
// 保存ロジックがここに入ります
$this->set('article', $article);
}
// View/Articles/edit.ctp:
// $article->isNew() は false なので、編集フォームが得られます
<?= $this->Form->create($article) ?>
出力結果:
<form method="post" action="/articles/edit/5">
<input type="hidden" name="_method" value="PUT" />
注釈
これは 編集 フォームなので、デフォルトの HTTP メソッドを上書きするために
hidden input
フィールドが生成されます。
場合によっては、フォームの action
の URL の最後にエンティティーの ID が自動的に付加されます。
URL に ID が付加されることを避けたい場合、 $options['url']
に '/my-acount'
や
\Cake\Routing\Router::url(['controller' => 'Users', 'action' => 'myAccount'])
のように文字列を渡すことができます。
フォーム作成のためのオプション
$options
配列は、ほとんどのフォーム設定が行われる場所です。この特別な配列には、
form タグの生成方法に影響を与えるさまざまなキーと値のペアが含まれます。
有効な値:
'type'
- 作成するフォームの種類を選択できます。type が未指定の場合、
フォームコンテキストに基づいて自動的に決まります。
有効な値:
'get'
- フォームの method に HTTP GET を設定します。
'file'
- フォームの method に POST を設定し、 enctype
に
"multipart/form-data" を設定します。
'post'
- method に POST を設定します。
'put', 'delete', 'patch'
- フォームの送信時に、HTTP メソッドを
PUT、 DELETE もしくは PATCH に上書きします。
'method'
- 有効な値は、上記と同じです。フォームの method を明示的に上書きできます。
'url'
- フォームを送信する URL を指定します。文字列および URL 配列を指定できます。
'encoding'
- フォームに accept-charset
エンコーディングをセットします。
デフォルトは、 Configure::read('App.encoding')
です。
'enctype'
- 明示的にフォームのエンコーディングをセットできます。
'templates'
- このフォームで使用したいテンプレート。指定したテンプレートは、
既に読み込まれたテンプレートの上にマージされます。 /config
のファイル名 (拡張子を除く) か、
使用したいテンプレートの配列のいずれかを指定します。
'context'
- フォームコンテキストクラスの追加オプション。(例えば、
EntityContext
は、フォームのベースとなる特定の Table クラスを設定するための
'table'
オプションを受け付けます。)
'idPrefix'
- 生成された ID 属性のプレフィックス。
'templateVars'
- formStart
テンプレートのためのテンプレート変数を提供することができます。
autoSetCustomValidity
- コントロールの HTML5 検証メッセージでカスタム必須および notBlank 検証メッセージを使用するには、
true
を設定します。デフォルトは false
です。
Tip
上記のオプションの他に、 $options
引数の中で、 作成した form
要素に渡したい
有効な HTML 属性を指定できます。
フォームの HTTP メソッドを変更
type
オプションを使用することにより、フォームが使用する HTTP メソッドを変更することができます。
echo $this->Form->create($article, ['type' => 'get']);
出力結果:
<form method="get" action="/articles/edit/5">
type
の値に 'file'
を指定すると、フォームの送信方法は、'POST' に変更し、form タグに
"multipart/form-data" の enctype
が含まれます。
これは、フォーム内部に file 要素がある場合に使用されます。
適切な enctype
属性が存在しない場合は、ファイルのアップロードが機能しない原因となります。
例:
echo $this->Form->create($article, ['type' => 'file']);
出力結果:
<form enctype="multipart/form-data" method="post" action="/articles/add">
'type'
の値として 'put'
、 'patch'
または 'delete'
を使用すると、
フォームは機能的に 'post' フォームに相当しますが、送信されると、HTTP リクエストメソッドは、
それぞれ 'PUT'、 'PATCH' または 'DELETE' で上書きされます。
これで、CakePHP は、ウェブブラウザーで適切な REST サポートをエミュレートすることができます。
フォームの URL を設定
url
オプションを使うと、フォームを現在のコントローラーやアプリケーションの別のコントローラーの
特定のアクションに向けることができます。
例えば、フォームを現在のコントローラーの publish()
アクションに向けるには、次のような
$options
配列を与えます。
echo $this->Form->create($article, ['url' => ['action' => 'publish']]);
出力結果:
<form method="post" action="/articles/publish">
目的のフォームアクションが現在のコントローラーにない場合は、フォームアクションの完全な URL を指定できます。
出力される URL は CakePHP アプリケーションに対する相対になります。
echo $this->Form->create(null, [
'url' => [
'controller' => 'Articles',
'action' => 'publish'
]
]);
出力結果:
<form method="post" action="/articles/publish">
または外部ドメインを指定することができます。
echo $this->Form->create(null, [
'url' => 'https://www.google.com/search',
'type' => 'get'
]);
出力結果:
<form method="get" action="https://www.google.com/search">
フォームアクションに URL を出力したくない場合、 'url' => false
を使用してください。
カスタムバリデーターの利用
多くの場合、モデルには複数の検証セットがあり、コントローラーアクションが適用される
特定の検証ルールに基づいて必要なフィールドに FormHelper を設定する必要があります。
たとえば、Users テーブルには、アカウントの登録時にのみ適用される特定の検証ルールがあります。
echo $this->Form->create($user, [
'context' => ['validator' => 'register']
]);
上記では UsersTable::validationRegister()
で定義されている register
バリデーターの中で定義されたルールを $user
と関連するすべてのアソシエーションに使用します。
関連付けられたエンティティーのフォームを作成する場合は、配列を使用して各アソシエーションの検証ルールを
定義できます。
echo $this->Form->create($user, [
'context' => [
'validator' => [
'Users' => 'register',
'Comments' => 'default'
]
]
]);
上記は、ユーザーには register
、そしてユーザーのコメントには default
を使用します。
コンテキストクラスの作成
組み込みのコンテキストクラスは基本的なケースをカバーすることを目的としていますが、
異なる ORM を使用している場合は新しいコンテキストクラスを作成する必要があります。
このような状況では、 Cake\View\Form\ContextInterface
を実装する必要があります。
このインターフェイスを実装すると、新しいコンテキストを FormHelper に追加することができます。
View.beforeRender
イベントリスナーやアプリケーションビュークラスで行うのが最善の方法です。
$this->Form->addContextProvider('myprovider', function ($request, $data) {
if ($data['entity'] instanceof MyOrmClass) {
return new MyProvider($request, $data);
}
});
コンテキストのファクトリー関数では、正しいエンティティータイプのフォームオプションを確認するための
ロジックを追加できます。一致する入力データが見つかった場合は、オブジェクトを返すことができます。
一致するものがない場合は null を返します。
フォームコントロールの作成
-
Cake\View\Helper\FormHelper::control(string $fieldName, array $options = [])
control()
メソッドを使うと完全なフォームコントロールを生成できます。これらのコントロールには、
必要に応じて、囲い込む div
、 label
、コントロールウィジェット、および検証エラーが含まれます。
フォームコンテキストでメタデータを使用することにより、このメソッドは各フィールドに適切な
コントロールタイプを選択します。内部的に control()
は FormHelper の他のメソッドを使います。
Tip
control()
メソッドによって生成されたフィールドは、このページでは一般的に
"入力" と呼ばれますが、技術的にいえば、 control()
メソッドは、 HTML の
input
型の要素だけでなく、他の HTML フォーム要素 (select
、 button
、
textarea
など) も生成できることに注意してください。
デフォルトでは、 control()
メソッドは、次のウィジェットテンプレートを使用します。
'inputContainer' => '<div class="input {{type}}{{required}}">{{content}}</div>'
'input' => '<input type="{{type}}" name="{{name}}"{{attrs}}/>'
検証エラーが発生した場合は、以下も使われます。
'inputContainerError' => '<div class="input {{type}}{{required}} error">{{content}}{{error}}</div>'
作成されたコントロールの型(生成された要素タイプを指定する追加のオプションを指定しない場合)は、
モデルの内部で推測され、列のデータ型に依存します。
作成されるコントロールの型は、カラムのデータ型に依存します。
- カラムの型
得られたフォームのフィールド
- string, uuid (char, varchar, その他)
text
- boolean, tinyint(1)
checkbox
- decimal
number
- float
number
- integer
number
- text
textarea
- text で、名前が password, passwd
password
- text で、名前が email
email
- text で、名前が tel, telephone, または phone
tel
- date
day, month, および year の select
- datetime, timestamp
day, month, year, hour, minute, および meridian の select
- time
hour, minute, および meridian の select
- binary
file
$options
パラメーターを使うと、必要な場合に特定のコントロールタイプを選択することができます。
echo $this->Form->control('published', ['type' => 'checkbox']);
Tip
とても些細なことですが、 control()
フォームメソッドを使用して特定の要素を生成すると、
デフォルトでは div
の囲い込みが常に生成されます。特定のフォームメソッド(例えば
$this->Form->checkbox('published');
)を使用して同じタイプの要素を生成すると、
ほとんどの場合、 div
の囲い込みが生成されません。
あなたのニーズに応じて、どちらかを使うことができます。
モデルのフィールドの検証ルールで入力が必須であり、空を許可しない場合は、囲い込む div
は、
クラス名に required
が追加されます。
required
オプションを使用して自動的に必須フラグを無効にすることができます。
echo $this->Form->control('title', ['required' => false]);
フォーム全体のブラウザー検証トリガーをスキップするには、
submit()
を使って生成する入力ボタンに対して
'formnovalidate' => true
オプションを設定したり、
create()
のオプションで
'novalidate' => true
を設定できます。
たとえば、Users モデルに username (varchar), password (varchar), approved (datetime)
および quote (text) のフィールドがあるとします。FormHelper の control()
メソッドを使用すると、
これらのフォームフィールドすべてに適切なコントロールを作成できます。
echo $this->Form->create($user);
// 以下は、テキスト入力を生成します
echo $this->Form->control('username');
// 以下は、パスワード入力を生成します
echo $this->Form->control('password');
// 'approved' を datetime か timestamp フィールドとみなし、
// 以下は、日・月・年・時・分を生成します
echo $this->Form->control('approved');
// 以下は、テキストエリア要素を生成します
echo $this->Form->control('quote');
echo $this->Form->button('Add');
echo $this->Form->end();
日付フィールドのいくつかのオプションを示すより広範な例:
echo $this->Form->control('birth_dt', [
'label' => '生年月日',
'minYear' => date('Y') - 70,
'maxYear' => date('Y') - 18,
]);
特定の コントロールのオプション に加えて、選択された (または CakePHP によって推論された)
コントロールタイプや HTML 属性 (例えば onfocus
) に対応する特定のメソッドによって
受け入れられるオプションを指定することができます。
belongsTo または hasOne を使用していて select
フィールドを作成する場合は、
Users コントローラーに次のものを追加できます(User belongsTo Group を前提とします)。
$this->set('groups', $this->Users->Groups->find('list'));
その後、ビューテンプレートに以下を追加します。
echo $this->Form->control('group_id', ['options' => $groups]);
belongsToMany で関連付く Groups の select
ボックスを作成するには、
UsersController に以下を追加します。
$this->set('groups', $this->Users->Groups->find('list'));
その後、ビューテンプレートに以下を追加します。
echo $this->Form->control('groups._ids', ['options' => $groups]);
モデル名が2つ以上の単語 (たとえば "UserGroup") で構成されている場合、
set()
を使用してデータを渡すときは、データを次のように複数形と
ローワーキャメルケース
で名前を付ける必要があります。
$this->set('userGroups', $this->UserGroups->find('list'));
注釈
送信ボタンを生成するために FormHelper::control()
を使用しないでください。
代わりに submit()
を使用してください。
フィールドの命名規則
コントロールウィジェットを作成するときは、フィールドの名前をフォームのエンティティーに一致する属性の後に
指定する必要があります。たとえば、 $article
エンティティーのフォームを作成した場合、
そのプロパティーの名前を付けたフィールドを作成します。例えば title
、 body
と published
。
association.fieldname
を最初のパラメーターとして渡すことで、関連するモデルや任意のモデルの
コントロールを作成できます。
echo $this->Form->control('association.fieldname');
フィールド名のドットは、ネストされたリクエストデータに変換されます。
たとえば、 0.comments.body
という名前のフィールドを作成した場合、
0[comments][body]
のような名前属性が得られます。
この規則により、ORM でデータを簡単に保存できます。
さまざまなアソシエーションタイプの詳細は、 関連データの入力を作成 セクションにあります。
datetime に関連するコントロールを作成する場合、FormHelper はフィールドのサフィックスを追加します。
year
、 month
、 day
、 hour
、 minute
、または meridian
というフィールドが追加されていることがあります。エンティティーがマーシャリングされると、
これらのフィールドは自動的に DateTime
オブジェクトに変換されます。
コントロールのオプション
FormHelper::control()
は、その $options
引数を通して、多数のオプションをサポートしています。
control()
自身のオプションに加えて、生成されたコントロールタイプに対するオプションと
HTML 属性を受け付けます。以下は FormHelper::control()
で特有のオプションについて説明します。
$options['type']
- 生成するためのウィジェットタイプを指定する文字列。
フォームコントロールの作成 にあるフィールド型に加えて、 'file'
、 'password'
、
および HTML5 でサポートされているすべてのタイプを作成することもできます。
'type'
を指定することで、モデルの設定を上書きして、コントロールのタイプを強制することができます。
デフォルトは null
。
例:
echo $this->Form->control('field', ['type' => 'file']);
echo $this->Form->control('email', ['type' => 'email']);
出力結果:
<div class="input file">
<label for="field">Field</label>
<input type="file" name="field" value="" id="field" />
</div>
<div class="input email">
<label for="email">Email</label>
<input type="email" name="email" value="" id="email" />
</div>
$options['label']
- 文字列の見出しや ラベルのオプション の配列。
このキーは、通常は input
HTML 要素に付随するラベル内に表示したい文字列に設定することができます。
デフォルトは null
です。
例:
echo $this->Form->control('name', [
'label' => 'The User Alias'
]);
出力結果:
<div class="input">
<label for="name">The User Alias</label>
<input name="name" type="text" value="" id="name" />
</div>
あるいは、 label
要素の出力を無効にするには、このキーに false
を設定します。
例:
echo $this->Form->control('name', ['label' => false]);
出力結果:
<div class="input">
<input name="name" type="text" value="" id="name" />
</div>
これに配列を設定すると、 label
要素の追加オプションが提供されます。
これを行う場合、配列中の text
キーを使ってラベルテキストをカスタマイズすることができます。
例:
echo $this->Form->control('name', [
'label' => [
'class' => 'thingy',
'text' => 'The User Alias'
]
]);
出力結果:
<div class="input">
<label for="name" class="thingy">The User Alias</label>
<input name="name" type="text" value="" id="name" />
</div>
$options['options']
- ここには、アイテムの配列を引数として必要とする radio
や
select
のようなウィジェットのために、生成される要素を含む配列を提供することができます
(詳細は、 ラジオボタンの作成 と 選択ピッカーの作成 をご覧ください)。
デフォルトは、 null
です。
$options['error']
- このキーを使用すると、デフォルトのモデルエラーメッセージを
無効にすることができ、たとえば国際化メッセージを設定するために使用できます。
エラーメッセージの出力とフィールドクラスを無効にするには、 'error'
キーを
false
に設定してください。デフォルトは null
。
例:
echo $this->Form->control('name', ['error' => false]);
モデルのエラーメッセージを上書きするには、
元の検証エラーメッセージと一致するキーを持つ配列を使用します。
例:
$this->Form->control('name', [
'error' => ['Not long enough' => __('This is not long enough')]
]);
上記のように、モデルにある各検証ルールに対してエラーメッセージを設定することができます。
さらに、フォームに国際化メッセージを提供することもできます。
$options['nestedInput']
- チェックボックスとラジオボタンで使用。
input 要素を label
要素の内側か外側に生成するかどうかを制御します。
control()
がチェックボックスやラジオボタンを生成する時、これに false
を設定して、
label
要素の外側に HTML の input
要素を強制的に生成することができます。
一方、任意のコントロールタイプに対して、これを true
に設定することで、
生成された input 要素をラベルの中に強制的に入れることができます。
これをラジオボタンで変更する場合は、デフォルトの radioWrapper
テンプレートも変更する必要があります。生成されるコントロールタイプによっては、
デフォルトが true
や false
になります。
$options['templates']
- この入力に使用するテンプレート。
指定したテンプレートは、既に読み込まれたテンプレートの上にマージされます。
このオプションは、ロードするテンプレートを含む /config
のファイル名 (拡張子を除く) か、
使用するテンプレートの配列のいずれかです。
$options['labelOptions']
- これを false
に設定すると nestedWidgets
の周りのラベルを無効にします。または、 label
タグに提供される属性の配列を設定します。
コントロールの特定のタイプを生成
汎用的な control()
メソッドに加えて、 FormHelper
には様々な種類の
コントロールタイプを生成するために個別のメソッドがあります。
これらは、コントロールウィジェットそのものを生成するのに使えますが、
完全に独自のフォームレイアウトを生成するために
label()
や
error()
といった
他のメソッドを組み合わせることができます。
特定のコントロールのための共通オプション
さまざまなコントロール要素メソッドは、共通のオプションをサポートしており、
使用されるフォームメソッドに応じて、 $options
または $attributes
配列の引数の中に
指定する必要があります。これらのオプションはすべて、 control()
でもサポートされています。
繰り返しを減らすために、すべてのコントロールメソッドで共有される共通オプションは次の通りです。
'id'
- このキーを設定すると、コントロールの DOM id の値が強制的に設定されます。
これにより、設定可能な 'idPrefix'
が上書きされます。
'default'
コントロールフィールドのデフォルト値を設定します。
この値は、フォームに渡されるデータにそのフィールドに関する値が含まれていない場合
(または、一切データが渡されない場合) に使われます。
明示的なデフォルト値は、スキーマで定義されたデフォルト値を上書きします。
使用例:
echo $this->Form->text('ingredient', ['default' => 'Sugar']);
select
フィールドを持つ例("Medium" サイズがデフォルトで選択されます)
$sizes = ['s' => 'Small', 'm' => 'Medium', 'l' => 'Large'];
echo $this->Form->select('size', $sizes, ['default' => 'm']);
注釈
checkbox をチェックする目的では default
は使えません。その代わり、コントローラーで
$this->request->getData()
の中の値をセットするか、またはコントロールオプションの
checked
を true
にします。
デフォルト値への代入の際 false
を使うのは注意が必要です。
false
値はコントロールフィールドのオプションを無効または除外するために使われます。
そのため 'default' => false
では値を全く設定しません。
代わりに 'default' => 0
を使用してください。
'value'
- コントロールフィールドに特定の値を設定するために使用します。
これは、Form、Entity、 request->getData()
などのコンテキストから
注入される可能性のある値を上書きします。
注釈
コンテキストや valuesSource から値を取得しないようにフィールドを設定したい場合、
'value'
を ''
に設定する必要があります (もしくは null
に設定) 。
上記のオプションに加えて、任意の HTML 属性を混在させることができます。
特に規定のないオプション名は HTML 属性として扱われ、生成された HTML のコントロール要素に反映されます。
バージョン 3.3.0 で変更: 3.3.0 では、FormHelper は、自動的にデータベーススキーマで定義されたデフォルト値を使用します。
schemaDefault
オプションを false
に設定することで、この動作を無効にすることができます。
ラベルの作成
-
Cake\View\Helper\FormHelper::label(string $fieldName, string $text, array $options)
$fieldName
- 'Modelname.fieldname'
の形式のフィールド名。
$text
- ラベルの見出しテキストを指定するためのオプション文字列。
$options
- オプション。特定のコントロールのための共通オプション と有効な HTML 属性を含む配列。
label
要素を作成します。引数の $fieldName
は、要素の HTML for
属性を
生成するために使われます。 $text
が未定義の場合、 $fieldName
はラベルの
text
属性を変えるために使われます。
例:
echo $this->Form->label('name');
echo $this->Form->label('name', 'Your username');
出力結果:
<label for="name">Name</label>
<label for="name">Your username</label>
第3パラメーター $options
に id や class を設定できます。
echo $this->Form->label('name', null, ['id' => 'user-label']);
echo $this->Form->label('name', 'Your username', ['class' => 'highlight']);
出力結果:
<label for="name" id="user-label">Name</label>
<label for="name" class="highlight">Your username</label>
エラーの表示と確認
FormHelper は、フィールドエラーを簡単にチェックしたり、必要に応じてカスタマイズされた
エラーメッセージを表示できる、いくつかのメソッドを公開しています。
エラーの表示
-
Cake\View\Helper\FormHelper::error(string $fieldName, mixed $text, array $options)
$fieldName
- 'Modelname.fieldname'
の形式のフィールド名。
$text
- オプション。エラーメッセージを提供する文字列または配列。
配列の場合、 キー名 => メッセージのハッシュになります。デフォルトは null
。
$options
- 'escape'
キーのブール値のみを含みます。これは、
エラーメッセージの内容を HTML エスケープするかどうかを定義します。デフォルトは true
です。
検証エラーが発生した際に、与えられたフィールドの $text
で指定された、
検証エラーメッセージを表示します。フィールドの $text
がない場合、
そのフィールドのデフォルトの検証エラーメッセージが使用されます。
次のテンプレートウィジェットを使います。
'error' => '<div class="error-message">{{content}}</div>'
'errorList' => '<ul>{{content}}</ul>'
'errorItem' => '<li>{{text}}</li>'
'errorList'
と 'errorItem'
テンプレートは、1つのフィールドに複数の
エラーメッセージを書式化するために使用されます。
例:
// TicketsTable に 'notEmpty' 検証ルールがある場合:
public function validationDefault(Validator $validator)
{
$validator
->requirePresence('ticket', 'create')
->notEmpty('ticket');
}
// そして、 Templates/Tickets/add.ctp の中が次のような場合:
echo $this->Form->text('ticket');
if ($this->Form->isFieldError('ticket')) {
echo $this->Form->error('ticket', 'Completely custom error message!');
}
もし、 Ticket フィールドの値を指定せずにフォームの Submit ボタンをクリックした場合、
フォームは次のように出力されます。
<input name="ticket" class="form-error" required="required" value="" type="text">
<div class="error-message">Completely custom error message!</div>
注釈
control()
を使用している時、
デフォルトではエラーは描画されますので、 isFieldError()
を使用したり、
手動で error()
を呼び出す必要はありません。
Tip
あるモデルのフィールドを使用して、 control()
で複数のフォームフィールドを生成し、
それぞれ同じ検証エラーメッセージを表示させたい場合、それぞれの
検証ルール の中でカスタムエラーメッセージを
定義する方が良いでしょう。
エラーの確認
-
Cake\View\Helper\FormHelper::isFieldError(string $fieldName)
指定された $fieldName
に有効な検証エラーがある場合は true
を返します。
そうでなければ fales
を返します。
例:
if ($this->Form->isFieldError('gender')) {
echo $this->Form->error('gender');
}
HTML5 検証メッセージにバリデーションメッセージを表示
autoSetCustomValidity
FormHelper オプションが true
に設定されている場合、
デフォルトのブラウザーの HTML5 必須メッセージの代わりに、フィールドの必須および
notBlank バリデーションメッセージに対するエラーメッセージが使用されます。
このオプションを有効にすると、フィールドに onvalid
と oninvalid
イベント属性が追加されます。
例えば、
<input type="text" name="field" required onvalid="this.setCustomValidity('')" oninvalid="this.setCustomValidity('Custom notBlank message')" />
カスタム Javascript を使用してこれらのイベントを手動で設定したい場合は、
autoSetCustomValidity
オプションを false
に設定して、
代わりに 特別な customValidityMessage
テンプレート変数を使用することができます。
このテンプレート変数はフィールドが必須の場合に追加されます。
// テンプレート例
[
'input' => '<input type="{{type}}" name="{{name}}" data-error-message="{{customValidityMessage}}" {{attrs}}/>',
]
// このような input が作成されます
<input type="text" name="field" required data-error-message="Custom notBlank message" />
それから Javascript を使って onvalid
と oninvalid
イベントを好きなように設定できます。
ボタンと submit 要素の作成
Submit 要素の作成
-
Cake\View\Helper\FormHelper::submit(string $caption, array $options)
$caption
を値としてもつ submit
タイプの input
要素を作成します。
指定された $caption
が画像の URL である場合 (つまり、 '://' を含む文字列または、拡張子
'.jpg, .jpe, .jpeg, .gif' を含む場合)、画像の送信ボタンが生成され、指定された画像が
存在する場合は、それを使用します。最初の文字が '/' の場合、画像は webroot からの
相対パスになり、最初の文字が '/' ではない場合、画像は webroot/img からの相対パスになります。
デフォルトで次のウィジェットテンプレートを使用します。
'inputSubmit' => '<input type="{{type}}"{{attrs}}/>'
'submitContainer' => '<div class="submit">{{content}}</div>'
Submit のオプション
'type'
- リセットボタンを生成するためにこのオプションに 'reset'
を設定します。
デフォルトは 'submit'
です。
'templateVars'
- input 要素や、そのコンテナーにテンプレート変数を追加するために、
この配列を設定します。
その他の指定された属性は input
要素に割り当てられます。
例:
echo $this->Form->submit('Click me');
出力結果:
<div class="submit"><input value="Click me" type="submit"></div>
見出しテキストの代わりに見出しパラメーターとして画像への相対 URL または
絶対 URL を渡すことができます。
echo $this->Form->submit('ok.png');
出力結果:
<div class="submit"><input type="image" src="/img/ok.png"></div>
submit 入力は、基本的なテキストやイメージが必要な場合に便利です。
より複雑なボタンの内容が必要な場合は、 button()
を使用してください。
ボタン要素の作成
-
Cake\View\Helper\FormHelper::button(string $title, array $options = [])
指定されたタイトルと 'button'
のデフォルトタイプの HTML ボタンを作成します。
ボタンのオプション
例:
echo $this->Form->button('ボタン');
echo $this->Form->button('別のボタン', ['type' => 'button']);
echo $this->Form->button('フォームのリセット', ['type' => 'reset']);
echo $this->Form->button('フォームの送信', ['type' => 'submit']);
出力結果:
<button type="submit">ボタン</button>
<button type="button">別のボタン</button>
<button type="reset">フォームのリセット</button>
<button type="submit">フォームの送信</button>
'escape'
オプションの使用例:
// エスケープされた HTML を描画します。
echo $this->Form->button('<em>Submit Form</em>', [
'type' => 'submit',
'escape' => true
]);
フォームを閉じる
-
Cake\View\Helper\FormHelper::end($secureAttributes = [])
end()
は、フォームを閉じて完成します。
多くの場合、 end()
は終了タグだけを出力しますが、 end()
を使うと、
FormHelper が Cake\Controller\Component\SecurityComponent
に必要な
hidden フォーム要素を挿入できるようになります。
<?= $this->Form->create(); ?>
<!-- フォーム要素はここにあります -->
<?= $this->Form->end(); ?>
生成された hidden 入力に属性を追加する必要がある場合は、
$secureAttributes
引数を使用できます。
echo $this->Form->end(['data-type' => 'hidden']);
出力結果:
<div style="display:none;">
<input type="hidden" name="_Token[fields]" data-type="hidden"
value="2981c38990f3f6ba935e6561dc77277966fabd6d%3AAddresses.id">
<input type="hidden" name="_Token[unlocked]" data-type="hidden"
value="address%7Cfirst_name">
</div>
注釈
アプリケーションで Cake\Controller\Component\SecurityComponent
を使用している場合は、必ずフォームを end()
で終わらせてください。
単独のボタンと POST リンクの作成
POST ボタンの作成
-
Cake\View\Helper\FormHelper::postButton(string $title, mixed $url, array $options = [])
$title
- ボタンの見出しテキストを提供する必須の文字列。
デフォルトでは HTML エンコードされません。
$url
- 文字列や配列として提供される URL。
$options
- 特定のコントロールのための共通オプション 、特定のオプション(下記参照)と
有効な HTML 属性を含むオプション配列。
デフォルトでは、POST で送信する <form>
要素で囲まれた <button>
タグを作成します。
また、デフォルトでは、SecurityComponent のために非表示入力フィールドも生成します。
POST ボタンのオプション
'data'
- hidden 入力に渡すキーと値の配列。
'method'
- 使用するリクエスト方法。例えば、 'delete'
をセットすると、
HTTP/1.1 DELETE リクエストをシミュレートします。デフォルトは 'post'
です。
'form'
- FormHelper::create()
に渡す任意のオプションの配列。
また、 postButton()
メソッドは、 button()
メソッドで有効なオプションも受け付けます。
例:
// Templates/Tickets/index.ctp の中で
<?= $this->Form->postButton('Delete Record', ['controller' => 'Tickets', 'action' => 'delete', 5]) ?>
出力結果:
<form method="post" accept-charset="utf-8" action="/Rtools/tickets/delete/5">
<div style="display:none;">
<input name="_method" value="POST" type="hidden">
</div>
<button type="submit">Delete Record</button>
<div style="display:none;">
<input name="_Token[fields]" value="186cfbfc6f519622e19d1e688633c4028229081f%3A" type="hidden">
<input name="_Token[unlocked]" value="" type="hidden">
<input name="_Token[debug]" value="%5B%22%5C%2FRtools%5C%2Ftickets%5C%2Fdelete%5C%2F1%22%2C%5B%5D%2C%5B%5D%5D" type="hidden">
</div>
</form>
このメソッドは form
要素を作成します。
なので、開かれたフォームの中でこのメソッドを使用しないでください。
代わりに Cake\View\Helper\FormHelper::submit()
または
Cake\View\Helper\FormHelper::button()
を使用して、
開かれたフォームの中でボタンを作成してください。
POST リンクの作成
-
Cake\View\Helper\FormHelper::postLink(string $title, mixed $url = null, array $options = [])
$title
- <a>
タグに囲まれたテキストを提供する必須の文字列。
$url
- オプション。フォームの URL (相対 URL 、または http://
で始まる外部 URL)
を含む文字列または配列。
$options
- 特定のコントロールのための共通オプション 、特有のオプション(下記参照)と
有効な HTML 属性を含むオプション配列。
HTML リンクを作成しますが、指定した方法 (デフォルトは POST)で URL にアクセスします。
ブラウザーで有効にするには JavaScript が必要です。
POST リンクのオプション
'data'
- hidden 入力に渡すキーと値の配列。
'method'
- 使用するリクエスト方法。例えば、 'delete'
をセットすると、
HTTP/1.1 DELETE リクエストをシミュレートします。デフォルトは 'post'
です。
'confirm'
- クリック時に表示される確認メッセージ。デフォルトは null
です。
'block'
- ビューブロック 'postLink'
へフォームの追加するために
このオプションに true
をセットしたり、カスタムブロック名を指定します。
デフォルトは null
です。
また、 postLink
メソッドは、 link()
メソッドの有効なオプションを受け付けます。
このメソッドは <form>
要素を作成します。
このメソッドを既存のフォームの中で使いたい場合は、 block
オプションを使用して、
新しいフォームがメインフォームの外部でレンダリング可能な
ビューブロック に設定されるようにする必要があります。
あなたが探しているものがフォームを送信するボタンであれば、代わりに
Cake\View\Helper\FormHelper::button()
または
Cake\View\Helper\FormHelper::submit()
を使用してください。
注釈
開いているフォームの中に postLink を入れないように注意してください。
代わりに、 block
オプションを使ってフォームを
ビューブロック にバッファリングしてください。
フォーム全体の生成
複数のコントロールの作成
-
Cake\View\Helper\FormHelper::controls(array $fields = [], $options = [])
fieldset
で囲まれた指定された一連のコントロールセットを生成します。
生成されたフィールドを含めることで指定できます。
echo $this->Form->controls([
'name',
'email'
]);
オプションを使用して legend のテキストをカスタマイズすることができます。
echo $this->Form->controls($fields, ['legend' => 'Update news post']);
$fields
パラメーターで追加のオプションを定義することによって、
生成されたコントロールをカスタマイズすることができます。
echo $this->Form->controls([
'name' => ['label' => 'カスタムラベル']
]);
$fields
をカスタマイズする場合、生成された legend/fieldset を制御するために
$options
パラメーターを使用することができます。
例えば:
echo $this->Form->controls(
[
'name' => ['label' => 'カスタムラベル']
],
['legend' => 'Update your post']
);
fieldset
を無効にすると、 legend
は出力されません。
エンティティー全体のコントロールを作成
-
Cake\View\Helper\FormHelper::allControls(array $fields, $options = [])
このメソッドは controls()
と密接に関係していますが、 $fields
引数は
現在のトップレベルエンティティーの 全ての フィールドにデフォルト設定されています。
生成されたコントロールから特定のフィールドを除外するには、 $fields
パラメーターで
false
を設定します。
echo $this->Form->allControls(['password' => false]);
// 3.4.0 より前の場合:
echo $this->Form->allInputs(['password' => false]);
独自ウィジェットの追加
CakePHP を使うと、アプリケーションに独自のコントロールウィジェットを簡単に追加でき、
他のコントロールタイプと同様に使用することができます。
すべてのコアコントロールタイプはウィジェットとして実装されています。
つまり、独自の実装でコアウィジェットを上書きすることができます。
ウィジェットの使用
FormHelper を読み込むときや、
addWidget()
メソッドを使って独自のウィジェットを読み込むことができます。
FormHelper を読み込むとき、ウィジェットは設定として定義されます。
// View クラスの中で
$this->loadHelper('Form', [
'widgets' => [
'autocomplete' => ['Autocomplete']
]
]);
あなたのウィジェットが他のウィジェットを必要とする場合は、それらの依存関係を宣言することによって
FormHelper に取り込ませることができます。
$this->loadHelper('Form', [
'widgets' => [
'autocomplete' => [
'App\View\Widget\AutocompleteWidget',
'text',
'label'
]
]
]);
上記の例では、 autocomplete
ウィジェットは text
と label
ウィジェットに依存します。
ウィジェットがビューにアクセスする必要がある場合は、 _view
'ウィジェット' を使用してください。
autocomplete ウィジェットが作成されると、 text
と label
の名前に関連するウィジェットオブジェクトが渡されます。
addWidget()
メソッドを使ってウィジェットを追加すると、次のようになります。
// classname の使用。
$this->Form->addWidget(
'autocomplete',
['Autocomplete', 'text', 'label']
);
// インスタンスの使用 - 依存関係を解決する必要があります。
// 3.6.0 より前は、ウィジェットの取得に widgetRegistry() を使用。
$autocomplete = new AutocompleteWidget(
$this->Form->getTemplater(),
$this->Form->getWidgetLocator()->get('text'),
$this->Form->getWidgetLocator()->get('label'),
);
$this->Form->addWidget('autocomplete', $autocomplete);
追加/置換されると、ウィジェットはコントロールの 'type' として使用できます。
echo $this->Form->control('search', ['type' => 'autocomplete']);
これは、 controls()
とまったく同じように label
と囲い込む div
を持つ独自ウィジェットを作成します。
あるいは、マジックメソッドを使用してコントロールウィジェットだけを作成することもできます。
echo $this->Form->autocomplete('search', $options);
SecurityComponent との連携
Cake\Controller\Component\SecurityComponent
には、
フォームをより安全で安全にするためのいくつかの機能があります。
コントローラーに SecurityComponent
を含めるだけで、
フォームの改ざん防止機能が自動的に有効になります。
SecurityComponent を利用する際は、前述のようにフォームを閉じる際は、
必ず end()
を使う必要があります。
これにより特別な _Token
入力が生成されます。
-
Cake\View\Helper\FormHelper::unlockField($name)
SecurityComponent
によるフィールドのハッシュ化が行われないようにフィールドのロックを
解除します。またこれにより、そのフィールドを JavaScript で操作できるようになります。
$name
には入力のためのエンティティーのプロパティー名を指定します。
$this->Form->unlockField('id');
-
Cake\View\Helper\FormHelper::secure(array $fields = [], array $secureAttributes = [])
フォームで使用されるフィールドに基づくセキュリティーハッシュをもつ
非表示の input
フィールドを生成し、または、保護されたフォームが使用されていない場合は
空の文字列を生成します。
$secureAttributes
を設定した場合、これらの HTML 属性は、
SecurityCompnent によって生成された非表示の input タグの中にマージされます。
これは、 'form'
のような HTML5 属性を設定するのに特に便利です。