0

I have hound_view.php which displays the records based on search/filter criteria. When a user clicks on a row, a modal is displayed with a form for editing the hound info, which I want to be pre-populated based on the row that was clicked.

When a row in hound_view.php is clicked hound_record_click_event.js sends it's data-id to fill_hound_records.php where the database is queried and each row of data is assigned a variable to then pass to the modal in edit_hound_records.php

My issue is that when I click on any row, I am only getting the very first row's data to populate, but in fill_hound_records.php I echo back the variable to be sure each row is capturing its correct info and it is.

visualized error

Please Note: This code is vulnerable to SQL injection attacks and should not be copied directly. You should use mysqli or PDO prepared statements with bound parameters as described in this post.

hound_view.php

  <tbody class="clickable-row" data-toggle="modal" data-target="#editModal" data-id="<?php echo $row['RegNumber'] ?>"> 

hound_record_click_event.js

 $(window).ready(function() {
      //bind the event using jquery not the onclick attribute of the button
      $('.clickable-row').on('click', updateClick);
 });

 function updateClick() {
  var dataid = $(this).data("id");
  $.ajax ({
         type: 'POST',
         url: "fill_hound_record.php",
         data: { dataid : dataid },
         success: function( result ) {
                alert(result);
         }
     });
 };

fill_hound_record.php

<?php
//include database configuration file
include('db.php');

$hounddataid = $_POST["dataid"];

//get rows
$prefillsql = "SELECT * FROM Hounds WHERE RegNumber = '$hounddataid'";
$prefillquery = mysqli_query($con,$prefillsql)or die(mysql_error());
$prefillnumrows = mysqli_num_rows($prefillquery);

if($prefillnumrows > 0){

  while($row = mysqli_fetch_array($prefillquery)){

    $prefillbreed = $row['Breed'];
    $_SESSION['pfbreed'] = $prefillbreed;
    $prefillregnumber = $row['RegNumber'];
    $_SESSION['pfregnumber'] = $prefillregnumber;

    echo $_SESSION['pfregnumber'];
}}
?>

edit_hound_record.php

  <input type="text" class="form-control" id="regnumber" name="regnumber" placeholder="Reg Number" value="<?php echo $_SESSION['pfregnumber']; ?>">
  • 2
    Your code is vulnerable to [**SQL injection**](https://en.wikipedia.org/wiki/SQL_injection) attacks. You should use [**mysqli**](https://secure.php.net/manual/en/mysqli.prepare.php) or [**PDO**](https://secure.php.net/manual/en/pdo.prepared-statements.php) prepared statements with bound parameters as described in [**this post**](https://stackoverflow.com/questions/60174/how-can-i-prevent-sql-injection-in-php). – Alex Howansky May 17 '17 at 18:33
  • Thanks Alex, I am aware and plan on going back to correct this as this is my first production scale mysql/php project and am learning much as I go. – Tyler S. Smith May 17 '17 at 18:35
  • _"plan on going back"_ Don't get into the bad habit of thinking that. Write it correctly from the start, it's not like it takes any additional effort. – Alex Howansky May 17 '17 at 18:55
  • Though I agree, I didn't initially have knowledge or I would have done it in the first place, hence why I said I plan on going back. – Tyler S. Smith May 17 '17 at 19:02

4 Answers4

1

Because there is no info about boostrap version and if the table is generated with a plugin or not, I would suggest you to change this line:

<tbody class="clickable-row" data-toggle="modal" data-target="#editModal" data-id="<?php echo $row['RegNumber'] ?>"> 

with:

<tbody class="clickable-row" data-toggle="modal" data-target="#editModal">

The data-id is the current second cell text of clicked row. In order to get this value you can use:

$(e.target).closest('tr').find('td:eq(1)').text()

$(window).ready(function () {
    //bind the event using jquery not the onclick attribute of the button
    $('.clickable-row').on('click', updateClick);
});

function updateClick(e) {
    var dataid = $(e.target).closest('tr').find('td:eq(1)').text();
    $.ajax({
                type: 'POST',
                url: "fill_hound_record.php",
                data: {dataid: dataid},
                success: function (result) {
                    alert(result);
                },
                error: function () {
                    $('#editModal').find('.modal-body p').text(dataid);
                }
            }
    );
}
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<script src="https://code.jquery.com/jquery-2.1.1.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>


<table class="table table-bordered">
    <thead>
    <tr>
        <th>Breed</th>
        <th>Reg Number</th>
        <th>Call Name</th>
        <th>Reg Name</th>
    </tr>
    </thead>
    <tbody class="clickable-row" data-toggle="modal" data-target="#editModal">
    <tr>
        <td>AH</td>
        <td>024193</td>
        <td>Nia</td>
        <td>Dog</td>
    </tr>
    <tr>
        <td>AH</td>
        <td>022222</td>
        <td>Nia</td>
        <td>Dog</td>
    </tr>
    </tbody>
</table>

<div class="modal fade" tabindex="-1" role="dialog" id="editModal">
    <div class="modal-dialog" role="document">
        <div class="modal-content">
            <div class="modal-header">
                <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span
                        aria-hidden="true">&times;</span></button>
                <h4 class="modal-title">Modal title</h4>
            </div>
            <div class="modal-body">
                <p>One fine body&hellip;</p>
            </div>
            <div class="modal-footer">
                <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
            </div>
        </div>
    </div>
</div>
gaetanoM
  • 41,594
  • 6
  • 42
  • 61
  • This feels cleaner and will use, but I am still at the same exact point. Alert shows correct id for each row which is echoed in **fill_hound_record.php**, but when assigned to session variable and called in **edit_hound_records.php** it only returns that first rows id in the RegNumber field. – Tyler S. Smith May 17 '17 at 19:22
  • @TylerS.Smith Because alert print the correct value you need to set this value in the corresponding field: $('#regnumber').val(result). I created only a demo in order to help you. I hope this could help you more. Let me know. Thanks – gaetanoM May 17 '17 at 19:28
  • @TylerS.Smith Like you can see I added a modal fragment at the end, instead you create it in PHP. The final html page should be similar. – gaetanoM May 17 '17 at 19:30
  • How would I target the input field #regnumber if it goes php1 to js to php2 to php3 where php3 holds the modal. – Tyler S. Smith May 17 '17 at 19:50
  • @TylerS.Smith How do you show the modal? I assume with your data-target="#editModal". If you do it in a different way you can use the modal events: [show.bs.modal](http://getbootstrap.com/javascript/#modals-events). I hope this will help you. – gaetanoM May 17 '17 at 19:53
  • Yes, with data-target on tbody. – Tyler S. Smith May 17 '17 at 19:55
1

For anybody else with a similar problem; In fill_hound_record.php I added an if statement before the $hounddataid variable so I don't receive an undefined index before a row is clicked.

if (isset($_POST["dataid"])) { 
  $hounddataid = $_POST["dataid"];
  ...
  }

I removed the value attribute in edit_hound_record.php and in fill_hound_record.php I created an array of all the values I will need for populating the form and encoded in json.

$arr = array(
  'breed'=>$prefillbreed,
   ...
   );

echo json_encode($arr);
exit();

Finally I added

dataType: 'json',
 success: function( data ) {
    $("#breed").val(data.breed);
    ...
    }

to my hound_record_click_event.js which sends the selected json array value data.breed to the field in the form with an id of breed.

0

First, I think your <tbody> is meant to be a table row <tr>

<tbody class="clickable-row" data-toggle="modal" data-target="#editModal" data-id="<?php echo $row['RegNumber'] ?>"> 

Second, in your JS, you want to get the data-id:

 $(this).attr("data-id") // will return the string "123"

or .data() (if you use newer jQuery >= 1.4.3)

$(this).data("id") // will return the number 123
Woodrow
  • 2,740
  • 1
  • 14
  • 18
  • tbody and tr have the same results, tbody could technically be omitted if attributes were moved to tr. And $(this).data("id") is assigned to var dataid. The data-id is correct all the way through when echoing back from fill_hound_record.php, but when it comes to actually filling the form it only populates the first rows data-id. – Tyler S. Smith May 17 '17 at 18:46
  • Okay, can you post some sample HTML table rows from the DOM after the PHP has rendered the ID's etc? – Woodrow May 17 '17 at 18:47
0

Error in your java script. Change

    $(this).data ('id') to $(this).attr ('id')
CoderSam
  • 179
  • 1
  • 5