简体   繁体   English

嵌入式表单多个字段-Symfony2 jQuery多个字段

[英]Embedded Forms Multiple Fields - Symfony2 JQuery multiple fields

What I'm trying to do is "Embed a Collection of Forms" as described here : http://symfony.com/doc/2.3/cookbook/form/form_collections.html 我正在尝试做的是“嵌入表格的集合”,如此处所述: http : //symfony.com/doc/2.3/cookbook/form/form_collections.html

I have managed to get it set up correctly and up to the stage where I add JavaScript/JQuery it works fine. 我设法正确地设置了它,直到添加JavaScript / JQuery的阶段为止,它都能正常工作。 However now I have added the JQuery section I can't get it to work quite right. 但是,现在我添加了JQuery部分,但我无法使其正常运行。

屏幕截图显示了issue2 Initial Loaded Form 初始加载表格 屏幕截图显示了issue1 Form after clicking add product once. 单击一次添加产品后形成表格。

As you can see above when I click add product it is adding 2 sets of the add product form. 正如您在上面看到的那样,当我单击“添加产品”时,它正在添加2套“添加产品”表单。 This in it's self is not right. 这本身就是不对的。 To make matters worse, the first of the 2 new rows added doesn't persist to the database. 更糟糕的是,添加的2个新行中的第一个不会持久保存到数据库中。 The same thing happens each time I 'add new product'. 每当我“添加新产品”时,都会发生相同的情况。

Now the documentation only deals with one filed 'tags' but I assumed just adapting the tutorial to my needs would be enough. 现在,文档仅处理一个归档的“标签”,但我认为仅根据自己的需要对教程进行调整就足够了。 I have fiddled everywhere inside my Entities/Mappings/Controllers and Views trying to sort this. 我在实体/映射/控制器和视图中到处摆弄各种东西,试图对此进行排序。 Think I have tinkered with everything trying to get it right but cannot. 认为我已经设法解决所有问题,但是没有办法。 Except for the JQuery code itself as I have no idea about JQuery or Javascript (Having enough of a job learning PHP at the moment without complicating things though I fully intend on learning it as soon as I've got a grasp of Symfony). 除了JQuery代码本身外,我对JQuery或Javascript不了解(目前我有足够的工作来学习PHP,而不会使事情复杂化,尽管我完全打算在掌握Symfony之后立即学习它)。

//Recipe Form //收据表格

class RecipeType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder
        ->add('recipename') ->add('recipedesc')
        ->add('recipeyeild') ->add('recipecost');
    $builder->add('product', 'collection', array(
    'type' => new ProductRecipeType(),
    'allow_add'    => true,
    'by_reference' => false,
    'allow_delete' => true,));
}

//ProductRecipe Form // ProductRecipe表格

class ProductRecipeType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder
->add('amount') ->add('product');
}

//Recipe view new.twig //配方视图new.twig

<h1>Recipes creation</h1>
{{ form_start(form) }}
{{ form_row(form.recipename) }} {{ form_row(form.recipedesc) }}
{{ form_row(form.recipeyeild) }} {{ form_row(form.recipecost) }}

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

{% for products in form.product %}
    {{ form_row(products.amount) }}
    {{ form_row(products.product) }}
{% endfor %}
</ul>
{{ form_end(form) }}

//JQuery for the recipe form (Currently in the Twig file however I do intent on moving it to a separate file once working properly) // Jquery获取配方形式(当前在Twig文件中,但是我确实打算在正常工作后将其移动到单独的文件中)

<script>
var $collectionHolder;
// setup an "add a product" link
var $addProductsLink = $('<a href="#" class="add_product_link">Add a product</a>');
var $newLinkLi = $('<li></li>').append($addProductsLink);

jQuery(document).ready(function() {
    // Get the ul that holds the collection of tags

    $collectionHolder = $('ul.product');

    // add a delete link to all of the existing tag form li elements
    $collectionHolder.find('li').each(function() {
        addProductsFormDeleteLink($(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);

    $addProductsLink.on('click', function(e) {
        // prevent the link from creating a "#" on the URL
        e.preventDefault();

        // add a new tag form (see next code block)
        addProductsForm($collectionHolder, $newLinkLi);
    });
});
function addProductsForm($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(/__product__/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);

    addProductsFormDeleteLink($newFormLi);
}
function addProductsFormDeleteLink($productsFormLi) {
    var $removeFormA = $('<a href="#">Delete</a>');
    $productsFormLi.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
        $productsFormLi.remove();
    });
}

Now what I think is causing the issue is this line : 现在,我认为导致此问题的是此行:

$collectionHolder.data('index', $collectionHolder.find(':input').length);

Specifically the .find(':input') section as I'm guessing it is counting the input fields but this is just pure guess work. 特别是.find(':input')部分,因为我猜测它正在计算输入字段,但这纯粹是猜测工作。

Also while I'm asking this question I also would prefer it if the 'Add products' link didn't have a delete button as when clicked it completely removes the 'Add products' link from the form, and the only way to get it back is by refreshing the page. 同样,当我问这个问题时,如果“添加产品”链接没有删除按钮,我也会更喜欢它,因为单击它会从表单中完全删除“添加产品”链接,这是获取链接的唯一方法返回是通过刷新页面。 Think I've covered everything. 认为我已经涵盖了所有内容。

EDIT 编辑

This is the prototype stuff created from 'view source' (Which looks disgusting to be honest lol) 这是从“查看源代码”创建的原型内容(说实话,这看起来真令人恶心,哈哈)

     <ul class="product" data-prototype="&lt;div
 id=&quot;bc_inventorybundle_recipe_product___name__&quot;&gt;&lt;div&gt;&lt;
 label for=&quot;bc_inventorybundle_recipe_product___name___amount&quot;
 class=&quot;required&quot;&gt;Amount&lt;/label&gt;&lt;input type=&quot;
 text&quot; id=&quot;bc_inventorybundle_recipe_product___name___amount&quot;
 name=&quot;bc_inventorybundle_recipe[product][__name__][amount]&quot; 
 required=&quot;required&quot; /&gt;&lt;/div&gt;&lt;div&gt;&lt;label
 for=&quot;bc_inventorybundle_recipe_product___name___product&quot;&gt;Product&lt;
 /label&gt;&lt;select id=&quot;bc_inventorybundle_recipe_product___name___product&quot;
 name=&quot;bc_inventorybundle_recipe[product][__name__][product]&quot;&gt;&lt;option  
 value=&quot;&quot;&gt;&lt;/option&gt;&lt;option 
 value=&quot;66&quot;&gt;Butter&lt;/option&gt;&lt;option 
 value=&quot;67&quot;&gt;Beef&lt;/option&gt;&lt;option 
 value=&quot;68&quot;&gt;Jam&lt;/option&gt;&lt;option value=&quot;69&quot;&gt;Xanthan
 Gum&lt;/option&gt;&lt;option value=&quot;70&quot;&gt;Test
 Product&lt;/option&gt;&lt;option
 value=&quot;71&quot;&gt;test&lt;/option&gt;&lt;option 
 value=&quot;72&quot;&gt;test&lt;/option&gt;&lt;option 
 value=&quot;73&quot;&gt;Beef&lt;/option&gt;&lt;option  
 value=&quot;74&quot;&gt;Beef&lt;/option&gt;&lt;/select&gt;&lt;/div&gt;&lt;/div&gt;"> 

Ok then, so I think I've pretty much cracked it. 好的,那我想我已经破解了。

Issue 1: Add product button resulted in 3 'forms' however only 2 would be persisted. 问题1:“添加产品”按钮生成了3个“表格”,但是只有2个可以保留。

Answer 1: Add < li > tags to all rows in form. 答案1:将<li>标记添加到表单中的所有行。

 {% for products in form.product %}
   <li>{{ form_row(products.amount) }}</li>
   <li>{{ form_row(products.product) }}</li>
 {% endfor %}

This fixes persistence but... 这可以解决持久性问题,但是...

Issue 2: The reason I had initially removed the < li > tags was because It would add 'Delete' buttons to everything ... 问题2:之所以我最初删除<li>标签是因为它将在所有内容中添加“删除”按钮...

固定图像示例

Answer 2: I fixed this by adding a class to the < li > for one field. 答案2:我通过在<li>中为一个字段添加一个类来解决此问题。

  <li class="formrowprod">{{ form_row(products.product) }}</li>

and then selected it by modifying this in the JQuery: 然后通过在JQuery中对其进行修改来选择它:

$collectionHolder.find('li').each(function()

To this: 对此:

$collectionHolder.find('li.formrowprod').each(function()

Issue 3: Now almost everything is fixed, everything except there is still "DeleteDelete" (Two Delete buttons next to each other on the starting row which is both ugly and unnecessary (Every recipe will have at least one product so no one will want to remove all) 问题3:现在几乎所有内容都已修复,除了“ DeleteDelete”以外,其他所有内容(在开始行上彼此相邻的两个Delete按钮都是丑陋且不必要的(每个配方至少都有一种产品,因此没人愿意这样做)移除所有)

Answer 3: 答案三:

Remove the li. 取下锂。 completely from .find(): 完全来自.find():

    $collectionHolder.find('formrowprod').each(function() {
    addProductsFormDeleteLink($(this));
    });

So it now all works, pretty well however it still loads 2 rows instead of 1 when I click 'Add Product' but it's not the end of the world but would love to know why if anyone can help. 因此,现在一切正常,但是当我单击“添加产品”时,它仍然加载2行而不是1行,但这不是世界末日,但我想知道为什么有人可以提供帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM