Link to home
Start Free TrialLog in
Avatar of Art Williams
Art Williams

asked on

jQuery UI Autocomplete with Wordpress, fetching custom taxonomy

jQuery UI Autocomplete integration with Wordpress.

I have been working on integrating jQuery UI Autocomplete within my wordpress theme. I have been following this guide: https://gabrieleromanato.name/adding-jquery-ui-autocomplete-to-the-wordpress-search-form

--

Currently it is working as intended, I have on search the right results, and with them being able to log in the right div. But along with the post_title I want to fetch the posts custom taxonomy 'services_cat' - So then I can separate my search results within these categories. At the moment my below code will show the results all with the EXACT same category. So it's not actually pulling the posts right category, it's just pulling what I assume is first in the list.

Here is my code.

jQuery
(function( $ ) {
	$(function() {
		var url = MyAutocomplete.url + "?action=my_search";
		
		function split( val ) {
      return val.split( /,\s*/ );
    }
    function extractLast( term ) {
      return split( term ).pop();
    }
    function log( message ) {
      $( "<div>" ).text( message ).prependTo( ".selected-results" );
      $( ".selected-results" ).scrollTop( 0 );
    }
		
		$( "#autocomplete" ).autocomplete({
			source: url,
			appendTo: ".search-results",
      search: function() {
        // custom minLength
        var term = extractLast( this.value );
        if ( term.length < 2 ) {
          return false;
        }
      },
      focus: function() {
        // prevent value inserted on focus
        return false;
      },
      select: function( event, ui ) {
        log(ui.item.category + ui.item.value);
        var terms = split( this.value );
        // remove the current input
        terms.pop();
        // add the selected item
        terms.push( ui.item.value );
        // add placeholder to get the comma-and-space at the end
        terms.push( "" );
        this.value = terms.join( ", " );
        return false;
      },
      close: function (event, ui) {
        if (!$("ul.ui-autocomplete").is(":visible")) {
          $("ul.ui-autocomplete").show();
        }
      }
		});	
	});

})( jQuery );

Open in new window


The functions php
function my_search() {
		$term = strtolower( $_GET['term'] );
		$suggestions = array();
		
		$taxonomies = get_terms( 'services_cat', array(
        'hide_empty' => 1,
				'exclude' => array( 1 )
      )
    );
		
		$loop = new WP_Query( 's=' . $term );
		
		while( $loop->have_posts() ) {
			$loop->the_post();
			$suggestion = array();
			$suggestion['label'] = get_the_title();
			$suggestion['link'] = get_permalink();
      
      foreach( $taxonomies as $category ) {
	      $suggestion['category'] = $category->name;
	    }
			
			$suggestions[] = $suggestion;
		}
		
		wp_reset_query();
    	
    	$response = json_encode( $suggestions );
    	echo $response;
    	exit();

}

add_action( 'wp_ajax_my_search', 'my_search' );
add_action( 'wp_ajax_nopriv_my_search', 'my_search' );

Open in new window



The HTML (Not sure if this is really needed but just so everyone can see)
<input id="autocomplete" size="50" placeholder="Enter a search term">
        <div class="search-results"></div>
        <div class="selected-results"></div>

Open in new window



Any adivce will be greatly appreciated. Thank you
Avatar of leakim971
leakim971
Flag of Guadeloupe image

use chrome to run your test
BEFORE searching, do a right click on the page, for example on the search textbox and choose "inspect" element
now, go on the "Network" tab
below the tabs, locate for XHR and click on it to limit network log to Ajax call only
now do a search, a new line (maybe more than one if you type more than once) will appear
click on this line
click on the "response" tab for this line
select all, copy/paste the content here (maybe you want remove sensitive information)
(use the keyboard Ctrl+A to select all, Ctrl+C to copy, Ctrl+P to paste once you back to Expert-Exchange)
Avatar of Art Williams
Art Williams

ASKER

[{"label":"Synthetic hair","link":"{REMOVED}","category":"Class 9"},{"label":"Synthetic hairpieces","link":"{REMOVED}","category":"Class 9"}]

Okay so interesting, it seems the category at this stage is incorrect
I would try to var_dump the whole  $categorie or try to replace :
foreach( $taxonomies as $category ) {
            $suggestion['category'] = $category->name;
          }
by just, so you get all to see what is coming back  :
            $suggestion['category'] = $taxonomies;
That returns

[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
I think you're supposed to get taxonomies everytime for each post and not get all taxonomies (your php line 5) and loop line 19 to 21 on the same taxonomies
I can't get it to display the taxonomies properly, it just still shows all the object Object array
so use var_dump to see how that look, post the result here if needed:

function my_search() {
		$term = strtolower( $_GET['term'] );
		$suggestions = array();
		
		$taxonomies = get_terms( 'services_cat', array(  'hide_empty' => 1, 'exclude' => array( 1 )));
		var_dump($taxonomies); // it's not JSON, but you should be able to read the the network log
                exit();

}
add_action( 'wp_ajax_my_search', 'my_search' );
add_action( 'wp_ajax_nopriv_my_search', 'my_search' );

Open in new window

The array is quite large so I will paste a shortened version of it. It seems at this point the right categories (classes) are there.

array(44) {
  [0]=>
  object(WP_Term)#9601 (10) {
    ["term_id"]=>
    int(7)
    ["name"]=>
    string(7) "Class 1"
    ["slug"]=>
    string(7) "class-1"
    ["term_group"]=>
    int(0)
    ["term_taxonomy_id"]=>
    int(7)
    ["taxonomy"]=>
    string(12) "services_cat"
    ["description"]=>
    string(0) ""
    ["parent"]=>
    int(0)
    ["count"]=>
    int(2801)
    ["filter"]=>
    string(3) "raw"
  }
  [1]=>
  object(WP_Term)#9602 (10) {
    ["term_id"]=>
    int(15)
    ["name"]=>
    string(8) "Class 10"
    ["slug"]=>
    string(8) "class-10"
    ["term_group"]=>
    int(0)
    ["term_taxonomy_id"]=>
    int(15)
    ["taxonomy"]=>
    string(12) "services_cat"
    ["description"]=>
    string(0) ""
    ["parent"]=>
    int(0)
    ["count"]=>
    int(2823)
    ["filter"]=>
    string(3) "raw"
  }
  [2]=>
  object(WP_Term)#9603 (10) {
    ["term_id"]=>
    int(16)
    ["name"]=>
    string(8) "Class 12"
    ["slug"]=>
    string(8) "class-12"
    ["term_group"]=>
    int(0)
    ["term_taxonomy_id"]=>
    int(16)
    ["taxonomy"]=>
    string(12) "services_cat"
    ["description"]=>
    string(0) ""
    ["parent"]=>
    int(0)
    ["count"]=>
    int(2210)
    ["filter"]=>
    string(3) "raw"
  }
  [3]=>
  object(WP_Term)#9604 (10) {
    ["term_id"]=>
    int(17)
    ["name"]=>
    string(8) "Class 13"
    ["slug"]=>
    string(8) "class-13"
    ["term_group"]=>
    int(0)
    ["term_taxonomy_id"]=>
    int(17)
    ["taxonomy"]=>
    string(12) "services_cat"
    ["description"]=>
    string(0) ""
    ["parent"]=>
    int(0)
    ["count"]=>
    int(262)
    ["filter"]=>
    string(3) "raw"
  }
  [4]=>
  object(WP_Term)#9605 (10) {
    ["term_id"]=>
    int(18)
    ["name"]=>
    string(8) "Class 14"
    ["slug"]=>
    string(8) "class-14"
    ["term_group"]=>
    int(0)
    ["term_taxonomy_id"]=>
    int(18)
    ["taxonomy"]=>
    string(12) "services_cat"
    ["description"]=>
    string(0) ""
    ["parent"]=>
    int(0)
    ["count"]=>
    int(564)
    ["filter"]=>
    string(3) "raw"
  }
  [5]=>
  object(WP_Term)#9606 (10) {
    ["term_id"]=>
    int(19)
    ["name"]=>
    string(8) "Class 15"
    ["slug"]=>
    string(8) "class-15"
    ["term_group"]=>
    int(0)
    ["term_taxonomy_id"]=>
    int(19)
    ["taxonomy"]=>
    string(12) "services_cat"
    ["description"]=>
    string(0) ""
    ["parent"]=>
    int(0)
    ["count"]=>
    int(181)
    ["filter"]=>
    string(3) "raw"
  }
  [6]=>
  object(WP_Term)#9607 (10) {
    ["term_id"]=>
    int(20)
    ["name"]=>
    string(8) "Class 16"
    ["slug"]=>
    string(8) "class-16"
    ["term_group"]=>
    int(0)
    ["term_taxonomy_id"]=>
    int(20)
    ["taxonomy"]=>
    string(12) "services_cat"
    ["description"]=>
    string(0) ""
    ["parent"]=>
    int(0)
    ["count"]=>
    int(4149)
    ["filter"]=>
    string(3) "raw"
  }
  [43]=>
  object(WP_Term)#9644 (10) {
    ["term_id"]=>
    int(4)
    ["name"]=>
    string(7) "Class 9"
    ["slug"]=>
    string(7) "class-9"
    ["term_group"]=>
    int(0)
    ["term_taxonomy_id"]=>
    int(4)
    ["taxonomy"]=>
    string(12) "services_cat"
    ["description"]=>
    string(0) ""
    ["parent"]=>
    int(0)
    ["count"]=>
    int(10000)
    ["filter"]=>
    string(3) "raw"
  }
}

Open in new window

it's not actually pulling the posts right category, it's just pulling what I assume is first in the list.

it put the last one
so replace :
        foreach( $taxonomies as $category ) {
            $suggestion['category'] = $category->name;
        }

Open in new window

by :
        $suggestion['category'] = array();
        foreach( $taxonomies as $category ) {
            $suggestion['category'][] = $category->name;
        }

Open in new window


but you're going to have the same array for all posts
not sure that make sense
Here is my updated functions.php

function my_search() {
		$term = strtolower( $_GET['term'] );
		$suggestions = array();	
		
		$loop = new WP_Query( 's=' . $term );
		
		while( $loop->have_posts() ) {
			$loop->the_post();
			$suggestion = array();
			$suggestion['label'] = get_the_title();
			
			$suggestion['category'] = array();
			
      foreach( $taxonomies as $category ) {
        $suggestion['category'][] = $category->name;
      }
			
			$suggestions[] = $suggestion;
		}
		
		wp_reset_query();
    	
    	$response = json_encode( $suggestions );
    	echo $response;
    	exit();

}

Open in new window


It just loads the JSON with an empty category

[{"label":"Synthetic hair","category":[]},{"label":"Synthetic hairpieces","category":[]}]

Open in new window

It now loads each post with every single category
It now loads each post with every single category

this is what I'm saying here :
but you're going to have the same array for all posts
not sure that make sense

and here :
I think you're supposed to get taxonomies everytime for each post and not get all taxonomies (your php line 5) and loop line 19 to 21 on the same taxonomies

this is basically what you asked your code to do, so this is what you get
Oh sorry If I misunderstood, I want each post to have their correct category displayed, not all of them.
I want each post to have their correct category displayed

function my_search() {
    $term = strtolower( $_GET['term'] );
    $suggestions = array();

    $taxonomies = get_terms( 'services_cat', array(
            'hide_empty' => 1,
            'exclude' => array( 1 )
        )
    );

    $loop = new WP_Query( 's=' . $term );

    while( $loop->have_posts() ) {
        $loop->the_post();
        $suggestion = array();
        $suggestion['label'] = get_the_title();
        $suggestion['link'] = get_permalink();

        $suggestion['category'] = array();
        $categories = wp_get_post_categories($post->ID);
        foreach( $categories as $category ) {
            $suggestion['category'][] = $category->name;
        }
        $suggestions[] = $suggestion;
    }

    wp_reset_query();

    $response = json_encode( $suggestions );
    echo $response;
    exit();

}

add_action( 'wp_ajax_my_search', 'my_search' );
add_action( 'wp_ajax_nopriv_my_search', 'my_search' );

Open in new window

This question needs an answer!
Become an EE member today
7 DAY FREE TRIAL
Members can start a 7-Day Free trial then enjoy unlimited access to the platform.
View membership options
or
Learn why we charge membership fees
We get it - no one likes a content blocker. Take one extra minute and find out why we block content.