Nếu bạn muốn Tạo ô tìm kiếm nhanh bằng Ajax trong WordPress để nâng cấp chức năng tìm kiếm, bài viết này sẽ giúp bạn.

Tạo ô tìm kiếm nhanh bằng Ajax trong WordPress

Demo tại đây, các bạn thử tìm kiếm bài viết / chuyên mục / series / định nghĩa / khóa học bất kì nhé. Khung tìm kiếm này có các tính năng:

  • Tăng thời gian nhập liệu khi người dùng sử dụng điện thoại
  • Dùng phím LênXuống để chọn kết quả
  • Bấm Enter để đi đến liên kết của kết quả

HTML

HTML đơn giản như sau.

<div class="search-wrapper form-group">
    <input class="form-control search-txt" type="text" placeholder="Tìm kiếm gì đó..." />
    <button type="button" class="search-btn"><i class="glyphicon glyphicon-search"></i></button>
</div>

CSS

CSS mình cũng làm đơn giản, bạn có thể tùy chỉnh tùy nhu cầu sử dụng nhé.

.search-wrapper {
	padding: 25px;
	background: #efefef;
	position: relative;
}
.search-txt {
	font-size: 16px;
	padding: 10px;
	height: auto;
}
.search-wrapper .search-btn {
    position: absolute;
    top: 35px;
    right: 35px;
    border: none;
    background: 0 0;
    padding-top: 1px;
    padding-bottom: 0;
    color: #414a51;
}
.search-result {
	width: 100%;
	margin-top: 25px;
}
.search-result ul {
	padding-left: 0;
	list-style: none;
}
li.focus-ing a {
	text-decoration: underline;
}
.lds-ellipsis {
    display: inline-block;
    position: relative;
    width: 80px;
    height: 10px;
}
.lds-ellipsis span {
    position: absolute;
    top: 0;
    width: 10px;
    height: 10px;
    border-radius: 50%;
    background: #d9dbdd;
    animation-timing-function: cubic-bezier(0, 1, 1, 0);
}
.lds-ellipsis span:nth-child(1) {
    left: 8px;
    animation: lds-ellipsis1 0.6s infinite;
}
.lds-ellipsis span:nth-child(2) {
    left: 8px;
    animation: lds-ellipsis2 0.6s infinite;
}
.lds-ellipsis span:nth-child(3) {
    left: 32px;
    animation: lds-ellipsis2 0.6s infinite;
}
.lds-ellipsis span:nth-child(4) {
    left: 56px;
    animation: lds-ellipsis3 0.6s infinite;
}
@keyframes lds-ellipsis1 {
    0% {
        transform: scale(0);
    }
    100% {
        transform: scale(1);
    }
}
@keyframes lds-ellipsis3 {
    0% {
        transform: scale(1);
    }
    100% {
        transform: scale(0);
    }
}
@keyframes lds-ellipsis2 {
    0% {
        transform: translate(0, 0);
    }
    100% {
        transform: translate(24px, 0);
    }
}

CSS có sử dụng bài viết:

PHP

Thêm phương thức tìm kiếm tại functions.php.

/**
 * Tìm kiếm bằng Ajax
 */
add_action('wp_ajax_search', 'init_search');
add_action('wp_ajax_nopriv_search', 'init_search');
function init_search() {
    if ($_POST['keyword']) {
        $args = array(
            'taxonomy' => array('category', 'series', 'course'),
            'hide_empty' => true,
            'fields' => 'all',
            'name__like' => sanitize_text_field($_POST['keyword']),
            'number' => 5
        );
        $term_query = new WP_Term_Query($args);

        $res = [];

        if (!empty($term_query->terms)) {
            foreach ($term_query->terms as $term) {
                $res[] = array(
                        'title' => $term->name,
                        'link' => get_category_link($term->term_id)
                );
            }
        }

        $query = new WP_Query(array(
            'post_type' => array('post', 'glossary', 'lesson'),
            'posts_per_page' => 5, 
            'post_status' => 'publish',
            's' => sanitize_text_field($_POST['keyword'])
            
        ));

        if ($query->have_posts()) {
            while ($query->have_posts()) {
                $query->the_post();
                $res[] = array(
                        'title' => get_the_title(),
                        'link' => get_the_permalink()
                );
            }
        } wp_reset_query();

        wp_send_json_success($res);
    }
    die();
}

JavaScript

Tìm kiếm bằng Ajax với các tính năng như demo.

var initAjax = '<?php echo admin_url('admin-ajax.php'); ?>';

$(document).ready(function() {
	var typingTimer;
    var doneTypingInterval = 500;
    var $input = $('input.search-txt');
    var ctrlDown = false;

    $input.on('keyup', function(event) {
        if (detectMobile()) { // Nếu người dùng sử dụng điện thoại, thời gian từ lúc kết thúc nhập đến lúc bắt đầu tìm kiếm tăng gấp đôi
            clearTimeout(typingTimer);
            typingTimer = setTimeout(function() {
                if ($input.val() != '' && !$input.hasClass('selecting')) {
                    if ($('.search-wrapper .search-result').length > 0) {
                        $('.search-wrapper .search-result').html('<div class="text-center"><span class="lds-ellipsis"><span></span><span></span><span></span><span></span></span></div>');
                    } else {
                        $('.search-wrapper').append('<div class="search-result"><div class="text-center"><span class="lds-ellipsis"><span></span><span></span><span></span><span></span></span></div></div>');
                    }
                    searchPost($input.val());
                }
            }, doneTypingInterval * 2);
        } else { // Người dùng sử dụng máy tính
            var keycode = (event.keyCode ? event.keyCode : event.which);
            if ((keycode >= 48 && keycode <= 57) || (keycode >= 65 && keycode <= 90) || (keycode == 13) || (keycode == 32) || (keycode == 46) || (keycode == 8)) {
                if (ctrlDown && (keycode == 65 || keycode == 67)) {
                    return false; // Không xử lí nếu người dùng bấm Ctrl + A hoặc Ctrl + C
                } else {
                    clearTimeout(typingTimer);
                    typingTimer = setTimeout(function() {
                        if ($input.val() != '' && !$input.hasClass('selecting')) {
                            if ($('.search-wrapper .search-result').length > 0) {
                                $('.search-wrapper .search-result').html('<div class="text-center"><span class="lds-ellipsis"><span></span><span></span><span></span><span></span></span></div>');
                            } else {
                                $('.search-wrapper').append('<div class="search-result"><div class="text-center"><span class="lds-ellipsis"><span></span><span></span><span></span><span></span></span></div></div>');
                            }
                            searchPost($input.val());
                        }
                    }, doneTypingInterval);
                }
            }
            if (keycode == 17) {
                ctrlDown = false;
            }
            if (keycode == 13) { // Bấm Enter
            	if ($('.search-result ul').find('li').hasClass('focus-ing')) {
            		location = $('.search-result ul').find('li.focus-ing').find('a').attr('href');
            	}
            }
        }
    });

    $input.on('keydown', function(event) {
	    clearTimeout(typingTimer);
	    var keycode = (event.keyCode ? event.keyCode : event.which);
	    if (keycode == 17) {
	        ctrlDown = true;
	    }

	    if (keycode == 38 || keycode == 40) {
	        if ($('.search-result').length > 0) {
	            if (keycode == 38) { // Bấm nút lên
	                if (!$('.search-result ul').find('li').hasClass('focus-ing')) {
	                    if (!$('.search-result ul').find('li').hasClass('focus-ing')) {
	                        $('.search-result ul li').last().addClass('focus-ing');
	                        $input.val($('.search-result ul').find('li.focus-ing').text().trim()).addClass('selecting');
	                    }
	                } else {
	                    if (!$('.search-result ul').find('li.focus-ing').is(':first-child')) {
	                        $('.search-result ul').find('li.focus-ing').prev().addClass('focus-ing').next().removeClass('focus-ing');
	                        $input.val($('.search-result ul').find('li.focus-ing').text().trim()).addClass('selecting');
	                    } else {
	                        $('.search-result ul').find('li').removeClass('focus-ing');
	                        $input.val('').removeClass('selecting');
	                    }
	                }
	            }
	            if (keycode == 40) { // Bấm nút xuống
	                if (!$('.search-result ul').find('li').hasClass('focus-ing')) {
	                    if (!$('.search-result ul').find('li').hasClass('focus-ing')) {
	                        $('.search-result ul li').first().addClass('focus-ing');
	                        $input.val($('.search-result ul').find('li.focus-ing').text().trim()).addClass('selecting');
	                    }
	                } else {
	                    if (!$('.search-result ul').find('li.focus-ing').is(':last-child')) {
	                        $('.search-result ul').find('li.focus-ing').next().addClass('focus-ing').prev().removeClass('focus-ing');
	                        $input.val($('.search-result ul').find('li.focus-ing').text().trim()).addClass('selecting');
	                    } else {
	        	            $('.search-result ul').find('li').removeClass('focus-ing');
	                        $input.val('').removeClass('selecting');
	                    }
	                }
	            }
	        }
	    } else if (keycode == 36) { // Nút Home
	        if (!$('.search-result ul li').first().hasClass('focus-ing')) {
	            $('.search-result ul').find('li').removeClass('focus-ing');
	            $('.search-result ul li').first().addClass('focus-ing');
	            $input.val($('.search-result ul').find('li.focus-ing').text().trim()).addClass('selecting');
	        }
	    } else if (keycode == 35) { // Nút End
	        if (!$('.search-result ul li').last().hasClass('focus-ing')) {
	            $('.search-result ul').find('li').removeClass('focus-ing');
	            $('.search-result ul li').last().addClass('focus-ing');
	            $input.val($('.search-result ul').find('li.focus-ing').text().trim()).addClass('selecting');
	        }
	    } else if (keycode != 13 && keycode != 17 && keycode != 37 && keycode != 39) {
	        $('.search-result ul').find('li').removeClass('focus-ing');
	        $input.removeClass('selecting');
	    }

	    if (keycode == 27) { // Bấm Esc
	        removeSearchResult();
	    }
	});
});

function searchPost(keyword) {
    if (keyword != '' && keyword.length < 100) {
        $.ajax({
            type: 'post',
            dataType: 'json',
            url: initAjax,
            data: {
                'action': 'search',
                'keyword': keyword
            },
            success: function(response) {
                if(response.success) {
                    if (response.data.length > 0) {
                        var resultHTML = '<div class="search-result"><ul>';
                        for (var i = 0; i < response.data.length; i++) {
                            resultHTML += '<li><a href="' + response.data[i].link + '" title="' + response.data[i].title + '">' + response.data[i].title + '</a></li>';
                        }
                        resultHTML += '</ul></div>';
                        $('.search-wrapper .search-result').remove();
                        $('.search-wrapper').append(resultHTML);
                    } else {
                        resultHTML = '<div class="search-result"><ul><li>Không tìm thấy kết quả.</li></ul></div>';
                        $('.search-wrapper .search-result').remove();
                        $('.search-wrapper').append(resultHTML);
                    }
                    $('.search-btn').addClass('turn-search-off').html('<i class="glyphicon glyphicon-remove"></i>').on('click', function() { removeSearchResult(); });
                }
            }
        });
    }
}

function removeSearchResult() {
    $('.search-wrapper .search-result').remove();
    $('.search-btn').removeClass('turn-search-off').html('<i class="glyphicon glyphicon-search"></i>');
    $('input.search-txt').val('').blur();
}

function detectMobile() {
    const toMatch = [
        /Android/i,
        /webOS/i,
        /iPhone/i,
        /iPod/i,
        /BlackBerry/i,
        /Windows Phone/i
    ];

    return toMatch.some((toMatchItem) => {
        return navigator.userAgent.match(toMatchItem);
    });
}

Chúc các bạn thành công!

5/5 (8 bình chọn)