Skip to content

Instantly share code, notes, and snippets.

@eversionsystems
Last active September 26, 2021 17:24
Show Gist options
  • Save eversionsystems/27348faf40408831e0b13883130fecdb to your computer and use it in GitHub Desktop.
Save eversionsystems/27348faf40408831e0b13883130fecdb to your computer and use it in GitHub Desktop.
WordPress AJAX Live Search Without jQuery Dependency Using Fetch API
<?php
namespace ES_AJAX_Search;
function ajax_search_shortcode()
{
ob_start();
?>
<div class="search-wrapper">
<div id="overlay">
<div class="cv-spinner">
<span class="spinner"></span>
</div>
</div>
<div class="search-input">
<input type="search" class="ajax-input" name="keyword" id="ajax_search" placeholder="Search...">
</div>
<div class="search-results">
<ul id="ajax_results" class="ajax-results"></ul>
</div>
</div>
<?php
return ob_get_clean();
}
add_shortcode('es-ajax-search', __NAMESPACE__ . '\ajax_search_shortcode');
function shortcode_scripts()
{
global $post;
if (has_shortcode($post->post_content, 'es-ajax-search')) {
wp_enqueue_style('es-ajax-search', get_stylesheet_directory_uri() . '/css/ajax-search.css', [], filemtime(get_stylesheet_directory() . '/css/ajax-search.css'));
wp_enqueue_script('es-ajax-search', get_stylesheet_directory_uri() . '/js/ajax-search.js', [], filemtime(get_stylesheet_directory() . '/js/ajax-search.js'), true);
wp_localize_script('es-ajax-search', 'esAjaxSearch', ['ajaxUrl' => admin_url('admin-ajax.php')]);
}
}
add_action('wp_enqueue_scripts', __NAMESPACE__ . '\shortcode_scripts');
function ajax_search()
{
ob_start();
if (strlen($_POST['keyword']) > 0) {
$the_query = new \WP_Query(
array(
'posts_per_page' => 20,
'post_status' => 'publish',
's' => esc_attr($_POST['keyword']),
'no_found_rows' => true
//'post_type' => 'post'
)
);
if ($the_query->have_posts()) :
foreach ($the_query->posts as $res) {
echo '<li><div class="result-wrap"><div class="post-thumb">' . get_the_post_thumbnail($res->ID, 'post-thumbnail') .
'</div><div class="post-text"><a href="' . esc_url(get_the_permalink($res->ID)) . '"><strong>' .
$res->post_title . '</strong> - ' . wp_trim_words($res->post_content, 10) . '</a></div></li>';
}
else :
echo '<li>No results</li>';
endif;
}
$result = ob_get_clean();
wp_send_json([
'posts' => $result,
'count' => count($the_query->posts)
]);
}
add_action('wp_ajax_ajax_search', __NAMESPACE__ . '\ajax_search');
add_action('wp_ajax_nopriv_ajax_search', __NAMESPACE__ . '\ajax_search');
.ajax-results {
list-style: none;
margin: 0;
position: absolute;
background: white;
padding: 0;
width: 100%;
overflow: auto;
height: auto;
max-height: 25rem;
}
.search-wrapper {
position: relative;
width: 100%;
}
#ajax_search {
width: 100%;
margin: 0;
}
.ajax-results li {
margin: 0;
border: solid 1px;
padding: 1rem;
}
.result-wrap {
display: flex;
align-items: center;
}
.post-thumb {
padding: 1rem;
max-width: 10rem;
}
.post-text {
font-size: 1rem;
}
#overlay {
position: absolute;
top: 0;
z-index: 100;
width: 100%;
height: 100%;
display: none;
background: rgba(0, 0, 0, 0.6);
}
.cv-spinner {
height: 100%;
display: flex;
justify-content: center;
align-items: center;
}
.spinner {
width: 40px;
height: 40px;
border: 4px #ddd solid;
border-top: 4px var(--global--color-primary) solid;
border-radius: 50%;
animation: sp-anime 0.8s infinite linear;
}
@keyframes sp-anime {
100% {
transform: rotate(360deg);
}
}
.is-hide {
display: none;
}
var ajaxResults = document.getElementById('ajax_results'),
ajaxUrl = esAjaxSearch.ajaxUrl,
overlay = document.getElementById('overlay'),
searchInput = document.getElementById('ajax_search');
searchInput.addEventListener("search", ajaxSearchTrigger);
searchInput.addEventListener("keyup", searchWordPress);
function ajaxSearchTrigger(e) {
ajaxResults.innerHTML = ''
ajaxResults.style.height = 'unset'
}
function searchWordPress(e) {
var sInput = e.target,
delay = 500;
if (sInput.value.length >= 3) {
setTimeout(function() {
overlay.style.display = 'block'
fetch(ajaxUrl, {
method: 'POST',
credentials: 'same-origin',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Cache-Control': 'no-cache',
},
body: new URLSearchParams({
action: 'ajax_search',
keyword: searchInput.value,
})
}).then(response => response.json())
.then(response => {
ajaxResults.innerHTML = response.posts
if (response.count == 0)
ajaxResults.style.height = 'unset'
else
ajaxResults.style.height = 'auto'
})
.catch(err => console.log(err))
.then(always => {
overlay.style.display = 'none'
});
}, delay);
} else {
ajaxResults.innerHTML = ''
}
}
<?php
include_once('inc/ajax-search.php');
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment