2012-07-25 83 views
0

我有三個實體:自定義表單字段類型嵌入形式的Symfony2

  • 飲食,菜單和膳食
  • 飲食方面有菜單的一個集合,
  • 菜單有膳食之一collectiion。

所以我必須爲飲食創建一個嵌入式表單。

我遵循Symfony2嵌入式形式的文檔,但並不那麼簡單。

好的。我首先需要的是:

  • 每種飲食形式都需要有兩個菜單。
  • 菜單的每種形式都需要三餐。 (我不知道這是否可能)。

我可以在控制器中做到這一點,併發送到樹枝。但問題是當我'allow_add', 動態添加表單。

這就是問題所在:

enter image description here

代碼:

class DietType extends AbstractType 
{ 
    public function buildForm(FormBuilder $builder, array $options) 
    { 
     $builder 
      ->add('calories') 
      ->add('menus', 'collection', array('type' => new MenuType(), 
      'allow_add' => true, 'by_reference' => false, 'prototype' => true 
     )); 
    } 

    public function getDefaultOptions(array $options) 
    { 
     return array(
      'data_class' => 'Project\FoodBundle\Entity\Diet', 
      ); 
    } 

    public function getName() 
    { 
     return 'diet'; 
    } 
} 

class MenuType extends AbstractType 
{ 

    public function buildForm(FormBuilder $builder, array $options) 
    { 
     $builder 
      ->add('description') 
      ->add('meals', 'collection', array('type' => new MealType(), 
          'allow_add' => true, 'by_reference' => false, 
          'prototype' => true 
       )); 
    } 

    public function getDefaultOptions(array $options) 
    { 
     return array(
      'data_class' => 'Project\FoodBundle\Entity\Menu', 
     ); 
    } 

    public function getName() 
    { 
     return 'menu'; 
    } 
} 

class MealType extends AbstractType 
{ 
    public function buildForm(FormBuilder $builder, array $options) 
    { 
     $builder 
      ->add('name'); 
    } 

    public function getDefaultOptions(array $options) 
    { 
     return array(
      'data_class' => 'Project\FoodBundle\Entity\Meal', 
     ); 
    } 

    public function getName() 
    { 
     return 'meal'; 
    } 
} 

而且枝條模板:

{% extends '::base.html.twig' %} 

{% block body %} 

<h1>Diet creation</h1> 

<form action="{{ path('diet_create') }}" method="post" {{ form_enctype(form) }}> 

    {{ form_row(form.calories) }} 

     <div id = "menus" data-prototype="{{ form_widget(form.menus.vars.prototype)|e }}"> 

     <h3>Menus</h3> 
     {% for menu in form.menus %} 
     <ul class="menu"> 
       {{ _self.prototype(menu) }} 
     </ul> 
     {% endfor %} 

     {% macro prototype(menu) %} 
     {{ form_row(menu.description) }} 
     <li class="meal"> 
      {% for meal in menu.meals %} 
       {{ form_row(meal.name) }} 
      {% endfor %} 
     </li> 
     {% endmacro %} 
    </div> 

    <p> 
     <button type="submit">Save</button> 
    </p> 
</form> 

<script> 

var collectionHolder = $('#menus'); 

var $addMenuLink = $('<a href="#" class="add_menu_link">Add menu</a>'); 
var $newLinkMenuLi = $('<li></li>').append($addMenuLink); 

$(document).ready(function(){ 

    $('#menus').append($newLinkMenuLi); 

    $.each($('ul.menu'), function(){ 
     $(this).append('<a href="#"> Add meal </a>'); 
    }); 

    $addMenuLink.click(function(e) { 
     // prevent the link from creating a "#" on the URL 
     e.preventDefault(); 

     // add a new menu form (see next code block) 
     addMenuForm(collectionHolder, $newLinkMenuLi); 
    }); 

    function addMenuForm(collectionHolder, $newLinkMenuLi){ 
     // Get the data-prototype we explained earlier 
     var prototype = collectionHolder.attr('data-prototype'); 

     // Replace '$$name$$' in the prototype's HTML to 
     // instead be a number based on the current collection's length. 
     var newForm = prototype.replace(/\$\$name\$\$/g, collectionHolder.children().length); 

     // Display the form in the page in an li, before the "Add a menu" link li 
     var $newFormLi = $('<li></li>').append(newForm); 
     $newLinkMenuLi.before($newFormLi); 
    } 


}); 

</script> 

{% endblock %} 

回答

0

關於驗證,嘗試添加上一個validator callback您飲食和菜單實體,它應該是OK :)

現在的形式主題,你可以去看看form theming documentation

+0

謝謝您的回答@GeoffreyBrier。但這不是我想要做的=/ – Munir 2012-07-25 17:08:24

+0

對不起,我從來沒有試過'初始'收集表單的集合。你不能簡單地把它分成3部分嗎?一個用於創建飲食,第二個用於飲食=>菜單集合(爲特定飲食添加多個菜單),最後一個用於菜單=>膳食集合(爲特定菜單添加多餐)。我認爲實施起來肯定會更快。 – 2012-07-25 20:16:13

+0

該程序的以前的版本。在這次更新中,我們試圖在程序中添加新的動態方法。不管怎麼說,還是要謝謝你。 – Munir 2012-07-26 16:38:14

相關問題