I have used the jQuery UI Autocomplete demo source code for the Categories example (http://jqueryui.com/autocomplete/#categories) and have it working (querying a database which returns a JSON array).
I'm building a search function for an art gallery and my categories are Artists and Exhibitions. I want to show results from one or both categories. My problem is that results are only showing when the search term covers a result in both categories.
My suggestions script uses the search term to query two different database tables. I format and append the results into a single JSON array with rows for ["id"], ["value"], ["label"] and ["category"].
So for the search term CORN, the results that come back might be:
{ label: "Christopher Corner", category: "Artists" },
{ label: "New Pictures From Cornwall", category: "Exhibitions" },
{ label: "Cornie Collins", category: "Artists" },
At the moment when I type a search term, the possible results are only shown as long as a result is possible in ALL my categories, rather than what I want, which is one or more. So when I type CORN, I can see an Artist named Corner, and an Exhibition about Cornwall, but the minute I type the E of CORNE, all the options disappear, including the Artist whose name is Corner (which I would expect to remain).
I'm new to jQuery and jQuery UI and struggling to understand where the logic would be to select a list item from any category rather than all of them.
I have edited to add my code. This is the backend suggestions file - search_suggestions.php:
<?php
# if the 'term' variable is not sent with the request, exit
if (!isset($_REQUEST['term'])) {
exit;
}
# retrieve the search term that autocomplete sends
$term = trim(strip_tags($_GET['term']));
$a_json = array();
$a_json_row = array();
# connect to database, send relevant query and retrieve recordset
include 'includes/db_access.php';
$compoundFind = $fm->newCompoundFindCommand('web_Artists');
$request1 = $fm->newFindRequest('web_Artists');
$request2 = $fm->newFindRequest('web_Artists');
$request1->addFindCriterion('Last name', '*'.$term.'*');
$request2->addFindCriterion('First name', '*'.$term.'*');
$compoundFind->add(1, $request1);
$compoundFind->add(2, $request2);
$compoundFind->addSortRule('Last name', 1, FILEMAKER_SORT_ASCEND);
$result = $compoundFind->execute();
if (FileMaker::isError($result)) {
die();
}
$records = $result->getRecords();
# loop through records compiling JSON array
foreach ($records as $record) {
$artistID = htmlentities(stripslashes($record->getRecordID())) ;
$artistName = htmlentities(stripslashes($record->getField('Full name'))) ;
$a_json_row["id"] = $artistID;
$a_json_row["value"] = $artistName;
$a_json_row["label"] = $artistName;
$a_json_row["category"] = "Artists";
array_push($a_json, $a_json_row);
}
$findCommand = $fm->newFindCommand('web_Exhibitions');
$findCommand->addFindCriterion('Title', '*'.$term.'*');
$result = $findCommand->execute();
if (FileMaker::isError($result)) {
die();
}
$records = $result->getRecords();
foreach ($records as $record) {
$exhibitionID = htmlentities(stripslashes($record->getField('Exhibition ID'))) ;
$exhibitionTitle = htmlentities(stripslashes($record->getField('Title'))) ;
$a_json_row["id"] = $exhibitionID;
$a_json_row["value"] = $exhibitionTitle;
$a_json_row["label"] = $exhibitionTitle;
$a_json_row["category"] = "Exhibitions";
array_push($a_json, $a_json_row);
}
echo json_encode($a_json);
flush();
?>
And here is the JS in my section which sets things up:
<style>
.ui-autocomplete-category {
font-weight: bold;
padding: .2em .4em;
margin: .8em 0 .2em;
line-height: 1.5;
}
</style>
<script>
$.widget( "custom.catcomplete", $.ui.autocomplete, {
_create: function() {
this._super();
this.widget().menu( "option", "items", "> :not(.ui-autocomplete-category)" );
},
_renderMenu: function( ul, items ) {
var that = this,
currentCategory = "";
$.each( items, function( index, item) {
var li;
if ( item.category != currentCategory ) {
ul.append( "<li class='ui-autocomplete-category'>" + item.category + "</li>" );
currentCategory = item.category;
}
li = that._renderItemData( ul, item );
if ( item.category ) {
li.attr( "aria-label", item.category + " : " + item.label );
}
});
}
});
</script>
<script>
$(function() {
$( "#searchInput" ).catcomplete({
minLength: 2,
source:'search_suggestions.php'
});
});
</script>
Finally this is the actual input field on the page:
<input class="u-full-width" placeholder="Search" id="searchInput" />
Sorry if this is too much code!