2

hey guys I'm new at symfony2 and I'm trying to do a simple application!

I have 3 entities, called "CarInquerito", "CarPergunta" and "CarResposta" and they are related as you can see on "interesting" code below. All these properties have appropriate gets/sets.

What I pretend is when I create a form from CarInquerito, I embed a form from CarPergunta and a form from CarResposta to that CarPergunta form. I've already accomplished embedding a collection of CarResposta to CarPergunta form, but when I try to embed the result of this to CarInquerito it seems not to work.

class CarInquerito
{
     /**
     * @ORM\OneToMany(targetEntity="CarPergunta", mappedBy="idInquerito", cascade={"persist"})
     */
    private $perguntas;
}

class CarInqueritoType{
    $builder->add('perguntas', 'collection', array(
            'type' => new CarPerguntaType(),
            'allow_add' => true,
            'by_reference' => false,
            'prototype' => true,
            'allow_delete' => true,
            ));
}


class CarInquerito
{
 /**
     * @var CarInquerito
     *
     * @ORM\ManyToOne(targetEntity="CarInquerito", inversedBy="perguntas")
     * @ORM\JoinColumns({
     *   @ORM\JoinColumn(name="id_inquerito", referencedColumnName="id", onUpdate="cascade", onDelete="cascade", nullable = false)
     * })
     */
    private $idInquerito;

  /**
     * @ORM\OneToMany(targetEntity="CarResposta", mappedBy="idPergunta", cascade={"persist"})
     */
    private $respostas;
}

class CarPerguntaType{
   $builder->add('respostas', 'collection', array(
            'type' => new CarRespostaType(),
            'allow_add' => true,
            'by_reference' => false,
            'prototype' => true,
            'allow_delete' => true,
            ));
}

class CarResposta{
   /**
     * @var CarPergunta
     *
     * @ORM\ManyToOne(targetEntity="CarPergunta", inversedBy="respostas")
     * @ORM\JoinColumns({
     *   @ORM\JoinColumn(name="id_pergunta", referencedColumnName="id", onUpdate="cascade", onDelete="cascade", nullable = false)
     * })
     */
    private $idPergunta;
}


class CarRespostaType{
  $builder->add('resposta', 'text');
}

Now the controller:

public function newAction() {

        $CarInquerito = new CarInquerito();
        $form = $this->createForm(new CarInqueritoType(), $CarInquerito);

        return $this->render('CareAdminBundle:CarInquerito:new.html.twig', array(
                    'form' => $form->createView(),
                ));
    }

Now the views: new.html.twig:

<div class="inqueritos">
<div class="perguntas-list">
<ul class="perguntas" data-prototype="{% filter escape %}{% include 'CareAdminBundle:CarInquerito:prototypePergunta.html.twig' with {'form': form.perguntas.get('prototype')} %}{% endfilter %}">
        {% for pergunta in form.perguntas %}
            <li>
            {{ form_widget(pergunta.pergunta) }} 
            </li>
        {% endfor %}

       </ul>
</div>
</div>

---protoypePergunta.html.twig----------

<div class="respostas-list" style="background-color: red; padding: 10px;">
    <ul class="respostas" data-prototype="{{ form_widget(form.respostas.get('prototype')) | e }}">
       {% for resposta in form.respostas %}
        <li>{{ form_widget(resposta.resposta) }}</li>
     {% endfor %}

    </ul>
</div>

I have a javascript file where I add and remove links to add "Pergunta" and "Respostas" like below:

$(document).ready(function(){    

    var collectionHolderPerguntas = $('ul.perguntas');

    collectionHolderPerguntas.find('li').each(function() {
        addPerguntaFormDeleteLink($(this));
    });

    // setup an "add a tag" link
    var $addPerguntaLink = $('<a href="#" class="add_pergunta_link">Adicionar pergunta</a>');
    var $newLinkLi = $('<li></li>').append($addPerguntaLink);

      // add the "add a tag" anchor and li to the tags ul
    collectionHolderPerguntas.append($newLinkLi);

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

        // add a new tag form (see next code block)
        addPerguntaForm(collectionHolderPerguntas, $newLinkLi);
    });

    var collectionHolderRespostas = $('ul.respostas');
    collectionHolderRespostas.find('li').each(function() {
        alert("OL");
        addRespostaFormDeleteLink($(this));
    });

    // setup an "add a tag" link
    var $addRespostaLink = $('<a href="#" class="add_resposta_link">Adicionar resposta</a>');
    var $newLinkLiResposta = $('<li></li>').append($addRespostaLink);

    // add the "add a tag" anchor and li to the tags ul
    collectionHolderRespostas.append($newLinkLiResposta);

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

        // add a new tag form (see next code block)
        addRespostaForm(collectionHolderRespostas, $newLinkLiResposta);
    });


});

function addPerguntaForm(collectionHolderPerguntas, $newLinkLi) {
    // Get the data-prototype we explained earlier
    var prototype = collectionHolderPerguntas.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, collectionHolderPerguntas.children().length);

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

     // add a delete link to the new form
    addPerguntaFormDeleteLink($newFormLi);
}

function addPerguntaFormDeleteLink($perguntaFormLi) {
    var $removeFormA = $('<a href="#">apagar</a>');
    $perguntaFormLi.append($removeFormA);

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

        // remove the li for the tag form
        $perguntaFormLi.remove();
    });
}

function addRespostaForm(collectionHolderRespostas, $newLinkLiResposta) {

    // Get the data-prototype we explained earlier
    var prototype = collectionHolderRespostas.attr('data-prototype');
    // 
    // Replace '$$name$$' in the prototype's HTML to
    // instead be a number based on the current collection's length.
    var newFormResposta = prototype.replace(/\$\$name\$\$/g, collectionHolderRespostas.children().length);

    // Display the form in the page in an li, before the "Add a tag" link li
    var $newFormLiResposta = $('<li></li>').append(newFormResposta);
    $newLinkLiResposta.before($newFormLiResposta);

    // add a delete link to the new form
    addRespostaFormDeleteLink($newFormLiResposta);
}

function addRespostaFormDeleteLink($respostaFormLi) {
    var $removeFormA = $('<a href="#">apagar</a>');
    $respostaFormLi.append($removeFormA);

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

        // remove the li for the tag form
        $respostaFormLi.remove();
    });
}

Any suggestions guys? I search all day, and I have tried a lot of things but I didn't manage to find a solution.

Any help is appreciated!

Thanks

4

1 回答 1

0

您需要在 newAction() 中的对象“CarInquerito”中放入一些数据。就像表单集合食谱中的这个例子:

$tag1 = new Tag();
        $tag1->name = 'tag1';
        $task->getTags()->add($tag1);
        $tag2 = new Tag();
        $tag2->name = 'tag2';
        $task->getTags()->add($tag2);
        // end dummy code

        $form = $this->createForm(new TaskType(), $task);

如果您不这样做,则不会创建嵌入式表单。

于 2012-08-15T14:16:46.913 回答