我在Symfony2中有一个Javascript表单集合。
$(document).ready(function() {
// Create Input Text
$(document).on('click', '.btn-add[data-target]', function(event) {
event && event.preventDefault();
var collectionHolder = $('#' + $(this).attr('data-target'));
if (!collectionHolder.attr('data-counter')) {
collectionHolder.attr('data-counter', collectionHolder.children().length);
}
var prototype = collectionHolder.attr('data-prototype');
var form = prototype.replace(/__name__/g, collectionHolder.attr('data-counter'));
collectionHolder.attr('data-counter', Number(collectionHolder.attr('data-counter')) + 1);
collectionHolder.append(form);
typeInitialize();
return false;
});
// Remove Input Text
$(document).on('click', '.btn-remove[data-related]', function(event) {
event && event.preventDefault();
var name = $(this).attr('data-related');
($('*[data-content="'+ name +'"]')).remove();
});
// Initialize Typeahead
function typeInitialize() {
// Create typeahead instance
var url = Routing.generate('ajax_search', {name: 'WILDCARD'});
// Trigger typeahead + bloodhound
var products = new Bloodhound({
datumTokenizer: Bloodhound.tokenizers.obj.whitespace('value'),
queryTokenizer: Bloodhound.tokenizers.whitespace,
identify: function(obj) { return obj.u_name; },
prefetch: 'json/result.json',
remote: {
url: url,
wildcard: 'WILDCARD',
}
});
products.initialize();
$('.typeahead').typeahead({
minLength: 3,
highlight: true,
limit: 10,
},
{
name: 'product',
display: 'u_name',
source: products.ttAdapter()
});
}
});
树枝模板:
{% extends '::base.html.twig' %}
{% block body %}
{% macro widget_prototype(widget, remove_text) %}
{% if widget.vars.prototype is defined %}
{% set form = widget.vars.prototype %}
{% set name = widget.vars.prototype.vars.full_name %}
{% else %}
{% set form = widget %}
{% set name = widget.vars.full_name %}
{% endif %}
<div data-content="{{ name }}">
<div class="btn-remove">
<a class="btn-remove" data-related="{{ name }}">{{ remove_text }}</a>
</div>
{{ form_widget(form) }}
</div>
{% endmacro %}
<div class="row">
<div class="col-md-12">
<a class="btn-add" class="clicked" data-target="post_tags">Adauga Produs</a>
{{form_start(form, {'attr': {'class': 'form-horizontal'}})}}
{{form_row(form.name)}}
<div id="post_tags" data-prototype="{{ _self.widget_prototype(form.product, 'Delete Product')|escape }}">
{% for widget in form.product.children %}
{{ _self.widget_prototype(widget, 'Delete Product') }}
{% endfor %}
</div>
{{form_end(form)}}
</div>
</div>
{% endblock %}
代码不包含任何一整天都在测试它的错误,但是当我尝试添加一个新字段时,它会毫无问题地添加它,而第二个字段则添加第二个字段但是在第一个字段上从typeahead
添加空跨度,然后当我添加第三个字段时,它会向第一个元素添加另一个空跨度。在第四个字段中,它为第一个第二个和第三个输入添加了typeahead
的空跨度。
据我所知,问题来自于typeInitialize
函数以及我如何称呼它,但我无法弄清楚我在这部分做错了什么,然后第二个问题就是当我点击删除它删除了我添加的所有输入。
答案 0 :(得分:0)
我修改了整个代码修复了问题。以下是需要它的任何人的更新版本。
// setup an "add a tag" link
var $addTagLink = $('<a href="#" class="btn btn-primary add_tag_link">Adauga Produs</a>');
var $newLinkLi = $('#post_tags').append($addTagLink);
jQuery(document).ready(function() {
// Get the ul that holds the collection of tags
var $collectionHolder = $('#post_tags');
// 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);
$addTagLink.on('click', function(e) {
// prevent the link from creating a "#" on the URL
e.preventDefault();
// add a new tag form (see code block below)
addTagForm($collectionHolder, $newLinkLi);
typeInitialize();
});
});
function addTagForm($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 = $('<div class="post_tags"></div>').append(newForm);
// also add a remove button, just for this example
$newFormLi.append('<a href="#" class="btn btn-warning remove-tag">Sterge Produsul</a>');
$newLinkLi.before($newFormLi);
// handle the removal, just for this example
$('.remove-tag').click(function(e) {
e.preventDefault();
$(this).parent().remove();
return false;
});
}
// Initialize Typeahead
function typeInitialize() {
// Create typeahead instance
var url = Routing.generate('ajax_search', {name: 'WILDCARD'});
// Trigger typeahead + bloodhound
var products = new Bloodhound({
datumTokenizer: Bloodhound.tokenizers.obj.whitespace('value'),
queryTokenizer: Bloodhound.tokenizers.whitespace,
identify: function(obj) { return obj.u_name; },
prefetch: 'json/result.json',
remote: {
url: url,
wildcard: 'WILDCARD',
}
});
products.initialize();
$('.post_tags').find('input[type=text]:last').typeahead({
minLength: 3,
highlight: true,
limit: 10,
},
{
name: 'product',
display: 'u_name',
source: products.ttAdapter()
}).on('typeahead:selected', function (e, datum) {
console.log(datum);
});
}