フォームのレンダリング
フォームの外観は非常に多様です。実際には、2つの極端なケースに遭遇する可能性があります。一方では、アプリケーションで視覚的に互いに似ている多くのフォームをレンダリングする必要があり、$form->render()
を使ってテンプレートなしで簡単にレンダリングできる点が重宝されます。これは通常、管理インターフェースの場合です。
一方、それぞれがオリジナルである多様なフォームがあります。それらの外観は、フォームテンプレート内でHTML言語を使って記述するのが最適です。そしてもちろん、両方の極端なケースに加えて、その中間のどこかに位置する多くのフォームに遭遇します。
Latteによるレンダリング
テンプレートシステムLatteは、フォームとそのコントロールのレンダリングを大幅に簡素化します。まず、個々のコントロールを手動でレンダリングしてコードを完全に制御する方法を示します。後で、そのようなレンダリングを自動化する方法を示します。
フォームのLatteテンプレートの設計案は、Nette\Forms\Blueprint::latte($form)
メソッドを使って生成させることができ、これはブラウザページに出力されます。コードをクリックして選択し、プロジェクトにコピーするだけです。
{control}
フォームをレンダリングする最も簡単な方法は、テンプレートに次のように記述することです:
このようにレンダリングされたフォームの外観は、Rendererと個々のコントロールの設定によって影響を受ける可能性があります。
n:name
PHPコードでのフォーム定義は、HTMLコードと非常に簡単に連携できます。n:name
属性を追加するだけです。とても簡単です!
結果となるHTMLコードの形は、完全にあなたのコントロール下にあります。n:name
属性を <select>
、<button>
、または <textarea>
要素で使用すると、それらの内部コンテンツが自動的に補完されます。<form n:name>
タグは、レンダリングされるフォームのオブジェクトを持つローカル変数 $form
も作成し、閉じタグ </form>
はレンダリングされていないすべての隠しコントロールをレンダリングします({form} ... {/form}
にも同じことが当てはまります)。
ただし、発生しうるエラーメッセージのレンダリングを忘れてはいけません。addError()
メソッドによって個々のコントロールに追加されたもの({inputError}
を使用)と、フォームに直接追加されたもの($form->getOwnErrors()
によって返される)の両方です:
RadioListやCheckboxListなどのより複雑なフォームコントロールは、個々の項目ごとにこのようにレンダリングできます:
{label}
{input}
各コントロールについて、テンプレートでどのHTML要素、<input>
、<textarea>
など、を使用するか考えたくないですか?解決策は、汎用タグ {input}
です:
フォームがトランスレータを使用する場合、{label}
タグ内のテキストは翻訳されます。
この場合でも、RadioListやCheckboxListなどのより複雑なフォームコントロールは、個々の項目ごとにレンダリングできます:
Checkboxコントロールの <input>
自体をレンダリングするには、{input myCheckbox:}
を使用します。この場合、HTML属性は常にカンマで区切ります
{input myCheckbox:, class: required}
。
{inputError}
フォームコントロールにエラーメッセージがある場合、それを表示します。メッセージは通常、スタイリングのためにHTML要素でラップされます。
メッセージがない場合に空の要素のレンダリングを防ぐには、n:ifcontent
をエレガントに使用できます:
エラーの存在は hasErrors()
メソッドで確認でき、それに応じて親要素にクラスを設定できます:
{form}
{form signInForm}...{/form}
タグは <form n:name="signInForm">...</form>
の代替です。
自動レンダリング
{input}
および {label}
タグのおかげで、任意のフォームの汎用テンプレートを簡単に作成できます。それはすべてのコントロールを反復処理してレンダリングしますが、</form>
タグでフォームが終了するときに自動的にレンダリングされる隠しコントロールは除きます。レンダリングされるフォームの名前は、変数
$form
で期待されます。
使用される自己終了ペアタグ {label .../}
は、PHPコードのフォーム定義から来るラベルを表示します。
この汎用テンプレートを、たとえば basic-form.latte
ファイルに保存し、フォームをレンダリングするには、それをインクルードしてフォームの名前(またはインスタンス)を
$form
パラメータに渡すだけです:
特定のフォームをレンダリングする際にその外観に手を加え、例えば一つのコントロールを異なる方法でレンダリングしたい場合は、最も簡単な方法は、後で上書きできるブロックをテンプレートに事前に準備することです。 ブロックは動的な名前を持つこともできるため、レンダリングされるコントロールの名前を挿入することもできます。たとえば:
例えば username
コントロールの場合、ブロック input-username
が作成され、{embed}タグを使用して簡単に上書きできます:
または、basic-form.latte
テンプレートの全内容を、$form
パラメータを含めてブロックとして定義することもできます:
これにより、その呼び出しがわずかに簡単になります:
ブロックは、レイアウトテンプレートの冒頭の1か所でインポートするだけで十分です:
特殊なケース
HTMLタグ <form>
なしでフォームの内部部分のみをレンダリングする必要がある場合、たとえばスニペットを送信する場合、n:tag-if
属性を使用してそれらを非表示にします:
フォームコンテナ内のコントロールのレンダリングは、{formContainer}
タグが役立ちます。
Latteなしでのレンダリング
フォームをレンダリングする最も簡単な方法は、次を呼び出すことです:
このようにレンダリングされたフォームの外観は、Rendererと個々のコントロールの設定によって影響を受ける可能性があります。
手動レンダリング
各フォームコントロールには、フォームフィールドとラベルのHTMLコードを生成するメソッドがあります。それらは文字列またはNette\Utils\Htmlオブジェクトとして返すことができます:
getControl(): Html|string
コントロールのHTMLコードを返しますgetLabel($caption = null): Html|string|null
ラベルが存在する場合、そのHTMLコードを返します
したがって、フォームは個々のコントロールごとにレンダリングできます:
一部のコントロールでは getControl()
が単一のHTML要素(例:<input>
、<select>
など)を返しますが、他のコントロール(CheckboxList、RadioList)ではHTMLコード全体を返します。
その場合、各項目について個々の入力とラベルを生成するメソッドを使用できます:
getControlPart($key = null): ?Html
1つの項目のHTMLコードを返しますgetLabelPart($key = null): ?Html
1つの項目のラベルのHTMLコードを返します
これらのメソッドは歴史的な理由から get
プレフィックスを持っていますが、呼び出すたびに新しい Html
要素を作成して返すため、generate
の方が適切です。
Renderer
これはフォームのレンダリングを担当するオブジェクトです。$form->setRenderer
メソッドで設定できます。$form->render()
メソッドが呼び出されると、制御が渡されます。
カスタムレンダラーを設定しない場合、デフォルトのレンダラー Nette\Forms\Rendering\DefaultFormRenderer が使用されます。これはフォームコントロールをHTMLテーブルとしてレンダリングします。出力は次のようになります:
フォームの骨格にテーブルを使用するかどうかは議論の余地があり、多くのWebデザイナーは異なるマークアップを好みます。たとえば、定義リストです。したがって、DefaultFormRenderer
を再構成して、フォームをリストとしてレンダリングします。設定は $wrappers
配列を編集することによって行われます。最初のインデックスは常に領域を表し、2番目はその属性を表します。個々の領域は画像で示されています:

デフォルトでは、コントロールグループ controls
はテーブル <table>
でラップされ、各 pair
はテーブル行 <tr>
を表し、label
と
control
のペアはセル <th>
と <td>
です。次に、ラッピング要素を変更します。controls
領域を <dl>
コンテナに挿入し、pair
領域をコンテナなしのままにし、label
を
<dt>
に挿入し、最後に control
を <dd>
タグでラップします:
結果は次のHTMLコードです:
wrappers配列では、他の多くの属性に影響を与えることができます:
- 個々のフォームコントロールタイプにCSSクラスを追加する
- 奇数行と偶数行をCSSクラスで区別する
- 必須項目とオプション項目を視覚的に区別する
- エラーメッセージをコントロールのすぐ隣に表示するか、フォームの上に表示するかを決定する
Options
Rendererの動作は、個々のフォームコントロールに options を設定することによっても制御できます。これにより、入力フィールドの隣に表示される説明を設定できます:
HTMLコンテンツを含めたい場合は、Html クラスを使用します:
Htmlコントロールはラベルの代わりに使用することもできます:$form->addCheckbox('conditions', $label)
。
コントロールのグループ化
Rendererを使用すると、コントロールを視覚的なグループ(fieldset)にグループ化できます:
新しいグループを作成すると、それがアクティブになり、新しく追加された各コントロールもそれに追加されます。したがって、フォームはこのように構築できます:
Rendererは最初にグループをレンダリングし、次にどのグループにも属さないコントロールをレンダリングします。
Bootstrapのサポート
例では、Twitter Bootstrap 2、Bootstrap 3、Bootstrap 4 用にレンダラーを設定する方法の例を見つけることができます。
HTML属性
フォームコントロールの任意のHTML属性を設定するには、setHtmlAttribute(string $name, $value = true)
メソッドを使用します:
コントロールのタイプを指定します:
タイプやその他の属性の設定は、視覚的な目的のみです。入力の正確性の検証はサーバー側で行う必要があり、適切なフォームコントロールを選択し、検証ルールを指定することで保証されます。
ラジオまたはチェックボックスリストの個々の項目に、それぞれ異なる値を持つHTML属性を設定できます。
キーに基づいて値を選択することを保証する style:
の後のコロンに注意してください:
出力:
readonly
などの論理属性を設定するには、疑問符付きの表記を使用できます:
出力:
セレクトボックスの場合、setHtmlAttribute()
メソッドは <select>
要素の属性を設定します。個々の<option>
の属性を設定したい場合は、setOptionAttribute()
メソッドを使用します。上記で述べたコロンと疑問符付きの表記も機能します:
出力:
プロトタイプ
HTML属性を設定する代替方法は、HTML要素が生成されるテンプレートを変更することです。テンプレートは
Html
オブジェクトであり、getControlPrototype()
メソッドによって返されます:
この方法で、getLabelPrototype()
によって返されるラベルのテンプレートも変更できます:
Checkbox、CheckboxList、RadioListコントロールの場合、コントロール全体をラップする要素のテンプレートに影響を与えることができます。これは
getContainerPrototype()
によって返されます。デフォルトの状態では「空の」要素であるため、何もレンダリングされませんが、名前を設定することでレンダリングされます:
CheckboxListとRadioListの場合、個々の項目を区切るセパレータのテンプレートにも影響を与えることができます。これは
getSeparatorPrototype()
メソッドによって返されます。デフォルトの状態では
<br>
要素です。ペア要素に変更すると、区切る代わりに個々の項目をラップします。
さらに、個々の項目のラベルのHTML要素のテンプレートに影響を与えることができます。これは
getItemLabelPrototype()
によって返されます。
翻訳
多言語アプリケーションをプログラミングしている場合、おそらくフォームを異なる言語バージョンでレンダリングする必要があります。Nette Frameworkはこの目的のために翻訳用のインターフェース Nette\Localization\Translator を定義しています。Netteにはデフォルトの実装はありません。Componetteで見つけることができるいくつかの既製のソリューションから、ニーズに応じて選択できます。それらのドキュメントで、トランスレータの設定方法を学ぶことができます。
フォームは、トランスレータを介したテキストの出力をサポートしています。setTranslator()
メソッドを使用して渡します:
この時点から、すべてのラベルだけでなく、すべてのエラーメッセージやセレクトボックスの項目も別の言語に翻訳されます。
個々のフォームコントロールについて、異なるトランスレータを設定したり、null
値で翻訳を完全に無効にしたりすることが可能です:
検証ルールの場合、特定のパラメータもトランスレータに渡されます。たとえば、ルールの場合は:
トランスレータは次のパラメータで呼び出されます:
したがって、数に応じて単語 文字
の正しい複数形を選択できます。
onRenderイベント
フォームがレンダリングされる直前に、コードを実行させることができます。たとえば、フォームコントロールに正しい表示のためのHTMLクラスを追加できます。コードを
onRender
配列に追加します: