There is a table that the user fills. At the end of each line you need to get some result. I want to understand how to make javascript work within a single current line? And how can I get it the line number?

<table border="1"> <tr> <th>Товар</th> <th>Цена за кг</th> <th>Количество</th> <th>Стоимость</th> <th>Расчитать</th> </tr> <tr id="row0"> <td id="good0">Яблоки</td> <td><input id="price0" type="text"></td> <td> <select id="qty0"> <option value="0">-</option> <option value="1">1</option> <option value="2">2</option> </select> </td> <td id="cost0">0</td> <td><button onclick="jsfunc()">OK</button></td> </tr> <tr id="row1"> <td id="good1">Груши</td> <td><input id="price1" type="text"></td> <td> <select id="qty1"> <option value="0">-</option> <option value="1">1</option> <option value="2">2</option> </select> </td> <td id="cost1">0</td> <td><button onclick="jsfunc()">OK</button></td> </tr> </table> 

There is another idea to assign each cell id in the format (row number, column number) id="12" , for example. But how to tell it via the button?

  • worth adding script - Grundy
  • 2
    You have a gross error in the code! ID he ID and to be UNIQUE! Throughout DOMe - Shnur

3 answers 3

IDs must be unique - so replace the duplicate classes.

It is not necessary and tedious to press the OK button: let the better result be updated immediately, by changing the fields. To do this, listen to events - input'ov prices and quantities.

Each <input> sits in a <td> , and the cell, in turn, is in the <tr> row. Having input we get a string - this is the parent of the parent. Having a string, we find by the class names in it both input , take their values ​​and multiply. The result is written to the cell with the class cost inside this line.

 // по имени класса и имени события находим элементы // и вешаем на них слушателем события ф-ю calculate() function addEL( className, eventName) { var i, els = document.getElementsByClassName(className); for(i=0; i<els.length; i++) { els[i].addEventListener(eventName, calculate); } } addEL('price', 'input'); addEL('qty', 'change'); function calculate(e){ var row = e.target.parentNode.parentNode; var price = row.querySelector('.price').value; var qty = row.querySelector('.qty').value; row.querySelector('.cost').innerText = price * qty; } 
 table{border-collapse: collapse}table,td,th{border-color:#CCC} 
 <table border="1"> <tr> <th>Товар</th> <th>Цена за кг</th> <th>Количество</th> <th>Стоимость</th> </tr> <tr id="row0"> <td class="product">Яблоки</td> <td><input class="price" type="number"></td> <td> <select class="qty"> <option value="0">-</option> <option value="1">1</option> <option value="2">2</option> </select> </td> <td class="cost">0</td> </tr> <tr id="row1"> <td class="product">Груши</td> <td><input class="price" type="number"></td> <td> <select class="qty"> <option value="0">-</option> <option value="1">1</option> <option value="2">2</option> </select> </td> <td class="cost">0</td> </tr> </table> 

  • To tie the index is not very good, because HTML can change at any time and then everything will fly and it will not correctly display information regarding the fact that HTML itself will simply rip - Shnur
  • @Shnur, true that, thanks. Rewrote through querySelector () - Sergiks

With closed select, replacing id with class, since The id must be unique and to simplify the script itself. added null protection.

 var buttons = document.getElementsByTagName('button'); var inputs = document.getElementsByTagName('input'); if (!Element.prototype.matches) Element.prototype.matches = Element.prototype.msMatchesSelector; if (!Element.prototype.closest) Element.prototype.closest = function (selector) { var el = this; while (el) { if (el.matches(selector)) { return el; } el = el.parentElement; } }; [].forEach.call(inputs, function(input) { input.addEventListener('input', function(){ var val = this.value; var newValue = val.replace(/[^0-9.]/gi, ''); var valueDiff = val.length - newValue.length; if (valueDiff) { this.value = newValue; } }); }); [].forEach.call(buttons, function(button) { button.addEventListener('click', function(e){ var tr = this.closest('tr'); var price = tr.getElementsByClassName('price')[0].value || 0; var qty = tr.getElementsByClassName('qty')[0].value || 0; var cost = price * qty; tr.getElementsByClassName('cost')[0].innerText = cost; e.preventDefault(); e.stopPropagation(); }); }); 
 <table border="1"> <tr> <th>Товар</th> <th>Цена за кг</th> <th>Количество</th> <th>Стоимость</th> <th>Расчитать</th> </tr> <tr id="row0"> <td id="good0">Яблоки</td> <td><input class="price" type="text"></td> <td> <select class="qty"> <option value="0">-</option> <option value="1">1</option> <option value="2">2</option> </select> </td> <td class="cost">0</td> <td><button class="btn">OK</button></td> </tr> <tr id="row1"> <td id="good1">Груши</td> <td><input class="price" type="text"></td> <td> <select class="qty"> <option value="0">-</option> <option value="1">1</option> <option value="2">2</option> </select> </td> <td class="cost">0</td> <td><button class="btn">OK</button></td> </tr> </table> 

  • why innerHTML , not innerText is a number there, not a markup; type=text allows the input of valid values 0xFF (norm.) and not very FF => "NaN"; Finally, why preventDefault() and co.? - Sergiks
  • select is already closed. - ikerya
  • Yes, thanks, I missed this moment. and ko, more like a fool proof, because a button without a type and can run a form in which this code can be wrapped, well, or if they use the tag "a", which also entails a reload of the page. - Shnur
  • @ikerya I highly recommend you to be attentive (oh) because I edited the post and yours and the author himself. - Shnur
  • @Shnur Perhaps we have different understandings of what a select is? prntscr.com/bjp6e7 - ikerya

You can add the data-id attribute to the button, which means the id of the tr-element (row0, row1 ...):

 function jsfunc(parent) { var id = parent.getAttribute("data-id"); var price = document.getElementById("row" + id).getElementsByTagName("td")[1].getElementsByTagName("input")[0].value; var num = document.getElementById("row" + id).getElementsByTagName("td")[2].getElementsByTagName("select")[0].value; var cost = parseInt(price * num); document.getElementById("row" + id).getElementsByTagName("td")[3].innerHTML = cost; } 
 <table border="1"> <tr> <th>Товар</th> <th>Цена за кг</th> <th>Количество</th> <th>Стоимость</th> <th>Расчитать</th> </tr> <tr id="row0"> <td>Яблоки</td> <td><input type="text"></td> <td> <select> <option value="0">-</option> <option value="1">1</option> <option value="2">2</option> </select> </td> <td>0</td> <td><button data-id="0" onclick="jsfunc(this)">OK</button></td> </tr> <tr id="row1"> <td>Груши</td> <td><input type="text"></td> <td> <select> <option value="0">-</option> <option value="1">1</option> <option value="2">2</option> </select> </td> <td>0</td> <td><button data-id="1" onclick="jsfunc(this)">OK</button></td> </tr> </table> 

  • Would you even correct the mistakes ... it will not work - Shnur
  • @Shnur try clicking on the Выполнить код button. I am sure you will succeed. I am not going to make global changes in the author’s code. Let him do it better himself, as it will be more convenient for him, and then, if necessary, turn to SO for help again. I gave the author an example of how to do it. Learn to think, and then minus both me and the author. We came here to learn, and I think that it is worth pointing out the author’s problem, and not minus it immediately. We all made and make mistakes and there is nothing terrible in this. - ikerya
  • So, teach and show him where he made mistakes, and then produce the same mistakes and no one learns anything. but only copy-paste makes the same mistakes. therefore a minus. - Shnur
  • Corrected errors. - ikerya