article

Friday, December 2, 2022

React Autocomplete Search with PHP Mysql

React Autocomplete Search with PHP Mysql

Create Project
C:\react>npx create-react-app demo-project

Run
C:\react\my-app> npm start

Install React Router Dom
https://www.npmjs.com/package/react-router-dom
C:\react\my-app>npm i react-router-dom --save

Install Axios
https://www.npmjs.com/package/axios
C:\react\my-app>npm install axios --save


C:\react\demo-project\src\App.js
//C:\react\demo-project\src\App.j
import React from 'react'

import "./App.css";
import { useEffect, useRef, useState } from "react";
import axios from "axios";

const App = () => {
  // fetching data
  const [users, setusers] = useState([]);

  const fetchUsers = async () => {
    const response = await axios.get(
      //"https://jsonplaceholder.typicode.com/users"
      "http://localhost/react/api/"
    );
    setusers(response.data);
  };
  useEffect(() => {
    fetchUsers();
  }, []);

  // filter users

  const [filtered, setfiltered] = useState([]);
  const [search, setsearch] = useState("");

  const searchRef = useRef();

  useEffect(() => {
    setfiltered(
      users.filter((item) =>
        item.name.toLowerCase().includes(search.toLowerCase())
      )
    );
  }, [search]);

  return (
    <div className="app">
        <div className="searchbox">
		<form className="form-wrapper">
          <input
            type="text"
			id="search"
            placeholder="Search for..."
            onChange={(e) => setsearch(e.target.value)}
            ref={searchRef}
          />
		  <input type="submit" value="go" id="submit"/>
		</form>
		
        {search.length > 0 && (
          <div className="dropdown">
            {filtered.length > 0 ? (
              filtered.map((item, index) => {
                return (
                  <div
                    className="card"
                    key={index}
                    onClick={(e) => {
                      searchRef.current.value = item.name;
                      setsearch("");
                    }}>
                    <p>{item.name}</p>
                  </div>
                );
              })
            ) : (
              <p>no match</p>
            )}
          </div>
        )}
		</div>
    </div>
  );
};

export default App;
C:\react\demo-project\src\App.css
//C:\react\demo-project\src\App.css
.app {
	width:100%;

}
.searchbox {
  width: 450px;
  border-radius: 16px;margin:100px;
}
input {
  border: none;
  outline: none;
  background-color: transparent;
}
.dropdown {
  display: flex;background-color: #f6f6f6;
  flex-direction: column;text-align:left;
}
.card {
  padding: 0 8px;
}
.card:hover {
  background: rgb(211, 210, 210);
}

body {
  background: #eee;
  font: 12px Lucida sans, Arial, Helvetica, sans-serif;
  color: #333;
  text-align: center;
}

a {
  color: #2A679F;
}
/*========*/

.form-wrapper {
  background-color: #f6f6f6;
  background-image: -webkit-gradient(linear, left top, left bottom, from(#f6f6f6), to(#eae8e8));
  background-image: -webkit-linear-gradient(top, #f6f6f6, #eae8e8);
  background-image: -moz-linear-gradient(top, #f6f6f6, #eae8e8);
  background-image: -ms-linear-gradient(top, #f6f6f6, #eae8e8);
  background-image: -o-linear-gradient(top, #f6f6f6, #eae8e8);
  background-image: linear-gradient(top, #f6f6f6, #eae8e8);
  border-color: #dedede #bababa #aaa #bababa;
  border-style: solid;
  border-width: 1px;
  -webkit-border-radius: 10px;
  -moz-border-radius: 10px;
  border-radius: 10px;
  -webkit-box-shadow: 0 3px 3px rgba(255,255,255,.1), 0 3px 0 #bbb, 0 4px 0 #aaa, 0 5px 5px #444;
  -moz-box-shadow: 0 3px 3px rgba(255,255,255,.1), 0 3px 0 #bbb, 0 4px 0 #aaa, 0 5px 5px #444;
  box-shadow: 0 3px 3px rgba(255,255,255,.1), 0 3px 0 #bbb, 0 4px 0 #aaa, 0 5px 5px #444;
  overflow: hidden;
  padding: 8px;
  width: 450px;
}

.form-wrapper #search {
  border: 1px solid #CCC;
  -webkit-box-shadow: 0 1px 1px #ddd inset, 0 1px 0 #FFF;
  -moz-box-shadow: 0 1px 1px #ddd inset, 0 1px 0 #FFF;
  box-shadow: 0 1px 1px #ddd inset, 0 1px 0 #FFF;
  -webkit-border-radius: 3px;
  -moz-border-radius: 3px;
  border-radius: 3px;
  color: #999;
  float: left;
  font: 16px Lucida Sans, Trebuchet MS, Tahoma, sans-serif;
  height: 20px;
  padding: 10px;
  width: 320px;
}

.form-wrapper #search:focus {
  border-color: #aaa;
  -webkit-box-shadow: 0 1px 1px #bbb inset;
  -moz-box-shadow: 0 1px 1px #bbb inset;
  box-shadow: 0 1px 1px #bbb inset;
  outline: 0;
}

.form-wrapper #search:-moz-placeholder,
.form-wrapper #search:-ms-input-placeholder,
.form-wrapper #search::-webkit-input-placeholder {
  color: #999;
  font-weight: normal;
}

.form-wrapper #submit {
  background-color: #0483a0;
  background-image: -webkit-gradient(linear, left top, left bottom, from(#31b2c3), to(#0483a0));
  background-image: -webkit-linear-gradient(top, #31b2c3, #0483a0);
  background-image: -moz-linear-gradient(top, #31b2c3, #0483a0);
  background-image: -ms-linear-gradient(top, #31b2c3, #0483a0);
  background-image: -o-linear-gradient(top, #31b2c3, #0483a0);
  background-image: linear-gradient(top, #31b2c3, #0483a0);
  border: 1px solid #00748f;
  -moz-border-radius: 3px;
  -webkit-border-radius: 3px;
  border-radius: 3px;
  -webkit-box-shadow: 0 1px 0 rgba(255, 255, 255, 0.3) inset, 0 1px 0 #FFF;
  -moz-box-shadow: 0 1px 0 rgba(255, 255, 255, 0.3) inset, 0 1px 0 #FFF;
  box-shadow: 0 1px 0 rgba(255, 255, 255, 0.3) inset, 0 1px 0 #FFF;
  color: #fafafa;
  cursor: pointer;
  height: 42px;
  float: right;
  font: 15px Arial, Helvetica;
  padding: 0;
  text-transform: uppercase;
  text-shadow: 0 1px 0 rgba(0, 0 ,0, .3);
  width: 100px;
}

.form-wrapper #submit:hover,
.form-wrapper #submit:focus {
  background-color: #31b2c3;
  background-image: -webkit-gradient(linear, left top, left bottom, from(#0483a0), to(#31b2c3));
  background-image: -webkit-linear-gradient(top, #0483a0, #31b2c3);
  background-image: -moz-linear-gradient(top, #0483a0, #31b2c3);
  background-image: -ms-linear-gradient(top, #0483a0, #31b2c3);
  background-image: -o-linear-gradient(top, #0483a0, #31b2c3);
  background-image: linear-gradient(top, #0483a0, #31b2c3);
}

.form-wrapper #submit:active {
  -webkit-box-shadow: 0 1px 4px rgba(0, 0, 0, 0.5) inset;
  -moz-box-shadow: 0 1px 4px rgba(0, 0, 0, 0.5) inset;
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.5) inset;
  outline: 0;
}

.form-wrapper #submit::-moz-focus-inner {
  border: 0;
}
C:\xampp\htdocs\react\api\index.php
//C:\xampp\htdocs\react\api\index.php
<?php
error_reporting(E_ALL);
ini_set('display_errors', 1);
header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Headers: *");
header("Access-Control-Allow-Methods: *");

include 'DbConnect.php';
$objDb = new DbConnect;
$conn = $objDb->connect();

$method = $_SERVER['REQUEST_METHOD'];
switch($method) {
    case "GET":
        $sql = "SELECT * FROM users";
        $stmt = $conn->prepare($sql);
        $stmt->execute();
        $users = $stmt->fetchAll(PDO::FETCH_ASSOC);

        echo json_encode($users);
        break;
}
C:\xampp\htdocs\react\api\DbConnect.php
//C:\xampp\htdocs\react\api\DbConnect.php
<?php
    class DbConnect {
        private $server = 'localhost';
        private $dbname = 'reactDB';
        private $user = 'root';
        private $pass = '';
 
        public function connect() {
            try {
                $conn = new PDO('mysql:host=' .$this->server .';dbname=' . $this->dbname, $this->user, $this->pass);
                $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
                return $conn;
            } catch (\Exception $e) {
                echo "Database Error: " . $e->getMessage();
            }
        }
         
    }
?>
Run C:\react\my-app>npm start

Related Post