【问题标题】:it's possible to have two collection type in one form?一种形式可以有两种集合类型吗?
【发布时间】:2020-11-14 13:10:10
【问题描述】:

我想为我的表单设置两种集合类型。 我按照文档https://symfony.com/doc/current/form/form_collections.html 我的表格

class TrickType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder
        
        ->add('Name', TextType::class, [
            'label' => 'Titre',
            'attr' => [
                'placeholder' => 'Titre du trick',
            ],
        ])
        ->add('description', TextareaType::class, [
            'label' => 'Description',
            'attr' => [
                'placeholder' => 'Description du trick',
            ],
        ])
        ->add('picture', FileType::class,[
            'label' => 'Image principale',
            'required' => false,
            'mapped' => false
            
        ])
        ->add('images', CollectionType::class,[
            'entry_type' => ImageType::class,
            'entry_options' => ['label' => false],
            'allow_add' => true,
            'allow_delete' => true,
            'by_reference' => false,
            'required' => false,
        ])
        ->add('videos', CollectionType::class,[
            'entry_type' => VideoType::class,
            'entry_options' => ['label' => false],
            'allow_add' => true,
            'allow_delete' => true,
            'by_reference' => false,
            'required' => false,
        ])
        ->add('categoryId', EntityType::class, [
            'class' => Category::class,
            'choice_label' => 'title',
            'label' => 'Catégorie',
        ])
        ->add('save', SubmitType::class)
    ;
}

我的视频收集技巧或图像有效,但不能同时使用

在我的表单视图中,我像文档一样插入 js 代码:

{% block javascripts %}
{{ parent() }}
<script src="{{ asset('js/addPicture.js') }}"></script>
<script src="{{ asset('js/addVideo.js') }}"></script>
{% endblock %}

addVideo.js:

  var $collectionHolder;

 // setup an "add a tag" link
 var $addTagButton = $('<button type="button" class="add_tag_link">Add a tag</button>');
 var $newLinkLi = $('<li></li>').append($addTagButton);

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

$collectionHolder.find('li').each(function() {
    addTagFormDeleteLink($(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);

$addTagButton.on('click', function(e) {
    // add a new tag form (see next code block)
    addTagForm($collectionHolder, $newLinkLi);
});

$removeTagButton.on('click', function(e) {
    // add a new tag form (see next code block)
    removeTagForm($collectionHolder, $removeLinkLi);
 });
});
 function addTagForm($collectionHolder, $newLinkLi) {
// Get the data-prototype explained earlier
var prototype = $collectionHolder.data('prototype');


// get the new index
var index = $collectionHolder.data('index');

var newForm = prototype;
// You need this only if you didn't set 'label' => false in your tags field in TaskType
// Replace '__name__label__' in the prototype's HTML to
// instead be a number based on how many items we have
// newForm = newForm.replace(/__name__label__/g, index);

// Replace '__name__' in the prototype's HTML to
// instead be a number based on how many items we have
newForm = newForm.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 a tag" link li
var $newFormLi = $('<li></li>').append(newForm);
$newLinkLi.before($newFormLi);
addTagFormDeleteLink($newFormLi);
}

 function addTagFormDeleteLink($tagFormLi) {
var $removeFormButton = $('<button type="button">Delete this tag</button>');
$tagFormLi.append($removeFormButton);

$removeFormButton.on('click', function(e) {
    // remove the li for the tag form
    $tagFormLi.remove();
});
}

我对 addPicture 做同样的事情(我更改 jQuery(document).ready(function() { // Get the ul that holds the collection of tags $collectionHolder = $('ul.videos');for 'ul.pictures')

我的表单技巧树枝:

    {{ form_start(form) }}
        {{ form_row(form.Name) }}
        {{ form_row(form.description) }}
        {{ form_row(form.picture) }}
        <ul class="images" id="image_list" data-prototype="{{ form_widget(form.images.vars.prototype)|e('html_attr') }}">
            {% for row in form.images %}
            <li>{{ form_row(row) }}</li>
            {% endfor %}
        </ul>
        <ul class="videos" id="video_list" data-prototype="{{ form_widget(form.videos.vars.prototype)|e('html_attr') }}">
            {% for row in form.videos %}
            <li>{{ form_row(row) }}</li>
            {% endfor %}
        </ul>
        {{ form_row(form.categoryId) }}
{{ form_end(form) }}

如果有人知道该怎么做,如果他们帮助我,我会很高兴,我真的不知道我刚刚接管文档的 ajax 和 js 代码。谢谢

【问题讨论】:

    标签: forms symfony collections prototype


    【解决方案1】:

    一种形式可以有两种集合类型吗?绝对地。在这种情况下,我会做的是找到一种将 js 事件侦听器“链接”到特定集合的方法。

    假设您的表单如下所示:

    {{ form_start(form) }}
    {{ form_row(form.Name) }}
    {{ form_row(form.description) }}
    {{ form_row(form.picture) }}
    <ul class="images" id="image_list"
        data-prototype="{{ form_widget(form.images.vars.prototype)|e('html_attr') }}"
        data-widget-tags="<li></li>"
    >
        {% for row in form.images %}
            <li>{{ form_row(row) }}
                <button data-collection-remove>remove image</button>
            </li>
        {% endfor %}
    </ul>
    <button data-collection-id="#image_list" data-collection-add>add image</button>
    
    <ul class="videos" id="video_list" 
        data-prototype="{{ form_widget(form.videos.vars.prototype)|e('html_attr') }}"
        data-widget-tags="<li></li>"
    >
        {% for row in form.videos %}
            <li>{{ form_row(row) }}
                <button data-collection-remove>remove video</button>
            </li>
        {% endfor %}
    </ul>
    <button data-collection-id="#video_list" data-collection-add>add video</button>
    {{ form_row(form.categoryId) }}
    {{ form_end(form) }}
    

    然后在 javascript 中,我会像这样对我的所有集合使用通用函数。

      $(function() {
        $(document).on('click', '[data-collection-add]', function(event) {
          event.preventDefault();
          var $collectionHolder = $($(this).data('collection-id'));
          var counter           = $collectionHolder.data('widget-counter') || $collectionHolder.children().length;
          var newWidget         = $collectionHolder.data('prototype');
          newWidget             = newWidget.replace(/__name__/g, counter);
          counter++;
          $list.data('widget-counter', counter);
          var $newElem = $($collectionHolder.data('widget-tags')).html(newWidget);
          $newElem.appendTo($collectionHolder);
        });
        
        $(document).on('click', '[data-collection-remove]', function(event) {
          event.preventDefault();
          var $element = $($(this).closest('li'));
          $element.remove();
        });
      });
    

    请注意,我没有测试此代码,但它应该足够接近可以工作的东西。

    【讨论】:

      猜你喜欢
      • 2011-02-03
      • 2013-12-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-03-08
      相关资源
      最近更新 更多