Вычислить столбец в строке добавить для всех строк

Я разработал код для расчета затрат на заработную плату для проекта. Проблема в том, что вычисляется только первая строка.

Я искал и нашел несколько форумов, обсуждающих одну и ту же проблему, но каждый подход/код выглядит совершенно по-разному. Кроме того, я скопировал целые примеры кодирования из видео/форумов 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>

Я хотел бы иметь возможность добавлять и удалять строки с расчетами, правильно вычисляемыми для каждой строки на основе входных данных.

первый <form> отсутствует = JS где концевые скобки ??

Mister Jojo 21.06.2019 04:43

Извините, я случайно не разместил этот бит, но он существует.

Pan 21.06.2019 04:59

ну а поправить не хочешь?

Mister Jojo 21.06.2019 05:12

Хорошо, обновил код :). Не могли бы вы подсказать, что я делаю не так?

Pan 21.06.2019 05:25

в вашем JS еще 14 { и 11 }

Mister Jojo 21.06.2019 05:35

Извините, мне пришлось обновить снова, но я не уверен, что вы имеете в виду.

Pan 21.06.2019 05:38

Если ваш код сформирован неправильно, у вас всегда будут ошибки. инструкция будет хороша, но не даст ожидаемого результата

Mister Jojo 21.06.2019 05:52

Теперь я понял про скобки. Спасибо. Однако код был обновлен и по-прежнему не работает.

Pan 21.06.2019 06:02

Мне нужно больше времени для построения решения

Mister Jojo 21.06.2019 06:35
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
9
93
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Моим первым шагом было бы изменить ваш код с использования 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> или где-то еще?

Pan 21.06.2019 08:30

Получил работу, большое спасибо. Я так благодарен за ваше время и терпение в помощи с этой проблемой. Ваше здоровье

Pan 21.06.2019 08:45

Пожалуйста! Вы разобрались, куда добавить функции?

Arvind 21.06.2019 10:06

Привет Арвинд. Я использую тот же код, который вы предоставили в качестве ссылки для другой таблицы со строками, но строки не вычисляются. Любая идея, почему это было бы?

Pan 27.06.2019 07:22

Привет. Я не уверен, что вы имели в виду? Теперь вы хотите вместо этого добавлять и удалять строки и вычислять сумму по столбцу?

Arvind 27.06.2019 10:39

Другие вопросы по теме