Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Grouping suggestions with sub headings in Typeahead

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:

enter image description here

...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?

like image 400
ParkerDigital Avatar asked Mar 03 '14 09:03

ParkerDigital


People also ask

What is typeahead?

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.

How ngxtypeahead handles server-side responses?

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.

What is type ahead in angular?

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.

Is ngxtypeahead a good option?

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.


1 Answers

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.

like image 196
ericsaupe Avatar answered Nov 06 '22 22:11

ericsaupe