Typeahead With Results Starting With Query Ranked Higher
Solution 1:
I tried Ben's approach which may be right in most cases, but for me it din't work because I have recursive ng-includes and cannot make use of ng-model.
Here is how I solved my problem (it's a little of a hack, I admit, but I'd call it a clean hack):
I misuse the following filter purposely, in order to save viewValue and the property on which the filter is applied as queryObj
in my typeaheadService
before ordering. I also use it to filter on a property of choice.
app.filter('typeaheadFilter', ['typeaheadService', function (typeaheadService) {
returnfunction (input, queryObj) {
var key = Object.keys(queryObj)[0],
query = queryObj[key];
typeaheadService.setQueryObject(queryObj); // called once, when the viewValue changesif (!query) {
return input;
}
var result = [];
angular.forEach(input, function (object) {
if (object[key].toLowerCase().indexOf(query.toLowerCase()) !== -1) {
result.push(object);
}
});
return result;
};
}]);
And here is how the typeaheadService
looks like (this service is used to set and get the query object for all typeaheads):
app.factory('typeaheadService', [
function () {
var typeaheadQueryObj;
return {
getQueryObject: function () {
return typeaheadQueryObj;
},
setQueryObject: function (queryObj) {
typeaheadQueryObj = queryObj;
}
};
}
]);
In my MainController
I add my smartOrder
function to the $scope
:
$scope.smartOrder = function (obj) {
var queryObj = typeaheadService.getQueryObject(),
key = Object.keys(queryObj)[0],
query = queryObj[key];
if (obj[key].toLowerCase().indexOf(query.toLowerCase()) === 0) {
return ('a' + obj[key]);
}
return ('b' + obj[key]);
};
Finally, my typeahead
:
typeahead="element.name for element in elements | typeaheadFilter:{name:$viewValue} | orderBy:smartOrder | limitTo:dropdownMenuLimit"
Solution 2:
You would need to change the orderBy, not the filter. Maybe doing a function instead of a property on the orderBy would achieve the desired effect.
Possibly something like
$scope.typeAheadModel = '';
$scope.orderByPriority = function (element) {
return element.name.indexOf($scope.typeAheadModel);
}
And in your HTML add an ng-model
on your input
ng-model="typeAheadModel" typeahead="element.name for element in someObject.elements | filter:{name:$viewValue} | orderBy:orderByPriority
edit
Here's a plunkr of it, for some reason it doesn't do it properly when you type in just "f", but once you type in "fo" it orders it correctly. Not sure why.
Solution 3:
Bens Approach is not bad, it was useful to me, but it has a problem if your list contains uppercases.
so you have to transform the two endpoints:
$scope.typeAheadModel = '';
$scope.orderByPriority = function (element) {
var lower_model = $scope.typeAheadModel.toLowerCase();
var lower_name = element.name.toLowerCase();
return lower_name.indexOf(lower_model);
}
Post a Comment for "Typeahead With Results Starting With Query Ranked Higher"