#javascript #html
Вопрос:
Я хотел бы динамически обновлять значение одного столбца в таблице на основе пользовательского ввода в другом столбце. Редактируемый пользователем столбец-это количество, и я хотел бы умножить его на значение цены (id = ‘pmvalue’), чтобы отобразить общую цену (id ‘totalpmvalue’) в качестве вывода.
Я не понимаю, какой javascript здесь использовать — я пытался искать решения в Интернете, но не смог найти что-то, что точно соответствует моему варианту использования (и у меня недостаточно опыта, чтобы понять, как адаптировать решения для немного разных вариантов использования). Любые советы будут очень признательны!
Вот мой код:
<?php
require_once 'dbconfig.php';
include 'scrape.php';
$pdo = new PDO("mysql:host=$host;dbname=$dbname", $username, $password);
$submit_value = isset($_POST['q']) ? $_POST['q'] : false;
$sql = 'SELECT DISTINCT year
,country
,name
,metal
,round(weight/31.1035,2) as weight
,round(pm_weight,2) as pm_weight
,round(pm_weight*' . $num . ',2) as silver_value
FROM uscoins
WHERE name = ?';
$stmt = $pdo->prepare($sql);
$stmt->bindParam(1,$submit_value,PDO::PARAM_STR);
$stmt->execute();
$stmt->setFetchMode(PDO::FETCH_ASSOC);
$row = $stmt->fetch();
//echo $row['year'] ?? ' ';
?>
<script type="text/javascript">
function() {
var quantity = Number(document.getElementById('quantity').value);
var silvervalue = Number(document.getElementById('pmvalue').value);
document.getElementById('totalpmvalue').value = quantity * silvervalue;
}
</script>
<!-- to-do: add hover-over definitions for each table header-->
<div id="container">
<h1>Coins</h1>
<table class="table table-bordered table-condensed"; border = "1px solid black"; cellpadding = "6px">
<thead>
<tr>
<!--<th align = "left">Year</th>-->
<th align = "left">Quantity</th>
<th align = "left">Country</th>
<th align = "left">Coin</th>
<th align = "left">Metal</th>
<!--<th align = "left">Weight (oz)</th>-->
<th align = "left">PM Weight (oz)</th>
<th align = "left">Current Silver Price</th>
<th align = "left">Silver Value</th>
<th align = "left">Total Silver Value</th>
</tr>
</thead>
<tbody>
<tr>
<td id = "quantity" type = "number" align = "left" contenteditable="true">1</td>
<!--<td align = "left"><?php echo $row['year'] ?? ' '; ?></td>-->
<td align = "left"><?php echo $row['country'] ?? ' '; ?></td>
<td align = "left"><?php echo $row['name'] ?? ' '; ?></td>
<td align = "left"><?php echo $row['metal'] ?? ' '; ?></td>
<!--<td align = "left"><?php echo $row['weight'] ?? ' '; ?></td>-->
<td align = "left"><?php echo $row['pm_weight'] ?? ' '; ?></td>
<td align = "left">
lt;?php echo $num; ?>/oz</td>
<td id = "pmvalue" align = "left">
lt;?php echo $row['silver_value'] ?? ' '; ?></td>
<td id = "totalpmvalue" align = "left"></td>
</tr>
</tbody>
</table>
Комментарии:
1. .значение для любого элемента будет работать только в случае входных данных, но, как вы можете видеть, они <td>означают, что они не имеют никакого значения, а только html, поэтому вам нужно<td>
.html
не .значение. Во-вторых, я не понимаю, как вы можете сделать качественную колонку доступной для редактирования. В-третьих, у вас будет только одна строка в таблице?2. Если столбец качества редактируется нормально, и если в таблице будет только одна строка, то ваш код javascript будет работать просто отлично
.html
. Вам нужно только удалитьfunction() {}
декларацию и убрать эти 3 строки из нее, как они есть.
Ответ №1:
Если у вас будет несколько строк, вы должны использовать class
, нет id
, id
атрибут должен быть уникальным в документе.
Как только вы это исправите, вы сможете создать слушателя:
element.addEventListener("input", function() {
updateValue(this);
}, false);
Это input
событие-хорошее место для начала, оно запускается при изменении contenteditable
добавления или удаления содержимого, если вам нужно работать с большим количеством вариантов использования, таких как копирование/вставка, вам также нужно обрабатывать другие события.
Как только событие срабатывает, вы сохраняете ссылку на элемент, который сработал, и извлекаете братьев и сестер следующим образом:
cell.parentNode.querySelector('.pmvalue');
cell.parentNode.querySelector('.totalpmvalue');
Как только у вас появится ссылка на братьев и сестер, вы сможете рассчитать и отобразить значение по мере его обновления.
function updateValue(cell) {
const quantity = cell.textContent;
const value = cell.parentNode.querySelector('.pmvalue').innerText;
cell.parentNode.querySelector('.totalpmvalue').innerText = quantity * value;
}
const qCells = document.getElementsByClassName("quantity");
// Attatch the event listener.
for (let i = 0; i < qCells.length; i ) {
qCells[i].addEventListener("input", function() {
updateValue(this);
}, false);
}
<table class="table table-bordered table-condensed" ; border="1px solid black" ; cellpadding="6px">
<thead>
<tr>
<!--<th align = "left">Year</th>-->
<th align="left">Quantity</th>
<th align="left">Country</th>
<th align="left">Coin</th>
<th align="left">Metal</th>
<!--<th align = "left">Weight (oz)</th>-->
<th align="left">PM Weight (oz)</th>
<th align="left">Current Silver Price</th>
<th align="left">Silver Value</th>
<th align="left">Total Silver Value</th>
</tr>
</thead>
<tbody>
<tr>
<td class="quantity" type="number" align="left" contenteditable="true">1</td>
<!--<td align = "left"><?php echo $row['year'] ?? ' '; ?></td>-->
<td align="left">
Example country
</td>
<td align="left">
Ex name
</td>
<td align="left">
Ex metal
</td>
<!--<td align = "left"><?php echo $row['weight'] ?? ' '; ?></td>-->
<td align="left">
<?php echo $row['pm_weight'] ?? ' '; ?>
</td>
<td align="left">$
<?php echo $num; ?>/oz</td>
<td class="pmvalue" align="left">
20
</td>
<td class="totalpmvalue" align="left"></td>
</tr>
</tbody>
</table>
Комментарии:
1. Спасибо, что откликнулись! Я понимаю суть этого, и, похоже, он работает в «фрагменте кода запуска» здесь, а также когда я тестирую его на jsfiddle. Но когда я заменяю свой JS-скрипт на ваш в своем php-файле, функциональность, похоже, не работает на сайте. Я дважды проверил метки классов, и все правильно — есть еще что-нибудь, что я должен устранить?
2. Неважно, я понял это — просто нужно было переместить скрипт ниже затронутого html. Теперь просто нужно придумать, как округлить его до двух знаков после запятой.