Zend_Form の高度な使用法Zend_Form にはさまざまな機能があり、 その多くは熟練者向けに用意されています。本章では、 それらの機能について例を交えて説明します。 配列記法関連するフォーム要素について、要素名を配列形式にしてグループ化したいこともあるでしょう。 たとえば、配送先と請求先のふたつの住所を受け取りたい場合、 それぞれに同じ要素を使った上で配列でグループ化すれば、 結果を別々に受け取ることができます。 たとえば次のようなフォームを例に考えてみましょう。
この例では、請求先住所と配送先住所に同じフィールドを使用しているため、 一方が他方を上書きしてしまいます。 これを解決するには、配列記法を使用します。
上の例では、住所をそれぞれ個別に受け取ることができます。 このフォームを送信すると、受け取り側では 3 つの要素を取得できます。 'save' が送信ボタン、そしてふたつの配列 'shipping' と 'billing' の中にはさまざまなキーとそれに対応する要素が含まれています。 Zend_Form は、この処理を サブフォーム で自動化します。 デフォルトで、サブフォームは、リストしている前の HTML フォームで示されたように、配列を用いて表記法をレンダリングします、 そして ID で完了します。 配列の名前はサブフォーム名からとられ、 配列のキーはサブフォーム内に含まれる要素となります。 サブフォームは、何段階でもネストさせることができます。 その場合も、ネストした配列形式でその構造を表します。 さらに、Zend_Form のさまざまなバリデーション機能は、この配列構造をきちんと処理するようにできています。 サブフォームをどれだけ深くネストさせたとしても、 フォームの検証は正しく行ってくれます。 この機能を使うために特に何かしなければならないということはありません。 この機能はデフォルトで有効になっています。 さらに、条件付きで配列記法を有効にしたり 特定の配列を指定してそこに要素やコレクションを所属させたりといった機能もあります。
さらに、要素レベルでは、特定の要素を特定の配列に属させるために Zend_Form_Element::setBelongsTo() メソッドを使うこともできます。 この値が何者なのか (明示的に設定されたものなのか フォームを経由して暗黙的に設定されたものなのか) を知るには getBelongsTo() アクセサを使用します。 複数ページのフォーム現在、複数ページのフォームは Zend_Form では公式にはサポートしていません。 しかし、それを実装するための機能の大半はサポートしており、 ほんの少し手を加えるだけでこの機能を実現できます。 複数ページのフォームを作成する鍵となるのが、 サブフォームの活用です。各ページに、ひとつのサブフォームだけを表示させるわけです。 こうすれば、それぞれのサブフォームの内容を各ページで検証し、 かつすべてのサブフォームの入力を終えるまでフォームの処理を行わないということができます。 Example #1 登録フォームの例 例として、登録フォームを考えてみましょう。 まず最初のページでユーザ名とパスワードを入力してもらい、 次のページではユーザのメタデータ (姓、名、住所など)、そして最後のページでは 参加したいメーリングリストを選択するといったものです。 まずはフォームを作成し、 その中でサブフォームをいくつか定義します。
submit ボタンがないこと、 またサブフォームのデコレータではなにもしていないことに注意しましょう。 そのままでは、これらのサブフォームはフィールドセットとして表示されることになります。 つまり、処理をオーバーライドしてそれらを個別のサブフォームになるようにし、 さらに submit ボタンを追加して処理を進められるようにする必要があります。 submit ボタンには action プロパティと method プロパティも必要です。 では、これらの機能のとっかかりを先ほどのクラスに追加してみましょう。
次に、アクションコントローラ用の仕組みを追加する必要があります。 さらにいくつか考えなければならないこともあります。 まず、フォームの入力内容をリクエスト間で持続させなければなりません。 次に、フォームの情報のうちどの部分が入力済みなのか、 そしてその部分に対応するサブフォームがどれなのか といった情報を取得するロジックも必要です。今回は Zend_Session_Namespace を使用してデータを持続させることにします。 そうすれば、二番目の問題に対応するのも簡単になるでしょう。 それではコントローラを作成していきましょう。 そして、フォームのインスタンスを取得するためのメソッドを追加します。
それでは、どのフォームを表示するのかを決める機能を追加していきましょう。 基本的に、フォーム全体の入力内容の検証を終えるまでは フォームの一部の表示を続けることになります。 さらに、普通はそれを決まった順序で表示することになるでしょう。 今回の場合は user、demog、そして最後に lists といった具合です。 どのデータが入力済みかを調べるには、セッションの名前空間を調べます。 各サブフォームに対応するキーが存在するかどうかを調べるというわけです。
上のメソッドを使用すると、たとえば "$subForm = $this->getCurrentSubForm();" で現在のサブフォームを取得してそれを検証したり "$next = $this->getNextSubForm();" で次に表示するフォームを取得したりできます。 では、実際にサブフォームを処理したり表示したりする方法を考えてみましょう。 getCurrentSubForm() を使用すれば、 今送信されてきたデータがどのサブフォームのものなのかがわかります (FALSE が返された場合は、まだ何も表示あるいは送信されていないことを表します)。 また、 getNextSubForm() を使用すれば次に表示すべきフォームを取得できます。 そして、フォームの prepareSubForm() メソッドを使用すれば、フォームを表示するための準備を行えます。 フォームを送信したら、サブフォームのデータを検証し、 そしてフォーム全体の入力が完了したかどうかを調べることができます。 これらの作業を行うためには、さらにいくつかのメソッドを追加しなければなりません。 送信されたデータをセッションに追加するメソッドや、 フォーム全体の検証を行う際にセッションの全セグメントを検証するメソッドなどです。
これで足場は固まりました。 ではこのコントローラのアクションを作っていきましょう。 まずこのフォームの最初のページ、 それからフォームを処理するための 'process' アクションが必要となります。
お気づきのとおり、実際にフォームを処理する部分のコードは比較的シンプルです。 注目すべき点は、どのサブフォームが送信されてきたのかを調べ、 何も送信されていない場合は先頭ページに飛ばしている部分です。 サブフォームが送信されてきた場合はそれを検証し、 問題がある場合は同じサブフォームを再表示します。 問題がない場合は、フォーム全体の入力が妥当か (つまりすべての入力が終わっているか) を調べ、 問題がある場合は次のサブフォームを表示します。 最後に、セッションの中身を確認ページに表示します。 ビュースクリプトは非常にシンプルなものになります。
将来的に、Zend Framework には複数ページのフォームを より簡単に作成するためのコンポーネントが用意される予定です。 このコンポーネントは、 セッションや各フォームの順序などの管理を抽象化したものとなります。 現時点では、複数ページのフォームをあなたのサイトで使用するには 上の例のようにするのが最も無難でしょう。
|
|