0

I have a group of dropdowns with a list of players. When a player is selected, their 'Value' should appear next to the drop down and the Total should update to be the sum of all selected players values.

php code below is for two players but I have ten, will likely have ten different similar functions for each of the dropdowns

select-player.php

<!--player1-->
      <tr>
        <td style="width:50%;">
            <select name="player1" id="player1" onchange="showvalue1()">
                <option disabled selected value></option>
                <?php
    $sql = "SELECT * FROM players ORDER BY value DESC";
    $result = mysqli_query($conn, $sql);
    $resultCheck = mysqli_num_rows($result);

    if ($resultCheck > 0) {
        while ($row = mysqli_fetch_assoc($result)) {
      echo "<option value='". $row['playername'] ."'>" .$row['playername'] ."</option>";
        }
    }
    ?>
            </select>
        </td>
        <td style="width:50%;" id="value1">
        </td>
      </tr>
<!--player2-->
      <tr>
        <td style="width:50%;">
            <select name="player2" id="player2" onchange="showvalue2()">
                <option disabled selected value></option>
                <?php
    $sql = "SELECT * FROM players ORDER BY value DESC";
    $result = mysqli_query($conn, $sql);
    $resultCheck = mysqli_num_rows($result);

    if ($resultCheck > 0) {
        while ($row = mysqli_fetch_assoc($result)) {
      echo "<option value='". $row['playername'] ."'>" .$row['playername'] ."</option>";
        }
    }
    ?>
            </select>
        </td>
        <td style="width:50%;" id="value2">
        </td>
      </tr>
<tr>
        <th style="width:50%";>Total</th>
        <th style="width:50%;"  id="total"></th>
      </tr>

ajax.js

function showvalue1(){
    var x = document.getElementById("player1").value;
    var t = document.getElementById("total").value;
    $.ajax({
        url:"../showvalue.php",
        method: "GET",
        datatype: 'json',
        data:{
            id : x,
            total : t
        },
        success:function(data){
            $("#value1").html(data.price);
            $("#total").html(data.newtotal);
        }
    })
}

function showvalue2(){
    var x = document.getElementById("player2").value;
    var t = document.getElementById("total").value;
    $.ajax({
        url:"../showvalue.php",
        method: "GET",
        datatype: 'json',
        data:{
            id : x,
            total : t
        },
        success:function(data){
            $("#value2").html(data.price);
            $("#total").html(data.newtotal);
        }
    })
}

I've read that jsonencode is used to send arrays back that I can then assign to IDs in js.

showvalue.php

<?php
    include_once 'includes/dbh.inc.php';
    $pl = $_POST['id'];
    $pl = trim($pl);
    $total = 0;
    $total = $_POST['total'];
    $sql = "SELECT value FROM players WHERE playername='{$pl}'";
    $result = mysqli_query($conn, $sql);
    while($rows = mysqli_fetch_array($result)){
        $newtotal = 0;
        $value = $rows['value'];
        $newtotal = $total + $value;
        $ret = array('price'=>$value, 'newtotal'=>$newtotal);
        echo json_encode($ret);
    }
?>

Not getting any errors or console returns but also no values are being returned.

What am I missing?

Matt Drake
  • 144
  • 8
  • Nope should make the function where you call the query and get the data, in your select-player.php call that function store data in local variable and loop through it in every place you want – Shakeel Ahmad Aug 25 '21 at 07:36
  • What does browser devtools show? Is the POST really happening, and if so are the `id` and `total` being sent correctly? How about the response, are you getting 200/OK, and if so are you seeing the data from your PHP? Have you tried adding `header('Content-Type: application/json');` in your PHP to make sure JS understands the response? – Don't Panic Aug 25 '21 at 07:50
  • As to your approach, a better way would be to have a single `showvalue()` function which works out which player was selected, eg in that function `$(this).attr('id')` will get you the `id` of the select that was changed. It is also better practice to not use inline JS like `onchange="showvalue1()"`, instead in your JS use something like `$('select').on('change', showvalue);` (and you only need one with this approach). – Don't Panic Aug 25 '21 at 07:54
  • Thanks for your idea on a better approach, i was struggling building this thought i'd build the longer first and enhance later. Looking at the DevTools, it seems that `total` isn't being sent, `id` is. – Matt Drake Aug 25 '21 at 08:55
  • OK so now the problem is clear :-) I've added an answer. – Don't Panic Aug 25 '21 at 10:24
  • **Warning:** You are wide open to [SQL Injections](https://php.net/manual/en/security.database.sql-injection.php) and should use parameterized **prepared statements** instead of manually building your queries. They are provided by [PDO](https://php.net/manual/pdo.prepared-statements.php) or by [MySQLi](https://php.net/manual/mysqli.quickstart.prepared-statements.php). Never trust any kind of input! Even when your queries are executed only by trusted users, [you are still in risk of corrupting your data](http://bobby-tables.com/). [Escaping is not enough!](https://stackoverflow.com/q/5741187) – Dharman Aug 25 '21 at 10:47

1 Answers1

1

Checking your HTML source, #total is a table cell:

<th id="total"></th>

And you are retrieving it using .value:

var t = document.getElementById("total").value;

But .value is for inputs, not text in a table cell, so that won't work.

To get the text, using jQuery instead of vanilla JS (since the rest of your code is jQuery):

var t = $('#total').text();
Don't Panic
  • 13,965
  • 5
  • 32
  • 51