I am encountering a usability problem with AngularStrap Typeahead and wondering if anyone else has experienced this or possibly has a workaround. Any feedback is appreciated, seriously.
The problem can easily be demonstrated from this plunkr, which i JUST created from the AngularStrap documentation and ripped out all the unnecessary stuff, just focusing on the problem at hand.
http://plnkr.co/edit/MlTb0wN5vRJ9NeaigrGX?p=preview
In the icon search box, type: class="fa fa-
And notice that all four icons show up. Now add a "g" to the end and watch it become limted to the gear icon. Why is that? Because the label value in $scope.icons has all share the same prefix for the icons, of course. Now imagine that you have a more complex template, or something that shares much more in common between elements, like this:
Item1: <img src="http://myawesomehost/atmygreatlocation/somewhere/abc.jpg> ABC
Item2: <img src="http://myawesomehost/atmygreatlocation/somewhere/lmnop.jpg> LMNOP
Item3: <img src="http://myawesomehost/atmygreatlocation/somewhere/xyz.jpg> XYZ
Because there are so many common characters here and TypeAhead is matching the entire value, including the urls, virtually ANYTHING you type in will result in a match.
If there is no work around, I have a hard time believing that anyone would be able to use this as end users will always complain that the search results don't match what they are typing.
Any thoughts?
Cheers! Stabby
By default, the bs-typeahead
directive will append this filter to your ng-options
:
| filter:$viewValue
It means if any properties in an item contains $viewValue
(text that you typed), that item will show up.
If you want to filter on specific fields e.g. only value
not label
, you could put a filter in the ng-options
directly like this:
ng-options="icon as icon.label for icon in icons | filter: { value: $viewValue }"
Or an alternative would be pass your custom filter like this:
<input ... data-filter="myFilter" bs-typeahead />
And put the filtering logic in your custom filter:
.filter('myFilter', function (filterFilter) {
return function (items, searchValue) {
return filterFilter(items, { value: searchValue });
};
});
Example Plunker: http://plnkr.co/edit/iX8S8VSTHNAzQftSIFvf?p=preview