Symfony2:具有动态的多种集合类型以相同的形式添加

时间:2017-01-11 13:39:38

标签: javascript php symfony

我的收藏类型有问题,所以我想做的是: 产品形式包括另外两种形式(atouts和proprietes),我可以添加一个产品多个“atouts”和多个“proprieties”所以我使用集合类型和原型与JavaScript在树枝但但问题始终适用于一种形式而不是两者。请帮助你想想。 这是一张描述我想做的图像 enter image description here

<?php

namespace IcebergBundle\Form;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Form\FormEvents;
use Symfony\Component\Form\FormEvent;



use Symfony\Component\OptionsResolver\OptionsResolverInterface;
use IcebergBundle\Form\EventListener\AddSsouscategorieFieldSubscriber;
use IcebergBundle\Form\EventListener\AddSouscategorieFieldSubscriber;
use Symfony\Component\Form\Extension\Core\Type\CollectionType;
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;


class ProduitType extends AbstractType
{
    /**
     * @param FormBuilderInterface $builder
     * @param array $options
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
     
        
        $builder


            ->add('nom','text' ,array('label' => 'Nom:', 'attr' => array('class' => 'form-control')))

            ->add('Nouveau' ,CheckboxType::class, array('label'    => 'Est ce que ce produit est nouveau ?','required' => false))

            ->add('prix','text',array('label' => 'Prix:', 'attr' => array('class' => 'form-control')))
            ->add('description','textarea' ,array('label' => 'Description:', 'attr' => array('class' => 'form-control')))
            ->add('caracteristiques','ckeditor' ,array('label' => 'Caractéristiques techniques:', 'attr' => array('class' => 'form-control')))
            
         
           
          
          
            ->add('souscategori', 'entity', array('label'=> ' Sous Categories','attr'=> array('class'=>'form-control'),'class'      => 'IcebergBundle:Souscategorie'
                                   , 'required'   => true
                                   , 'empty_value'=> 'Choisir sous categorie '))
            ->add('sscategori', 'shtumi_dependent_filtered_entity'
                , array('label'=> ' Sous Sous Categories','attr'=> array('class'=>'form-control'),

                  'entity_alias' => 'region_by_country'
                      , 'empty_value'=> 'Choisir sous sous categorie'
                      , 'parent_field'=>'souscategori'))
            

            
            ->add('file','file',array('label' => 'Image:  ', 'attr' => array('class' => 'btn btn-default') ))
    

            ->add('doc', CollectionType::class, array(
                'label' => 'Document:  ',
                'attr' => array('class' => ' content-box-header panel-heading'),
                'label_attr' => array('class' => 'h2'),
                'entry_type' => DocumentType::class,
                'allow_add' => true,
                'allow_delete' => true,
                'entry_options'  => array( 'label' => false )
            
        ))

 
       ->add('proprietes', CollectionType::class, array(
                'label' => 'Les proprietes:  ',

                'label_attr' => array('class' => 'h2'),
                'entry_type' => ProprieteType::class,
                'allow_add' => true,
                'allow_delete' => true,
                'prototype' => true,
                       'by_reference' => false,
                'prototype_name' => '__proprietes__',
                'entry_options'  => array( 'label' => false )
            
        ))

       ->add('atouts', CollectionType::class, array(
                'label' => 'Les atouts:  ',

                'label_attr' => array('class' => 'h2'),
                'entry_type' => AtoutType::class,
                'allow_add' => true,
                'allow_delete' => true,
                'prototype' => true,
                'by_reference' => false,
                'prototype_name' => '__atouts__',
                'entry_options'  => array( 'label' => false )
            
        ))

        ->add('parent' )


            ->getForm();
            


        ;
           
/*
  $propertyPathToSscategorie = 'sscategori';
 
        $builder
         ->addEventSubscriber(new AddSouscategorieFieldSubscriber( $propertyPathToSscategorie))
         ->addEventSubscriber(new AddSsouscategorieFieldSubscriber( $propertyPathToSscategorie))
           
            ;  */        
    }
    
    /**
     * @param OptionsResolver $resolver
     */
    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'IcebergBundle\Entity\Produit'
        ));
    }
}

这是我的产品/ new.html.twig

{% extends 'base_back.html.twig' %}
 
{% block body %}
  
  
     {% for type, flashMessage in app.session.flashbag.all() %}
    <div class="alert alert-{{ flashMessage.type }} fade in">
        <button class="close" data-dismiss="alert" type="button">×</button>
        {% if flashMessage.title is defined %}
        <strong>{{ flashMessage.title }}</strong>
        {{ flashMessage.message }}
        {% else %}
        {{ type }}
        {% endif %}
    </div>
{% endfor %}

<style >
.btn-default1 {
    color: #333;
    background-color: #fff;
    border-color: #ccc;
    float: right;
}
.btn1 {
    display: inline-block;
    padding: 6px 12px;
    margin-bottom: 0;
    font-size: 14px;
    font-weight: normal;
    line-height: 1.428571429;
    text-align: center;
    white-space: nowrap;
    vertical-align: middle;
    cursor: pointer;
    background-image: none;
    border: 1px solid transparent;
    border-radius: 4px;
    -webkit-user-select: none;
    -moz-user-select: none;
    -ms-user-select: none;
    -o-user-select: none;
    user-select: none;
  }
</style>
 <h1>Ajouter un nouveau produit</h1>

    {{ form_start(form) }}

    </br>
    </br>
    <div class="row">
        <div class="col-md-3">
        {{ form_row(form.nom) }}
    </div>
    <div class="col-md-3">
         {{ form_row(form.prix) }}
          
           </div>
           <div class="col-md-3">
       {{ form_row(form.file) }}
          </div>
    </div>
<br>
        {{ form_row(form.description) }}
        <br>

        {{ form_row(form.caracteristiques) }}
 <br>
 <div class="row">
 <div class="col-md-4">
          {{ form_row(form.souscategori) }}
      </div>
 

<div class="col-md-4">
            {{ form_row(form.sscategori) }}
 </div>
  </div>
    </br>
    </br>
 <!-- {{ form_label(form.doc, 'label', { 'attr': {'class': 'content-box-header panel-heading'} }) }}-->

       {{form_row(form.doc)}}


       <br>

       <h2> Atouts </h2>

{{form_row(form.atouts)}}




<br>
<h2>Proprietes</h2>

  
<ul class="proprietes" data-prototype="{{ form_widget(form.proprietes.vars.prototype)|e('html_attr') }}">

      {% for propriete in form.proprietes %}
       
   <div class="del"> {{form_row(propriete)}}</div>
  
      {% endfor %}
    
  
 
</ul>


  {{form_row(form.parent)}}
 <a class="btn btn-default" type="submit" href="{{ path('atout_new') }}">Suivant<i class="glyphicon glyphicon-eye-open"></i></a>

   
    <a class="btn btn-default" href="{{ path('produit_index') }}">Retourner à la liste<i class="glyphicon glyphicon-eye-open"></i></a>


    {{ form_end(form) }}


<script>
  // setup an "add a tag" link
var $addAtoutLink = $('<a href="#" >Ajouter un atout</a>');
var $newLinkLi = $('<div class="testdel"></div>').append($addAtoutLink);

jQuery(document).ready(function() {
p an "add a tag" link
var $addpropLink = $('<a href="#" class="btn btn-primary">Ajouter une prop</a>');
var $newLinkLi = $('<div class="del"></div>').append($addpropLink);

jQuery(document).ready(function() {
    // Get the ul that holds the collection of tags
   var $collectionHolder = $('ul.proprietes');

    $collectionHolder.find('del').each(function() {
        addpropFormDeleteLink($(this));
    });
    
    // 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);
    
    $addpropLink.on('click', function(e) {
        // prevent the link from creating a "#" on the URL
        e.preventDefault();
        
        // add a new tag form (see code block below)
        addpropForm($collectionHolder, $newLinkLi);
    });
    
    
});

function addpropForm($collectionHolder, $newLinkLi) {
    // Get the data-prototype explained earlier
    var prototype = $collectionHolder.data('prototype');
    
    // get the new index
    var index = $collectionHolder.data('index');
   var compteur = 1;



 
 

    
    // Replace '$$name$$' in the prototype's HTML to
    // instead be a number based on how many items we have
    var newForm = prototype.replace(/__proprietes__/g, index);
    
    // increase the index with one for the next item
    $collectionHolder.data('index', index + 1);
    
    // Display the form in the page in an li, before the "Add a tag" link li
    var $newFormLi = $('<div class="del"><h2>Prop</h2></div>').append(newForm);

    
    // also add a remove button, just for this example
  
    
    $newLinkLi.before($newFormLi);
    
   
    addpropFormDeleteLink($newFormLi);

}
function addpropFormDeleteLink($propFormLi) {
    var $removeFormA = $('<a href="#" class="btn1 btn-default1">supprimer cette prop</a>');
    $propFormLi.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
        $propFormLi.remove();
    });
}
</script>
  {% endblock %} 
<script src="https://code.jquery.com/jquery.js"></script>
{% endblock %}

1 个答案:

答案 0 :(得分:0)

如果您需要动态添加嵌套表单,您肯定需要一个控制器操作来通过ajax请求新表单。 如果你有这样的动作,请显示它(以及脚本)。

编辑:基本上你需要一个脚本,当点击添加按钮时,它将通过ajax调用你的控制器动作,并检索新表格的html并将其插入到dom中。

对于控制器,您需要执行一个操作来初始化表单,将其呈现为变量并将呈现的html返回给脚本。

如果您不想自己制作麻烦,可以使用Symfony提供的CollectionType,它可以完全符合您的要求:http://symfony.com/doc/current/reference/forms/types/collection.html