Search code examples
javascriptphponchangefunction-callfunction-parameter

How to fix Uncaught ReferenceError with onchange() event when passing parameters to custom function?


I am trying to create an order system where once the user updates the status of the order, it updates it in the server as well without refreshing the page each time (as that seems tedious).

The trouble is, I am generating javascript errors onchange:

Uncaught ReferenceError

Here is the function that displays the orders:

function showOrders()
{
    global $con;

    $getOrders = "SELECT * FROM `Purchase_Order`";
    $rungetOrders = mysqli_query($con, $getOrders);

    $getOrder = "SELECT * FROM `Purchase_Order` WHERE status = 'pending' ORDER BY date ASC";
    $rungetOrders = mysqli_query($con, $getOrder);
    echo '<form action ="PurchaseOrders.php">
              <table style="border :1px solid black; border-collapse: collapse; width: 1300px; margin-bottom: 50px; margin-top: 5px; font-size:20px "> 
                  <tr style="border :1px solid black; background-color: black; color: whitesmoke">
                      <th>ORDER #</th>
                      <th>PRODUCT ID</th>
                      <th>COLOR</th>
                      <th>SIZE</th>
                      <th>QTY</th>
                      <th>DATE ORDERED</th>
                      <th>STATUS</th>
                  </tr>';  
    $counter = 0;
    while($row = mysqli_fetch_array($rungetOrders))
    {
        $ordernum = $row['OrderNum'];
        $product_id = $row['product_id'];
        $product_color = $row['product_color'];
        $product_size = $row['product_size'];
        $product_quantity = $row['product_quantity'];
        $date = $row['date'];
        $status = $row['status'];
        if($counter% 2 == 0)
        {
            $bg = 'rgba(50,205,50, 0.2);';   
        } else {
            $bg = ''; 
        }

        if ($status === "shipped")
        {
            $newstat = "pending";
        } else {
            $newstat = "shipped";
        }

        echo '<tr style="background-color:'.$bg.'">
                  <td>'.$ordernum.'</td>
                  <td>'.$product_id.'</td>
                  <td>'.$product_size.'</td>
                  <td>'.$product_color.'</td>
                  <td>'.$product_quantity.'</td>
                  <td>'.$date.'</td>
                  <td><select name="status" onchange="ship('.$ordernum.','.$product_id.')"><option>'.$status.'</option><option>'.$newstat.'</option</td>
              </tr>';
        $counter++;
    }
}

Here is the ajax that I put on the page where the function is being executed:

<script type="text/javascript">
function ship(order,id) {
    var xhttp = new XMLHttpRequest();
    xhttp.onreadystatechange = function() {
        if (this.readyState == 4 && this.status == 200) {
            document.getElementById("txtHint").innerHTML = this.responseText;
        }
        alert('triggered');
    };
    xhttp.open("GET", "updateStatus.php?update=false&order="+order+"&id="+id, true);
    xhttp.send();
}
</script>

Here is what I have in the updateStatus.php file:

if(isset($_GET['update']))
{
    $update = $_GET['update'];
    $id = $_GET['id'];
    $order = $_GET['order'];

    $make = "UPDATE `Purchase_Order` SET `status`='shipped' WHERE `OrderNum` = $order AND `product_id` = $id";
    $runmake = mysqli_query($con, $make);

    if($runmake)
    {
        echo "go";
    } else {
        echo "stop";
    }
}

I am very new to AJAX. Please help me to understand what I am doing wrong.


Solution

  • On this line:

    <select name="status" onchange="ship('.$ordernum.','.$product_id.')"><option>'.$status.'</option><option>'.$newstat.'</option</td>
    

    There are a few concerns.

    • You have not closed your </option> closing tag.
    • You have not written a closing </select> tag.
    • If your $ordernum or product_id values are strings they will need to be quoted or else you will generate an Uncaught ReferenceError:

    Uncaught ReferenceError: [thevalue] is not defined at HTMLSelectElement.onchange

    Here are some of my scripts and suggestions and supporting links from my comments:

    Form PHP: https://3v4l.org/D7TY9

    JSFiddle: https://jsfiddle.net/v0Lzatqh/11/

    Alternate table row color using CSS?

    Here are my pieces of advice from comments (so that I can remove my comments):

    If you don't need $update (and I don't think you do), don't declare it. If you are going to use user-supplied data in a query, you need to take security measures. For your case, I believe $id and $order are integers, so just cast them (using (int)$id and (int)$order) before building your query. If they are not, you should use prepared statements with placeholders. Declaring new variables to hold resultset data is useless ($ordernum = $row['OrderNum']); spare your code some bloat and potential points of failure by just echoing the $row variables. Where is your script failing?

    Rather than declaring a global variable, many developers will urge you to simply pass the $con variable into the function scope as a parameter like this: function showOrders($con) {

    Do you have a $con (live connection) @ updateStatus.php? You should be performing error checks in your script or at the very least checking your error logs before posting a question here. These details are required as part of a complete question and they make it much easier for us to help you. if($runmake) will only check for "no syntax errors" in the query. When trying to determine whether the database has been affected, you will need to count the affected rows after the query is deemed to be error-free.

    You should comment out or delete $getOrders = "SELECT * FROM Purchase_Order"; $rungetOrders = mysqli_query($con, $getOrders); because those lines are overwritten/not used. Unless you have a compelling need for the distinction in your database table structure, I would remove the product_ prefix from your columns to make your code more concise.

    You won't need <form> tags if you are only performing ajax operations on the tabular data.