2013-10-28 114 views
6

我正在爲廣告製作一個頁面。廣告可以是不同的類型,因此具有不同的數據。例如,一輛汽車將有makemodel作爲額外的數據。動態表單(切換實體)symfony2

現在,我有一個基本的學說實體Advert其中包含每個廣告所需的數據。如果用戶選擇創建車輛廣告,我需要動態地填充表單(我想要顯示車輛廣告的選項)。我需要動態填充表單(使用ajax和symfony2表單)。我需要動態填充表單(使用ajax和symfony2表單)。但我也需要將實體更改爲AdvertVehicle

這可能嗎?我看過在Symfony2的主頁

菜譜條目「如何動態地修改表單中使用表格活動」: 這應通過AJAX調用返回到您的應用程序進行處理。在該控制器中,您可以提交表單,而不是處理它,只需使用提交的表單來呈現更新的字段即可。然後可以使用來自AJAX調用的響應來更新視圖。

我瞭解如何使Ajax調用回我的控制器,我明白瞭如何使用表格的事件,但我怎麼得到渲染選擇框的響應(包含例如車型)回?有了新的AbstractType?或formbuilder?

然後,當用戶實際提交表單時,我需要使用所選廣告類型的實體。我可以根據用戶選擇動態地更改實體嗎?

編輯 我檢查了很好的表單innheritance,謝謝。我擴展AdvertType並覆蓋buildForm()方法,並在我添加我需要的項目AdvertVehicleType我稱之爲父方法。

Futher說明 每個廣告實體包含pricedescriptiontitlecategory。有些廣告包含更多,例如makemodel。它們由discriminatormap(doctrine2)分化

例子:

// -- Entity 
class CarAdvert extends Advert { 

    protected $model; 
    protected $make; 

} 

// -- Entity 
// -- This uses discriminator mapping 
class Advert { 
    protected $title; 
    protected $description; 
    protected $price; 
    protected $category; 
} 

如果用戶選擇cars我想用CarAdvert實體(驗證和持久性)類別,如果用戶選擇的房子hold itemcategory我只想使用正常的Advert實體。

一個主要問題仍然是我無法弄清楚如何通過ajax渲染擴展窗體。這部分的任何提示?當用戶選擇汽車作爲一個類別時,我希望表單被更新(通過jQuery/ajax),但是如何製作一個控制器來檢索表單的擴展部分,並將html作爲響應發回(不使用樹枝並在視圖中渲染它,這是可能的)?

解決方案:

見下面回答!

+1

你可以在你的表單類型中使用繼承,它可以避免爲2個類似的表單重複代碼,例如:'AdvertType'有2個領域。 'AdvertVehicleType'可以擴展'AdvertType'以添加2個字段。請告訴我們更多關於您的實體的信息,他們如何聲明,您如何區分兩種類型的「廣告」等。 –

+0

對此問題的任何更新@Asbestos?我面臨着類似的問題,所以我對這個問題可能的解決方案或經驗感興趣,等等。謝謝! – acrobat

+1

我希望更新後的答案已經足夠好了@acrobat如果您需要更多信息,請不要猶豫留下另一條評論! – Asbestos

回答

2

解決方案:

我的問題的解決方案是在控制器中創建了一些額外的功能來解決,我希望能夠改變「對飛」從實體和形式問題用戶的選擇..

public function indexAction(Request $request) 
{ 
    $form = $this->getForm($request); 
    $form->handleRequest($request); 

    return array(
      'form' => $form->createView(), 
      'request' => $request->request, 
    ); 
} 

getForm檢索形式(例如AdvertVehicleType車輛或AdvertType爲「默認」廣告)。

getForm方法看起來像這樣:

private function getForm(Request $request) 
{ 
    $categoryTitle = 'NONE'; 
    $categoryId = $request->request->get('advert', false)['category']; 

    if ($categoryId) { 
     $categoryTitle = $this->getDoctrine()->getRepository('Bundle:Category')->find($categoryId)->getTitle(); 
    } 

    return $this->createForm($this->getFormType($categoryTitle), $this->getEntity($categoryTitle)); 

}

這裏我檢索categoryID(即在請求中的形式選擇的)和retreives與getFormTypeand與getEntity該實體的formType。

private function getEntity($categoryTitle) 
{ 
    $entity = new Advert(); 
    switch ($categoryTitle) { 
     case Category::CARS: 
      $entity = new AdvertCar(); 
    } 

    return $entity; 
} 

private function getFormType($categoryTitle) 
{ 
    switch ($categoryTitle) { 
     case Category::CARS: 
      return new AdvertCarType(); 
     default: 
      return new AdvertType(); 
    } 
} 

爲了能夠更新這一「對飛」使用Ajax(但如果用戶嘗試提交表單它也可以),我創建的控制器中的另一個動作。

此動作呈現我想要更新(在ajax調用)的窗體部分,我通過實際選取我不需要的窗體中的小枝來設置窗體對象,使其呈現像這樣:

{% do form.title.setRendered %} 

(這只是一個例子,我真正做到這一點的所有,我不想渲染表單對象

我後來乾脆就叫:

{{ form_rest(form) }} 

這將檢索不同類別的表格的「休息」。

現在讓我們假設你有州和城鎮來選擇。首先選擇狀態,然後用樹枝渲染該州的城鎮(但您可以實際渲染您需要的部分,例如{{ form_row(form.towns) }},並將此呈現的模板作爲json響應返回,並將其放入您想要的div中jQuery的。

$html = $this->renderView('@Bundle/NewAddPage/filter_area.twig', array('form' => $form->createView())); 

,然後在響應返回$ HTML變量。

我希望這有助於,而對此的解釋是不夠好,如果不只是做一個評論,我會用這個更新我的回答!