【发布时间】:2019-08-11 14:31:33
【问题描述】:
前言:
我有一个 HTML 表格,用户在其中填写他们拥有帐户的社交网络的名称和 URL。每行都有一个复选框。在 jQuery 和 JavaScript 的帮助下,按下 Add Row 按钮时,会动态地将一行添加到表中,按下 delete row 按钮时,那些选中复选框的行将被删除。
目标:
当删除选定的行时,我想以串行方式分配 id到每个剩余行的输入元素和复选框,以便行总是串行声音。
问题:
我无法找到导致错误的原因,因为childNodes[] 似乎不会导致元素不可用。请帮忙!
片段:
// variable to keep track of rows(records)
var social_recs_num = 1;
$(document).ready(function () {
$("#social_add_rec").click(function () {
social_recs_num++;
var markup = "<tr> <th scope=\"row\"> <div class=\"form-group\"> <div class=\"form-check\"> <input type=\"checkbox\" class=\"form-check-input\" id=\"social_rec" + social_recs_num + "\" name=\"social_rec\"> <label class=\"form-check-label\" for=\"social_rec" + social_recs_num + "\"> " + social_recs_num + "</label> </div></div></th> <td> <div class=\"form-group shadow-sm\"> <label for=\"name_social" + social_recs_num + "\">Select or Type</label> <input type=\"text\" list=\"name_social" + social_recs_num + "\" class=\"form-control\" placeholder=\"Name\"> <datalist id=\"name_social" + social_recs_num + "\"> <option value=\"Wikipedia\">Wikipedia</option> <option value=\"Youtube\">Youtube</option> <option value=\"Facebook\">Facebook</option> <option value=\"Twitter\">Twitter</option> <option value=\"Pinterest\">Pinterest</option> </datalist> </div></td><td> <div class=\"form-group shadow-sm\"> <textarea class=\"form-control\" id=\"url_social" + social_recs_num + "\" cols=\"30\" rows=\"1\" placeholder=\"URL\"></textarea> </div></td></tr>"; //in case of id we need to do it like: "min_sysreq" +social_recs_num...as social_recs_num has been incremented priorly it will be the row number of row to be added
$("table tbody").append(markup);
});
// Find and remove selected table rows...only condition is that there must be present attribute name='sysreq_rec' in input element for checkbox of every row
$("#social_delete_rec").click(function () {
$("table tbody").find('input[name="social_rec"]').each(function () {
if ($(this).is(":checked")) {
social_recs_num = social_recs_num - $(this).length;
$(this).parents("tr").remove();
}
});
// to be run when a row is deleted...this assigns ids to input elements in serial manner
var table = document.getElementById("mytab1");
var rowCount = table.rows.length;
// i has been initiated with 1, as header row is the 0th row
for (var i = 1; i < rowCount; i++) {
var row = table.rows[i];
// on this line, getting error: `Uncaught TypeError: Cannot read property 'id' of undefined`
row.childNodes[0].childNodes[0].childNodes[0].childNodes[0].id = "social_rec" + i;
row.childNodes[0].childNodes[0].childNodes[0].childNodes[1].for = "social_rec" + i;
row.childNodes[0].childNodes[0].childNodes[0].childNodes[1].innerHTML = " " + i;
row.childNodes[1].childNodes[0].childNodes[0].for = "name_social" + i;
row.childNodes[1].childNodes[0].childNodes[1].list = "name_social" + i;
row.childNodes[1].childNodes[0].childNodes[2].id = "name_social" + i;
row.childNodes[2].childNodes[0].childNodes[0].id = "url_social" + i;
//iterate through rows
//rows would be accessed using the "row" variable assigned in the for loop
}
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table class="table table-bordered" id="mytab1">
<thead>
<tr>
<th scope="col">
#
</th>
<th scope="col">
Name
</th>
<th scope="col">
URL
</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">
<div class="form-group">
<div class="form-check">
<input type="checkbox" class="form-check-input" id="social_rec1" name="social_rec">
<label class="form-check-label" for="social_rec1"> 1</label>
</div>
</div>
</th>
<td>
<div class="form-group shadow-sm">
<label for="name_social1">Select or Type</label>
<input type="text" list="name_social1" class="form-control" placeholder="Name">
<datalist id="name_social1">
<option value="Wikipedia">Wikipedia</option>
<option value="Youtube">Youtube</option>
<option value="Facebook">Facebook</option>
<option value="Twitter">Twitter</option>
<option value="Pinterest">Pinterest</option>
</datalist>
</div>
</td>
<td>
<div class="form-group shadow-sm">
<textarea class="form-control" id="url_social1" cols="30" rows="1" placeholder="URL"></textarea>
</div>
</td>
</tr>
</tbody>
</table>
<button class="btn btn-primary" type="button" id="social_add_rec">Add Row</button>
<button class="btn btn-primary" type="button" id="social_delete_rec">Delete Row</button>
附言:
- 我用过 jQuery 和 Bootstrap。
- this 问题似乎很接近,但我认为我没有同样的错误。
编辑:
我需要按用户显示(或存储)输入,为此我编写了以下 JavaScript 代码。
var social = function () {
var val = "social:\n";
for (x = 1; x <= social_recs_num; x++) {
//where social_recs_num is number of rows
val = val + "\s\s-\n";
val = val + "\s\s\s\s" + "name: " + getElementById("name_social" + x) + "\n";
val = val + "\s\s\s\s" + "url: " + getElementById("url_social" + x) + "\n";
}
return val;
}
function social 以 YAML 格式返回用户输入的值。对于此代码,当删除选定的行时,我想以串行方式将id 分配给剩余每一行的输入元素和复选框。
【问题讨论】:
-
在我看来,如果您在此之前由于某种原因不需要该索引,那么当您要提交/保存它们时序列化/索引它们要比在界面中动态地容易得多。跨度>
-
我想以串行方式将 id 分配给剩余每一行的输入元素和复选框,以便这些行总是连续正确的。 这不是真的,会导致一个非常脆弱的解决方案,需要大量维护并且无法很好地扩展。您始终可以通过 id 以外的其他方式识别元素。
-
有比链接
childNodes[0].childNodes[0].childNodes[0]...更简洁的方法来定位嵌套元素。仅仅阅读它就不可能知道最后是什么。混合原生方法和 jQuery 方法也不是一个好习惯。使用其中一种并保持一致 -
@NathanChampion 谢谢。我实际上需要为另一个功能连续分配 id。我已经相应地编辑了这个问题,并提供了进一步的解释。
-
@ScottMarcus 我对 JS 很陌生。我是否应该知道一些比 ids 识别元素更好的替代方法(也许对于这种情况)?问题中的代码是我经过一番谷歌搜索和努力后得出的,但我很想知道是否有更可扩展的替代方案。我也进一步澄清了这个问题。
标签: javascript jquery html delete-row typeerror