Stamping out DOM templates

by jorgeluis

HTML

<template id="item-template">
  <div class="control-group" data-item-id="1">
    <input name="itemName" class="item-name" type="text"/>
    <input name="itemPrice" class="item-price" type="text"/>
    <textarea name="itemDesc" class="item-desc"></textarea>
  </div>
</template>


<form action="#">

  <fieldset id="items">

    <div class="control-group" data-item-id="1" id="item-1">
      <input name="itemName" class="item-name" type="text"/>
      <input name="itemPrice" class="item-price" type="text"/>
      <textarea name="itemDesc" class="item-desc"></textarea>
    </div>

  </fieldset>

</form>

<button id="addItem">Add Item</button>

CSS

* {
  box-sizing: border-box;
}
form {
  max-width: 300px;
  margin: 0 auto;
}
fieldset {
  border: 0;
}

.control-group {
  padding: 0.5em;
  border: solid 1px #ddd;
}

input, textarea {
  width: 100%;
  margin: 2px 0;
  padding: 6px;
}

JavaScript

document.getElementById('addItem').addEventListener('click', addItem);

function addItem() {
  var itemContent = document.querySelector('#item-template').content;

	// Update ID in the template.
  var itemGroup = itemContent.querySelector('.control-group');
  var newId = parseInt(itemGroup.dataset.itemId, 10) + 1;
	var itemFields = itemContent.querySelectorAll('input, textarea');

	itemGroup.dataset.itemId = newId;
  
  itemFields.forEach(function() {
  	alert(this.name);
  	this.setAttribute('name', this.name + '-' + newId);
  });


	document.querySelector('#items').appendChild(document.importNode(itemContent, true));
}