2012-02-26 23 views
0

all。1つから選択した複数のフォームを選択

複数の選択フィールドの代わりに1つのページに複数のフォーム(現在は選択オプションごとに)を使用できるかどうかを質問したいと思います。

状況は次のとおりです。@ManyToManyサービスと 'user_services'関係記憶テーブルとの関係はありますが、min_pricemax_priceなどの追加フィールドがUserService Doctrine Entityクラスで拡張されています。

私の特別なケースでは、チェックボックス、サービス名、価格フィールドを含むテーブルレイアウトを保存ボタン1つではなく、複数のフォームを作成する方法がわかりませんたとえば、選択リストから1つのオプションに、その後にこのオプションの追加フィールドが続きます。

ありがとうございました。

答えて

0

あなたはサービスの束を持っていて、

enter image description here

は何だろう、それらを表示することを想像してみてあなたがやる?

マイソリューション:

コントローラー:

class DefaultController extends Controller 
{ 
    public function indexAction(Request $request) 
    { 
     /** @var $em \Doctrine\ORM\EntityManager */ 
     $em = $this->get('doctrine.orm.entity_manager'); 
     $services = $em->getRepository('ThestudioscheduleProfileBundlesServiceBundle:Service')->findAll(); 
     $user = $this->get('security.context')->getToken()->getUser(); 
     $form = $this->createForm(new UserServiceType($services, $user->getServiceDetails())); 
     if ('POST' == $request->getMethod()) { 
      $form->bindRequest($request); 
      if ($form->isValid()) { 
       $data = $form->getData(); 
       $em->getConnection()->beginTransaction(); 
       try { 
        foreach ($data['services'] as $serviceDetails) { 
         // if service is selected 
         if ($serviceDetails['id']) { 
          $serviceDetails['details']->setUser($user); 
          $serviceDetails['details']->setService($em->getRepository('ThestudioscheduleProfileBundlesServiceBundle:Service')->find($serviceDetails['service'])); 
          $serviceDetails['details'] = $em->merge($serviceDetails['details']); 
         } else { 
          // if the entity is exist but user unchecked it - delete it 
          if ($serviceDetails['details']->getId()) { 
           $serviceDetails['details'] = $em->merge($serviceDetails['details']); 
           $em->remove($serviceDetails['details']); 
          } 
         } 
        } 
        $em->flush(); 
        $em->getConnection()->commit(); 
        // TODO: display success message to user 
        return $this->redirect($this->generateUrl('ThestudioscheduleProfileBundlesServiceBundle_homepage')); 
       } catch (\Exception $e) { 
        $em->getConnection()->rollback(); 
        $em->close(); 
        var_export($e->getMessage());die; 
        // TODO: log exception 
        // TODO: display something to user about error 
       } 
      } 
     } 
     return $this->render('ThestudioscheduleProfileBundlesServiceBundle:Default:index.html.twig', array(
      'form' => $form->createView() 
     )); 
    } 
} 

UserServiceType:

class UserServiceType extends AbstractType 
{ 
    private $services; 
    private $userServiceDetails; 
    public function __construct($services, $userServiceDetails) 
    { 
     $this->services = $services; 
     $this->userServiceDetails = $userServiceDetails; 
    } 
    /** 
    * @param \Symfony\Component\Form\FormBuilder $builder 
    * @param array $options 
    * @return void 
    */ 
    public function buildForm(FormBuilder $builder, array $options) 
    { 
     // all application services 
     $builder->add('services', 'collection'); 
     foreach ($this->services as $key => $service) { 
      $serviceType = new ServiceType($service, null); 
      foreach ($this->userServiceDetails as $details) { 
       if ($service == $details->getService()) { 
        $serviceType->setUserServiceDetails($details); 
       } 
      } 
      $builder->get('services')->add('service_' . $key, $serviceType); 
     } 
    } 
    /** 
    * Returns the name of this type. 
    * 
    * @return string The name of this type 
    */ 
    public function getName() 
    { 
     return 'profile_user_service'; 
    } 
} 

サービス種別:

class ServiceType extends AbstractType 
{ 
    private $service; 
    private $userServiceDetails; 
    public function __construct($service, $userServiceDetails) 
    { 
     $this->service = $service; 
     $this->userServiceDetails = $userServiceDetails; 
    } 
    /** 
    * @param \Symfony\Component\Form\FormBuilder $builder 
    * @param array $options 
    * @return void 
    */ 
    public function buildForm(FormBuilder $builder, array $options) 
    { 
     $builder->add('id', 'checkbox', array(
        'label' => $this->service->getName(), 
        'required' => false)) 
       ->add('service', 'hidden') 
       ->add('details', new ServiceDetailsType($this->userServiceDetails)); 
     $values = array('service' => $this->service->getId()); 
     if (null !== $this->userServiceDetails) { 
      $values = array_merge($values, array('id' => true)); 
     } 
     $builder->setData($values); 
    } 
    /** 
    * Returns the name of this type. 
    * 
    * @return string The name of this type 
    */ 
    public function getName() 
    { 
     return 'profile_service'; 
    } 
    public function setUserServiceDetails($details) 
    { 
     $this->userServiceDetails = $details; 
    } 
} 

ServiceDetailsType:

class ServiceDetailsType extends AbstractType 
{ 
    private $details; 
    public function __construct($details) 
    { 
     $this->details = $details; 
    } 
    /** 
    * @param \Symfony\Component\Form\FormBuilder $builder 
    * @param array $options 
    * @return void 
    */ 
    public function buildForm(FormBuilder $builder, array $options) 
    { 
     $builder->add('id', 'hidden') 
       ->add('minPrice', 'money', array('required' => false)) 
       ->add('maxPrice', 'money', array('required' => false)) 
       ->add('unit', 'choice', array(
        'choices' => array(
         'hour' => 'Hours', 
         'photo' => 'Photos' 
        ), 
        'required' => false 
       )) 
       ->add('unitsAmount', null, array('required' => false)); 
     if (!empty($this->details)) { 
      $builder->setData($this->details); 
     } 
    } 
    public function getDefaultOptions(array $options) 
    { 
     return array(
      'data_class' => 'Thestudioschedule\ProfileBundles\ServiceBundle\Entity\UserService', 
      'csrf_protection' => false 
     ); 
    } 
    /** 
    * Returns the name of this type. 
    * 
    * @return string The name of this type 
    */ 
    function getName() 
    { 
     return 'profile_service_details'; 
    } 
} 

すべて、この作品で最も驚くべきこと!フロリアンは、私の時間を費やしてくれてありがとうございました。私は解決策について考え続けていました。不確かな質問があれば謝ります。私は、Symfonyのドキュメントは、このようなより多様なフォームの埋め込み/コレクションの例で更新されるべきだと思います。

乾杯、 Dima。

1

この場合、多対多リレーションを処理するために使用できるcollectionタイプを使用する必要があります。

わかりましたらuseruser_servicesのリストを処理したいと思います。 :ユーザとサービス(プラスそのMIN_PRICE、MAX_PRICE、など)との関係を表しますUserServiceTypeを作成し、

  • 1:

    あなたは、このような何かをしなければなりません

    class UserServiceType extends AbstractType 
    { 
        public function buildForm(FormBuilder $builder, array $options) 
        { 
         $builder 
          ->add('min_price', 'currency') 
          ->add('max_price', 'currency') 
         ; 
        } 
    
        public function getDefaultOptions() 
        { 
         return array('data_class' => 'Entity\UserService'); 
        } 
    } 
    
    • 2、form_typeとして登録:
    // app/config/config.yml (for example) 
    services: 
        user_service_type: 
         class: UserServiceType 
         tags: 
          - { name: form.type, alias: user_service } 
    
    • 3、このコレクションを処理するために、あなたのUserTypeを設定:
    class UserType extends AbstractType 
    { 
        public function buildForm(FormBuilder $builder, array $options) 
        { 
         $builder 
          ->add('services', 'collection', array(
           'type'  => 'user_service', // this is the id of the form type registered above 
           'allow_add' => true, 
           'allow_delete' => true, 
           'prototype' => true, 
          )) 
         ; 
        } 
    
        public function getDefaultOptions() 
        { 
         return array('data_class' => 'Entity\User'); 
        } 
    } 
    
+0

あなたの返事をいただき、ありがとうございました。今日は夕方に試してみます – Dmitry

+0

「コレクション」のようなものはまったく機能していないようです。私はタスクを簡略化しようとしました。 $ builder-> add( 'services); - 複数選択をレンダリングします。 $ builder-> add( 'services'、 'collection'、array( 'type' => 'text')); - 'サービス'ラベル以外は何も表示されません。 {{form_widget(form)}}を使ってフォームをレンダリングしました。 – Dmitry

+0

私は$ builder-> add( 'services'、 'collection'、array( 'type' => new ServiceType()))を試しました。 ServiceType()クラス($ builder-> add( 'name'))内のサービスの 'name'のみを使用します。しかしまた何も。奇妙な、非常に奇妙な、それは動作していない、または私は何か大きなものを欠いている。私はSymfony 2 Book(またはCookbook、私は覚えていません)の例を試しましたが、何も私のために働いていませんでした。 2.0.10 Symfonyを使用しています。 – Dmitry