0

私には3つのエンティティがあります:

  • ダイエット、メニュー、食事
  • ダイエットにはメニューのコレクションが1つあります。
  • メニューには食事のコレクションが1つあります。

したがって、Diet用の埋め込みフォームを作成する必要があります。

私はSymfony2の埋め込み形式のドキュメントに従いますが、それはそれほど単純ではありません。

Ok。私が最初に必要なもの:

  • ダイエットの各形式には、2つのメニューが必要です。
  • メニューの各形式には、3つの食事が必要です。(それが可能かどうかはわかりません)。

これはコントローラーで実行して、小枝に送信できます。しかし、問題は、フォームを動的に追加するために「allow_add」を実行する場合です。

それは問題:

ここに画像の説明を入力してください

コード:

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

そしてTwigテンプレート:

{% 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 %}
4

1 に答える 1

0

検証に関しては、ダイエット エンティティとメニュー エンティティにバリデータ コールバックを追加してみてください。問題ないはずです :)

フォーム テーマについては、フォーム テーマのドキュメントを参照してください。

于 2012-07-25T15:36:39.257 に答える