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

#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. Теперь просто нужно придумать, как округлить его до двух знаков после запятой.