Я разработал код для расчета затрат на заработную плату для проекта. Проблема в том, что вычисляется только первая строка.
Я искал и нашел несколько форумов, обсуждающих одну и ту же проблему, но каждый подход/код выглядит совершенно по-разному. Кроме того, я скопировал целые примеры кодирования из видео/форумов YouTube, чтобы воспроизвести решение, и, похоже, ни один из них не работает. Я знаю, что могут быть проблемы с идентификатором/классом, но, поскольку я новичок в кодировании, меня все просто смущает. Помощь!
<!DOCTYPE html>
<html lang = "en" dir = "ltr">
<head>
<meta charset = "utf-8">
<title></title>
</head>
<body>
<form name='vetCosting'>
<h3> Salaries </h3>
<table ID = "salaries">
<tr>
<th>Classification</th>
<th>Hourly rate</th>
<th>Hours</th>
<th>Cost</th>
<th>Comments</th>
<th>Type</th>
<th></th>
<th></th>
</tr>
<tr>
<td>
<select>
<option value = "T1.0">Teacher 1.0</option>
<option value = "T1.1">Teacher 1.1</option>
<option value = "T1.2">Teacher 1.2</option>
<option value = "T1.3">Teacher 1.3</option>
</select>
</td>
<td><input type = "number" name = "hourlyRate" value = "" onFocus = "startCalc();" onBlur = "stopCalc()"></td>
<td><input type = "number" name = "salaryHours" value = "" onFocus = "startCalc();" onBlur = "stopCalc()"></td>
<td><input type = "number" name = "salaryCost" readonly = "readonly"></td>
<td><input type = "text" name = "salComments"></td>
<td><input type = "text" name = "salType"></td>
<td><input type = "button" value = "+" ; onclick = "ob_adRows.addRow(this)"></td>
<td><input type = "button" value = "-" ; onclick = "ob_adRows.delRow(this)"></td>
</tr>
</table>
</form>
<script>
function startCalc() {
interval = setInterval("calc()", 2);
}
function calc() {
hrRate = document.vetCosting.hourlyRate.value;
salHours = document.vetCosting.salaryHours.value;
document.vetCosting.salaryCost.value = ((hrRate * 1) * (salHours * 1));
}
function stopCalc() {
clearInterval(interval);
}
</script>
<script>
function adRowsTable(id) {
var table = document.getElementById(id);
var me = this;
if (document.getElementById(id)) {
var row1 = table.rows[1].outerHTML;
function setIds() {
var tbl_id = document.querySelectorAll('#' + id + ' .tbl_id');
for (var i = 0; i < tbl_id.length; i++) tbl_id[i].innerHTML = i + 1;
}
me.addRow = function (btn) {
btn ? btn.parentNode.parentNode.insertAdjacentHTML('afterend', row1) :
table.insertAdjacentHTML('beforeend', row1);
setIds();
}
me.delRow = function (btn) {
btn.parentNode.parentNode.outerHTML = '';
setIds();
}
}
}
var ob_adRows = new adRowsTable('salaries');
</script>
</body>
</html>
Я хотел бы иметь возможность добавлять и удалять строки с расчетами, правильно вычисляемыми для каждой строки на основе входных данных.
Извините, я случайно не разместил этот бит, но он существует.
ну а поправить не хочешь?
Хорошо, обновил код :). Не могли бы вы подсказать, что я делаю не так?
в вашем JS еще 14 {
и 11 }
Извините, мне пришлось обновить снова, но я не уверен, что вы имеете в виду.
Если ваш код сформирован неправильно, у вас всегда будут ошибки. инструкция будет хороша, но не даст ожидаемого результата
Теперь я понял про скобки. Спасибо. Однако код был обновлен и по-прежнему не работает.
Мне нужно больше времени для построения решения
Моим первым шагом было бы изменить ваш код с использования setInterval(), потому что он запускается каждые 2 миллисекунды, даже если ввод не меняется, а пользователь просто сидит там. Я бы изменил его на событие onKeyUp, которое срабатывает гораздо реже.
Это делается путем простого изменения ваших входных данных на это:
<td><input type = "number" name = "hourlyRate" value = "" onKeyUp = "calc();"></td>
Таким образом, мы избавляемся от функций startCalc() и stopCalc().
Теперь, когда у нас есть несколько строк, нам нужен способ идентифицировать каждую строку. Поэтому мы даем вашей первой строке идентификатор «row_0», а также передаем ее через ваши функции calc() следующим образом:
<td><input type = "number" name = "hourlyRate" value = "" onKeyUp = "calc('row_0');"></td>
Затем мы обновляем ваш метод calc(), чтобы он мог использовать каждую строку отдельно:
function calc(id) {
var row = document.getElementById(id);
var hrRate = row.querySelector('input[name=hourlyRate]').value;
var salHours = row.querySelector('input[name=salaryHours]').value;
row.querySelector('input[name=salaryCost]').value = ((hrRate * 1) * (salHours * 1));
}
Далее при нажатии кнопок вылетает вот такая ошибка:
Uncaught ReferenceError: ob_adRows не определен в HTMLInputElement.onclick
Чтобы изменить это, мы изменим функцию, которую вы написали. Давайте сначала подготовим шаблон для каждой строки, а затем просто добавим его к innerHTML таблицы. Однако это не сработает, потому что при этом будет обновлена вся таблица, а значит, и данные из существующих строк будут удалены. Итак, мы используем это для создания нового узла HTML со строкой с идентификатором 'row_x':
function newRowTemplate(rowCount) {
var temp = document.createElement('table');
temp.innerHTML = `<tr id='row_${rowCount}'>
<td>
<select>
<option value = "T1.0">Teacher 1.0</option>
<option value = "T1.1">Teacher 1.1</option>
<option value = "T1.2">Teacher 1.2</option>
<option value = "T1.3">Teacher 1.3</option>
</select>
</td>
<td><input type = "number" name = "hourlyRate" value = "" onKeyUp = "calc('row_${rowCount}');"></td>
<td><input type = "number" name = "salaryHours" value = "" onkeyUp = "calc('row_${rowCount}');"></td>
<td><input type = "number" name = "salaryCost" readonly = "readonly"></td>
<td><input type = "text" name = "salComments"></td>
<td><input type = "text" name = "salType"></td>
<td><input type = "button" value = "+" ; onclick = "addRow()"></td>
<td><input type = "button" value = "-" ; onclick = "removeRow(this)"></td>
</tr>`;
return temp.firstChild;
}
Непосредственно делаем наши новые функции:
function addRow() {
var newRow = newRowTemplate(rowCount);
table.appendChild(newRow);
rowCount += 1;
}
function removeRow(el) {
el.parentNode.parentNode.remove();
rowCount -= 1;
}
И, наконец, мы используем эти новые функции в наших исходных элементах следующим образом:
<td><input type = "button" value = "+" ; onclick = "addRow()"></td>
<td><input type = "button" value = "-" ; onclick = "removeRow(this)"></td>
Вот окончательный результат:
function calc(id) {
var row = document.getElementById(id);
var hrRate = row.querySelector('input[name=hourlyRate]').value;
var salHours = row.querySelector('input[name=salaryHours]').value;
row.querySelector('input[name=salaryCost]').value = ((hrRate * 1) * (salHours * 1));
}
var table = document.getElementById('salaries');
var rowCount = 1;
function newRowTemplate(rowCount) {
var temp = document.createElement('table');
temp.innerHTML = `<tr id='row_${rowCount}'>
<td>
<select>
<option value = "T1.0">Teacher 1.0</option>
<option value = "T1.1">Teacher 1.1</option>
<option value = "T1.2">Teacher 1.2</option>
<option value = "T1.3">Teacher 1.3</option>
</select>
</td>
<td><input type = "number" name = "hourlyRate" value = "" onKeyUp = "calc('row_${rowCount}');"></td>
<td><input type = "number" name = "salaryHours" value = "" onkeyUp = "calc('row_${rowCount}');"></td>
<td><input type = "number" name = "salaryCost" readonly = "readonly"></td>
<td><input type = "text" name = "salComments"></td>
<td><input type = "text" name = "salType"></td>
<td><input type = "button" value = "+" ; onclick = "addRow()"></td>
<td><input type = "button" value = "-" ; onclick = "removeRow(this)"></td>
</tr>`;
return temp.firstChild;
}
function addRow() {
var newRow = newRowTemplate(rowCount);
table.appendChild(newRow);
rowCount += 1;
}
function removeRow(el) {
el.parentNode.parentNode.remove();
rowCount -= 1;
}
<body>
<form name = "vetCosting">
<h3> Salaries </h3>
<h3> Salaries </h3>
<table id = "salaries">
<tr>
<th>Classification</th>
<th>Hourly rate</th>
<th>Hours</th>
<th>Cost</th>
<th>Comments</th>
<th>Type</th>
<th></th>
<th></th>
</tr>
<tr id = "row_0">
<td>
<select>
<option value = "T1.0">Teacher 1.0</option>
<option value = "T1.1">Teacher 1.1</option>
<option value = "T1.2">Teacher 1.2</option>
<option value = "T1.3">Teacher 1.3</option>
</select>
</td>
<td><input type = "number" name = "hourlyRate" value = "" onKeyUp = "calc('row_0');"></td>
<td><input type = "number" name = "salaryHours" value = "" onkeyUp = "calc('row_0');"></td>
<td><input type = "number" name = "salaryCost" readonly = "readonly"></td>
<td><input type = "text" name = "salComments"></td>
<td><input type = "text" name = "salType"></td>
<td><input type = "button" value = "+" ; onclick = "addRow()"></td>
<td><input type = "button" value = "-" ; onclick = "removeRow(this)"></td>
</tr>
</table>
</form>
</body>
Я только что обнаружил ошибку в своем коде. Как только row_x будет создан, и я удалю и добавлю еще одну строку, она снова создаст row_x, потому что rowCount возвращается к x. Вы можете исправить это, удалив декремент в функции удаления строки.
Большое спасибо, Арвинд, за то, что нашли время, чтобы помочь, и ваши пошаговые комментарии. Просто еще один вопрос, и я прошу прощения за то, что он очень простой, потому что я новичок в этом. Где мне разместить функции? т.е. в разделе <head>, разделе <body> или где-то еще?
Получил работу, большое спасибо. Я так благодарен за ваше время и терпение в помощи с этой проблемой. Ваше здоровье
Пожалуйста! Вы разобрались, куда добавить функции?
Привет Арвинд. Я использую тот же код, который вы предоставили в качестве ссылки для другой таблицы со строками, но строки не вычисляются. Любая идея, почему это было бы?
Привет. Я не уверен, что вы имели в виду? Теперь вы хотите вместо этого добавлять и удалять строки и вычислять сумму по столбцу?
первый
<form>
отсутствует = JS где концевые скобки ??