I've got an instance of Typeahead pulling in a remote JSON object that lists airports, and I need to group them in the suggestions by 'location groups', as in the image below:
...and here's an example of how the JSON is formatted:
{
"locations":[
{
"name":"London Intl Apt (YXU), Middlesex, Ontario, Canada",
"type":"airport",
"id":"528cc236e4b0ec1df53b21af",
"iata":"YXU",
"locationGroup":"",
"locationGroupName":""
},
{
"name":"London - Gatwick Apt (LGW), West Sussex, England, United Kingdom",
"type":"airport",
"id":"528cc236e4b0ec1df53b28cb",
"iata":"LGW",
"locationGroup":"LON",
"locationGroupName":"London - All Airports (LON)"
},
{
"name":"London - Heathrow Apt (LHR), Greater London, England, United Kingdom",
"type":"airport",
"id":"528cc236e4b0ec1df53b28b1",
"iata":"LHR",
"locationGroup":"LON",
"locationGroupName":"London - All Airports (LON)"
}
]
}
So where an item has a 'locationGroup' value it should be grouped with all other items with the same 'locationGroup'. If there is no 'locationGroup' it should just be listed individually.
I'm guessing that (assuming this is possible) this should be done when I'm setting up the Bloodhound engine - possibly within the Filter - but I'm really struggling to work out how. Can anybody help with this?
What is Typeahead? Typeahead, or autocomplete, is a feature in which an application guesses the rest of a word as the user inputs it. In most graphical user interfaces, users can accept a suggestion by hitting the tab key or many suggestions by pressing the down arrow key.
In real-world applications, we always an API endpoint to get results to show in suggestions as a user types the query. NgxTypeahead neatly handles server-side responses with debounce feature already added which earlier we added using custom RxJS operators in Angular Material Autocomplete.
Typeahead is basically an Input field where user can type and get matching results in a dropdown list to select from. Article compatible with Angular version starting 4+ up to latest version including 6,7,8,9,10,11 and 12.
Conclusion: NgxTypeahead package is a stand-alone Autocomplete module which is free from any dependencies. It can be a good option if you are not looking for Angular Material like UI frameworks.
Unfortunately, it seems the only way to get headers and sections in your Typeahead.js is to follow their Multiple Sections with Headers example. Their code is not entirely complete as to what they are doing so I'll try and mimic your code and their example.
// Get the data
var londonUk = new Bloodhound({
datumTokenizer: function(d) { return Bloodhound.tokenizers.whitespace(d.name); },
queryTokenizer: Bloodhound.tokenizers.whitespace,
prefetch: '../data/londonUk.json'
});
var londonCa = new Bloodhound({
datumTokenizer: function(d) { return Bloodhound.tokenizers.whitespace(d.name); },
queryTokenizer: Bloodhound.tokenizers.whitespace,
prefetch: '../data/londonCa.json'
});
// Intialize the Bloodhound
londonUk.initialize();
londonCa.initialize();
// Set up Typeahead
$('.transit-search .typeahead').typeahead({
highlight: true
},
{
name: 'London UK All Airports',
displayKey: 'name',
source: londonUk.ttAdapter(),
templates: {
// This is the group header that will be shown at the top of a grouping
header: '<h3 class="group-name">London - All Airports (LON)</h3>',
// These will be the templates for the items within a group.
suggestion: Handlebars.compile(['<p class="indent">{{name}} {{type}}</p>'])
}
},
{
name: 'London CA All Airports',
displayKey: 'name',
source: londonCa.ttAdapter(),
templates: {
header: '<h3 class="group-name">London, ON, Canada - All Airports</h3>',
suggestion: Handlebars.compile(['<p class="indent">{{name}} {{type}}</p>'])
}
});
The difficulty here lies in making your data work with the way that Typeahead.js wants the data structured so it can make groups out of it. You could pass back one giant JSON file and then sort out each airport into its own list that you can then use as a local data variable for each of the Bloodhound initializations or you could make a query for every JSON file and airport you support, like I've done with the example above.
The first one would probably be more consistent and makes considerably less hits to the server but will require some data massaging to get going but you already have a variable for the group in each item so this shouldn't be too difficult. This will require a lot of initialization but I think the grouping will work out just as you want it to.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With