【问题标题】:SYMFONY FormTypeCollection with various fields带有各种字段的 SYMFONY FormTypeCollection
【发布时间】:2020-10-23 09:12:23
【问题描述】:

在我的项目中,我希望能够在表单上添加一个集合。我想到了 FormTypeCollection。但问题是,我需要这样的东西: 表单末尾有一个“新建”按钮,每次单击新建时,都会添加一个“迷你表单”,您需要填写三个输入:“名称、文本、链接”。例如,我希望它以艺术家 = [名称、文本、链接] 的形式存储在数据库中。我不知道该怎么做。我不想添加实体艺术家,因为我只需要它来显示,我不需要将它作为实体存储在数据库中。 我现在的代码是这样的:

protected function configureFormFields(FormMapper $formMapper)
    {
        $formMapper
            ->with('Contenu')
            ->add('published', CheckboxType::class, ['required' => false, 'label' => 'Publier'])
            ->add('title', TextType::class, ['required' => true, 'label' => 'Titre'])
            ->add('marketingEtiquette', TextType::class, ['required' => false, 'label' => 'Etiquette Marketing'])
            ->add('textLink', TextType::class, ['required' => true, 'label' => 'Texte du lien'])
            ->add('shoppingLink', TextType::class, ['required' => true, 'label' => 'Lien'])
            ->add('media', ElFinderType::class, array(
                'label' => 'Photo',
                'instance' => 'form',
                'enable' => true,
                'required' => true,
                'attr' => array('class' => 'form-control')
                )
            )
            ->add('position',ChoiceType::class, array(
                'label' => 'Position dans la page',
                'choices' => array(
                    'Bloc Artistes' => 'artists',
                    'Bloc haut de page' => 'top',
                    'Bloc bas de page' => 'bottom'
                )
            ))
            ->add('artists',CollectionType::class,array(
                'label' => 'Les artistes',
                'allow_add' => true,
            ))
            ->end();
    }

我不知道如何向字段艺术家添加 3 个字段并在单击添加按钮时生成它们。我什至不知道这是否可能。我也不知道数据库中的“艺术家”类型应该是什么。

编辑: 我想做类似的事情,所以我不需要创建实体或 FormType:

->add('artists',CollectionType::class,array(
                'entry_type' => TextType::class ,
                'entry_options' => [
                    'artistName' => TextType::class,
                    'artistText' => TextType::class,
                    'artistLink' => TextType::class,
                ],
                'label' => 'Les artistes',
                'allow_add' => true,
                'allow_delete' => true,
                'delete_empty' => true,
                'by_reference' => false
            ))

但它不起作用,所以我想我不能。错误:

The current field `artists` is not linked to an admin. Please create one for the target entity : ``

编辑 2: 我创建了我的 ArtistFormType:

class ArtistFormType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('artistName', TextType::class, array(
                'label' => 'Nom de l\'artiste'
            ))
            ->add('artistText', TextType::class, array(
                'label' => 'Texte sous l\'artiste'
            ))
            ->add('artistLink', TextType::class, array(
                'label' => 'Lien vers l\'artiste'
            ))
            ;
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults([
           'data_class' => null,
       ]);
    }
}

我是这样称呼它的:

->add('artists',CollectionType::class,array(
                'entry_type' => ArtistFormType::class,
                'label' => 'Les artistes',
                'allow_add' => true,
                'allow_delete' => true,
                'delete_empty' => true,
                'by_reference' => false
            ))

但我得到了同样的错误:

The current field `artists` is not linked to an admin. Please create one for the target entity : ``

【问题讨论】:

    标签: forms symfony


    【解决方案1】:

    编辑:此解决方案仅限于 Symfony\Component\Form\Extension\Core\Type\CollectionType,它可能与 Sonata Admin 的解决方案不同。

    您可以在documentation 中找到这方面的一些信息。

    “最简单”的方法是使用您希望添加的字段创建另一个表单(例如 ArtistFormType)。 然后在您的父表单中添加 CollectionType :

    $formMapper
            // ...
            ->add('artists', CollectionType::class, [
                'entry_type' => ArtistFormType::class,
                'label' => 'Artists',
                'allow_add' => true,
                'allow_delete' => true,
                'delete_empty' => true,
                'by_reference' => false
            ])
        ;
    

    然后,如果您的实体中已经有一些艺术家,它将为每个艺术家呈现一次 ArtistFormType。

    如果您想添加新艺术家,这有点棘手,并且需要一些 Javascript。

    首先,在<ul></ul> 标签内渲染集合:

    <ul class="artists">
        {{ form_row(form.artists) }}
    </ul>
    

    关注jsfiddle: 找到收藏并向其中添加“添加艺术家”按钮

    <script>
    var $addArtistLink = $('<a href="#" class="add_artist_link">Add an artist</a>');
    var $newLinkLi = $('<li></li>').append($addArtistLink);
    
    jQuery(document).ready(function() {
        // Get the ul that holds the collection of artists
        var $collectionHolder = $('ul.artists');
    
        // add the "add a tag" anchor and li to the tags ul
        $collectionHolder.append($newLinkLi);
        
        // ...
    }
    </script>
    

    添加带有一些 dom 操作的“click”事件以添加新艺术家:

    jQuery(document).ready(function() {
        // ...
        
        // 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);
    
        $addArtistLink.on('click', function(e) {
            // prevent the link from creating a "#" on the URL
            e.preventDefault();
        
            // add a new artist form
            addArtistForm($collectionHolder, $newLinkLi);
        });
    
    
    });
    
    function addArtistForm($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, 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 an artist" link li
        var $newFormLi = $('<li></li>').append(newForm);
    
        // also add a remove button
        $newFormLi.append('<a href="#" class="remove-artist">x</a>');
    
        $newLinkLi.before($newFormLi);
    
        // handle the removal
        $('.remove-artist').click(function(e) {
            e.preventDefault();
        
            $(this).parent().remove();
        
            return false;
       });
    

    }

    那么它应该可以正常工作。当然可以进行一些更改以适应您的项目(字段名称,在现有艺术家上添加删除按钮,...)。

    【讨论】:

    • 非常感谢您的回答!我正在尝试,但我必须创建一个艺术家实体才能做到这一点?问题是,我不想创建艺术家实体。这可能吗?还是我必须创建一个实体?
    • 我认为创建一个与主窗体的实体具有多对一关系的 Artist 实体会更容易(也更好)。如果您真的不想创建此实体,您可以在 ArtistFormType 中指定“'data_class' => null”,然后它将数据规范化为数组而不是实体。
    • 好的,因为我认为我可以像我在编辑中所做的那样做一些事情,那是不可能的?
    • 这样不行。我认为您至少必须创建 ArtistFormType。此外,“entry_options”用于在“entry_type”中设置 FormType 的选项,而不是像您在编辑中所做的那样。
    • 好的,我做到了,但没有工作,我编辑了我的问题^^
    猜你喜欢
    • 2019-10-05
    • 2016-11-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-11
    相关资源
    最近更新 更多