0

次の(簡略化された)表があります。

Service:
  product_name
  number_of_clients

誰かが 3 つのクライアントを持つサービス A と 2 つのクライアントを持つサービス B を選択して保存した後、サービス A の詳細と 3 つのクライアントの入力フィールド (名前と電子メール) を含むページを表示し、次にサービス B の詳細と 2 つのクライアントの入力フィールドを表示する必要があります。このページから、クライアントに関する情報がデータベース内の別のテーブルに保存されます (強制された DB 構造)。

各サービスで表示する乱数のフォームを作成するにはどうすればよいですか? また、送信されたフォームのデータに後で適切にアクセスするにはどうすればよいですか? すべてのフォームは、個別にではなく、同時に編集および保存されます。

Advanced Formsを調べましたが、あまり役に立ちませんでした。

4

2 に答える 2

1

この単純なスキーマの例を次に示します。ニーズに合わせて調整できるはずです。

//schema.yml

Client:
  columns:
    name: string(255)
    service_id: integer
  relations:
    Service:
      local: service_id
      foreign: id
      foreignAlias: Clients

Service:
  columns:
    name: string(255)

//routing.yml

//i added this route to split 'new' action in 2 steps
service_choose:
  url: /service/choose
  param: {module: service, action: choose}

service:
  class: sfDoctrineRouteCollection
  options:
    model: Service
    module: service

//create a module based on service route collection (there's a task) and add choose action:
  public function executeChoose(sfWebRequest $request)
  {
    $form = new ServiceChooseForm();
    if (($method = $this->request->getMethod()) == 'POST')
    {
      $form->bind($request->getParameter($form->getName()), $request->getFiles($form->getName()));

      if ($form->isValid())
      {
        $total_clients = $form->getValue('total_clients');
        $this->redirect('@service_new?total_clients='.$total_clients);
      }      
    }
    $this->form = $form;
    $this->setTemplate('choose');
  }

また、choose アクション用のカスタム sfForm フォームを作成する必要があります。ここでは、多数のクライアントを設定します。

class ServiceChooseForm extends sfForm
{
  public function configure()
  {
    $this->widgetSchema->setNameFormat('service[%s]');

    $this->setWidget('total_clients', new sfWidgetFormInput());
    $this->setValidator('total_clients', new sfValidatorInteger());
  }
}
//ServiceForm embeds your new clients forms based on total_clients option.
class ServiceForm extends BaseServiceForm
{
  public function configure()
  {
    //clients sub form
    $clientsForm = new sfForm();
    for ($i=0; $i<$this->getOption('total_clients',2); $i++)
    {
      $client = new Client();
      $client->Service = $this->getObject();

      $clientForm = new ClientForm($client);
      $clientsForm->embedForm($i, $clientForm);      
    }
    $this->embedForm('newClients', $clientsForm);
  }
}

さらにいくつかの調整:

//chooseSuccess template, poinst a form to the same action:
<h1>New Service</h1>

<form action="<?php echo url_for('service_choose') ?>" method="post">
  <table>
    <tfoot>
      <tr>
        <td colspan="2">
          <?php echo $form->renderHiddenFields(false) ?>
          <input type="submit" value="Continue" />
        </td>
      </tr>
    </tfoot>
    <tbody>
      <?php echo $form ?>
    </tbody>
  </table>
</form>

//_form partial:

<form action="<?php echo url_for('@service_create?total_clients='. $form->getOption('total_clients')) ?>" method="post">

それでおしまい。まとめていただけると幸いです(=_=)

于 2011-04-16T16:40:31.200 に答える
0

私があなたの質問にあまりにも単純な回答をしている場合は申し訳ありませんが、もちろん、同じフォームクラスに基づいてフォームに異なる名前を付けたり宣言したりすることができます:

$form_1 = $form_2 = $form_3 = new someForm();

フォームの数が不明な場合は、ある種の動的パラメーターまたは識別子を使用して、ユーザーがポストバックしたときに使用できる一連の名前を作成します。

その後、単一のフォームの場合と同様に、送信された各フォーム オブジェクトのデータに個別にアクセスできます (おそらくループまたは同様の構造を介して)。

于 2011-04-15T15:57:53.677 に答える