#javascript #html #jquery #css
Вопрос:
У меня есть таблица со многими расширяемыми/складываемыми строками, которые скрыты метками до щелчка (показано ниже). Входные данные в правом столбце таблицы предназначены для редактирования и суммирования, поэтому у меня есть функция, чтобы настроить каждую ячейку .contentEditable
и вычислить общую сумму введенных пользователем чисел. Однако, поскольку я не хочу, чтобы сама сумма (в последней строке таблицы) редактировалась, у меня есть следующее ограничение на обработчик событий в jQuery:
document.querySelectorAll("table tr:not(:last-child) td ~ td");
В то время :not(:last-child)
как часть избавляется от проблемы редактируемой последней строки, она создает еще одну проблему: теперь последние строки каждого расширяемого раздела (строки «Джилл» и «Джим» в приведенном ниже примере) также невозможно редактировать. Есть ли способ исправить это, не делая абсолютную последнюю строку таблицы («Всего») редактируемой в процессе?
Чтобы лучше визуализировать проблему, я приложил пример таблицы, демонстрирующей проблему.
$(document).ready(function() {
$('.hide').hide();
$('[data-toggle="toggle"]').change(function() {
$("label[for='" this.id "'] span").toggle();
$(this).parents().next('.hide').toggle();
});
});
function editcell() {
let cellnum = document.querySelectorAll("table tr:not(:last-child) td ~ td");
cellnum.forEach(td => {
td.setAttribute("contentEditable", true);
td.addEventListener("change", getsum());
});
}
function getsum() {
let sum = 0;
let cellnum = document.querySelectorAll("table tr td ~ td");
let count = cellnum.length - 1;
for (i = 0; i < count; i ) {
sum = parseInt(cellnum[i].innerHTML) || 0;
}
cellnum[count].innerHTML = sum;
}
editcell();
table {
width: 100%;
}
table,
tr,
th,
td {
border: 1px solid black;
border-collapse: collapse;
font-family: Arial;
}
[data-toggle="toggle"] {
display: none;
}
label {
display: block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table id="table">
<thead>
<tr>
<th>Name</th>
<th>Number</th>
</tr>
</thead>
<tbody class="section">
<tr>
<td colspan="2">
<label class="label" for="class1">
<b>Class 1</b>
<span>(Click this!)</span>
</label>
<input type="checkbox" name="class1" id="class1" data-toggle="toggle">
</td>
</tr>
</tbody>
<tbody class="hide">
<tr>
<td>Jack</td>
<td id="jack" oninput="editcell()">
<span>0</span>
</td>
</tr>
<tr>
<td>John</td>
<td id="john" oninput="editcell()">
<span>0</span>
</td>
</tr>
<tr>
<td>Jill</td>
<td id="jill" oninput="editcell()">
<span>0</span>
</td>
</tr>
</tbody>
<tbody class="section">
<tr>
<td colspan="2">
<label class="label" for="class2">
<b>Class 2</b>
<span>(Click this!)</span>
</label>
<input type="checkbox" name="class2" id="class2" data-toggle="toggle">
</td>
</tr>
</tbody>
<tbody class="hide">
<tr>
<td>Joe</td>
<td id="joe" oninput="editcell()">
<span>0</span>
</td>
</tr>
<tr>
<td>Jane</td>
<td id="jane" oninput="editcell()">
<span>0</span>
</td>
</tr>
<tr>
<td>Jim</td>
<td id="jim" oninput="editcell()">
<span>0</span>
</td>
</tr>
</tbody>
<tr>
<td style="font-weight:bold; text-align: center">Total</td>
<td id="total"></td>
</tr>
</table>
Ответ №1:
Вы можете выбрать (игнорировать) общую ячейку, так как она имеет уникальный идентификатор:
let cellnum = document.querySelectorAll("table tr td ~ td:not(#total)");
$(document).ready(function() {
$('.hide').hide();
$('[data-toggle="toggle"]').change(function() {
$("label[for='" this.id "'] span").toggle();
$(this).parents().next('.hide').toggle();
});
});
function editcell() {
let cellnum = document.querySelectorAll("table tr td ~ td:not(#total)");
cellnum.forEach(td => {
td.setAttribute("contentEditable", true);
td.addEventListener("change", getsum());
});
}
function getsum() {
let sum = 0;
let cellnum = document.querySelectorAll("table tr td ~ td");
let count = cellnum.length - 1;
for (i = 0; i < count; i ) {
sum = parseInt(cellnum[i].innerHTML) || 0;
}
cellnum[count].innerHTML = sum;
}
editcell();
table {
width: 100%;
}
table,
tr,
th,
td {
border: 1px solid black;
border-collapse: collapse;
font-family: Arial;
}
[data-toggle="toggle"] {
display: none;
}
label {
display: block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table id="table">
<thead>
<tr>
<th>Name</th>
<th>Number</th>
</tr>
</thead>
<tbody class="section">
<tr>
<td colspan="2">
<label class="label" for="class1">
<b>Class 1</b>
<span>(Click this!)</span>
</label>
<input type="checkbox" name="class1" id="class1" data-toggle="toggle">
</td>
</tr>
</tbody>
<tbody class="hide">
<tr>
<td>Jack</td>
<td id="jack" oninput="editcell()">
<span>0</span>
</td>
</tr>
<tr>
<td>John</td>
<td id="john" oninput="editcell()">
<span>0</span>
</td>
</tr>
<tr>
<td>Jill</td>
<td id="jill" oninput="editcell()">
<span>0</span>
</td>
</tr>
</tbody>
<tbody class="section">
<tr>
<td colspan="2">
<label class="label" for="class2">
<b>Class 2</b>
<span>(Click this!)</span>
</label>
<input type="checkbox" name="class2" id="class2" data-toggle="toggle">
</td>
</tr>
</tbody>
<tbody class="hide">
<tr>
<td>Joe</td>
<td id="joe" oninput="editcell()">
<span>0</span>
</td>
</tr>
<tr>
<td>Jane</td>
<td id="jane" oninput="editcell()">
<span>0</span>
</td>
</tr>
<tr>
<td>Jim</td>
<td id="jim" oninput="editcell()">
<span>0</span>
</td>
</tr>
</tbody>
<tr>
<td style="font-weight:bold; text-align: center">Total</td>
<td id="total"></td>
</tr>
</table>