sfWidgetでチェックボックスなどを表示したい場合

sfWidgetFormChoiceを使用します。
sfWidgetFormChoiceのコンストラクタに渡す第1パラメータのオプションで、multipleとexpandedがあり、この値の組み合わせでラジオボタンチェックボックスになります。

  1. multiple=>false, expanded=>false :単一選択リスト(プルダウン)
  2. multiple=>true, expanded=>false :複数選択リスト
  3. multiple=>false, expanded=>true :ラジオボタンのリスト
  4. multiple=>true, expanded=>true :チェックボックスのリスト

チェックボックス(のリスト)を表示する場合の例:

<?php
$this->setWidgets( array(
    'options'=> new sfWidgetFormChoice(
        array(
            'choices'=>array( 'value1'=>'name1',  'value2'=>'name2'),
            'multiple'=>true,
            'expanded'=>true
        )
    )
));
?>

表示例:
http://farm4.static.flickr.com/3281/3059958456_69d4a8ff6c_o.jpg


参考:http://www.aide-de-camp.org/chapter_10.htmlの「List Widgets」

sfWidget系クラスごとの必須オプション/対応オプションの調べ方

例:sfWidgetFormChoice

~SYMFONY_LIB_DIR/widget/sfWidgetFormChoice.class.php
configureメソッドが以下のように定義されています。

<?php
41  protected function configure($options = array(), $attributes = array())
42  {
43    $this->addRequiredOption('choices');
44
45    $this->addOption('multiple', false);
46    $this->addOption('expanded', false);
47    $this->addOption('renderer_class', false);
48    $this->addOption('renderer_options', array());
49    $this->addOption('renderer', false);
50  }
?>

つまり、sfWidgetFormChoiceクラスでは、

  • choicesが必須オプション
  • multiple、expanded、render_class、render_options、rendererがサポートされるオプション

となっていて、共通オプションと上記以外のオプション名が指定された場合はエラーになります。

sfWidget系クラスの初期化チェーン

例:sfWidgetFormChoice

1.sfForm派生クラス内にて、各フォームへの要素割り当て

<?php
$this->setWidgets( array(
    'options'=> new sfWidgetFormChoice(
        array(
            'choices'=>array( 'value1'=>'name1',  'value2'=>'name2'),
            'multiple'=>true,
            'expanded'=>true
        )
    )
));
?>

2.~SYMFONY_LIB_DIR/widget/sfWidgetFormChoice.class.php
sfWidgetFormChoiceにはコンストラクタが定義されていないので、親クラスのsfWidgetFormのコンストラクタへ
3.~SYMFONY_LIB_DIR/widget/sfWidgetForm.class.php
コンストラクタで共通オプションが設定された後、さらに親クラスのsfWidgetのコンストラクタへ
(共通オプションは、id_format、is_hidden、needs_multipart、default、labelです)
4.~SYMFONY_LIB_DIR/widget/sfWidget.class.php
コンストラクタ内で、configureメソッドが呼び出されます。
configureが派生クラスでオーバーライドされている場合は、派生クラスのメソッドが呼び出されます。
つまりここで sfWidgetFormChoice の configure が呼び出されます。
(コンストラクタに指定した $options、$attributes を引き継ぐ)

単一チェックボックス

sfWidgetFormChoiceは複数の値からの選択を前提としたものですが、オン/オフを指定するような単一のチェックボックスの場合は、sfWidgetFormInputCheckboxを使用します。

<?php
$this->setWidgets( array(
    '同意'=> new sfWidgetFormInputCheckbox(
        array(
            'value_attribute_value'=>'1',
            'default'=>true
        )
    )
));
?>

value_attribute_value」って何?と思ってよくよく考えてみたら「VALUE属性の値」ってことでそのままでしたw

★sfWidgetFormInputCheckboxでは共通オプション以外にはvalue_attribute_valueオプションのみがサポートされています。

sfWidgetFormDateの表示フォーマット

sfWidgetFormDateを使用した日付選択は、デフォルトでは次のような要素が表示されます。
[ 月 ▼]/[ 日 ▼]/[ 年 ▼]
この表示を「年月日」に変えたい場合は、sfWidgetFormDateに渡すオプション「format」で変更します。

<?php
new sfWidgetFormDate(
    array( 'format'=>'%year%年%month%月%day%日' )
)
?>

ちなみにformatのデフォルト値はsfWidgetFormDate.class.phpの40行目で定義されています。

<?php
38  protected function configure($options = array(), $attributes = array())
39  {
40    $this->addOption('format', '%month%/%day%/%year%');
?>

sfWidgetFormDateRangeの初期化方法と表示フォーマット

●月●日~●月●日という日付の範囲を選択する場合に、sfWidgetFormDateRangeを使います。
sfWidgetFormDateRangeには、開始日用と終了日用にそれぞれsfWidgetFormDate要素を作成します。
また、全体のフォーマットは「template」というオプションで変更できます。

<?php
new sfWidgetFormDateRange(
    array(
        'from_date'=> new sfWidgetFormDate(
            array( 'format'=>'%year%年%month%月%day%日' )
        ), 
        'to_date'=>new sfWidgetFormDate(
            array( 'format'=>'%year%年%month%月%day%日' )
        ),
        'template'=>'%from_date% ~ %to_date%'
    )
)
?>

参考:sfWidgetFormDateRangeのconfigureメソッド

sfWidgetで表示するフォーム要素のラベルの変更

http://symfony.xrea.jp/1.1/forms_book/01-Form-Creation.htmlの「ラベル」の項によると、sfFormのwidgetSchema->setlabelsやwidgetSchema->setLabelを使用する方法が紹介されていますが、ウィジェットのコンストラクタへのオプションで直接labelを指定する方法もあります。

<?php
new sfWidgetFormChoice(
    array(
        'choices'=>array( 'value1'=>'name1',  'value2'=>'name2'),
        'multiple'=>false,
        'expanded'=>true,
        'label'=>'選択5'
    )
)
?>

FORMタグを生成するrenderFormTagメソッド

Google Code Archive - Long-term storage for Google Code Project Hosting.の「新しい sfForm メソッド」参照

sfForm::renderFormTag()を使用すると、フォームの開始タグを上手く生成できます。

条件に従ってアクションをforward/redirect/forward404するメソッド

  • sfAction::forwardIf($condition, $module, $action)
  • sfAction::forwardUnless($condition, $module, $action)
  • sfAction::redirectIf($condition, $url, $statusCode = 302)
  • sfAction::redirectUnless($condition, $url, $statusCode = 302)
  • sfAction::forward404If($condition, $message = null)
  • sfAction::forward404Unless($condition, $message = null)

sfValidatorSchemaのオプションを変更する

フォーム定義クラス(sfForm派生クラス)内でバリデーションの設定を行う場合、SymfornyのFormsドキュメントでは以下のようなサンプルコードになっています。

http://symfony.xrea.jp/1.1/forms_book/02-Form-Validation.html 「バリデータ」

<?php
$this->setValidators(array(
  'name'    => new sfValidatorString(array('required' => false)),
  'email'   => new sfValidatorEmail(),
  'subject' => new sfValidatorChoice(array('choices' => array_keys(self::$subjects))),
  'message' => new sfValidatorString(array('min_length' => 4)),
));
?>

通常フォームのすべての要素にバリデータを設定することがほとんどだと思われますが、定義したフォーム要素のすべてに対して対応するバリデータが設定されていない場合、「Unexpected extra form field named~」というエラーメッセージが表示されてしまいます。

この挙動は、sfValidatorSchemaのオプション「allow_extra_fields」の値がfalseの場合、つまり「余分なフィールドを許可しない」という設定の場合のものです。

allow_extra_fieldsをtrueに設定すれば、バリデータが定義されていない要素があってもこのようなエラーにはなりません。


しかし、setValidators等のメソッドを使用している場合、sfFormクラスのメソッド内部で暗黙的に(オプションなしで)sfValidatorSchemaオブジェクトが作成されるため、コンストラクタへオプションを引き渡すことが出来ません。

このような場合は、自前でsfValidatorSchemaオブジェクトを作成し、sfForm::setValidatorSchemaメソッドを使用して用意したsfValidatorSchemaオブジェクトを直接セットします。

★allow_extra_fieldsをtrueにして、バリデータを持たないフォーム要素を許可することは、セキュリティの観点から推奨されていません。trueにする場合は、予期しないパラメータに対するチェックを慎重に行ってください。

<?php
$this->setValidatorSchema(
  new sfValidatorSchema( array(
    'name'    => new sfValidatorString(array('required' => false)),
    'email'   => new sfValidatorEmail(),
    'subject' => new sfValidatorChoice(array('choices' => array_keys(self::$subjects))),
    ),
    array( 'allow_extra_fields'=>true )
  )
);
?>


追記:sfValidatorSchema::setOptionメソッドを使用すれば、コンストラクタのパラメータでなくてもオプションを設定できるということを忘れていました(勉強不足でしたw
(以下のコードは http://symfony.xrea.jp/1.1/forms_book/02-Form-Validation.html のリスト2-9です)

<?php
    $this->setValidators(array(
      'email'   => new sfValidatorEmail(),
      'subject' => new sfValidatorChoice(array('choices' => array_keys(self::$subjects))),
      'message' => new sfValidatorString(array('min_length' => 4)),
    ));
 
    $this->validatorSchema->setOption('allow_extra_fields', true);
?>

sfWidgetSchemaの設定変更はsetWidgetsの後で

sfForm派生クラス内でフォーム要素の設定を行う場合、

  • sfForm->setWidgets()でのウィジェットの初期化
  • sfForm->widgetSchema->setLabelsでラベルの設定
  • sfForm->widgetSchema->setNameFormatでフォーム要素のNameフォーマットの変更

などを行いますが、sfForm->setWidgets()呼び出して内部に保持しているsfWidgetSchemaオブジェクトは書き換えられてしまいます。
したがって、setLabelsやsetNameFormatなどを呼び出す場合は、setWidgetsの後に記述しなくてはなりません。