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.
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ên và Xuố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!
Không có bình luận.