0

I'm trying to build an autocomplete dropdown input text box using jQuery Autocomplete. I've had it working previously but now I'm building the program with OOP PHP instead of procedural PHP to keep it a bit cleaner.

I'm able to send the AJAX request and it posts to the correct file, but I'm not getting any response in return, I'm not exactly sure why. Take a look:

This is the input:

<div class="form-floating shadow" id="inputBox">
     <input type="text" class="form-control mb-4 autocomplete" id="existingCustomerSearch" name="existingCustomerSearch" placeholder="Search existing buyers (name, phone number)">
     <label for="existingCustomerSearch">Search existing customers... (name, phone number)</label>
</div>

The jquery autocomplete request:

$('#existingCustomerSearch').autocomplete({
     source: function(request, response) {
          $.ajax({
               url: '../models/Pages.php',
               type: 'POST',
               dataType: 'JSON',
               data: {
                     userInput: request.term
               },
               
               success: function(data) {
                     console.log(data);
                     response ($.map(data, function(item) {
                          return {
                             label: item.customer_id,
                             value: item.first_name
                          }
                     }))
               }

          });
     }
});

The model

if ($_SERVER['REQUEST_METHOD'] == 'POST') {
     $_POST = filter_input_array(INPUT_POST, FILTER_SANITIZE_STRING);

     if (isset($_POST['userInput'])) {
                
           $searchInput = $_POST['userInput'];

           $searchData = $this->customerModel->searchCustomer($searchInput);

           $searchData = json_encode($searchData);

           echo $searchData
     }
}

The controller

public function searchCustomer($data) {

     $this->db->query('SELECT * FROM customer WHERE last_name LIKE :last_name');

     $this->db->bind(':last_name', $data . '%');

     $results = $this->db->resultSet();

     return $results;
}

The way this should function is the user inputs some text, AJAX posts it to the model which passes the input as a parameter of the searchCustomer method and returns the data in a json format as the 'source' in the jquery autocomplete.

I think what's happening is the data is not returning correctly, I can't figure out how to get it back to the view through the ajax call. Please if anyone has any idea why this doesn't work I'd be very appreciative.

Here is the Database to answer the $this->db and query/bind questions.:

<?php
    class Database {
        private $dbHost = DB_HOST;
        private $dbUser = DB_USER;
        private $dbPass = DB_PASS;
        private $dbName = DB_NAME;

        private $statement;
        private $dbHandler;
        private $error;

        public function __construct() {
            $conn = 'mysql:host=' . $this->dbHost . ';dbname=' . $this->dbName;
            $options = array(
                PDO::ATTR_PERSISTENT => true,
                PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
            );
            try {
                $this->dbHandler = new PDO($conn, $this->dbUser, $this->dbPass, $options);
            } catch (PDOException $e) {
                $this->error = $e->getMessage();
                echo $this->error;
            }
        }

        //Allows us to write queries
        public function query($sql) {
            $this->statement = $this->dbHandler->prepare($sql);
        }

        //Bind values
        public function bind($parameter, $value, $type = null) {
            switch (is_null($type)) {
                case is_int($value):
                    $type = PDO::PARAM_INT;
                    break;
                case is_bool($value):
                    $type = PDO::PARAM_BOOL;
                    break;
                case is_null($value):
                    $type = PDO::PARAM_NULL;
                    break;
                default:
                    $type = PDO::PARAM_STR;
            }
            $this->statement->bindValue($parameter, $value, $type);
        }

        //Execute the prepared statement
        public function execute() {
            return $this->statement->execute();
        }

        //Return an array
        public function resultSet() {
            $this->execute();
            return $this->statement->fetchAll(PDO::FETCH_ASSOC);
        }

        //Return a specific row as an object
        public function single() {
            $this->execute();
            return $this->statement->fetch(PDO::FETCH_ASSOC);
        }

        //Get's the row count
        public function rowCount() {
            return $this->statement->rowCount();
        }
    }

Here is the full customer model for more clarity.. db is a private method of the customer object that deals with all database interactions... database.php (above) is where all those actions live

<?php 
    class Customer {
        private $db;
        public function __construct() {
            $this->db = new Database;
        }


        public function createCustomer($data) {
            $this->db->query('INSERT INTO customer (first_name, last_name, phone_number, phone_number_2, email, email_2, referral_type_id) VALUES (:first_name, :last_name, :phone_number, :phone_number_2, :email, :email_2, :referral_type_id)');

            //Bind values
            $this->db->bind(':first_name', $data['first_name']);
            $this->db->bind(':last_name', $data['last_name']);
            $this->db->bind(':phone_number', $data['phone_number']);
            $this->db->bind(':phone_number_2', $data['phone_number_2']);
            $this->db->bind(':email', $data['email']);
            $this->db->bind(':email_2', $data['email_2']);
            $this->db->bind(':referral_type_id', $data['referral_type_id']);

            //Execute the function
            if ($this->db->execute()) {
                return true;
            } else {
                return false;
            }
        }

        public function getCustomers() {
            $this->db->query('SELECT * FROM customer');

            $results = $this->db->resultSet();

            return $results;
        }

        public function searchCustomer($data) {

            $this->db->query('SELECT * FROM customer WHERE last_name LIKE :last_name');

            $this->db->bind(':last_name', $data . '%');

            $results = $this->db->resultSet();

            $results = json_encode($results);

            echo $results;
        }

        public function getReferralType() {
            $this->db->query('SELECT * FROM referral ORDER BY  referral_type ASC');

            $results = $this->db->resultSet();

            return $results;
        }

    }
  • 1
    You have to `echo` your data back to the browser, not `return`. Also you need to `json_encode($searchData)` your data before you echo it. Is `response()` in your jquery success a function that you have created? Try and `console.log(data)` just before to check that it was returned properly (or you could check the Response in the Network tab). – mark_b Nov 29 '21 at 17:06
  • Thanks, I've tried what you mentioned above.. response() is not a function I already made, I just edited that though. When I console.log it there is no response.. – Christopher Ansbaugh Nov 29 '21 at 22:19
  • I wouldn't recommend overwriting `$_POST`, just store the result of `filter_input_array()` in a new variable – Phil Nov 29 '21 at 22:23
  • Missing parts in this question... what is `$this->db`? What do the `query()` and `bind()` methods do? Have you made sure there's [no server-side errors](https://stackoverflow.com/q/845021/283366)? Try debugging the value of `$results` before you return it – Phil Nov 29 '21 at 22:31
  • The $this->db and query() bind() functions all work properly, query prepared the statement and bind binds the statement to params, db is my connection to the db. – Christopher Ansbaugh Nov 29 '21 at 22:34
  • How do you know they're working properly? If you're not getting a result, that's the first place I'd be checking. Also, `$this->db` is obviously some sort of class instance, not a _"connection to the db"_ so what class is it? What **exactly** does `query()` do (please show actual code)? What **exactly** does `bind()` do? Where is your prepared statement executed? – Phil Nov 29 '21 at 22:56
  • Take a look above, I posted the full customer model (queries for the database, toward the top you'll see the db) and the full database library so you can see exactly what the query() and bind() do – Christopher Ansbaugh Nov 29 '21 at 23:12
  • Keeping a transient reference to the statement in your `Database` class is just asking for trouble. That's just a design problem though, your code looks like it should work. Have you checked your error reporting settings as mentioned previously? I also note you have no error handler in your AJAX call. Try adding `error: (_, ...errors) => console.error(...errors)` to the `$.ajax()` options. You can also use your browser's dev-tools _Network_ panel to inspect requests and responses – Phil Nov 29 '21 at 23:22
  • My guess is your PHP is echo-ing something other than the JSON response which causes JSON parsing to fail. – Phil Nov 29 '21 at 23:26
  • You're correct. I find that the response now is the index page, I've got the data streaming through to there as well on the first line but it's still not populating the dropdown – Christopher Ansbaugh Nov 29 '21 at 23:29

0 Answers0