0

I have a form which lists a number of items from a mysql database table. Each of the items is a unique entry in the table thus has a unique id. I'd like to update all rows in the db table at a go; based on the value of each input field in the form. Here is how I'm trying to do it but for some reason, only the last value in the array seems to work.

The form

  <form action="" method="POST">
    <div class="mb-2">
    </div>
    <div class="mt-1">
      <span class="ml-4 text-right" id="submitComponent"></span>
    </div>
    <table class="table table-bordered table-responsive table-hover table-sm rounded-3 mt-4 mb-5">
      <thead class="table-dark text-white mb-3 p-5">
        <!-- <th></th> -->
        <th class="d-flex justify-content-between fs-6"><span id="title">Client Categories</span>
          <span class="btn btn-primary btn-sm" data-bs-toggle="modal" data-bs-target="#addClientCatModal" type="button">
            <strong>Add New</strong></span>
        </th>
      </thead>
      <tbody>
        <?php foreach ($result as $row) : ?>
          <tr>
            <td class="center" type="button" onclick="editFileCat()">
              <input class="cat-input border-0 p-2 col-12 rounded" name="cat" value="<?php echo $row["cat"]; ?>" readonly></input>
              <!-- <input id="hidden_cat" type="hidden" name="cat_id" value="<?php echo $row["cat_id"]; ?>"> -->
              <input type="hidden" name="cats_array[]" value="<?= $row["cat"] ?>">
              <input type="hidden" name="cat_ids_array[]" value="<?= $row["cat_id"] ?>">
            </td>
          </tr>
        <?php endforeach; ?>
      </tbody>
    </table>
  </form>

The event-triggered (onclick) javascript function works alright by removing readonly attribute in all input fields in the filed, which is what is desired.

Update script

if ($_SERVER["REQUEST_METHOD"] == "POST") {


  if (isset($_POST['cat_ids_array'])) {

    $categories_array = $_POST["cats_array"];

    $cat_ids_array = $_POST["cat_ids_array"];
    foreach ($categories_array as $category) {
      foreach ($cat_ids_array as $item) {
        $sql = "UPDATE client_cats SET cat = '$category' WHERE cat_id = '$item' ";
        if ($mysqli->query($sql) === true) {
          echo "<script>setTimeout(\"location.replace('');\",1500);</script>";
        } else {
          echo "ERROR: Unable to execute $sql. " . $mysqli->error;
        }
        unset($item);
      }
      unset($cat);
    }
  }
}

NB: Yes, the code is vulnerable but all I'm trying right now is something that works, above everything else. I'll improve its security much later.

cal ibra
  • 49
  • 8
  • You shouldn't be using nested loops, use something like https://stackoverflow.com/questions/4480803/two-arrays-in-foreach-loop so that it combines the values from both arrays in the same loop. – Nigel Ren Apr 25 '21 at 07:10
  • That worked. Thanks for pointing me in the right direction! I also had an error in the form: the categories array was hidden meaning the code would never have worked. – cal ibra Apr 25 '21 at 07:40
  • @NigelRen no conceptual problems with nested loops. It is quite natural. @cal-ibra - this code is full of unnecessary details, first of all separate your presentation from your models - then you can test what is sent from the server and how your update code works. Because now you are asking to debug your ugly code someone else, and that's no fun. And try removing those `unset`'s in loops. – dmitry Apr 25 '21 at 07:40
  • @dmitry, the comment was related to the current problem and not a general thing about nested loops. – Nigel Ren Apr 25 '21 at 07:42
  • @dmitry Sure. I'll improve the code for readability. For now the problem at hand's solved. – cal ibra Apr 25 '21 at 07:45

0 Answers0