我有此表数据被追加;但是,我想使其成为可以使用“文本”输入类型添加表数据并在添加表数据之前和之后使表数据“可编辑”的地方。
问题是附件会覆盖我之前添加的先前数据/值。我相信这样做是因为在准备好dom时已填充表格了?
我想使它类似于代码片段,但它没有那样做。
$(document).ready(function () {
var arr1 = generateItem();
if (arr1) {
var arr2 = [].concat(arr1);
var tr;
$.each(arr2, function (i, e) {
tr = $('<tr>');
tr.append("<td>" + "<button id='modalBtn" + i + "' type='button' class='btn btn-info' data-toggle='modal' data-target='#myModal'>Info</button>" +
"<button id='editBtn" + i + "' type='button' class='btn btn-default editBtn' data-target='#editBtn'>Edit</button>" +
"<button id='delete" + i + "' type='button' class='btn btn-danger deleteBtn' data-target='#deleteBtn' style='width:50px'>X</button>" + "</td>");
tr.append("<td>" + (e.Name || "") + "</td>");
tr.append("<td>" + (e.Email || "") + "</td>");
tr.append("<td>" + (e.Phone || "") + "</td>");
$('#parentTableBody').append(tr);
populateSchoolInfo(i, e);
});
}
$('#myModal').on('show.bs.modal', function (e) {
var idx = $(e.relatedTarget).closest('tr').index();
$('#schoolModalBody tr').hide().filter('[studentidx=' + idx + ']').show();
});
$('.editBtn').on('click', function () {
var currentTD = $(this).parents('tr').find('td');
if ($(this).html() == 'Edit') {
currentTD = $(this).parents('tr').find('td');
$.each(currentTD, function () {
$(this).prop('contenteditable', true)
});
} else {
$.each(currentTD, function () {
$(this).prop('contenteditable', false)
});
}
$(this).html($(this).html() == 'Edit' ? 'Save' : 'Edit')
});
$('.deleteBtn').on('click', function () {
$(this).closest('tr').remove();
return false;
});
$("#addBtn").click(function () {
$("#parentTable").each(function () {
var tds = '<tr>';
jQuery.each($('tr:last td', this), function () {
tds += '<td>' + $(this).html() + '</td>';
});
tds += '</tr>';
if ($('tbody', this).length > 0) {
$('tbody', this).append(tds);
} else {
$(this).append(tds);
}
});
});
});
function populateSchoolInfo(idx, kid) {
var tr;
$.each(kid.Edu, function (j, v) {
tr = $('<tr>', {studentidx: idx});
tr.append("<td>" + (v.School || "") + "</td>");
tr.append("<td>" + (v.Grade || "") + "</td>");
tr.append("<td>" + (v.Job || "") + "</td>");
tr.append("<td>" + (v.Martial || "") + "</td>");
tr.append("<td>" + (v.ETC || "") + "</td>");
$('#schoolModalBody').append(tr);
});
}
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: "senior", Job: "cashier", Martial: "S", ETC: "honors"}]
}
];
return kids;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/>
<table id="parentTable">
<thead>
<tr class="category">
<th></th>
<th>Name</th>
<th>Email</th>
<th>Phone</th>
</tr>
</thead>
<tbody id="parentTableBody">
<td><button id='addBtn' type='button' class='btn btn-success' data-target='#addRow'>Add Row</button></td>
<td><input type="text" class="form-control" name="name" id="name" placeholder="name"></td>
<td><input type="text" class="form-control" name="email" id="email" placeholder="email"></td>
<td><input type="text" class="form-control" name="phone" id="phone" placeholder="phone"></td>
</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)
这就是问题–为什么要创建一种完全不同的机制来添加行而不是表的初始填充?在功能上完全相同。
如果您查看addRow处理程序,实际上并没有从输入中获取数据-您似乎只是在克隆东西。
如果我们将创建表格行的HTML DOM片段的逻辑放入其自身的函数createRow()中,该怎么办?可以期望有一个索引和一个对象,并使用它们来填充行的单元格。然后,我们可以简单地将该行追加到#parentTableBody的末尾,然后将该对象完全添加到school集合中。
将代码提取到其自身功能中的好处是,当您创建新学生时,您将使用完全相同的功能!您将创建索引和学生对象,但随后将调用createRow(),然后追加该行,并将新的学生记录添加到学校。没有任何东西可以被克隆或重新添加-它只是在做与往常相同的事情。
这是我根据上述建议重构您的代码的方式,并注释了所有内容。我坚信评论,并使用console.log或某种调试器!
$(document).ready(function() {
// create the original collection of student records.
let arr1 = generateItem();
if (arr1) {
// 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(index, element);
// Stick that row we just created into the parent table.
$('#parentTableBody').append(myRow);
// Add that student into the actual school info.
populateSchoolInfo(index, element);
});
}
$('#myModal').on('show.bs.modal', function(e) {
var idx = $(e.relatedTarget).closest('tr').index();
$('#schoolModalBody tr').hide().filter('[studentidx=' + idx + ']').show();
});
$("#parentTableBody").on('click', '.editBtn', function() {
var currentTD = $(this).parents('tr').find('td');
if ($(this).html() == 'Edit') {
currentTD = $(this).parents('tr').find('td');
$.each(currentTD, function() {
$(this).prop('contenteditable', true)
});
} else {
$.each(currentTD, function() {
$(this).prop('contenteditable', false)
});
}
$(this).html($(this).html() == 'Edit' ? 'Save' : 'Edit')
});
$("#parentTableBody").on('click', '.deleteBtn', function() {
$(this).closest('tr').remove();
return false;
});
/****
* 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);
// Add the student to the school collection itself.
populateSchoolInfo(myStudentIndex, myStudentObj)
});
});
function populateSchoolInfo(idx, kid) {
var tr;
$.each(kid.Edu, function(j, v) {
tr = $('<tr>', {
studentidx: idx
});
tr.append("<td>" + (v.School || "") + "</td>");
tr.append("<td>" + (v.Grade || "") + "</td>");
tr.append("<td>" + (v.Job || "") + "</td>");
tr.append("<td>" + (v.Martial || "") + "</td>");
tr.append("<td>" + (v.ETC || "") + "</td>");
$('#schoolModalBody').append(tr);
});
}
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: "senior",
Job: "cashier",
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);
tr = $('<tr class="student-row">');
tr.append("<td>" + "<button id='modalBtn" + index + "' type='button' class='btn btn-info' data-toggle='modal' data-target='#myModal'>Info</button>" +
"<button id='editBtn" + index + "' type='button' class='btn btn-default editBtn' data-target='#editBtn'>Edit</button>" +
"<button id='delete" + index + "' type='button' class='btn btn-danger deleteBtn' data-target='#deleteBtn' style='width:50px'>X</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">
<td><button id='addBtn' type='button' class='btn btn-success' data-target='#addRow'>Add Row</button></td>
<td><input type="text" class="form-control" name="name" id="name" placeholder="name"></td>
<td><input type="text" class="form-control" name="email" id="email" placeholder="email"></td>
<td><input type="text" class="form-control" name="phone" id="phone" placeholder="phone"></td>
</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>
请注意,这没有任何有效性检查,它只是接受这三个字段的任何值并创建该Student对象。验证是整个“ NOTHER对话”。
答案 1 :(得分:0)
$('.editBtn').on('click', function () {...
此代码在执行时会添加一个事件侦听器,之后添加的每个DOM元素均不会触发任何操作。
要使事情正常进行,您必须先听document
上的事件,然后再听您想要的元素:
$(document).on('click', '.editBtn', function () {...