我有此表添加一行,并且正在添加行;但是,当我单击一个按钮以显示将行添加到何处(当前代码)时,它会创建多个行。
例如,如果我单击加载当前页面的按钮3次,然后单击“添加行”按钮,它将添加3行。
此方法在其中寻找导致行增加3次的输入:
let inputs = $(this).parent().siblings().find("input[type='text']");
有人知道为什么要这么做吗?
谢谢
var globalIndex = 0;
$(document).ready(function() {
// create the original collection of student records.
let arr1 = generateItem();
if (arr1) {
var tr;
tr = $('<tr class="student-row">');
tr.append("<td>" +"<button id='addBtn' type='button' class='btn btn-success addBtn' data-target='#addBtn' style='width:50px'>Add</button>" + "</td>");
tr.append("<td>" + ("<input type='text' class='form-control' style='width:50px' name='name' id='name'>") + "</td>");
tr.append("<td>" + ("<input type='text' class='form-control' style='width:80px' name='email' id='email'>") + "</td>");
tr.append("<td>" + ("<input type='text' class='form-control' style='width:80px' name='phone' id='phone'>") + "</td>");
$('#parentTableBody').append(tr);
// clone that collection into a second array (?)
let arr2 = [...arr1];
// For each member of the student collection, create a table row.
$.each(arr2, function(index, element) {
// createRow() creates the DOM student row.
let myRow = createRow(globalIndex, element);
// Stick that row we just created into the parent table.
$('#parentTableBody').append(myRow);
// Add that student into the actual school info.
// globalIndex++;
});
}
/****
* When the add button is clicked, we first create a new Student object.
* By doing this, we can then re-use the same createRow function we
* used when we created each initial row, thus ensuring the same result.
****/
$("#addBtn").click(function() {
// Get all the text input fields for this form.
let inputs = $(this).parent().siblings().find("input[type='text']");
// Create an empty student object.
let myStudentObj = {};
// Iterate over all the text inputs, and create properties for the student
// Each text input name will become the property name.
inputs.each(function(index, input){
/***
* This is a complicated conversion: as the createRow has been defined to
* expect a Titlecase property (first letter is capitalized), but the input
* names are lower case, we need to retrieve the input name, convert it
* to all lowercase (just to be safe), then convert the first char to upper.
***/
let propName = $(input).prop("name")
.toLowerCase();
propName = propName.replace(propName[0], propName[0].toUpperCase());
// Now, create a property on the object with the proper value.
myStudentObj[propName] = $(input).val();
// And let's also blank that input field, so we can create a new student easily.
$(input).val("");
});
/***
* A little more funkiness: the index is the object's position in an array, or list.
* As we have been adding the records sequentially, the number of rows is the index
* of the last row. Adding one to that will give us the index of the current student.
***/
let myStudentIndex = $("#parentTableBody tr.student-row").length,
// And we can create that DOM fragment, as we did when we initialized the list above.
myRow = createRow(myStudentIndex, myStudentObj);
// add our newly created DOM fragment to the parent container.
$("#parentTableBody").append(myRow);
});
});
function generateItem() {
var kids = [{
Name: "Gina",
Email: "gina@email.com",
Phone: "211-456-1234",
Edu: [{
School: "college",
Grade: "Freshmen",
Job: "Student",
Martial: "S",
ETC: " "
},
{
School: "college2",
Grade: "Freshmen2",
Job: "Student2",
Martial: "S2",
ETC: "2"
},
{
School: "college3",
Grade: "Freshmen3",
Job: "Student3",
Martial: "S3",
ETC: "3"
}
]
},
{
Name: "Mark",
Email: "mark@email.com",
Phone: "144-411-2312",
Edu: [{
School: "highschool",
Grade: "senior",
Job: "cashier",
Martial: "S",
ETC: "honors"
}]
},
{
Name: "Jake",
Email: "jake@email.com",
Phone: "333-211-1111",
Edu: [{
School: "highschool",
Grade: "junior",
Job: "waiter",
Martial: "S",
ETC: "honors"
}]
}
];
return kids;
}
/****
* createRow() -- create the student row DOM fragment.
* index = the student index
* obj = the student object, formatted like:
* obj = { Name: "name", Email: "email", Phone: "555-555-5555", <other optional fields>}
*
* returns a td DOM node containing the student info.
****/
function createRow(index, obj) {
// console.log(obj);
globalIndex++;
tr = $('<tr class="student-row">');
tr.append("<td>" + "<button id='modalBtn " + globalIndex + "' type='button' class='btn btn-info' data-toggle='modal' data-target='#myModal'>Info</button>" +
"</td>");
tr.append("<td>" + (obj.Name || "") + "</td>");
tr.append("<td>" + (obj.Email || "") + "</td>");
tr.append("<td>" + (obj.Phone || "") + "</td>");
return tr;
}
<script src="https://code.jquery.com/jquery-3.3.1.min.js" integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=" crossorigin="anonymous"></script>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" />
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.bundle.min.js"></script>
<table id="parentTable">
<thead>
<tr class="category">
<th></th>
<th>Name</th>
<th>Email</th>
<th>Phone</th>
</tr>
</thead>
<tbody id="parentTableBody">
</tbody>
</table>
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-body">
<h3>Info</h3>
<div class="well well-sm overflow-auto">
<table class="table table-striped table-hover table-condensed" id="schoolTable">
<thead>
<tr>
<th>School</th>
<th>Grade</th>
<th>Job</th>
<th>Martial</th>
<th>Etc</th>
</tr>
</thead>
<tbody id="schoolModalBody">
</tbody>
</table>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-info" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
答案 0 :(得分:1)
从描述测试场景的方式来看,每次加载页面时,表中将再增加1行。这可能与以下代码行有关:
$("#addBtn").click(function() { ... }
每次加载页面时,都会在DOM元素中添加另一个“点击”处理程序。这意味着您第三次加载页面时,添加了3个事件处理程序。您应该只添加一次这些事件处理程序,或者在添加另一个之前删除所有先前的事件处理程序。我在另一篇文章中找到了最佳解决方案:jQuery click events firing multiple times
$(".bet").unbind().click(function() {
//Stuff
});