另一种选择是使用递归函数:
// Accepts an element and a function
function childRecursive(element, func){
// Applies that function to the given element.
func(element);
var children = element.children();
if (children.length > 0) {
children.each(function (){
// Applies that function to all children recursively
childRecursive($(this), func);
});
}
}
然后,您可以创建一个或三个函数来设置尚未克隆的表单字段的属性和值:
// Expects format to be xxx-#[-xxxx] (e.g. item-1 or item-1-name)
function getNewAttr(str, newNum){
// Split on -
var arr = str.split('-');
// Change the 1 to wherever the incremented value is in your id
arr[1] = newNum;
// Smash it back together and return
return arr.join('-');
}
// Written with Twitter Bootstrap form field structure in mind
// Checks for id, name, and for attributes.
function setCloneAttr(element, value){
// Check to see if the element has an id attribute
if (element.attr('id') !== undefined){
// If so, increment it
element.attr('id', getNewAttr(element.attr('id'),value));
} else { /*If for some reason you want to handle an else, here you go*/ }
// Do the same with name...
if(element.attr('name') !== undefined){
element.attr('name', getNewAttr(element.attr('name'),value));
} else {}
// And don't forget to show some love to your labels.
if (element.attr('for') !== undefined){
element.attr('for', getNewAttr(element.attr('for'),value));
} else {}
}
// Sets an element's value to ''
function clearCloneValues(element){
if (element.attr('value') !== undefined){
element.val('');
}
}
然后添加一些标记:
<div id="items">
<input type="hidden" id="itemCounter" name="itemCounter" value="0">
<div class="item">
<div class="control-group">
<label class="control-label" for="item-0-name">Item Name</label>
<div class="controls">
<input type="text" name="item-0-name" id="item-0-name" class="input-large">
</div>
</div><!-- .control-group-->
<div class="control-group">
<label for="item-0-description" class="control-label">Item Description</label>
<div class="controls">
<input type="text" name="item-0-description" id="item-0-description" class="input-large">
</div>
</div><!-- .control-group-->
</div><!-- .item -->
</div><!-- #items -->
<input type="button" value="Add Item" id="addItem">
然后你所需要的只是一些 jQuery 的优点将它们整合在一起:
$(document).ready(function(){
$('#addItem').click(function(){
//increment the value of our counter
$('#itemCounter').val(Number($('#allergyCounter').val()) + 1);
//clone the first .item element
var newItem = $('div.item').first().clone();
//recursively set our id, name, and for attributes properly
childRecursive(newItem,
// Remember, the recursive function expects to be able to pass in
// one parameter, the element.
function(e){
setCloneAttr(e, $('#itemCounter').val());
});
// Clear the values recursively
childRecursive(newItem,
function(e){
clearCloneValues(e);
}
);
// Finally, add the new div.item to the end
newItem.appendTo($('#items'));
});
});
显然,如果您确切地知道需要克隆和更改哪些内容,则不一定需要使用递归来获取所有内容。但是,这些函数允许您将它们重用于具有任意数量字段的任何大小的嵌套结构,只要它们都以正确的模式命名。
有一个工作的jsfiddle这里。