2

Ubuntu で Symfony 1.3.6 を使用しています。

多くのフィールドを含むフォームがあります - すべてのフィールドを一度に表示するのではなく (ユーザーを怖がらせる可能性があります)、フォームを段階的に分割して、ユーザーが表示されたフィールドのみに入力できるようにしたいと考えています。 、各ステップ/ステージで(ウィザードのようなものです)。

そのためには、フォームのカスタム メソッドを記述する必要があります。

validateStep1();
validateStep2();
...
validate StepN();

上記の各関数では、使用可能なウィジェットのサブセットのみを検証します。つまり、そのステップでユーザーに表示されるウィジェットのみを検証します。

そのためには、ウィジェットで isValid() メソッドを呼び出すことができれば便利ですが、sfWidget クラスを調べたところ、ウィジェット レベルでそのような isValid() メソッドはありません。

これはDRYではないため、使用している各ウィジェットの検証をハードコーディングしたくありません

フォーム内の個々のウィジェットをチェックして、ユーザーが入力した値が有効かどうかを確認する方法を知っている人はいますか?

4

2 に答える 2

3

Symfony でマルチパート フォームを実装するには、別の方法を使用します。うまくいけば、次のシェルで作業を開始できます。

ステップ 1: ステージ ウィジェットをフォームに追加する

public function configure()
{
  $this->setWidget('stage', new sfWidgetFormInputHidden(array('default' => 1));
  $this->setValidator('stage', new sfValidatorFormInteger(array('min' => 1, 'max' => $maxStages, 'required' => true));
}

ステップ 2: ステージに関する情報をフォームに追加する

protected $stages = array(
  1 => array('stage1field1', 'stage1field2',
  2 => array('stage2field1', ... //etc for as many stages you have
);

ステップ 3: configure as stage メソッドをフォームに追加する

public function configureAsStage($currentStage)
{
  foreach($this->stages as $stage => $field)
  {
    if ($currentStage > $stage)
    {
      $this->setWidget($stage, new sfWidgetFormInputHidden()); //so these values carry through
    }
    if ($stage > $currentStage)
    {
       unset($this[$stage]); //we don't want this stage here yet
    }
  }
}

ステップ 4: doBind をオーバーライドする

直接オーバーライドする必要があるかもしれませんがbind()、忘れてしまいました。

public function doBind(array $taintedValues)
{
  $cleanStage = $this->getValidator('stage')->clean($taintedValues['stage']);
  $this->configureAsStage($cleanStage);
  parent::doBind($taintedValues);
}

ステップ 5: いくつかの補助メソッドをフォームに追加する

public function advanceStage()
{
  if ($this->isValid())
  {
    $this->values['stage'] += 1;
    $this->taintedValues['stage'] += 1;
    $this->resetFormFields();
  }
}

public function isLastStage()
{
  return $this->getValue('stage') == count($this->stages);
}

ステップ 6: アクションで必要に応じて configureAsStage/advanceStage を呼び出します

public function executeNew(sfWebRequest $request)
{
  $form = new MultiStageForm($record);
  $form->configureAsStep(1);
}

public function executeCreate(sfWebRequest $request)
{
  $record = new Record();
  $form = new MultiStageForm($record);
  $form->bind($request[$form->getName()]);
  if ($form->isValid())
  {
    if ($form->isLastStage())
    {
      $form->save();
      //redirect or whatever you do here
    }
    $form->advanceStage(); 
  }
  //render form
}

私はこれをその場で完全に作り上げました。うまくいくと思いますが、テストしていないので間違いがあるかもしれません!

于 2010-08-24T01:42:39.753 に答える
1

この関数isValid()は、関連付けられたフォームがバインドされているかどうか、およびバリデータ エラーの総数が 0 であることを確認することを除いて、実際には何もしません。実際の検証は、「バインド」段階で行われます ( $form->bind())。

バインド後、バリデーターのエラーはフォームの各フィールド (sfFormField) に格納されます。したがって、フォーム フィールドの個々のエラーを取得するには、次のようにします。

<?php
  foreach ($form as $formField) { // $formField is an instance of sfFormField
    if ($formField->hasError()) {
      // do something
    }
  }
?>

または、あなたの場合、制限されたフィールドのセットのみを処理する必要があるため、代わりにフィールド名の配列を反復処理してみてください。

<?php
  $fieldNames = array('name', 'email', 'address');
  foreach ($fieldNames as $fieldName) {
    if ($form[$fieldName]->hasError()) {
      // do something
    }
  }
?>

validateFields($fieldNames)これは、 DRY の期待に応えるなど、関数に簡単に適合させることができます。

フィールドから取得できるその他の情報については、 sfFormFieldのドキュメントを参照してください。

于 2010-08-23T09:49:45.603 に答える