2015-10-26 3 views
0

У меня проблема, которую я не смог решить. У меня есть 2 сущности:Symfony2 коллекция всегда пустая

<?php 
namespace ...\Entity; 

// ... 

/** 
* Pregunta 
* 
* @ORM\Table(name="pregunta", indexes={@ORM\Index(name="fk_respuesta_tipo_respuesta1_idx", columns={"tipo_respuesta_id"}))}) 
* @ORM\Entity 
*/ 
class Pregunta { 

    /** 
    * @var integer 
    * 
    * @ORM\Column(name="id", type="integer") 
    * @ORM\Id 
    * @ORM\GeneratedValue(strategy="IDENTITY") 
    */ 
    private $id; 

    /** 
    * @var \Doctrine\Common\Collections\Collection 
    * 
    * @ORM\ManyToMany(targetEntity="...\Entity\Respuesta", mappedBy="pregunta") 
    */ 
    private $respuesta; 


    public function __construct() { 
     $this->tipoPrueba = new \Doctrine\Common\Collections\ArrayCollection(); 
     $this->respuesta = new \Doctrine\Common\Collections\ArrayCollection(); 
    } 

    /** 
    * Add respuesta 
    * 
    * @param ...\Entity\Respuesta $respuesta 
    * @return Pregunta 
    */ 
    public function addRespuesta(...\Entity\Respuesta $respuesta) { 
     $this->respuesta[] = $respuesta; 

     return $this; 
    } 

    /** 
    * Remove respuesta 
    * 
    * @param ...\Entity\Respuesta $respuesta 
    */ 
    public function removeRespuesta(...\Entity\Respuesta $respuesta) { 
     $this->respuesta->removeElement($respuesta); 
    } 

    /** 
    * Get respuesta 
    * 
    * @return \Doctrine\Common\Collections\Collection 
    */ 
    public function getRespuesta() { 
     return $this->respuesta; 
    } 

    function setRespuesta(\Doctrine\Common\Collections\Collection $respuesta) { 
     $this->respuesta = $respuesta; 
    } 
} 

Тогда у меня есть Respuesta сущность:

<?php 
class Respuesta { 

    /** 
    * @var integer 
    * 
    * @ORM\Column(name="id", type="integer") 
    * @ORM\Id 
    * @ORM\GeneratedValue(strategy="IDENTITY") 
    */ 
    private $id; 

    /** 
    * @var string 
    * 
    * @ORM\Column(name="texto_respuesta", type="text", nullable=false) 
    */ 
    private $textoRespuesta; 

    // ... 

У меня есть PreguntaType, который имеет свои поля и коллекцию RespuestaType:

/** 
* @param FormBuilderInterface $builder 
* @param array $options 
*/ 
public function buildForm(FormBuilderInterface $builder, array $options) { 
    $builder 
      ->add('titulo', 'textarea', array("label" => "Enunciado: ", "required" => true, "attr" => array('class' => 'form-control'))) 
      ->add('numeroPagina', 'integer', array("label" => "Página: ", "required" => true, "attr" => array('class' => 'form-control'))) 
      ->add('areaConocimiento', 'entity', array('class' => 'UciBaseDatosBundle:AreaConocimiento', 'required' => false, 'attr' => array('style' => 'width: 100%'))) 
      ->add('trianguloTalento', 'entity', array('class' => 'UciBaseDatosBundle:TrianguloTalento', 'required' => false, 'attr' => array('style' => 'width: 100%'))) 
      ->add('capitulo', 'entity', array('class' => 'UciBaseDatosBundle:Capitulo', 'required' => false, 'attr' => array('style' => 'width: 100%'))) 
      ->add('grupoProcesos', 'entity', array('class' => 'UciBaseDatosBundle:GrupoProcesos', 'required' => false, 'attr' => array('style' => 'width: 100%'))) 
      ->add('tipoPrueba', 'entity', array('class' => 'UciBaseDatosBundle:TipoPrueba', 'expanded' => true, 'multiple' => true, 'required' => false, 'attr' => array('style' => 'width: 100%'))) 
      ->add('libro', 'entity', array('class' => 'UciBaseDatosBundle:Libro', 'required' => false, 'attr' => array('style' => 'width: 100%'))) 
      ->add('respuesta', 'collection', array(
       'type' => new RespuestaType(), 
       'prototype' => true, 
       'allow_add' => true, 
       'by_reference' => false, 
       'allow_delete' => true, 
       'label' => ' ' 
    )); 
} 

/** 
* @param OptionsResolverInterface $resolver 
*/ 
public function setDefaultOptions(OptionsResolverInterface $resolver) { 
    $resolver->setDefaults(array(
     'data_class' => 'Uci\Bundle\BaseDatosBundle\Entity\Pregunta' 
    )); 
} 

Однако, когда Я отлаживаю отправку своей формы, если я установил свою коллекцию в 'required' => true, она выдает эту ошибку An invalid form control with name='...[respuesta][Respuesta0][RespuestaField]' is not focusable. С другой стороны, если я устанавливаю его на 'required' => false, поля моих коллекций всегда пусты.

Это мой TWIG файл:

<form action="{{ path('uci_administrador_registrarPregunta', { 'idTipoRespuesta': tipoRespuesta.id }) }}" name="formulario" method="POST" enctype="multipart/form-data">    
    <h3 class="thin text-center">Registrar una nueva pregunta {{ tipoRespuesta.nombre }}</h3> 
    <p class="text-center text-muted">{{ tipoRespuesta.explicacion }}</p> 
    <hr> 

    {% if error %} 
     <div style="color:red">{{ error }}</div> 
    {% endif %} 

    <div class="row top-margin"> 
     <div class="cols-xs-12 col-sm-10 col-md-8 col-lg-8"> 
      {{ form_row(form.titulo) }} 
     </div> 
    </div> 
    <div class="row top-margin"> 
     <div class="cols-xs-12 col-sm-10 col-md-8 col-lg-8"> 
      {{ form_row(form.numeroPagina) }} 
     </div> 
    </div> 
    <div class="row top-margin"> 
     <div class="cols-xs-12 col-sm-10 col-md-8 col-lg-8"> 
      {{ form_row(form.areaConocimiento) }} 
     </div> 
    </div> 
    <div class="row top-margin"> 
     <div class="cols-xs-12 col-sm-10 col-md-8 col-lg-8"> 
      {{ form_row(form.capitulo) }} 
     </div> 
    </div> 
    <div class="row top-margin"> 
     <div class="cols-xs-12 col-sm-10 col-md-8 col-lg-8"> 
      {{ form_row(form.grupoProcesos) }} 
     </div> 
    </div> 
    <div class="row top-margin"> 
     <div class="cols-xs-12 col-sm-10 col-md-8 col-lg-8"> 
      {{ form_row(form.trianguloTalento) }} 
     </div> 
    </div> 
    <div class="row top-margin"> 
     <div class="cols-xs-12 col-sm-10 col-md-8 col-lg-8"> 
      {{ form_row(form.tipoPrueba) }} 
     </div> 
    </div> 
    <div class="row top-margin"> 
     <div class="cols-xs-12 col-sm-10 col-md-8 col-lg-8"> 
      {{ form_row(form.libro) }} 
     </div> 
    </div> 
    <br> 
    <hr> 
    <h3>Respuestas</h3><br> 
    <div class="respuestas" data-prototype="{{ form_widget(form.respuesta.vars.prototype)|e }}"> 
     {# iterate over each existing tag and render its only field: name #} 
     {% for respuesta in form.respuesta %} 
      <div class="row top-margin"> 
       <div class="cols-xs-12 col-sm-10 col-md-8 col-lg-8"> 
        {{ form_row(respuesta.correcta) }} 
       </div> 
      </div> 
     {% endfor %} 
    </div> 
    <br><br> 
    <div class="row"> 
     <div class="col-lg-8">      
     </div> 
     <div class="col-lg-4 text-right"> 
      <button class="btn btn-action" type="submit">Registrar</button> 
     </div> 
    </div> 
    {{ form_rest(form) }} 
</form> 

Я использую некоторые JavaScript, чтобы добавить свои формы коллекции:

var $collectionHolder; 
// setup an "add a tag" link 
var $addTagLink = $('<a href="#" class="add_tag_link">Añadir respuesta</a>'); 
var $newLinkLi = $('<div></div>').append($addTagLink); 
function addTagForm($collectionHolder, $newLinkLi) { 
    // Get the data-prototype explained earlier 
    var prototype = $collectionHolder.data('prototype'); 
    // get the new index 
    var index = $collectionHolder.data('index'); 
    // Replace '__name__' in the prototype's HTML to 
    // instead be a number based on how many items we have 
    var newForm = prototype.replace(/__name__/g, 'Respuesta' + index); 
    // increase the index with one for the next item 
    $collectionHolder.data('index', $collectionHolder.find(':input').length); 
    // Display the form in the page in an li, before the "Add a tag" link li 
    var $newFormLi = $('<div style="background-color:#F6F6F6; border-radius:10px;padding: 25px;border: 5px solid #003c70;margin: 5px;"></div><br>').append(newForm); 
    $newLinkLi.before($newFormLi); 
} 
document.ready = function() { 
    // Get the ul that holds the collection of tags 
    $collectionHolder = $('div.respuestas'); 
    // add the "add a tag" anchor and li to the tags ul 
    $collectionHolder.append($newLinkLi); 
    // count the current form inputs we have (e.g. 2), use that as the new 
    // index when inserting a new item (e.g. 2) 
    $collectionHolder.data('index', $collectionHolder.find(':input').length); 
    $addTagLink.on('click', function (e) { 
     // prevent the link from creating a "#" on the URL 
     e.preventDefault(); 
     // add a new tag form (see next code block) 
     addTagForm($collectionHolder, $newLinkLi); 
    }); 

    // ... 
} 

Я был бы очень признателен за любую помощь.

Спасибо.

+0

Как вы показываете форму в интерфейсе? Добавьте свой код в свой вопрос. – paulgv

ответ

0

Вы пытаетесь скрыть некоторые поля в своей форме? Похоже, что некоторые поля требуются, но на самом деле не отображаются на странице, что препятствует проверке браузером формы. Обратитесь к этому ответу: https://stackoverflow.com/a/28340579/4114297

Интересно, почему вы всего лишь оказываете respuesta.correcta в цикле. Вы могли бы хотеть, чтобы сделать этот пункт в то время как respuesta:

<div class="respuestas" data-prototype="{{ form_widget(form.respuesta.vars.prototype)|e }}"> 
    {# iterate over each existing tag and render its only field: name #} 
    {% for respuesta in form.respuesta %} 
     <div class="row top-margin"> 
      <div class="cols-xs-12 col-sm-10 col-md-8 col-lg-8"> 
       {{ form_row(respuesta) }} {# <- Here #} 
      </div> 
     </div> 
    {% endfor %} 
</div> 

Если вам нужно несколько полей, которые будут скрыты и/или предварительно заполнены, вы можете сделать это RespuestaType

+0

Спасибо за помощь @paulvg. У меня нет скрытых полей. Когда я пытаюсь отправить форму, она говорит: «Недействительный элемент управления формой с именем = 'uci_bundle_basedatosbundle_pregunta [respuesta] [Respuesta0] [textoRetroalimentacion]« не настраивается », и то же самое с другими полями Respuesta. Я изменил цикл, но он выдает ту же ошибку. –

1

Моя проблема была в моей JavaScript. Я не знаю, почему мой предыдущий код не работал, но я изменился, и это сработало. Мой Javascript заключается в следующем:

var collectionHolder = $('#respuestas'); 
var prototype = collectionHolder.attr('data-prototype'); 
var form = prototype.replace(/__name__/g, collectionHolder.children().length); //importante 
var removeFormA = $('<a href="#" onclick="addTagFormDeleteLink(event, this);">Borrar</a>'); 
var newLi = $('<li></li>'); 
newLi.append(form); 
newLi.append(removeFormA); 
collectionHolder.append(newLi); 

И это часть моего файла TWIG:

<ul id="respuestas" data-prototype="{{ form_widget(form.respuesta.vars.prototype)|e }}"> 
{% for respuesta in form.respuesta %} 
     <li> {{ form_row(respuesta) }}</li> 
{% endfor %} 
</ul> 

Я надеюсь, что это поможет кому-то еще.

С уважением.

Смежные вопросы