2

I have a challenge with a project i'm working on and have tried all i could to get it working without success. Any assistance will be appreciated please. I built an HTML/Bootstrap form whose fields value are sent to mysql database with ajax function and displays the updated database on the page without refreshing the page, the part which works fine. Each row has a delete button. However, when I delete any of the displayed rows, only the first row I click gets deleted and the updated database displays. Subsequent attempts to delete any other row doesn’t work, until the page is reloaded and the process is repeated then only the first delete operation works again. My challenge is to get the delete button delete a row, fetch and display the updated database immediately without having to refresh the page. Here is my ajax call:

var pry= $("#pry").val();
var sec  = $("#sec").val();
var coll = $("#coll ").val();
var urlId = window.location.search.substring(1);    
var pageId = urlId.split('=')[1];

//Insert into DB
$.ajax({
url: "process.php",
type: "POST",
async: false,
data:
  {
   "done": 1,   
   "pry": pry,  
   "sec": sec,                                      
   "coll": coll,
   "page_id": pageId
   },                                           
    success: function(){
         displayFromDb();   
         clearInputs();
    }
});

//delete from db
$(".my_butn").on("click", function(e){
    e.preventDefault();
    var id = $(this).attr("id");

$.ajax({
    type: "POST",
    url: "delete.php",
    async: false,
    data:
       {                                         
        "pry": pry, 
        "sec": sec,                                     
        "coll": coll,
        "page_id": pageId,
        “id”: id
       },
         success: function(){
           displayFromDb();
         }
      });
    });

//function displayFromDb
     function displayFromDb(){
       $.ajax({
          type: "POST",
          url: "process.php",
          async: false,
          data:
             {                                                                                                                                                        
              "display": 1,                                             
              "page_id": pageId
             },
          success: function(d){                                                                                                              
                $("#tab-display").fadeIn().html(d);
          }
       });
    }

//process.php file
<?php
//Insert to  sql    
  if (isset($_POST["done"])){
    $conn = mysqli_connect('localhost', 'root', '', 'educ');
    $student_id = mysqli_real_escape_string($conn, $_POST['page_id']);
    $pry = mysqli_real_escape_string($conn, $_POST["pry"]);
    $sec = mysqli_real_escape_string($conn, $_POST["sec"]);
    $coll = mysqli_real_escape_string($conn, $_POST["coll"]);

    $sql = mysqli_query($conn, "INSERT INTO students (id, student _id, pry, sec, coll) VALUES (' ', '$student_id ', '$pry', '$sec', '$coll')");
}

//display from sql  
if (isset($_POST['display'])){
    $i=1;
    $sql2 = mysqli_query($conn, "SELECT id, pry, sec, coll FROM students WHERE student_id = '$student_id");
    if ($sql2){
        echo '<table class="table table-striped table-bordered"><thead><tr><th>S/N</th><th>ID</th><th>PRY EDUC</th><th>SEC EDUC</th><th>COLL EDUC</th><th>DEL ROW</th></tr></thead>';

    while ($row = mysqli_fetch_array($sql2, MYSQLI_ASSOC)){
        $id = $row['id'];
        $pry = $row['pry']; 
        $sec = $row['sec'];
        $coll = $row['coll'];
$del = "<button type='button' class='btn btn-danger' id='$id'> X</button>";
echo '<tbody><tr><td>'.$i.'</td><td>'.$id.'</td><td>'.$pry.'</td><td>'.$sec.'</td><td>'.$coll.'</td><td>'.$del.'</td></tr></tbody>';
        $i++;
        }
        echo '</table>';
        }
    }?>

And my delete.php file here

  <?php
        $conn = mysqli_connect('localhost', 'root', '', 'educ');
        $student_id = mysqli_real_escape_string($conn, $_POST['page_id']);
        $pry = mysqli_real_escape_string($conn, $_POST["pry"]);
        $sec = mysqli_real_escape_string($conn, $_POST["sec"]);
        $coll = mysqli_real_escape_string($conn, $_POST["coll"]);
        $id =  $_POST["id"];

        $sql = mysqli_query($conn, "DELETE FROM students WHERE id = '$id' ");
    }
?>
banky
  • 838
  • 2
  • 13
  • 26
  • 1
    your delete query contains a tick; that alone would throw an error and there's a stray brace. – Funk Forty Niner Mar 14 '17 at 22:48
  • thanks @Fred-ii-.Original query doesnt contain that error, it happened while copying my code here. – banky Mar 14 '17 at 22:53
  • Using `async: false` in an AJAX request is not a good idea for various reasons - please see this [post](http://stackoverflow.com/q/28680897/2298301). – Dhruv Saxena Mar 14 '17 at 22:55
  • thanks @ Dhruv. But can that be the reason for this issue i'm having? What appropriate change will i have to make to remove the async: false please? – banky Mar 14 '17 at 23:06

1 Answers1

1

A simplistic approach....

Change 1:
In delete.php, you could add the following code after executing the DELETE query:

echo mysqli_affected_rows($conn); 
die;

This means that the AJAX call would receive whatever is echoed value. Now, mysqli_affected_rows() would return 0 if no rows were deleted or -1 if there was an error, which can be checked in the success section of $.ajax() to relay the appropriate messages to the user.

Once you've checked that the number of deleted rows is > 0, the <tr> corresponding to the button can then be removed safely. Please check the following code snippet which might be of some help in achieving this. You'd just need to wrap this code inside success : function(delete_count){ .... }

Change 2:

$(".my-del-btn").on("click", function(){
  // AJAX call, success: function(delete_count)
  //if(delete_count > 0){
      $(this).parents().closest("tr").fadeOut(1000)
      .promise().done(function(){
          $(this).parents().closest("tr").remove();
      });
  //}
  //else{
  //    console.log("Error in deleting id = " + id);
  //}

});
<head>
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.0.0/css/bootstrap.css" 
      rel="stylesheet" type="text/css">

<link href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/3.5.2/animate.min.css" 
      rel="stylesheet" type="text/css">

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.0.0/js/bootstrap.min.js"></script>
</head>
<body>
<table class="table table-striped table-bordered">
  <thead>
    <tr>
      <th>ID</th>
      <th>DEL ROW</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td> 1 </td>
      <td> 
          <button type='button' class='btn btn-danger my-del-btn'>DELETE</button> 
      </td>
    </tr>
    <tr>
      <td> 2 </td>
      <td> 
          <button type='button' class='btn btn-danger my-del-btn'>DELETE</button> 
      </td>
    </tr>
    <tr>
      <td> 3 </td>
      <td> 
          <button type='button' class='btn btn-danger my-del-btn'>DELETE</button> 
      </td>
    </tr>
</table>
</body>

A few important notes:

  • As the post linked in the comments above would indicate, having async: false is, in a way, detrimental to the application (besides it being deprecated in jQuery 1.8 onwards).

  • Please take a look at and consider implementing MySQLi Prepared Statements to secure your PHP code from SQL Injection Attacks.

Community
  • 1
  • 1
Dhruv Saxena
  • 1,336
  • 2
  • 12
  • 29
  • Thanks so much @Dhuv Saxena. I appreciate your time. I implemented your code just the way you suggested but things are exactly the way they were. I mean, after entering values, it displays an updated database fine. Then my first delete operation works and shows an updated database, however, subsequent deletes doesn't work, until i reload the page, add another row and then i can only delete just one row again. – banky Mar 15 '17 at 07:51
  • @banky May I ask what's the specific error with the second delete? Does it show anything in the console? If not, are you somehow recreating the whole table after entering new data in the database? (In which case it is possible that the buttons that the `click` event was bound to got removed from the DOM and the newer ones weren't mapped again). There's a possible fix for this too, but it'd be helpful to know a bit more about the error, please. – Dhruv Saxena Mar 15 '17 at 16:19
  • Thanks for your assistance @Dhuv.I appreciate.No errors are showing on the console,just 200 OK. I'm not recreating the whole table after entering data in the forms,rather I'm creating a new tr, which has its own del button dynamically. The database then gets updated and display on the appropriate Div on d browser.The first delete attempt works fine,with the clicked tr removed.However,click on another delete button and nothing works again until the page is refreshed. – banky Mar 15 '17 at 16:27
  • I see. It's a comparable situation again. The newly added buttons in the DOM don't have the `click` event associated with them. So, if you had 5 rows in the table at first, you'd be able to carry out the deletes without page refresh for all 5 of them, but not the ones that got added afterwards. The fix should be changing `$(".my-del-btn").on("click", function(){ .... } ` to `$("body").on("click", ".my-del-btn", function(){ .... }` – Dhruv Saxena Mar 15 '17 at 16:33
  • I think the newly added buttons do have the click events associated with them.If I had 5 rows in the table,I can only delete ONE row without page refresh,not all. Then refresh the page,add another,then only one row gets deleted again. – banky Mar 15 '17 at 16:38
  • If an `alert()` was added in the code as the first statement under `on("click", function(){...})` (or with the other variant of this as suggested above), does it show up every time that the buttons - whether old or new - are clicked? If not, then it'd indicate that the associativity of the event was somehow lost or not established in the first place. If it does exist, then the next question would be to trace the REQUEST parameters in the console and find out whether the `id` is getting passed to the AJAX call. – Dhruv Saxena Mar 15 '17 at 16:49
  • Thanks so very much @Dhruv for the assistance. I really do appreciate..I'm good now – banky Mar 17 '17 at 22:35
  • @banky - Thanks for confirming - glad to know! All the very best :) – Dhruv Saxena Mar 17 '17 at 22:39
  • Thanks once again! You are the best!! – banky Mar 17 '17 at 22:45