带有选择字段的表单集合

时间:2017-06-15 16:18:16

标签: forms symfony

我有一个表单来修改一个有一些子实体的实体。我使用表单集合来执行此操作。当我编辑这个实体时,应该出现子集合,但它不会出现。子集合由2个选择字段和1个整数字段组成。使用正确的数据很好地呈现整数字段,但是选择字段要求选择一个选项,而它应该显示Matiere和Colle of children实体。

在代码中,Colle实体是Matiere Entity的子代。我正在使用MaterialiseCSS作为框架。

这是我的代码:

儿童表格:

 $builder
        ->add('matiere', EntityType::class, [
            'class' => 'PACESColleBundle:Matiere',
            'attr' => ['class'=> 'matiere'],
            'choice_label' => 'name',
            'label' => false,
            'required' => false,
            'placeholder' => 'Choisissez une matière',
            'mapped' => false])
        ->add('colleEnfant', EntityType::class, [
            'class' => 'PACESColleBundle:Colle',
            'attr' => ['class' => 'colles'],
            'choice_label' => 'nom',
            'label' => false,
            'group_by' => 'matiere',
            'required' => true,
            'placeholder' => 'choose.colle'])
        ->add('ordre', IntegerType::class,[
            'attr'=>['class'=>'ordre'],
            'required' => true,
            'label' => false]);

父母表格:

$builder->add('nom', TextType::class,['label' => 'Nom de la colle'])
    ->add('collesEnfants', CollectionType::class,
        ['label' => false,
        'entry_type' => SousColleFormType::class,
        'required' => true,
        'allow_add' => true,
        'allow_delete' => true,
        'by_reference' => false]);

查看:

<table id="tableau" class="creneaux"
               data-prototype="{{ form_widget(form.collesEnfants.vars.prototype)|e }}">

   <thead>
       <tr>
          <th>Matière</th>
          <th>Colle</th>
          <th>Ordre</th>
          <th>Supprimer</th>
       </tr>
   </thead>

   <tbody>
       {% for colle in form.collesEnfants %}
          <tr>
             <td>{{ form_row(colle.matiere) }}</td>
             <td>{{ form_row(colle.colleEnfant) }}</td>
             <td>{{ form_row(colle.ordre) }}</td>
             <td><a href="" class="delete_colle_link"><i class="material-icons">delete</i></a></td>
          </tr>
       {% endfor %}
   </tbody>
</table>

<script>
    $(document).ready(function() {
        $('.matiere').material_select();
        $('.colles').material_select()
    });
</script>

3 个答案:

答案 0 :(得分:0)

您可以在实体类型中添加查询,并检查实体中是否存在“nom”字段。

$builder->add('colleEnfant', EntityType::class, [
    'class'        => 'PACESColleBundle:Colle',
    'attr'         => ['class' => 'colles'],
    'choice_label' => 'nom',
    'label'        => false,
    'required'     => true,
    'placeholder'  => 'choose.colle',
    'query_builder' => function(ColleRepository $repository) {
        $qb = $repository->createQueryBuilder('c');
        // the function returns a QueryBuilder object
        return $qb->groupBy('c.matiere')->orderBy('c.nom', 'ASC');
    }
])

在您需要添加检测选择修改的事件侦听器之后。

$builder->addEventListener(FormEvents::PRE_SUBMIT, function (FormEvent $event) {
    $data = $event->getData();
    $matiere = $this->em->getRepository('PACESColleBundle:Matiere')->find($data['matiere']);
    $form = $event->getForm();

    $form->add('colleEnfant', EntityType::class, [
        'class'        => 'PACESColleBundle:Colle',
        'attr'         => ['class' => 'colles'],
        'choice_label' => 'nom',
        'label'        => false,
        'required'     => true,
        'placeholder'  => 'choose.colle',
        'query_builder' => function(ColleRepository $repository) use ($matiere) {
            $qb = $repository->createQueryBuilder('c');
            // the function returns a QueryBuilder object
            return $qb
                ->where('c.matiere = :matiere')
                ->setParameter('matiere', $matiere)
                ->orderBy('c.nom', 'ASC');
        }
    ]);
});

我希望这能帮到你。

答案 1 :(得分:0)

我最终用JQuery做了。

脚本:

$(document).ready(function() {
    {% for colleEnfant in collesEnfants %}
         $('#paces_colle_colle_ajoutsupercolle_collesEnfants_{{ loop.index0 }}_matiere option[value="{{ colleEnfant.matiere }}"]').prop('selected', true);
         $('#paces_colle_colle_ajoutsupercolle_collesEnfants_{{ loop.index0 }}_colleEnfant option[value="{{ colleEnfant.colle }}"]').prop('selected', true);
    {% endfor %}
    $('.matiere').material_select();
    $('.colles').material_select();
}

控制器:

$collesEnfantsForm = [];
foreach ($colle->getCollesEnfants() as $colleEnfant) {
     $collesEnfantsForm[] = ['matiere' => $colleEnfant->getMatiere()->getId(), 'colle' => $colleEnfant->getId()];
}

答案 2 :(得分:0)

这是因为ArrayChoiceList :: getValuesForChoices()对引用进行对象比较。结果,如果您在数据和选项列表中没有相同的对象实例,则不会选择该对象。解决方案是对ChoiceType字段使用“ choice_value”选项。例如。

   $builder->add('type', ChoiceType::class, [
        'choices' => FeeType::getTypes(),
                'choice_label' => 'name',
                'required' => true,
                'choice_value' => static function (?FeeType $feeType) {
                    return $feeType ? $feeType->getId() : '';
                }
            ])