More or Less

I've implemented the design pattern of "add and remove rows from a grid" in a HTML form so many times that probably it is better to publish here a snippet of code to be recovered the next time...

The following example is styled with SemanticUI: all classes containing many-rows are involved in the interaction, all other classes and IDs are just for the sake of graphics. Of course, jQuery is required.

HTML reference:

<div class="ui segment many-rows">
	<div class="inline fields">
		<div class="six wide field">
			<input name="attribute_name[]" type="text">
		</div>
		<div class="six wide field">
			<select name="attribute_type[]">
				<option value="string">Testo</option>
				<option value="date">Data</option>
				<option value="address">Indirizzo</option>
			</select>
		</div>
	</div>

	<button class="ui button add-many-rows">Aggiungi Nuovo</button>
</div>

Javascript reference:

if ($('.many-rows').length != 0) {
	function manyRowsAddDeleteButtons(node) {
		if (node.find('.delete-many-rows').length == 0) {
			var fields = node.find('.fields');
			if (fields.length > 1) {
				fields.each(function() {
					var button = '<div class="four wide field"><a class="ui button delete-many-rows"><i class="red delete icon"></i></a></div>';
					$(this).append(button);
				});
			}
		}
	}

	$('.many-rows').on('click', '.delete-many-rows', function() {
		var container = $(this).parents('.many-rows');
		$(this).parents('.fields').remove();
		if (container.find('.fields').length <= 1)
			container.find('.delete-many-rows').parent().remove();
		return false;
	});

	$('.many-rows').on('click', '.add-many-rows', function() {
		var container = $(this).parents('.many-rows');
		var row = container.find('.fields').first().clone();
		row.find('input').val('');
		row.find('select option').removeAttr('selected');
		container.find('.add-many-rows').before(row);
		manyRowsAddDeleteButtons(container);
		return false;
	});

	$('.many-rows').each(function() {
		manyRowsAddDeleteButtons($(this));
	});
}

Final result:

Show Comments