JSFiddle - React, Tailwind, and code Playground

by john_s

HTML

<div class="sortable before">
	<div class="index row">
		<div class="label">Name</div>
		<div class="label">Field</div>
		<div class="label"><a class="add-row">Add Row</a></div>
	</div>
	<div class="sort-group group">
		<div class="row">
			<div class="field field-name">
				<input type="text" name="sort_row[1][name]" id="sort_row[1][name]" value="First Row Name" />
			</div>
			<div class="field field-field last">
				<input type="text" name="sort_row[1][field]" id="sort_row[1][field]" value="First Row Field" />
			</div>
		</div>
		<div class="row">
			<div class="field field-name">
				<input type="text" name="sort_row[2][name]" id="sort_row[2][name]" value="Second" />
			</div>
			<div class="field field-field last">
				<input type="text" name="sort_row[2][field]" id="sort_row[2][field]" value="Second" />
			</div>
		</div>
		<div class="row">
			<div class="field field-name">
				<input type="text" name="sort_row[3][name]" id="sort_row[3][name]" value="Third" />
			</div>
			<div class="field field-field last">
				<input type="text" name="sort_row[3][field]" id="sort_row[3][field]" value="Third" />
			</div>
		</div>
		<div class="row">
			<div class="field field-name">
				<input type="text" name="sort_row[4][name]" id="sort_row[4][name]" value="Fourth" />
			</div>
			<div class="field field-field last">
				<input type="text" name="sort_row[4][field]" id="sort_row[4][field]" value="Fourth" />
			</div>
		</div>
	</div>
</div>

CSS

.row {
		overflow: hidden;
	}

	.row .field,
	.row .label {
		width: 150px;
		float: left;
	}

JavaScript

$('.add-row').on('click', function () {

	function renumberRow($row, n) {
        function propCallback(i, value) {
            return value.replace(/(\d+)/, n);
        }
        $row.find('input:text, input:hidden, textarea, select')
            .prop('name', propCallback);
        $row.find('input, textarea, select').prop('id', propCallback);
	}

    var $sortable = $(this).parents('.sortable'),
        before = $sortable.is('.before'),
        $rows = $sortable.find('.sort-group').find('.row'),
        insert = before ? 'insertBefore' : 'insertAfter',
        insertLocation = before ? $rows.first() : $rows.last(),
        newRowNum = before ? 1 : ($rows.length + 1);

    if (before) {
        $rows.each(function(i) { renumberRow($(this), i + 2); });
    }

    var $newRow = $rows.last().clone(true)[insert](insertLocation)
        .addClass('add').removeClass('first');
    renumberRow($newRow, newRowNum);
    $newRow.find('input:text, input:hidden, textarea, select').val('');

    return false;
});