I've had success using .clone(true)
to clone a row of inputs, including their event listeners.
However, I am also duplicating the IDs. Surprisingly though, the event listeners know which button I'm clicking, even though the IDs are duplicated.
How does .clone(true)
attach event listeners to the correct elements when IDs are duplicated?
$(document).ready(function() {
//remove event listener
$("#remove").click(function() {
console.log($(this).parent().parent().attr("id"));
panelCount = $('div[id^="pos"]').length;
console.log(panelCount);
panelID = $(this).parent().parent().attr("id");
if (panelCount <= 1) {
console.log("there's only one panel yo; I won't delete it dog, I'll just clear the fields, holmes")
$("#" + panelID).find("input:not(input[type=button])").val('')
} else {
$("#" + panelID).remove();
}
});
/*
MUCH LOVE TO ROKO C. BULIJAN FOR THIS
HERE'S THE SOURCE: https://stackoverflow.com/a/10127093/3772763
*/
//add event listener
$("#add").click(function() {
// get the last DIV which ID starts with ^= "pos"
var $div = $('div[id^="pos"]:last');
// Read the Number from that DIV's ID (i.e: 3 from "pos3")
// And increment that number by 1
var num = parseInt($div.prop("id").match(/\d+/g), 10) + 1;
// Clone it and assign the new ID (i.e: from num 4 to ID "pos4")
//var $posClone = $div.clone().prop('id', 'pos' + num);
//true does a deep clone to include listeners
//think of .end() as an "edit, undo"
var $posClone = $div.clone(true).find("input:not(input[type=button])").val('').end().prop('id', 'pos' + num);
// Finally insert $pos wherever you want
$div.after($posClone);
});
//save event listener
$("#save").click(function() {
var ary = [];
var obj = {};
$('div[id^="pos"]').each(function() {
ary.push({
"posCode": $(this).find("input[id=posCode]").val(),
"posTitle": $(this).find("input[id=posTitle]").val(),
"posScale": $(this).find("input[id=posScale]").val(),
"posDesc": $(this).find("input[id=posDesc]").val(),
"posQual": $(this).find("input[id=posQual]").val(),
});
}); //end each loop
console.dir(ary);
}); //end save click function
}); //end document ready click function
/* Styles go here */
#addPanelWrapper {
height: 400px;
width: auto;
display: flex;
flex-direction: column;
background-color: powderblue;
font-family: Arial, Helvetica, sans-serif;
}
.addPanel {
display: block;
height: auto;
width: auto;
background-color: aqua;
padding: 5px;
}
.row {
display: flex;
justify-content: space-around;
align-items: center;
height: auto;
width: auto;
}
input {
margin: 2.5px;
}
.inputError {
border: 1px solid #c51244;
background: #fff0f4;
}
.cell-1 {
flex: 1;
}
.cell-2 {
flex: 2;
}
.cell-3 {
flex: 3;
}
.cell-4 {
flex: 4;
}
.cell-5 {
flex: 5;
}
.cell-6 {
flex: 6;
}
.cell-7 {
flex: 7;
}
.cell-8 {
flex: 8;
}
.cell-9 {
flex: 9;
}
.cell-10 {
flex: 10;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="addPanelWrapper">
<div id="pos1" class="addPanel">
<div class="row">
<input id="posCode" name="posCode" class="cell-1" type="text" placeholder="Position Code" required="" />
<input id="posTitle" class="cell-3" type="text" placeholder="Position Title" />
<input id="posScale" class="cell-1" type="text" placeholder="Salary Scale" />
</div>
<div class="row">
<input id="posDesc" class="cell-8" type="textarea" placeholder="Description" />
<input id="posQual" class="cell-8" type="textarea" placeholder="Qualifications" />
<input id="remove" class="cell-1" type="button" value="Remove" />
</div>
</div>
</div>
<input id="add" value="Add" type="button" />
<input id="save" value="Save" type="button" />