appending data from loop php

I’m having an issue appending data from loop. I am trying to append the result that is clicked on, but when theres multiple results every result is appended on click. I am using ajax to retrieve search results. Below is my php section. I think the issue is that every result has the same class so it appends every one, but I can’t figure out how to identify only one

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

include_once "connect.php";

$con = getConnection();
$search = "%{$_POST['inviteSearch']}%";

$query = "SELECT FirstName,LastName FROM `Profiles` WHERE FirstName LIKE ? OR LastName LIKE ? ";
$stmt = $con->prepare($query);
$stmt->bind_param("ss", $search ,$search);

if(!($stmt->execute())) {

    die(mysql_error());    

} else {

    $result = $stmt->get_result();

    $output = '<ol>';
    if(mysqli_num_rows($result) > 0) {
        while($row = mysqli_fetch_assoc($result)){

            $name = $row['FirstName'] . " " . $row['LastName'];

            $output .= "
            <li id='invitetoken'>

            <p>$name</p>

            </li>
            <script>
            $(document).ready(function(){
                $('#invitetoken').click(function(){
                    $('.invitedSection').show();
                    $('.invitedList').append('<li><p>$name</p><button>&times;</button></li>');
                });
            });
            </script>

            ";

        }
    } else {
        $output .= "<h3>We could not find $search</h3>";
    }
    $output .= '</ol>';
    echo "$output";

}
}

To start with the obvious, please use parameterized queries you are currently vulnerable to SQL injection attacks.

You are appending the same js repeatedly in your while loop, that is generally bad practice. I’m going to break this up a bit, since you have both php and JS issues

PHP

Here just generally cleaning up and using parameterized queries and class based mysqli (in line with the above suggestion comments). I also moved the javascript out of the loop as repeating it over and over doesn’t achieve anything. Obviously haven’t tested my changes but they are fairly boilerplate (see the docs)

if (!isset($_POST[''inviteSearch']) {
  return;
}

$connection = new mysqli('host', 'user', 'password', 'schema');
$param = filter_input(INPUT_POST, 'inviteSearch', FILTER_SANITIZE_STRING);

// setup query
$query = "SELECT CONCAT(FirstName, ' ', LastName) AS name
  FROM Profiles
  WHERE (FirstName LIKE ? OR LastName LIKE ?)";

// prepare statement
$stmt = $connection->prepare($query);
// need variable bind for each tokenized parameter
$stmt->bind_param('ss', $param, $param); 
$stmt->execute();
$results = $stmt->get_result();

$output = makeOutput($results);

// Siloing your presentational elements for clarity.
function makeOutput($results) {
  if ($results->num_rows === 0) {
    return "<h3>We could not find $search</h3>";
  }

  $output = '<ol>';
  while ($row = $results->fetch_assoc()) {
    $output .= "<li class='invitetoken'><p>{$row['name']}</p></li>";
  }
  $output .= '</ol>';

  return $output;
}

JavaScript

A few things here, enclosed the function into an IIFE to keep it namespace contained, generally a good practice. The changes to the click handler let the callback handle the update dynamically for any matching class that is clicked. I reference this (in this case it is helpful to think of this as event.target) and use it to find the name to be appended. from there it is pretty similar to what you already had. Of note, I’m using let for variable definitions and template literal syntax for the string data, but you should look up their availability and decide whether you need to worry about old browser support :).

(function($) {
  $(document).ready(function(){
    $('.invitetoken').on('click', function() {
      let name = $(this).children('p').text()
      ,   string = `<li><p>${name}</p><button>&times;</button></li>`;

      $('.invitedSection').show();
      $('.invitedList').append(string);
    });
  });
})(jQuery);