如何使用两个CollectionType子表单处理Symfony表单?

时间:2016-05-26 11:55:39

标签: javascript jquery forms symfony

我一直在关注Symfony指南here,该指南描述了如何生成(并刷新数据库)表单中关联实体的集合。

我已经按照示例进行操作,它完全符合预期(添加和删除),但是,在我实际需要它的情况下,我有两个关联的实体:

  • 任务 - < 标签
  • 任务 - <

第二部分的prototype部分很清楚:

<ul class="tags" data-prototype="{{ form_widget(form.tags.vars.prototype)|e }}">
    ...
</ul>

<ul class="persons" data-prototype="{{ form_widget(form.persons.vars.prototype)|e }}">
    ...
</ul>

然而,对于脚本的更改,我不知道要去做,因为我没有太多javascript / jQuery的经验。我应该创建一个单独的jQuery(document).ready(function() {}函数来处理第二个关联实体,还是应该将它集成到现有块中?

我只为一个关联实体运行的脚本(来自twig模板)是:

<script>
    var $addTagsLink = $('<a href="#" class="add_Tags_link">Add a Tag</a>');
    var $newLinkLi = $('<li></li>').append($addTagsLink);
    jQuery(document).ready(function() {
        // Get the ul that holds the collection of tags
        $collectionHolder = $('ul.Tags');
        // add a delete link to all of the existing tag form li elements
        $collectionHolder.find('li').each(function() {
            addTagsFormDeleteLink($(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);
        $addTagsLink.on('click', function(e) {
            // prevent the link from creating a "#" on the URL
            e.preventDefault();
            // add a new tag form (see next code block)
            addTagsForm($collectionHolder, $newLinkLi);
        });
    });
    function addTagsFormDeleteLink($TagFormLi) {
        var $removeFormA = $('<a href="#">delete this Tag</a>');
        $TagFormLi.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
            $TagFormLi.remove();
        });
    }
    function addTagsForm($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 a tag" link li
        var $newFormLi = $('<li></li>').append(newForm);
        // add a delete link to the new form
        addTagsFormDeleteLink($newFormLi);
        $newLinkLi.before($newFormLi);
    }
</script>

2 个答案:

答案 0 :(得分:0)

您可以附加到现有的jQuery(document).ready并创建您的函数:addPersonsFormDeleteLink,addPersonsForm

答案 1 :(得分:0)

您可以通过添加链接文本作为参数来使两个函数addTagsFormDeleteLinkaddTagsForm通用。所以你不要复制它们。在此,我将其重命名为addFormDeleteLinkaddForm

其余代码可以复制,也可以插入$.each() JQuery iterator。代码重复(只有两个项目,我发现它更简单,即使不那么优雅):

// "Add a Tag" link
var $addTagsLink = $('<a href="#" class="add_Tags_link">Add a Tag</a>');
var $newTagLinkLi = $('<li></li>').append($addTagsLink);

// "Add a Person" link
var $addPersonsLink = $('<a href="#" class="add_Persons_link">Add a Person</a>');
var $newPersonLinkLi = $('<li></li>').append($addPersonsLink);


jQuery(document).ready(function() {

    //-- Tags --

    // Get the ul that holds the collection of tags
    $tagsCollectionHolder = $('ul.Tags');
    // add a delete link to all of the existing tag form li elements
    $tagsCollectionHolder.find('li').each(function() {
        addFormDeleteLink($(this), 'delete this Tag');
    });
    // add the "add a tag" anchor and li to the tags ul
    $tagsCollectionHolder.append($newTagLinkLi);
    // count the current form inputs we have (e.g. 2), use that as the new
    // index when inserting a new item (e.g. 2)
    $tagsCollectionHolder.data('index', $tagsCollectionHolder.find(':input').length);
    $addTagsLink.on('click', function(e) {
        // prevent the link from creating a "#" on the URL
        e.preventDefault();
        // add a new tag form (see next code block)
        addForm($tagsCollectionHolder, $newTagLinkLi, 'delete this Tag');
    });

    //-- Persons --

    $personsCollectionHolder = $('ul.persons');
    $personsCollectionHolder.find('li').each(function() {
        addFormDeleteLink($(this), 'delete this Person');
    });
    $personsCollectionHolder.append($newPersonLinkLi);
    $personsCollectionHolder.data('index', $personsCollectionHolder.find(':input').length);
    $addPersonsLink.on('click', function(e) {
        e.preventDefault();
        addForm($personsCollectionHolder, $newPersonLinkLi, 'delete this Person');
    });
});

function addFormDeleteLink($formLi, $anchor) {
    var $removeFormA = $('<a href="#">' + $anchor + '</a>');
    $formLi.append($removeFormA);
    $removeFormA.on('click', function(e) {
        // prevent the link from creating a "#" on the URL
        e.preventDefault();
        // remove the li for the form
        $formLi.remove();
    });
}

function addForm($collectionHolder, $newLinkLi, $deleteText) {
    // 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 a tag/person" link li
    var $newFormLi = $('<li></li>').append(newForm);
    // add a delete link to the new form
    addFormDeleteLink($newFormLi, $deleteText);
    $newLinkLi.before($newFormLi);
}