То, что я пытаюсь сделать, это «Вставить коллекцию форм», как описано здесь: http://symfony.com/doc/2.3/cookbook/form/form_collections.html
Мне удалось настроить его правильно и до стадии, где я добавляю JavaScript / JQuery, он отлично работает. Однако теперь я добавил раздел JQuery, я не могу заставить его работать совершенно правильно.
Начальная загруженная форма Форма после нажатия добавить продукт один раз.
Как вы можете видеть выше, когда я нажимаю кнопку «Добавить продукт», он добавляет 2 набора формы для добавления продукта. Это в самом себе не так. Хуже того, первая из двух добавленных новых строк не сохраняется в базе данных. То же самое происходит каждый раз, когда я добавляю новый продукт.
Теперь документация касается только одного зарегистрированного «тега», но я предположил, что достаточно адаптировать учебник к моим потребностям будет достаточно. Я искал всюду внутри своих Entities / Mappings / Controllers и Views, пытаясь разобраться в этом. Думаю, я возился со всем, пытаясь понять это, но не могу. За исключением самого кода JQuery, поскольку я понятия не имею о JQuery или Javascript (имея достаточную работу, изучающую PHP на данный момент, не усложняя ситуацию, хотя я полностью намерен изучать ее, как только у меня есть понимание Symfony).
// Форма рецепта
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,)); }
// Форма продукта
class ProductRecipeType extends AbstractType { public function buildForm(FormBuilderInterface $builder, array $options) { $builder ->add('amount') ->add('product'); }
// Рецепт просмотра 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 для формы рецепта (в настоящее время в файле 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 (eg 2), use that as the new // index when inserting a new item (eg 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(); }); }
Теперь я думаю, что причиной этой проблемы является эта строка:
$collectionHolder.data('index', $collectionHolder.find(':input').length);
В частности раздел .find (': input'), поскольку я предполагаю, что он подсчитывает поля ввода, но это просто чистая работа.
Кроме того, в то время как я задаю этот вопрос, я также предпочел бы, чтобы ссылка «Добавить продукты» не имела кнопки удаления, так как при щелчке она полностью удаляет ссылку «Добавить продукты» из формы, и единственный способ ее получить назад, обновляя страницу. Думаю, я все освещал.
Это прототип материала, созданного из «источника просмотра» (который выглядит отвратительно, чтобы быть честным LOL)
<ul class="product" data-prototype="<div id="bc_inventorybundle_recipe_product___name__"><div>< label for="bc_inventorybundle_recipe_product___name___amount" class="required">Amount</label><input type=" text" id="bc_inventorybundle_recipe_product___name___amount" name="bc_inventorybundle_recipe[product][__name__][amount]" required="required" /></div><div><label for="bc_inventorybundle_recipe_product___name___product">Product< /label><select id="bc_inventorybundle_recipe_product___name___product" name="bc_inventorybundle_recipe[product][__name__][product]"><option value=""></option><option value="66">Butter</option><option value="67">Beef</option><option value="68">Jam</option><option value="69">Xanthan Gum</option><option value="70">Test Product</option><option value="71">test</option><option value="72">test</option><option value="73">Beef</option><option value="74">Beef</option></select></div></div>">