动态添加/删除输入字段以形成(Symfony 3 Events / Ajax)

时间:2018-05-25 10:48:40

标签: ajax symfony events

我正在一个小型广告网站上工作,但当我尝试动态添加输入字段时,Form Events出现此问题。

在这里,我有一个实体广告:

/**
 * Ad
 *
 * @ORM\Table(name="ma_ad")
 * @ORM\Entity(repositoryClass="MA\PlatformBundle\Repository\AdRepository")
 * @ORM\HasLifecycleCallbacks()
 */
class Ad
{
/**
 * @var int
 *
 * @ORM\Column(name="id", type="integer")
 * @ORM\Id
 * @ORM\GeneratedValue(strategy="AUTO")
 */
private $id;

/**
 * @var string
 *
 * @ORM\Column(name="title", type="string", length=255)
 * @Assert\Length(min=10)
 */
private $title;

/**
 * @ORM\ManyToOne(targetEntity="MA\PlatformBundle\Entity\Category")
 * @ORM\JoinColumn(nullable=false)
 */
private $category;

/** @var float
 *
 * @ORM\Column(name="speed", type="float")
 * @Assert\Valid()
 * @Assert\Range(min=0)
 */
private $speed;

 * @var float
 *
 * @ORM\Column(name="area", type="float")
 * @Assert\Valid()
 * @Assert\Range(min=0)
 */
private $area;

。    。    。 让我们说我有两个类别,汽车和房屋当用户选择汽车时应该出现速度输入字段,当他选择安置它的区域输入字段而不是速度时。

我尝试了documentary上的内容,因此这是我的AdType:

class AdType extends AbstractType
{
/**
 * {@inheritdoc}
 */
public function buildForm(FormBuilderInterface $builder, array $options)
{
    /**
     *  @var \Doctrine\ORM\EntityManager $em
     */
    $em = $options['entity_manager'];

    $builder->add('title', TextType::class)
        ->add('category', EntityType::class, array(
            'class' => 'MAPlatformBundle:Category',
            'choice_label' => 'name',
            'multiple' => false,
            'group_by' => 'category.name'
        ))

    $formModifier = function(FormInterface $form, Category $category = null) 
    {
            if( $category->getName() === "Cars" ){
                $form->add('speed',TextType::class);
            } else if( $category->getName() === "Houses" ){
                $form->add('area',TextType::class);
            }
    };

    $builder->addEventListener(
        FormEvents::PRE_SET_DATA, function (FormEvent $event) use ( $formModifier ) {
            $form = $event->getForm();
            $category = $event->getData()->getCategory();
            $formModifier($form, $category);
        }
    );

    $builder->get('category')->addEventListener(
        FormEvents::PRE_SUBMIT, 
        function( FormEvent $event ) use ( $formModifier, $em ){
            $id_category = $event->getData();
            $category = $em->getRepository("MAPlatformBundle:Category")->find($id_category);
            $form = $event->getForm()->getParent();
            $formModifier($form, $category);
        });

/**
 * {@inheritdoc}
 */
public function configureOptions(OptionsResolver $resolver)
{
    $resolver->setDefaults(array(
        'data_class' => 'MA\PlatformBundle\Entity\Annonce',
        'entity_manager' => null,
    ));
}

最后是树枝页面:

{{ form_start( form, { 'attr': { 'class': 'form-ad' }}) }}
              {{ form_row(form.title) }}
              {{ form_row(form.category) }}

            <div id="dynamic">
                {{ form_rest(form) }}
            </div>
            <div class="form-group">
              <div class="well">
                {{ form_widget(form.save, {'attr': {'class': 'btn btn-common', 'value': 'Add'}} ) }}
              </div> 
            </div> 
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<script>
$(document).ready(function(){
var $category = $('#ma_platformbundle_ad_category');

$category.change( function(){
    var $form = $(this).closest('form');
    var data = {
        'id_category': $category.val(),
    };
    $.ajax({
        url : "{{path('ma_platform_add')}}",
        type: 'POST',
        data : data,
        success: function (html) {
            $('#dynamic').replaceWith(
                $(html).find('#dynamic')
              );
        }
    });
});
});

因此,当我选择类别时,表格没有任何变化。 我试着让你们这么简单,所以你们可以帮助我。 提前致谢。

1 个答案:

答案 0 :(得分:0)

我认为你错过了解某些东西,预设数据事件发生在后端,所以表单永远不会自己添加字段。你需要用JS / Jquery来处理这个问题。我会建议以下......

  

后端的FormType

$builder->add('title', TextType::class)
        ->add('category', EntityType::class, array(
            'class' => 'MAPlatformBundle:Category',
            'choice_label' => 'name',
            'multiple' => false,
            'group_by' => 'category.name'
        )
->add('speed',TextType::class,[//modify attr or class options to disable and hide the field])
->add('area',TextType::class,[//modify attr or class options to disable and hide the field])
)
  

在前端

根据需要渲染表单并使用jquery处理该字段。

//来自你的代码

$(document).ready(function () {
        var $category = $('#ma_platformbundle_ad_category');

        $category.change(function () {
            if ($category.val() === 'some_especific_value') {
                $('#dynamic').find('some_specific_input_or_div').show()//or remove disabled/hidden
            } else {//some_other_specific_value
                $('#dynamic').find('some_other_specific_input_or_div').show()//or remove disabled/hidden
            }
        });
    });

此时您可以处理一些切换选项。

  

在后端

$builder->addEventListener(FormEvents::PRE_SUBMIT, function (FormEvent $event) {

            if ($event->getData()['category'] === 'house') {
                $event->getForm()->remove('speed');
            }else{
                $event->getForm()->remove('area');
            }
        });

此时,您只处理选定的数据,避免产生错误。

解决方案是使用jquery处理添加字段并正确设置数据或使用表单事件删除未使用的字段。

希望它有所帮助!