Zend_Formによるフォームの作成

ZendFrameworkでフォームを作成するのにFormヘルパーを使う方法もありますが、それよりももっと便利なフォーム生成機能が『Zend_Form』です。フォームのHTMLソースコードを生成したり、それらに各種のバリデーションやフィルター処理を組み込んだりすることが出来ます。今日は、『Zend_Form』について調べてみたいと思います。

addフォームの作成

『Zend_Form』は、クラスをロードさえすれば、コントローラでもビューでもどこでも利用することが出来ます。今回は、コントローラ側にフォーム作成の処理を用意し、ビュー側では、ただ作成されたフォームを表示するだけ、という形で作成してみたいと思います。

今回も、TestController.phpのファイルを修正して作成します。

1) TestControllerの冒頭にZend_Formのクラスをロードします。

Zend_Loader::loadClass(‘Zend_Form’);

2) 次に新たに追加するフォームを生成するためのメソッドであるcreateAddFormを作成します。

public function createAddForm(){}

3) 上記メソッドの中に、まず、Zend_Formのインスタンスを生成します。

$form=new Zend_Form();

4) 次に、フォームの基本属性を設定します。

$form->setMedhod(‘post’)->setAction(‘add’);

5) 次に、フォームに配置するコントロール類(input要素)の組込を行います。コントロールの組込は、『addElement』というメソッドを使って行います。Zend_Formでは、フォームに組み込まれるコントロールに相当するオブジェクトは『エレメント』として用意されていますので、これを組み込むのが、addElementです。

$form->addElement(‘text’,’title’);
$form->addElement(‘textarea’,’content’);
$form->addElement(‘submit’,’新規追加’);
return $form;

6) addActionの先頭に、フォームにデータの配列を渡すための下記のコードを挿入します。

$this->view->assign(‘form’,$this->createAddForm());

7) 最後に、add.phtmlの<form>から</form>の部分を削除して、$formの『render』というメソッドを呼び出します。これは、Zend_FormインスタンスからHTMLソースコードを生成するためのものです。

<?=$this->form->render()?>

7) それでは、ブラウザで確認してみます。ちょっと不格好ですが、下記のようなフォームが生成されました。

タグの属性を設定する

8) とりあえず、Zend_Formでフォームを生成することは出来ましたが、ラベルもついていませんし、テキストのサイズやテキストエリアのサイズも不格好です。各コントローラの属性を設定することにしましょう。

9) 『createAddForm』メソッドを修正します。addElementでは、第3引数にタグの属性を配列として渡すことが出来ます。

public function createAddForm(){
 //Zend_Formをインスタンス化します。
 $form=new Zend_Form();
 //フォームの基本情報をセットします。
 $form->setMethod('post')->setAction('add');
 /*************************************
 フォームのコントロールを組み込みます
 第3引数に属性を配列として渡します。
 **************************************/
 $form->addElement('text','title',array('label'=>'タイトル','size'=>40));
 $form->addElement('textarea','content',array('label'=>'コンテンツ','cols'=>40,'rows'=>5));
 $form->addElement('submit','新規追加');
 return $form;
 }

10) ブラウザで確認してみましょう。下記のようになりました。

Zend_Form_Elementによるエレメント属性

11) addElementの第3引数に、属性を配列として渡す方法を紹介してきましたが、Zend_Frameworkでは、それぞれのエレメントを扱うクラスが用意されていますので、そのクラスを使ってコードを記述してみたいと思います。

12) ZendFrameworkでは、『Zend_Form_Element』というエレメントの基底クラスを継承して各コントローラ向けのエレメントクラスが用意されています。これらのクラスのインスタンスを作成し、必要なメソッドを呼び出して設定を行った上で、addElementすれば、必要なエレメントを組み込むことが出来ます。

13) それでは、実際にTestController.phpの冒頭に、必要なクラスをロードするためのコードを記述をします。

Zend_Loader::loadClass('Zend_Form_Element_Text');
Zend_Loader::loadClass('Zend_Form_Element_Textarea');
Zend_Loader::loadClass('Zend_Form_Element_Submit');

14) createAddFormメソッドを下記のように変更します。尚、

public function createAddForm(){
 //Zend_Formをインスタンス化します。
 $form=new Zend_Form();
 //フォームの基本情報をセットします。
 $form->setMethod('post')->setAction('add');
 /*************************************
 フォームのコントロールを組み込みます
 Zend_Form_Elementによって組み込みます
 **************************************/
 $title=new Zend_Form_Element_Text('title');
 $title->setAttrib('size',40)->setLabel('タイトル');
 $content=new Zend_Form_Element_Textarea('content');
 $content->setAttribs(array('cols'=>40,'rows'=>3))->setLabel('コンテンツ');
 $send=new Zend_Form_Element_Submit('send');
 $send->setLabel('新規追加');
 //コントローラの組込
 $form->addElement($title);
 $form->addElement($content);
 $form->addElement($send);
 return $form;
 }

15) 先程のフォームと全く同じフォームが生成されれば、OKです。属性を設定する『setAttrib』は、配列を渡す場合は、『setAttribs』と、複数形になるみたいですので、間違えないようにして下さい。

Zend_Form_Elementの継承クラスの一覧

それでは、Zend_Form_Elementを継承して用意されているエレメントの一覧を下記にまとめてみます。

  • Zend_Form_Element_Text
    <input type=”text”>タグを生成するテキストの入力フィールドのクラスです。
  • Zend_Form_Element_Textarea
    <input type=”textarea”>タグを生成するテキストエリアの入力フィールドのクラスです。
  • Zend_Form_Element_Password
    <input type=”password”>タグを生成するパスワード入力フィールドのクラスです。
  • Zend_Form_Element_Hidden
    <input type=”hidden”>タグを生成する非表示フィールドのクラスです。
  • Zend_Form_Element_Checkbox
    <input type=”checkbox”>タグを生成するチェックボックスのクラスです。
  • Zend_Form_Element_MultiCheckbox
    複数の<input type=”checkbox”>タグをまとめて生成する チェックボックスのクラスです。
    『addMultiOptions』というメソッドを使い、表示項目を設定します。引数には、表示する項目を配列で渡します。
    例:$select->addMultiOptions(array(‘りんご’,’みかん’,’バナナ’));
  • Zend_Form_Element_Radio
    <input type=”radio”>タグを生成するラジオボタンのクラスです。
  • Zend_Form_Element_Select
    <select>タグによる選択リストのクラスです。
  • Zend_Form_Element_Multiselect
    複数項目を選択する<select>タグを生成します。
    MultiCheckbox同様『addMultiOptions』を使用します。
  • Zend_Form_Element_Button
    <input type=”button”>タグを生成するプッシュボタンのクラスです。
  • Zend_Form_Element_Submit
    <input type=”submit”>タグを生成する送信ボタンのクラスです。
  • Zend_Form_Element_Reset
    <input type=”reset”>タグを生成するリセットボタンのクラスです。

複数コントロールを生成するクラス

16) エレメントクラスの中で、下記の4つは、複数項目を生成しますので、『addMultiOptions』というメソッドを使い、表示項目を設定します。引数には、表示する項目名を配列でまとめたものを渡します。

  • Zend_Form_Element_MultiCheckbox
  • Zend_Form_Element_Radio
  • Zend_Form_Element_Select
  • Zend_Form_Element_Multiselect

サンプルコードを下記に記述します。

17) 各エレメントを使用する場合には、冒頭にZend_Loaderでロードして下さい。

//Zend_From_Elementのロード(サンプルコード用)
Zend_Loader::loadClass('Zend_Form_Element_Radio');
Zend_Loader::loadClass('Zend_Form_Element_Select');
Zend_Loader::loadClass('Zend_Form_Element_MultiCheckbox');

18) createAddFormに複数コントロールのサンプルを作成してみます。

//複数コントロールのサンプル
 $radio=new Zend_Form_Element_Radio('radio');
 $radio->addMultiOptions(array('男性','女性'));
 $select=new Zend_Form_Element_Select('select');
 $select->addMultiOptions(array('東京','千葉','神奈川'));
 $checks=new Zend_Form_Element_MultiCheckbox('checks');
 $checks->addMultiOptions(array('りんご','みかん','バナナ'));
 $form->addElement($radio);
 $form->addElement($checks);
 $form->addElement($select);

18) ブラウザで表示してみます。

本日は以上ですが、結構修正、修正でTestController.phpを弄くり回していますので、コードがわかりづらくなった人のために、本日時点でのコードを下記に記述しておきます。参考になれば幸いです。

<?php
require_once 'Zend/Controller/Action.php';
require_once 'Zend/View.php';
require_once 'Zend/Layout.php';
require_once 'Zend/Config/Xml.php';
require_once 'Zend/Db.php';
require_once 'Zend/Exception.php';
require_once 'Zend/Validate.php';
require_once 'Zend/Filter/StringTrim.php';
Zend_Loader::loadClass('Zend_Form');
//Zend_From_Elementのロード
Zend_Loader::loadClass('Zend_Form_Element_Text');
Zend_Loader::loadClass('Zend_Form_Element_Textarea');
Zend_Loader::loadClass('Zend_Form_Element_Submit');
//Zend_From_Elementのロード(サンプルコード用)
Zend_Loader::loadClass('Zend_Form_Element_Radio');
Zend_Loader::loadClass('Zend_Form_Element_Select');
Zend_Loader::loadClass('Zend_Form_Element_MultiCheckbox');
class TestController extends Zend_Controller_Action{
 //初期化
 public function init(){
 define('APP_DIR', dirname(dirname(__FILE__)));
 define('LAYOUT_DIR', APP_DIR.'/views/layouts');
 //ヘッドタイトル情報をセットする
 $this->view->headTitle('Winrado徒然草');
 //連想配列による情報のセット
 $this->view->assign('sitename','WinRoad徒然草');
 $this->view->assign('description','ZendFrameworkの為のテストサイトです。');
 $this->view->assign('content_header','header.phtml');
 $this->view->assign('content_footer','footer.phtml');
 $this->view->assign('content_footer_text','copyright Winroad徒然草2011.');
 //Zend_layoutのためのオプションの指定
 $options=array(
 'layout'=>'layout',
 'layoutPath'=>LAYOUT_DIR,
 'content'=>'content');
 //Zend_layoutメソッドの開始
 $layout=Zend_Layout::startMvc($options);

 //データベース設定情報を取得
 $config=new Zend_Config_Xml(APP_DIR.'/config/mysql-config.xml','db');
 $adapter=new Zend_Config_Xml(APP_DIR.'/config/mysql-config.xml','adapter');
 $this->db=Zend_Db::factory($adapter->name,$config);
 //データベースへの接続
 $this->db->getConnection();

 }
 public function indexAction()
 {
 //データベースからレコードを取得する
 $select=$this->db->select()->from('dvd_collections');

 //POST送信された場合の処理
 if($this->getRequest()->isPost()){
 //受け取った値を変数に代入する
 $find=$this->getRequest()->getParam('search');
 //titleとcontentの両方をOR検索する
 $select=$select->where("title like '%{$find}%'")->orwhere("content like '%{$find}%'");
 }

 $result=$this->db->fetchAll($select);
 //連想配列データベース情報をセット
 $this->view->assign('result',$result);
 }
 public function createAddForm(){
 //Zend_Formをインスタンス化します。
 $form=new Zend_Form();
 //フォームの基本情報をセットします。
 $form->setMethod('post')->setAction('add');
 /*************************************
 フォームのコントロールを組み込みます
 Zend_Form_Elementによって組み込みます
 **************************************/
 $title=new Zend_Form_Element_Text('title');
 $title->setAttrib('size',40)->setLabel('タイトル');
 $content=new Zend_Form_Element_Textarea('content');
 $content->setAttribs(array('cols'=>40,'rows'=>3))->setLabel('コンテンツ');
 $send=new Zend_Form_Element_Submit('send');
 $send->setLabel('新規追加');
 //コントローラの組込
 $form->addElement($title);
 $form->addElement($content);
 $form->addElement($send);

 //複数コントロールのサンプル
 $radio=new Zend_Form_Element_Radio('radio');
 $radio->addMultiOptions(array('男性','女性'));
 $select=new Zend_Form_Element_Select('select');
 $select->addMultiOptions(array('東京','千葉','神奈川'));
 $checks=new Zend_Form_Element_MultiCheckbox('checks');
 $checks->addMultiOptions(array('りんご','みかん','バナナ'));
 $form->addElement($radio);
 $form->addElement($checks);
 $form->addElement($select);

 return $form;
 }
 public function addAction()
 {
 $this->view->assign('form',$this->createAddForm());
 //POST送信されたら
 if($this->getRequest()->isPost()){
 $title=$this->getRequest()->getParam('title');
 $content=$this->getRequest()->getParam('content');
 $error='';
 //フィルタインスタンスの生成
 $filter=new Zend_Filter_StringTrim();
 $title=$filter->filter($title);
 $content=$filter->filter($content);
 //静的メソッドのバリデーション処理
 if(!Zend_Validate::is($title,'NotEmpty')){
 $error.="タイトル名は必須です。<br>";
 }
 if(!Zend_Validate::is($content,'NotEmpty')){
 $error.="コンテンツを入力して下さい。<br>";
 }
 //チェックOK時の処理
 if($error == ''){
 $data = array(
 'title' => $title,
 'content' => $content
 );
 //データベースにレコードを挿入
 $this->db->insert('dvd_collections',$data);
 //indexにリダイレクトします
 $this->_redirect('test/index');
 }
 //バリデーションエラー時の処理
 $this->view->assign('error',$error);
 }
 }
 public function editAction()
 {
 //POSTデータが送信された場合の処理
 if($this->getRequest()->isPost()){
 //変数idに送信されたidを代入する
 $id=$this->getRequest()->getParam('id');
 //配列dataに送信されたデータを代入する
 $data=array(
 'title'=>$this->getRequest()->getParam('title'),
 'content'=>$this->getRequest()->getParam('content')
 );
 //idが一致するデータを更新する
 $this->db->update('dvd_collections',$data,"id={$id}");
 //indexにリダイレクトする
 $this->_redirect('test/index');
 //POSTデータが送信されていない場合の処理
 }else{
 $id=$this->getRequest()->getParam('id')*1;
 if($id <= 0){
 throw new Zend_Exception('レコードが見つかりません');
 }
 //Zend_Db_Select構文でidの一致するデータを取得します
 $select=$this->db->select()->from('dvd_collections')->where("id={$id}");
 //fetchRowメソッドで最初の1レコードを取得します。
 $result=$this->db->fetchRow($select);
 //ビューにデータを配列で渡します
 $this->view->assign('result',$result);
 }
 }
 public function delAction(){
 if($this->getRequest()->isPost()){
 $id=$this->getRequest()->getParam('id');
 $this->db->delete('dvd_collections',"id={$id}");
 $this->_redirect('test/index');

 }else{
 $id=$this->getRequest()->getParam('id')*1;
 if($id <= 0){
 throw new Zend_Exception('レコードのIDが見つかりません');
 }
 $select=$this->db->select()->from('dvd_collections')->where("id={$id}");
 $result=$this->db->fetchRow($select);
 $this->view->assign('result',$result);
 }
 }
}

このエントリーを含むはてなブックマーク Buzzurlにブックマーク livedoorクリップ Yahoo!ブックマークに登録

トラックバック&コメント

この投稿のトラックバックURL:

コメントをどうぞ

このページの先頭へ