2011-04-15 103 views
0

我有以下(简化的)表:的Symfony:多种形式

Service: 
    product_name 
    number_of_clients 

有人选择并保存服务A与3级的客户和服务B与2个客户端后,我必须与服务A的细节显示一个页面和输入字段(名称&电子邮件)为3客户端然后服务B和2个客户端的输入字段的详细信息。在这个页面上,关于客户端的信息被保存在数据库的另一个表格中(强加的DB结构)。

如何创建每个服务下显示的随机表单数量,以及如何正确访问提交表单中的数据?所有表单都会同时进行编辑和保存,而不是单独进行。

我去了Advanced Forms但它没有多大帮助。

+0

所以,你有“服务有很多客户”架构,你希望用户在第一页上定义一些客户端,并在第二页上输入每个客户端的数据,对不对? – Dziamid 2011-04-15 21:35:59

+0

是的,那是对的。 – yoshi 2011-04-16 14:57:33

回答

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'); 
    } 

您还需要创建一个自定义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"> 

就是这样。希望你可以把它放在一起=)

+0

谢谢。这有助于:) – yoshi 2011-04-17 18:59:49

0

道歉,如果我放弃过简单回答你的问题,但你当然可以名称/形式相同类的基础上,不同的声明形式:

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

如果数量表单是未知的,我只是使用某种类型的动态参数或标识符来创建一组可以在用户回发时使用的名称。

然后,您可以分别访问每个提交表单对象的数据(可能通过循环或类似构造),就像您使用单个表单一样。