AndyPet74 AndyPet74 - 7 months ago 13
Javascript Question

Allow editing of Text dynamic php table

So basically I have a html table that is generated VIA PHP and data in a database, what I want to do is have a button in the last cell of each row that says edit and when you click that button the text in the other cells becomes textboxes or other types of input fields so that you can edit them and then press submit which would send that form off to be updated in the database. The code I have right now to generate the table is:

<table style="width:100%; " class = "table table-striped table-bordered table-hover">
<tr>
<th>Name</th>
<th>Status</th>
<th>Description</th>
<?php
if($_SESSION['editGroup'] != 0){
echo "<th>Edit</th>";
}
?>
</tr>
<?php
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$checkQuery = "SELECT userGiven, userStatus, userDesc FROM user_Status WHERE organization = 'myOrg' ORDER BY userGiven ASC";
$prepared = $dbh->prepare($checkQuery);
$prepared->execute();
$data = $prepared->fetchAll(PDO::FETCH_ASSOC);
foreach($data as $row){
echo "<tr>";
if($_SESSION['editGroup'] != 0){
echo "<td width='20%'>" . $row['userGiven'] . "</td><td width='10%'>" . $row['userStatus'] . "</td><td width='70%'>" . $row['userDesc'] . "</td><td width='10%'><button type='button' class='btn btn-info'>Edit</button></td>";
}else{
echo "<td width='20%'>" . $row['userGiven'] . "</td><td width='15%'>" . $row['userStatus'] . "</td><td width='75%'>" . $row['userDesc'] . "</td>";
}
echo "</tr>";
}
?>
</table>


What I am trying to do is change the cell with userStatus to a drop down field with the current value as the starting value and the other value in/out as the other value to select between.

I also want to change the userDesc to a textarea and I think I know how to do all this but I am running into a problem conceptually when I try to apply it to the dynamic table.

What I was thinking was that I could use jquery/javascript to get the innerhtml of span variable that could surround those two cells and then change the html to the various input fields containing the current text allowing the user editing them to change those values.

How do I do this for this sort of problem though, I would need onClick events for all the buttons and I wouldn't know how many buttons there would be, that's based off of the number of rows in the table.

That would result in hundreds of lines of redundant code so I assume there has to be a much better way. Anyone know what a way to accomplish this? I found this:
http://stackoverflow.com/questions/16202723/how-to-edit-data-onclick
which is close to what I want but that seems to be static values where I want to be able to do this for any of the rows in the table.

Answer

In your for loop, you'll want to put something identifiable in the <tr> and <td> elements. I'd personally go with a data-attribute. For example:

foreach($data as $row){
  echo "<tr data-row='{$row[id]}'>";
  if($_SESSION['editGroup'] != 0){
     echo "<td width='20%' data-column='name'>" . $row['userGiven'] . "</td><td width='10%' data-column='status'>" . $row['userStatus'] . "</td><td width='70%' data-column='description'>" . $row['userDesc'] . "</td><td width='10%'><button type='button' class='btn btn-info'>Edit</button></td>";
  }else{
     echo "<td width='20%'>" . $row['userGiven'] . "</td><td width='15%'>" . $row['userStatus'] . "</td><td width='75%'>" . $row['userDesc'] . "</td>";
  }
  echo "</tr>";             
}

So, as you can see I've added a data-row attribute to <tr> which should get the value of the database record's ID. Change it as necessary - I made the assumption it'd be named 'id'. Also, I added the data-column attribute to <td> which should identify each column for us. This is all the modification needed in the PHP.

Now, here's what the JQuery for the edit button looks like:

$( function(){

    $(document).on("click", ".btn-info", function(){

        var parent = $(this).closest("tr");
        var id = $(parent).attr("data-row");
        var name = $(parent).children("[data-column='name']");
        var status = $(parent).children("[data-column='status']");
        var desc = $(parent).children("[data-column='description']");
        var nameTxt = $(name).html();
        var statusTxt = $(status).html();
        var descTxt = $(desc).html();

        $(name).html("<input name='name' data-column='name' value='" + nameTxt + "'>");
        $(status).html("<input name='status' data-column='status' value='" + statusTxt + "'>");
        $(desc).html("<textarea name='desc' data-column='description'>" + descTxt + "</textarea>");

        $(this).replaceWith("<button class='btn-info-save' value='save'>");
    }

}

Finally, we need to define what happens upon hitting save (the above example changes the "edit" button into a "save" button). That could be anything, but we'll assume it'll be an AJAX call:

$( function(){

    $(document).on("click", ".btn-info-save", function(){

        var parent = $(this).closest("tr");
        var id = $(parent).attr("data-row");
        var name = $(parent).children("[data-column='name']");
        var status = $(parent).children("[data-column='status']");
        var desc = $(parent).children("[data-column='description']");
        var nameTxt = $(name).val();
        var statusTxt = $(status).val();
        var descTxt = $(desc).val();

        var data = {data_name: nameTxt, data_status: statusTxt, data_description: descTxt};

        $.ajax({
            url: "/dynamic-edit/edit.php", // Change this to your PHP update script!
            type: 'POST',
            dataType: 'json',
            data: data,
            success: function(ret){
                //Do Something
               },
            error: function(ret){
                console.log(ret.error);
               }
        });

    }

}

Now, in your PHP script that handles the AJAX request:

$name = $_POST['data_name'];
$status = $_POST['data_status'];
$description = $_POST['data_description'];

// Do whatever with the data

This is a very simple example, but it gets the point across. Be sure to change the AJAX url from "/dynamic-edit/edit.php" to wherever you'll make your PHP script that will actually make the updates after submitting.

You'll likely want to do cleanup after a successful edit; for example, changing the text boxes back to just text in a <td>. Also, please note that I just changed them to textboxes. I know you said in your post you wanted to make one the status a dropdown and the description a textarea, but this example should be easy enough to change. I don't know what the values of the dropdown should be, so you'll have to do that part.

Notes

I went with $(document).on("click" ... instead of $(".btn-info").on("click" ... because whenever you're dealing with dynamic content, you always want the event listener on the document, not the element. Why? Because if you click the "edit" button, it disappears and a "save" button appears, you now lose that event listener forever. If you were to re-add the "edit" button (say, after a successful save), that button would need the event listener added again. When you go the route of attaching the event listener to the document, however, you can remove/add all you want and it'll still work.

Comments