Skip to content

Instantly share code, notes, and snippets.

@troygnichols
Created November 12, 2014 14:58
Show Gist options
  • Save troygnichols/e3394e1fba6bf3d44d8a to your computer and use it in GitHub Desktop.
Save troygnichols/e3394e1fba6bf3d44d8a to your computer and use it in GitHub Desktop.
Nested form with Javascript
<html>
<head>
<title>Nested Form Example</title>
</head>
<body>
<center>
<h1>Order a pizza</h1>
<form id="pizza-form" method="POST" action="/pizzas">
<div>
<label>Crust:</label>
<label>
<input type="radio" name="crust" value="normal" required="required"> Normal
</label>
<label>
<input type="radio" name="crust" value="thin" required="required"> Thin
</label>
</div>
<div>
<h4>Toppings</h4>
<div class="toppings-container">
<div class="topping-selection">
<select name="toppings">
<option>Pepperoni</option>
<option>Sausage</option>
<option>Anchovies</option>
<option>Extra Cheese</option>
<option>Bacon</option>
<option>Brussels Sprouts</option>
<option>Kale</option>
<option>Candied Pecans</option>
<option>Pork Bellies</option>
<option>Ice</option>
<option>Bourbon</option>
<option>Mystery Meat ***NEW!***</option>
</select>
<button class="remove-topping">Remove</button>
</div>
</div>
<br/>
<button class="add-topping">Add Another Toppoing</button>
</div>
<br/>
<input type="submit" value="Place Order">
</form>
</center>
<script type="text/javascript" src="https://code.jquery.com/jquery-2.1.1.min.js"></script>
<script type="text/javascript">
$(function() {
// Use the div .topping-selection as a template for any new toppings that
// will be added. We'll make a copy of it (clone()) so that we have our own
// copy to work with and won't rely on or accidentally change the original DOM element
var toppingTemplate = $('#pizza-form .topping-selection:first').clone();
// function to set up "Add Topping" click listener and behavior
var listenForToppingAdded = function() {
$('#pizza-form .add-topping').on('click', function(event) {
// Default behavior for button is to submit the form; we don't want that
event.preventDefault();
// Insert a copy of the template into the DOM, at the end of the .toppings-container div
// (at the end of the list of toppings)
$('#pizza-form .toppings-container').append(toppingTemplate.clone());
});
};
// function to set up "Remove Topping" click listener and behavior
var listenForToppingRemoved = function() {
// This 'on' listener is slightly different from the one above.
// See: http://api.jquery.com/on/
// Note the second argument to the 'on' call. We pass a selector '.remove-topping' that
// makes it behave in a "live" fashion. So any element inside the '.toppings-container'
// div which has the class '.remove-topping' will respond to this click handler,
// **INCLUDING ELEMENTS THAT ARE ADDED DYNAMICALLY AFTER THIS CODE IS RUN**
// That's important because we're going to be adding new .remove-topping buttons at
// runtime, and we want them to have this behavior as well.
$('#pizza-form .toppings-container').on('click', '.remove-topping', function(event) {
// Same as above, don't sumbit the form:
event.preventDefault();
// The button that was just clicked:
var removeButton = $(this);
// Find the parent .topping-selection div and remove it from the DOM
removeButton.closest('.topping-selection').remove();
});
};
// call the setup functions to establish the listeners
listenForToppingAdded();
listenForToppingRemoved();
});
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment