sfFormでsetPreValidatorとsfValidatorCallbackを使って条件分岐させてみた

add to hatena hatena.comment 2 users add to del.icio.us 0 user add to livedoor.clip 0 user

Symfony1.1から搭載されているsfFormで、「Aが選択されているときにはBとCは必須」ってのを実装してみた。

sfValidatorSchemaを拡張したりすれば同じようなことが実現できそうだけど、今回は別解。
sfValidatorSchema::setPreValidatorにsfValidatorCallbackを渡して、callbackされるメソッドの中でValidatorを切り替えるという内容。

他で使いまわさないような処理の場合にはいいかなーと。
でも、Validatorを切り替えるためにValidatorを登録するってのがイマイチか。

<?php
class myForm extends sfForm
{
  public function setup()
  {
    parent::setup();

    $choices = array(0 => '必須じゃない',1 => '必須');

    // Widgets
    $this->setWidgets(array(
      'a' => new sfWidgetFormSelectRadio(array('choices' => $choices)),
      'b' => new sfWidgetFormInput(),
      'c' => new sfWidgetFormInput(),
    ));

    // Validators
    $this->setValidators(array(
      'a' => new sfValidatorChoice(array('choices' => array_keys($choices))),
      'b' => new sfValidatorPass(),
      'c' => new sfValidatorPass(),
    ));

    // b,cの条件を切り替えるための前処理をsfValidatorCallbackで登録
    $this->validatorSchema->setPreValidator(new sfValidatorCallback(array('callback' => array($this,'switchValidation'))));

    $this->errorSchema = new sfValidatorErrorSchema($this->validatorSchema);
  }

  // aの値を見て、b,cの値を切り替える
  public function switchValidation(sfValidatorBase $validator,$values,$args)
  {
    if($values['a'] == 1)
    {
      $this->validatorSchema['b'] = new sfValidatorString();
      $this->validatorSchema['c'] = new sfValidatorString();
    }
  }
}

Leave a Reply