Incrementing Dynamic HTML Element Attributes

On occasion I clone DOM elements to repeat form sections dynamically. During this I need to increment the name and id attributes so I can reference them later on.

For example: name=”txtField1″ becomes “txtField2”

To make this happen I use a little but of slick jQuery magic. This increments the id and name attributes and empties the value for input, select, and textarea elements.

var newNum = new Number(num + 1);
var newElem = $('.clonedInput:last').clone(false).attr('id', 'input' + newNum);
newElem.find('input,select,textarea')
    .attr('name', function() {
        return $(this).attr('name').replace(/^(.+?)(\d+)$/, function(s, p1) {
            return p1 + newNum;
        });
    })
    .attr('id', function() {
        return $(this).attr('id').replace(/^(.+?)(\d+)$/, function(s, p1) {
            return p1 + newNum;
        });
    })
    .val('');

I started out using the regex:

^(.+)(\d+)$

But that failed after 10. The .+ expression needs to be non-greedy using:

^(.+?)(\d+)$

Here’s another example using a table and an button to create a new row:

$("#productChildren").delegate("#btnAddAdditionalProductChildren", "click", function(event) {
	var $clone = $("#productChildren > tr").last().clone(false);
	$(this).remove();
	var $inputs = $( $clone ).find("input[type='text']");
	$($inputs).each(function() {
		var newNameAttr = $(this).attr('name').replace(/\d+$/, function(match, p1) {
			return parseInt(match) + 1;
		});	
		$(this).attr('name', newNameAttr);
		$(this).val('');	
	});
	$($clone).appendTo("#productChildren");
});