Read the nested form rendering note before customizing collection markup.
When you add collection items dynamically, register the new prototype with the validator after inserting it into the DOM:
function addTagForm($collectionHolder, $newLinkLi) {
// Get the data-prototype explained in the Symfony collection docs.
var prototype = $collectionHolder.data('prototype');
// Get the new index.
var index = $collectionHolder.data('index');
// Replace "__name__" in the prototype HTML with the new index.
var newForm = prototype.replace(/__name__/g, index);
// Increase the index for the next item.
$collectionHolder.data('index', index + 1);
// Display the form in the page before the "Add a tag" link.
var $newFormLi = $('<li></li>').append(newForm);
$newLinkLi.before($newFormLi);
// Add validation using jQuery.
$collectionHolder.jsFormValidator('addPrototype', index);
// Or using pure JavaScript.
FpJsFormValidator.customize($collectionHolder[0], 'addPrototype', index);
}Removing elements is similar:
function addTagFormDeleteLink($collectionHolder, $tagFormLi, index) {
var $removeFormA = $('<a href="#">delete this tag</a>');
$tagFormLi.append($removeFormA);
$removeFormA.on('click', function(e) {
e.preventDefault();
$collectionHolder.jsFormValidator('delPrototype', index);
// Or using pure JavaScript.
FpJsFormValidator.customize($collectionHolder[0], 'delPrototype', index);
$tagFormLi.remove();
});
}