Dynamic Form Inputs
$("#container").append("<input ...>"); // add a field
$("#container").on("click", ".child-selector", function() {
$(this).remove(); // remove a field
});
Adding Inputs
append() inserts brand-new input fields into a form at runtime, letting users add as many entries as they need, such as additional phone numbers or line items. The new fields become real form controls immediately, included in the form the same as any input written in the original HTML.
Example: Adding Inputs
<!DOCTYPE html>
<html>
<head>
<script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
<style>
button { padding:6px 14px; margin:4px; background:#2c6aa0; color:white; border:none; border-radius:4px; cursor:pointer; }
#resetBtn { background:white; color:#2c6aa0; border:1px solid #2c6aa0; }
#output { margin-top:10px; padding:8px; border:1px solid #ccc; border-radius:4px; background:#f7f7f7; font-family:monospace; min-height:24px; }
#demo :where(p, div, span, li, h1, h2, h3, h4, td, th, blockquote, label, section, article, aside) { border:1px solid #4a7fb5; background:#eaf2fb; padding:6px 10px; margin:4px 0; border-radius:4px; }
#demo :where(ul, ol) { border:1px dashed #888; background:#fafafa; padding:8px 8px 8px 32px; margin:6px 0; }
#demo :where(table) { border-collapse:collapse; }
#demo :where(td, th) { border-radius:0; }
#demo :where(input, select, textarea) { margin:4px 0; }
</style>
</head>
<body>
<button id="resetBtn">Reset</button>
<section id="demo">
<div id="fields"></div>
<button id="add">Add Field</button>
</section>
<div id="output"></div>
<script>
var original = $("#demo").html();
function init() {
$("#add").on("click", function() {
$("#fields").append("<input type='text'>");
});
}
init();
$("#resetBtn").click(function() {
$("#demo").html(original);
$("#output").empty();
init();
});
</script>
</body>
</html>
Removing Inputs
Dynamic fields can be removed with remove() when they are no longer needed, such as clicking a 'delete row' button next to a specific entry. Removing an input this way also removes it from what gets submitted with the form.
Example: Removing Inputs
<!DOCTYPE html>
<html>
<head>
<script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
<style>
button { padding:6px 14px; margin:4px; background:#2c6aa0; color:white; border:none; border-radius:4px; cursor:pointer; }
#resetBtn { background:white; color:#2c6aa0; border:1px solid #2c6aa0; }
#output { margin-top:10px; padding:8px; border:1px solid #ccc; border-radius:4px; background:#f7f7f7; font-family:monospace; min-height:24px; }
#demo :where(p, div, span, li, h1, h2, h3, h4, td, th, blockquote, label, section, article, aside) { border:1px solid #4a7fb5; background:#eaf2fb; padding:6px 10px; margin:4px 0; border-radius:4px; }
#demo :where(ul, ol) { border:1px dashed #888; background:#fafafa; padding:8px 8px 8px 32px; margin:6px 0; }
#demo :where(table) { border-collapse:collapse; }
#demo :where(td, th) { border-radius:0; }
#demo :where(input, select, textarea) { margin:4px 0; }
</style>
</head>
<body>
<button id="resetBtn">Reset</button>
<section id="demo">
<div id="fields"><div class="row"><input><button class="del">Remove</button></div></div>
</section>
<div id="output"></div>
<script>
var original = $("#demo").html();
function init() {
$("#fields").on("click", ".del", function() {
$(this).closest(".row").remove();
});
}
init();
$("#resetBtn").click(function() {
$("#demo").html(original);
$("#output").empty();
init();
});
</script>
</body>
</html>
Dynamic Events
Delegated events -- attaching a listener to a stable parent and checking event.target -- work with elements added later, unlike a direct listener bound only to elements that existed when the page loaded. This is essential for dynamic forms, since directly-bound listeners would never fire on inputs added after the fact.
Example: Dynamic Events
<!DOCTYPE html>
<html>
<head>
<script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
<style>
button { padding:6px 14px; margin:4px; background:#2c6aa0; color:white; border:none; border-radius:4px; cursor:pointer; }
#resetBtn { background:white; color:#2c6aa0; border:1px solid #2c6aa0; }
#output { margin-top:10px; padding:8px; border:1px solid #ccc; border-radius:4px; background:#f7f7f7; font-family:monospace; min-height:24px; }
.btn { display:inline-block; padding:6px 14px; margin:4px; background:#2c6aa0; color:white; border-radius:4px; cursor:pointer; font:13px sans-serif; }
#resetBtn.btn { background:white; color:#2c6aa0; border:1px solid #2c6aa0; }
#demo :where(p, div, span, li, h1, h2, h3, h4, td, th, blockquote, label, section, article, aside) { border:1px solid #4a7fb5; background:#eaf2fb; padding:6px 10px; margin:4px 0; border-radius:4px; }
#demo :where(ul, ol) { border:1px dashed #888; background:#fafafa; padding:8px 8px 8px 32px; margin:6px 0; }
#demo :where(table) { border-collapse:collapse; }
#demo :where(td, th) { border-radius:0; }
#demo :where(input, select, textarea) { margin:4px 0; }
</style>
</head>
<body>
<span id="resetBtn" class="btn" role="button">Reset</span>
<section id="demo">
<div id="fields"></div>
<button id="add">Add</button>
</section>
<div id="output"></div>
<script>
var original = $("#demo").html();
function init() {
$("#fields").on("click", "input", function() {
$("#output").append($("<div>").text("Clicked a field, even a new one"));
});
$("#add").on("click", function() {
$("#fields").append("<input type='text'>");
});
}
init();
$("#resetBtn").click(function() {
$("#demo").html(original);
$("#output").empty();
init();
});
</script>
</body>
</html>
Counting Fields
A running counter can generate unique field names or ids for each new dynamically-added input, avoiding collisions between entries. This matters because form data with duplicate names can behave unpredictably when submitted.
Example: Counting Fields
<!DOCTYPE html>
<html>
<head>
<script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
<style>
button { padding:6px 14px; margin:4px; background:#2c6aa0; color:white; border:none; border-radius:4px; cursor:pointer; }
#resetBtn { background:white; color:#2c6aa0; border:1px solid #2c6aa0; }
#output { margin-top:10px; padding:8px; border:1px solid #ccc; border-radius:4px; background:#f7f7f7; font-family:monospace; min-height:24px; }
#demo :where(p, div, span, li, h1, h2, h3, h4, td, th, blockquote, label, section, article, aside) { border:1px solid #4a7fb5; background:#eaf2fb; padding:6px 10px; margin:4px 0; border-radius:4px; }
#demo :where(ul, ol) { border:1px dashed #888; background:#fafafa; padding:8px 8px 8px 32px; margin:6px 0; }
#demo :where(table) { border-collapse:collapse; }
#demo :where(td, th) { border-radius:0; }
#demo :where(input, select, textarea) { margin:4px 0; }
</style>
</head>
<body>
<button id="resetBtn">Reset</button>
<section id="demo">
<div id="fields"></div>
<button id="add">Add</button>
</section>
<div id="output"></div>
<script>
var original = $("#demo").html();
function init() {
let count = 0;
$("#add").on("click", function() {
count++;
$("#fields").append("<input name='field" + count + "'>");
});
}
init();
$("#resetBtn").click(function() {
$("#demo").html(original);
$("#output").empty();
init();
});
</script>
</body>
</html>
Practical Dynamic Forms
Dynamic fields are useful for repeated data of unknown quantity ahead of time, like a variable number of guests or attachments. Combining append(), delegated events, and a counter covers the core mechanics needed to build this kind of form.
Example: Practical Dynamic Forms
<!DOCTYPE html>
<html>
<head>
<script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
<style>
button { padding:6px 14px; margin:4px; background:#2c6aa0; color:white; border:none; border-radius:4px; cursor:pointer; }
#resetBtn { background:white; color:#2c6aa0; border:1px solid #2c6aa0; }
#output { margin-top:10px; padding:8px; border:1px solid #ccc; border-radius:4px; background:#f7f7f7; font-family:monospace; min-height:24px; }
.btn { display:inline-block; padding:6px 14px; margin:4px; background:#2c6aa0; color:white; border-radius:4px; cursor:pointer; font:13px sans-serif; }
#resetBtn.btn { background:white; color:#2c6aa0; border:1px solid #2c6aa0; }
#demo :where(p, div, span, li, h1, h2, h3, h4, td, th, blockquote, label, section, article, aside) { border:1px solid #4a7fb5; background:#eaf2fb; padding:6px 10px; margin:4px 0; border-radius:4px; }
#demo :where(ul, ol) { border:1px dashed #888; background:#fafafa; padding:8px 8px 8px 32px; margin:6px 0; }
#demo :where(table) { border-collapse:collapse; }
#demo :where(td, th) { border-radius:0; }
#demo :where(input, select, textarea) { margin:4px 0; }
</style>
</head>
<body>
<span id="resetBtn" class="btn" role="button">Reset</span>
<section id="demo">
<div id="guests"></div>
<button id="addGuest">Add Guest</button>
</section>
<div id="output"></div>
<script>
var original = $("#demo").html();
function init() {
let guestCount = 0;
$("#addGuest").on("click", function() {
guestCount++;
$("#guests").append("<div class='row'><input name='g" + guestCount + "'><button class='del'>X</button></div>");
});
$("#guests").on("click", ".del", function() {
$(this).closest(".row").remove();
});
}
init();
$("#resetBtn").click(function() {
$("#demo").html(original);
$("#output").empty();
init();
});
</script>
</body>
</html>
- Binding
$(".del").on("click", ...)directly on rows that are added later, so new rows do nothing; use delegation such as$("#fields").on("click", ".del", ...). - Cloning or appending inputs with the same
ideach time, creating duplicate ids and giving fields identicalnamevalues; add a counter to make them unique. - Calling
.remove()on the wrong element, such as only the button instead of its.closest(".row"), leaving an orphaned input behind.
Chapter Quiz — Complete all 5 topics to unlock
0/5 topics done
Complete these topics first: