Created
October 2, 2018 14:03
-
-
Save stephanieland352/142c9704265e6a41ecd395702c8b1fb9 to your computer and use it in GitHub Desktop.
Woocommerce Ajax Typeahead Search
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!-- search --> | |
<form class="search" method="get" action="<?php echo get_permalink(get_option('woocommerce_shop_page_id')); ?>" role="search"> | |
<input type="hidden" name="ts" value="true" /> | |
<input class="search-input" type="search" name="s" placeholder="<?php _e( 'Search Our Products', 'html5blank' ); ?>" autocomplete="off" data-ajaxurl="<?php echo admin_url('admin-ajax.php'); ?>"> | |
<div class="search-results"></div> | |
<button class="search-submit" type="submit" role="button"><i class="fa fa-search" aria-hidden="true"></i></button> | |
</form> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function html5blank_header_scripts() | |
{ | |
wp_register_script( 'typeahead', get_template_directory_uri() . '/js/lib/typeahead/jquery.typeahead.min.js', array( 'jquery' ), '2.6.1', true ); | |
wp_enqueue_script( 'typeahead' ); | |
} | |
add_action('init', 'html5blank_header_scripts'); | |
//fancy search | |
add_action( 'wp_ajax_typeahead', 'get_typeahead_results' ); | |
add_action( 'wp_ajax_nopriv_typeahead', 'get_typeahead_results' ); | |
/** | |
* Action for handling cached Typeahead AJAX requests | |
*/ | |
function get_typeahead_results() { | |
if ( ! DOING_AJAX ) { | |
die; | |
} | |
$results = rebuild_typeahead_cache(); | |
echo $results; | |
die(); | |
} | |
/** | |
* Rebuild typeahead caches for categories / taxonomy search terms | |
* | |
* @return array|mixed|string|void | |
*/ | |
function rebuild_typeahead_cache(){ | |
$results = get_transient( 'typeahead_cache' ); | |
if ( $results ) { // Return if cached | |
return $results; | |
} | |
$results = array(); | |
$types = array( | |
'pa_brand', | |
'pa_hair-type', | |
'pa_skin-type', | |
'product' | |
); | |
foreach ( $types as $type ) { | |
if ( $type == 'product' ) { | |
$query = new WP_Query( array( | |
'nopaging' => true, | |
'post_type' => 'product', | |
'meta_query' => array( | |
array( | |
'key' => '_visibility', | |
'value' => 'visible' | |
) | |
) | |
) ); | |
foreach ( $query->get_posts() as $product ) { | |
$meta = array(); | |
$terms = wp_get_post_terms( $product->ID, 'pa_brand' ); | |
foreach ( $terms as $term ) { | |
$meta[] = $term->name; | |
} | |
$results[] = get_group_array( $product->post_title, get_the_permalink( $product->ID ), 'Product', $product->ID, get_the_post_thumbnail_url( $product->ID, 'thumbnail' ), implode( ',', $meta ) ); | |
} | |
} else { | |
$taxonomy = get_taxonomy( $type ); | |
$terms = get_terms( array( | |
'taxonomy' => $type | |
) ); | |
foreach ( $terms as $term ) { | |
$results[] = get_group_array( $term->name, get_term_link($term, $term->taxonomy), $taxonomy->label, $term->term_id ); | |
} | |
} | |
} | |
$results = json_encode($results); | |
set_transient( 'typeahead_cache', $results, 60 * 60 * 24 * 7 ); | |
return $results; | |
} | |
/** | |
* Assemble search query URL for products page - useful if we link to this search term in other locations | |
* | |
* @param $term | |
* | |
* @return string | |
*/ | |
function get_taxonomy_search_url_skin( $term, $taxonomy ) { | |
return add_query_arg( 'filters', $term->taxonomy.'['.$term->term_id.']', get_permalink( get_option('woocommerce_shop_page_id') ) ); | |
} | |
/** | |
* Format passed arguments into proper JSON array for Typeahead | |
* | |
* @param $name | |
* @param $href | |
* @param $type | |
* @param $image_url | |
* @param $meta | |
* | |
* @return array | |
*/ | |
function get_group_array($name, $href, $type, $id, $image_url = FALSE, $meta = FALSE){ | |
$group = array( | |
'name' => $name, | |
'href' => $href, | |
'type' => $type, | |
'id' => $id | |
); | |
if ( $image_url !== FALSE ) { | |
$group['image_url'] = $image_url; | |
} | |
if ( $meta !== false ) { | |
$group['meta'] = $meta; | |
} | |
return $group; | |
} | |
add_action('admin_notices',function(){ | |
if(user_can(get_current_user_id(),'manage_options') && isset($_GET['action']) && $_GET['action'] == 'recreate_caches'){ | |
delete_transient( 'typeahead_cache' ); | |
rebuild_typeahead_cache(); | |
?> | |
<div class="updated"> | |
<p><?php _e( 'Search caches rebuilt.', 'my-text-domain' ); ?></p> | |
</div> | |
<?php | |
} | |
}); | |
// Add recreate cache menu for manual cache creation | |
add_action('admin_bar_menu',function($menu){ | |
/* @var $menu WP_Admin_Bar */ | |
$menu->add_node(array( | |
'id'=>'typeahead-caches', | |
'parent'=>'site-name', | |
'recreate-typeahead-caches', | |
'title'=>'Recreate Caches', | |
'href'=>get_admin_url().'?action=recreate_caches' | |
)); | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(function ($, root, undefined) { | |
$(function () { | |
// Search Bar | |
setupTypeahead(); | |
}); | |
function setupTypeahead(){ | |
var searchbox = $('.search-input'); | |
$.ajax(searchbox.data('ajaxurl'), { | |
method: 'GET', | |
dataType: 'json', | |
cache: true, | |
data: { | |
action: 'typeahead' | |
}, | |
success: function(data){ | |
searchbox.typeahead({ | |
minLength: 1, | |
group: 'type', | |
maxItem: 20, | |
maxItemPerGroup: 10, | |
emptyTemplate: function(query){ | |
return '<div class="typeahead__display"><div class="typeahead__info">No results Found for "'+query+'"</div></div>'; | |
}, | |
compress: true, | |
highlight: 'any', | |
resultContainer: '.search-results', | |
display: ['name', 'meta'], | |
callback: { | |
onClick: function(event){ | |
return false; | |
}, | |
onNavigateBefore: function (node, query, event) { | |
if (~[38,40].indexOf(event.keyCode)) { | |
event.preventInputChange = true; | |
} | |
} | |
}, | |
template: function (query, item) { | |
var template = ""; | |
if (item.image_url != undefined) { | |
template += '<div class="typeahead__display typeahead__display--has-image"><img class="typeahead__image" src="{{image_url}}"/>'; | |
} else { | |
template += '<div class="typeahead__display">'; | |
} | |
template += '<div class="typeahead__info">{{name}}'; | |
template += '</div></div>'; | |
return template; | |
}, | |
href: function(item){ | |
return item.href; | |
}, | |
source: data | |
}); | |
} | |
}); | |
} | |
function escapeRegExp(str) { | |
return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&"); | |
} | |
})(jQuery, this); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
.header-search { | |
float:right; | |
margin-top:10px; | |
position:relative; | |
width:50%; | |
z-index: 400; | |
.search { | |
input[type="submit"], input[type="search"], button { | |
background: $primaryLight; | |
border:1px solid $primaryLight; | |
padding:5px; | |
} | |
&-input { | |
width: 80%; | |
float:left; | |
&:focus + .search-results { | |
display: block; | |
} | |
} | |
.search-submit, input[type="submit"], button { | |
float:right; | |
width:16%; | |
} | |
&-results { | |
display:none; | |
position: absolute; | |
z-index: 500; | |
top:100%; | |
right:0; | |
width: 100%; | |
background: $white; | |
@include boxShadow(0 0 5px rgba(black, .5)); | |
overflow: hidden; | |
overflow-y: scroll; | |
max-height: 400px; | |
&:hover { | |
display:block; | |
} | |
ul { | |
@include ulReset; | |
} | |
.typeahead { | |
&__list { | |
padding: $fieldPadding; | |
} | |
&__group { | |
color: $primary; | |
font-style: italic; | |
border-bottom: 1px solid darken($white, 14); | |
} | |
&__item { | |
@include clear; | |
cursor: pointer; | |
margin: $fieldPadding 0; | |
&:hover, &.active { | |
background: darken($white, 12); | |
} | |
} | |
&__display--has-image { | |
$imageSize: 50px; | |
.typeahead__image { | |
float: left; | |
width: $imageSize; | |
height: $imageSize; | |
margin-right: $fieldPadding; | |
} | |
.typeahead__info { | |
position: absolute; | |
width: 100%; | |
padding: 0 20px 0 ($imageSize + $fieldPadding); | |
&__meta { | |
overflow: hidden; | |
text-overflow: ellipsis; | |
white-space: nowrap; | |
} | |
} | |
} | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment