Chuyển đến nội dung chính

Tạo công cụ tìm kiếm bằng Jquery - Ajax - PHP

Hơn một năm rồi mới có dịp ngồi viết bài trên blog. Hôm này trời đẹp hơn hôm qua và việc cũng nhiều hơn hôm kia. Nhưng nó không liên quan gì đến bài viết ngày hôm nay cả!

Có một ông bạn đang cần tài liệu về tạo công cụ tìm kiếm bằng Ajax. Nên mình sẽ viết bài viết này như một tài liệu hướng dẫn làm cái chức năng này với Jquery Ajax còn server dùng PHP. Ngôn ngữ trên server là gì thì không quan trọng, quan trọng là server truy xuất được dữ liệu từ cơ sở dữ liệu theo từ khóa tìm kiếm và trả về dưới dạng Json.

Ở đoạn trên mình có đề cập tới các từ "Ajax, Jquery Ajax, Json" mấy cài này là gì thì mình không giải thích ở đây vì nó rất dài dòng. Nên để hiểu sâu hơn, ở đây mình có một vài đường link :


Chuẩn bị dữ liệu

Đầu tiên cần chuẩn bị phía server : Tạo CSDL, tạo server nhận từ khóa và trả về danh sách kết quả lấy trong CSDL tạm gọi là searchAPI.

Ở đây mình dùng MySQL :
Tạo cơ sở dữ liệu : 
CREATE SCHEMA `search_ajax_db` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

Tạo một bảng sản phẩm đơn giản:
CREATE TABLE `search_ajax_db`.`products` (
  `idproducts` INT NOT NULL AUTO_INCREMENT,
  `product_name` VARCHAR(255) NULL,
  `price` FLOAT NULL,
  `quantity` INT NULL,
  PRIMARY KEY (`idproducts`))
ENGINE = InnoDB;

Bây giờ cần chèn dữ liệu cho nó, nhiều nhiều một chút. Nhưng nhập bằng tay thì chắc gãy tay cũng chả được bao nhiêu. Nên chúng ta lên trang sau : https://mockaroo.com/ để tạo dữ liệu ảo.



Chọn các tên cột giống như bảng vừa tạo, định dạng là SQL, tên bảng giống tên bảng vừa tạo.
Tải dữ liệu về có một file sql : search_ajax_db.products.sql import vào CSDL:
File sql cho ai lười: https://vipshare.co/u/yfspi1rpsi (link die thì kêu bên dưới nhớ)

Sau khi import vào chúng ta được bảng dữ liệu 1000 hàng ngon lành:



Rồi tiếp theo cần viết một câu SQL để tìm kiếm sản phẩm:
SELECT * FROM search_ajax_db.products where product_name like "%{keyword}%";
Thay {keyword} bằng từ khóa cần tìm kiếm là xong!

Xây dựng server searchAPI

Tiếp đến là server! Phần này làm bằng ngôn ngữ nào thì làm kiểu của ngôn ngữ đó thôi, đáp ứng được ý đồ của mình được được:


Code file server PHP:
    $servername = "localhost";
    $username = "root";
    $password = "tienanh";
    $dbname = "search_ajax_db";
    
    $keyword = "";
    if(isset($_GET['keyword'])){
        $keyword = $_GET['keyword'];
    }
    
    // Create connection
    $conn = new mysqli($servername, $username, $password, $dbname) or die(mysql_error());
    // Check connection
    if ($conn->connect_error) {
         die("Connection failed: " . $conn->connect_error);
    }
    
    // Lấy resultProducts
    $resultProducts = $conn->query("SELECT * FROM search_ajax_db.products where product_name like '%$keyword%' limit 10;");
    $myProducts = array();
    while($row = $resultProducts->fetch_array(MYSQLI_ASSOC)) {
        $myProducts[] = $row;
    }

    header('Content-Type: application/json');
    echo json_encode($myProducts, JSON_UNESCAPED_UNICODE);
    
    $conn->close();
Bây giờ chỉ cần truy cập vào địa chỉ local của server, ở đây là http://localhost/search.php?keyword=xxx là sẽ nhận được dữ liệu trả về dạng Json.

Xây dựng Client

Xong server rồi! tiến tới làm một cái giao diện có một ô input để nhập từ khóa vào, sau đó dùng jquery ajax gửi keyword lên server và nhận dữ liệu trả về đổ ra giao diện!

Mẫu HTML:
<html>
    <head>
        <meta charset="utf-8"/>
        <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
        <style>
        </style>
    </head>
    <body>
        
        <form class="form" style="margin: 10% 20%">
            <h1 class="header-title">Tìm kiếm sản phẩm</h1>
            <div class="form-group" style="position: relative">
               <input class="form-control mr-sm-2 search-input" style="margin-bottom: 5px;" type="search" placeholder="Nhập sản phẩm muốn tìm!" aria-label="Search">      
               <div class="result-search-box p-2" style="position: absolute; top: 40px; width: 100%; min-height: 50px;z-index: 9; display: none; border: dashed 1px gray">
                  <code>Kết quả tìm kiếm :</code>             
                  <div class="list-result-search mt-2"></div>
               </div>
            </div>
         </form>
         <script
         src="https://code.jquery.com/jquery-3.3.1.min.js"
         integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8="
         crossorigin="anonymous"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
        <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
        <!-- Nhớ gắn đoạn script bên dưới vào đây -->
    </body>
</html>

Code javascript:
var typingTimer;// bộ đếm
var doneTypingInterval = 500;  //time in ms, thời gian chờ gõ phím
var $input = $('.search-input'); // selector ô input
var url = window.location; // lấy cái địa chỉ hiện tại
var historykey = ""; // lưu lại từ khóa cũ

//khi gõ xong 1 phím tạo một khoảng chờ nhỏ nếu không bị clear sẽ gọi hàm thực thi
$input.on('keyup', function () {
    clearTimeout(typingTimer);
    typingTimer = setTimeout(doneTyping, doneTypingInterval);
});

//khi nhấn phím xuống xóa thời gian chờ đã tạo ra ở trên
$input.on('keydown', function () {
    clearTimeout(typingTimer);
});

//on không có thay đổi về nội dung trong ô input thì mới tạo request
$input.on('change', function () {
    if (historykey !== $input.val())
        doneTyping();
});
// đặt chuột vào ô input cũng cần check xem dữ liệu có khác không
$input.focus(function () {
    if (historykey !== $input.val())
        doneTyping();
});

//hàm này thực thi sau khi gõ phím doneTypingInterval ms
function doneTyping() {
    historykey = $input.val();
    $('.list-result-search').html("");
    if ($input.val()) {
        $('.result-search-box').slideDown(50);
        $.get(url.origin + "/search.php?keyword=" + $input.val(), function (result, status) {
            if (result.length) {
                result.forEach(function (currentValue, index) {
                    $('.list-result-search')
                        .append('<div>' + currentValue.product_name + ' |  ' + currentValue.price + ' vnđ </div>');
                });
            } else {
                $('.list-result-search').html("<p class='w3-padding'>Không tìm thấy kết quả nào cho <i>\"" + $input.val() + "\"</i></p>");
            }
        });

    } else {
        $('.result-search-box').slideUp();
    }
} // End typingDone

Thành quả của chúng ta :

Với cái mớ code trên kia theo mình thì nếu ngồi đọc lại vài lượt thì cũng dễ hiểu thôi đã comment tương đối rồi, nhưng để ngồi giải thích thì lại hơi mất thời gian lên chịu khó đọc anh em nhé! Chỉ cần nắm được đoạn này thôi:


$.get(url.origin + "/search.php?keyword=" + $input.val(), function (result, status) {
    if (result.length) {
        result.forEach(function (currentValue, index) {
            $('.list-result-search')
                 .append('<div>' + currentValue.product_name + ' |  ' + currentValue.price + ' vnđ </div>');
            });
    } else {
        $('.list-result-search').html("<p class='w3-padding'>Không tìm thấy kết quả nào cho <i>\"" + $input.val() + "\"</i></p>");
    }
 });

Đây là đoạn dùng Ajax để gửi từ khóa và kéo dữ liệu từ server về!
OK đến đây thôi! chúc các bạn thành công.



Nhận xét

Bài đăng phổ biến từ blog này

Sách nổi tiếng nhưng không hay? Có thể chưa phải sách phù hợp ở hiện tại

Thật tuyệt vời khi bản thân không bị lười đọc, mình đọc khá nhiều. Phần lớn trong đó là truyện giải trí, giải trí một cách đơn thuần. Cũng may xen lẫn trong đó vẫn có một vài cuốn sách chính thống.  Trước khi có tiền mua sách, màn hình chiếc điện thoại nhỏ bé hoặc bộ máy tính được đầu tư cho chị học tiếng anh là nơi các dòng chữ được cuộn qua hàng ngày. Đúng, bạn không nghe nhầm, những năm cấp 2 tiền tiêu vặt giống như một phần thưởng xa xỉ phẩm, không phải được cho hằng ngày ở đâu đó mình được biết. Nhà mình không đến mức nghèo túng, mình được ăn học đàng hoàng cùng chăm sóc đầy đủ. Bố mẹ rất thoải mái chi tiêu phục vụ việc học của hai chị em. Đơn giản vì hồi đó ở quê chưa phát triển mạnh - làm gì có hiệu sách hay thư viện gì đâu, chúng khá hiếm hoi và phải di chuyển xa khỏi phạm vi hoạt động trung bình của người miền quê. Tới những khu vực sầm uất hơn tương đương việc "lên phố" bây giờ. Sách ngày đó với mình là những cuốn sách giáo khoa. Không hề kén chọn, mình đọc hầu hết ...

Chia sẻ bài tập thực hành Lập trình Web ASP

Với sự đề nghị của một số bạn học bài viết này mình chia sẻ những bài thực hành môn lập trình web tại khoa mình đang học. Tuy nhiên do không có đề bài (đề bài nộp lại trong quyển báo cáo thực hành) nên có thể nó chỉ phù hợp với bạn nào học cùng khoa mình (FITHOU) muốn xem tham khảo và những bạn muốn tự đọc hiểu code!! Tuần 1 & 2 : Tải xuống Tuần 3 : Tải xuống Tuần 4 : Tải xuống Tuần 5 : Tải xuống Tuần 6 : Tải xuống - Bài 2 Tải xuống - Bài 1