live-search-wolfactive-949x475
23/07/2020

WordPress: Thiết kế theme (P11: Live Search (UI Javascript))

Chào mừng các bạn đến với series WP thiết kế theme của mình. Ở phần này mình sẽ hướng dẫn các bạn tạo Live Search trên WordPress. Đây là chức năng tìm kiếm bài viết show ra trực tiếp tại trang của bạn thông qua với việc tương tác với API trên WordPress. Giờ mình cùng tạo một Live Search cho bản thân mình nhé.

1/ Chuẩn bị

Để làm một Live Search các bạn cần tạo một form tìm kiếm trước cái đã nhỉ? Vì nếu không có form thì chắc chắn các bạn sẽ không thể tìm kiếm kết quả được :))

<form role="search" method="get" id="searchForm" class="search-form" action="<?php echo esc_url(site_url('/')); ?>">
     <div class="search__field-container">
         <label>
            <input type="text" class="search-field" placeholder="Tìm Kiếm" value="" name="s">
            <input type="hidden" class="search-field" placeholder="Search …" value="1" name="sentence">
            <input type="hidden" class="search-field" placeholder="Search …" value="post" name="post_type">
         </label>
         <button type="submit" class="search-submit" value="Search" aria-label="Button Submit Search">
            search <i class="fas fa-angle-right"></i>
         </button>
      </div>
</form>

Okie giờ mình đã có một cái form search đẹp như thật luôn rồi nè. 😀 Tuy nhiên, nhìn vào các bạn sẽ thấy mình sử dụng tận ba input field lận. Chắc sẽ có bạn nghĩ rằng “tạo chi 3 cái nhỉ? 1 cái được rồi, tạo như vậy thì khác gì so 1 cái? ,…” hàng tá, hàng tỉ câu hỏi bạn sẽ đặt ra khi thấy mình làm như vậy.

Vậy câu trả lời là, mình tạo 3 field input nhưng chỉ có 1 field là nhập để nhận chuỗi tìm kiếm. Còn 2 field còn lại, mình tạo ra có nhiệm vụ là để tăng độ chính xác khi tìm kiếm, tìm kiếm bài viết có dạng  là post. Nếu các bạn không tạo như mình mà chỉ tạo một cái thôi vẫn được, khung tìm kiếm của bạn vẫn chạy ổn áp nhé.

Kế đến mình tạo một thẻ div với class là search__result-overlay để hiển thị kết quả tìm kiếm trên đây

<div class="search__result-overlay" id="searchResult"></div>

2/ Live Search (UI javascript)

Như vậy, tụi mình đã xong với bước chuẩn bị rồi. Cực kì dễ đúng không nè, kế tiếp các bạn cần liên kết với link api của mình. Ở đây chúng ta sẽ có 2 hướng đi, một là bạn sử dụng trực tiếp đường dẫn api của WP : exemple.com/wp-json/wp/v2/posts?search= , hoặc các bạn tự custom link API của mình (các bạn có thể đọc thêm cách custom link api search tại đây )

Hoặc các bạn làm theo mình nè.

add_action('rest_api_init','postRegisterApiSearch');
function postRegisterApiSearch(){
  register_rest_route('post-api/v1','search',array(
    'methods'   =>  WP_REST_SERVER::READABLE,
    'callback'  =>  'postApiSearchResult'
  ));
}
function postApiSearchResult($data){
  $postList = new WP_Query(array(
    'post_type'     => 'post',
    'sentence'      =>   1,
    's'             => sanitize_text_field($data['term']),
  ));
  $postResult = array();
  while($postList->have_posts()):$postList->the_post();
    array_push($postResult,
      array(
        'title' => get_the_title(),
        'thumbnail' => get_the_post_thumbnail(),
        'link' => get_the_permalink(),
        'date' => get_the_date( 'F j, Y' ),
        )
      );
   endwhile;
return $postResult;
}

Sau đó, các bạn cần tạo một file .js trước cái đã nhỉ? Sau đó các bạn cần làm như sau:

var searchResultDiv = document.querySelector("#searchResult");
var searchField = document.querySelector(".search-field");

Ở đây, mình tạo hai biến, một biến để DOM tới thẻ div sẽ hiện thị kết quả và cái còn lại thì DOM tới khung input search của mình.

function ResultSearch(){
  var apiUrl='';
  setTimeout(function(){
    if(searchField.value){
      apiUrl =window.location.pathname+`wp-json/post-api/v1/search?term=`+searchField.value;
    }
    fetch(apiUrl)
    .then(result => {
     console.log(result);
     return result.json();
    })
    .then(data => {
       console.log(data);
       let content= ``;
       data.forEach((item,i)=>{
          content += `
           <div class="Post__item">
              <div class="Post__item-img">
                <a href="${item.link}">
                 ${item.thumbnail}
                </a>
              </div>
              <div class="Post__item-content">
                <div class="date">
                   <i class="far fa-calendar-alt"></i> <span>${item.date}</span>
                </div>
                <h4 class="Post__item-title title--item">
                   <a href="${item.link}">
                     ${item.title}
                   </a>
                </h4>
               </div>
            </div>
`;
})
searchResultDiv.innerHTML = content;
})
.catch(error => console.log(error));
}, 1000);
}

Kế tiếp mình tạo một function để thực hiện lấy data từ api. Ở function này mình tạo một biến apiUrl để lưu lại link api của mình bằng cách kiểm tra điều kiện if xem có dữ liệu có trong search-field của mình hay không, nếu có thì mình sẽ bắt đầu gán link API cho nó.

Sau đó, mình bắt đầu lấy dữ liệu API từ hàm fetch() trong javascript. Khi fetch thì mình kiểm tra result trả về (các bạn có thể bỏ qua bước này nếu muốn) tuy nhiên các bạn nhớ return result về ở dạng json nhé.

Sau khi mình đưa result về json thì mình lại tiếp túc lấy data bằng cách sử dụng vòng lặp foreach, à mà các bạn nhớ tạo một biến content để nhằm phục vụ cho mình việc tạo html như mình nhé. Cuối cùng mình đưa dữ liệu content ra ngoài html searchResultDiv.innerHTML = content. Và việc này mình đặt trong hàm setTimeOut để trì hoãn tốc độ tìm kiếm lại tí ( các bạn thích thì làm theo mình không thích cũng làm theo nhé 😀 ).

Nói chớ mình nghĩ các bạn nên đặt setTimeOut. Tại sao ư? Tại vì như sau, giả sử mình nhấn 10 lần phím liên tiếp đi, thì nó sẽ gửi request lên 10 lần đúng chứ? Như vậy nó sẽ hiện kết quả liên tục 10 lần, như vậy thì nhìn rất là nhức mắt. Do đó mình đặt setTimeOut để cải thiện trải nghiệm và giảm số lượt request lại.

Các bạn có thể thấy mình sử dụng các cụm như sau để lấy dữ liệu:

  • ${item.link}: Lấy địa chỉ nhà bài viết.
  • ${item.thumbnail}: lấy ảnh mới sinh của bài viết.
  • ${item.date}: lấy ngày tháng năm sinh của bài viết.
  • ${item.title}: tên khai sinh hợp pháp bài viết.

Và các cụm từ link, thumbnail, date, title chính là tên mà mình đã đặt khi ta array push vào $postResult ở trên ấy. 😀

Sau đó việc cuối cùng mình làm chính là bắt sự kiện onkeydown. Để khi bạn nhấn vào bất kì phím gì thì nó sẽ bắt đầu tìm kiếm bài viết.

searchField.onkeydown = () =>{
  ResultSearch();
}

Cuối cùng mình style lại tí cho đẹp nhé!

.search__result-overlay{
    display: grid;
    grid-template-columns: repeat(auto-fill,minmax(160px,230px));
    justify-content: center;
    grid-gap: 1em;
}

Giờ là thành quả chúng mình vừa làm đây

3/ Lời kết

Như vậy mình đã giới thiệu và hướng dẫn cho các bạn cách Live Search (UI Javascript) trên wordpress mà không cần phải tạo thêm file search của mình nữa. Việc thực hiện cực kì dễ dàng đúng không nào. Đầu tiên các bạn tạo khung search đầu tiên. Sau đó ta bắt đầu tạo url API Search cho dễ gọi data. Cuối cùng thực hiện gọi data từ javascript.

Mọi thắc mắc các bạn liên hệ fanpage trực tiếp của mình để được giải đáp thắc mắc nhé. Và để lại comment ở bài share nếu bạn có muốn góp ý gì nha. <3 Mong các bạn sẽ ủng hộ Wolfactive tụi mình hơn nữa nhé <3. Chúc các bạn ngày mới vui vẻ.

Vui lòng chọn size trước khi đặt hàng (*)