I'd like to add a custom footer to the results where I can wire up some paging. I see that I can specify a footer template in the options, but can't find any examples of how to set those options from a controller.
The footer template would display "Now showing 1-{{offsetEnd}} of {{result.count}} Load More
Thank you everyone!
This is the tag I'm using:
< input type = "text"
id = "search"
name = "search"
ng - model = "profile.selectedProfile"
typeahead = "o.itemvalue as o.itemtext for o in getProfiles($viewValue) | filter: $viewValue"
typeahead - input - formatter = "formatLabel($model)"
class = "form-control"
autocomplete = "off" / >
UPDATE I converted this to a directive, and incorporated a footer that displays the total record count.
function findProfile() {
return {
restrict: 'E',
template: '<input type="text" id="search" name="search" ng-model="selectedProfile" typeahead="o as o.itemtext for o in getProfiles($viewValue) | filter: $viewValue" typeahead-input-formatter="formatLabel($model)" class="form-control" autocomplete="off" />',
controller: function($scope, $http) {
$scope.itemCount = 0;
$scope.getProfiles = function(searchtext) {
return $http.get('http://localhost:61402/api/Profile/FindProfile?searchText=' + searchtext)
.then(function(response) {
$scope.itemCount = response.data.itemcount;
return response.data.items;
});
}
$scope.formatLabel = function(model) {
return model == undefined ? '' : model.itemtext;
}
}
};
}
And the template:
angular.run(['$templateCache',
function($templateCache) {
var template = '' +
'<ul class="dropdown-menu" ng-show="isOpen()" ng-style="{top: position.top+\'px\', left: position.left+\'px\'}" style="display: block;" role="listbox" aria-hidden="{{!isOpen()}}">' +
'<li ng-repeat="match in matches track by $index" ng-class="{active: isActive($index) }" ng-mouseenter="selectActive($index)" ng-click="selectMatch($index)" role="option" id="{{match.id}}">' +
'<div typeahead-match index="$index" match="match" query="query" template-url="templateUrl"></div>' +
'</li>' +
'<li>Records Returned: {{$parent.itemCount}}</li>' +
'</ul>';
$templateCache.put('template/typeahead/typeahead-popup.html', template);
}
])
Ok, so I had to perform a bit of a hack here, but I liked your question.
What I ended up working with was the typeahead-template-url
. Unfortunately, the documentation for it is very hard to find, yet I had done a lot of work with this in the past. For some of the documentation, try here. Even more unfortunate, I never documented where I found the default typeahead-template-url
either, and I couldn't find it online today. Luckily, I did have my version of it on file.
Here is what I had before hacking at it:
<a>
<span bind-html-unsafe="match.model.label | myModelLabelFilter"></span>
</a>
As you can guess, this is the template
for each match shown in the Angular Typeahead
, and placing a filter
here (myModelLabelFilter
in our example) is a great way to modify and inject mostly whatever you want into each shown match.
Now, this may not have been the best way to add one button to the bottom of the typeahead
popup, but it's the only thing that I could think of. So, we will need to only show a button after the last match
. How about ng-if
.
<a>
<span bind-html-unsafe="match.model.label | cmcTicketingTypeaheadFilter"></span>
</a>
<div
ng-if="($parent.$parent.matches.length - 1) === index"
style="border-top:1px solid #DDDDDD;"
>
Example
<button
ng-click="$emit('foo', this)"
class="bt btn-primary"
>
Click To Emit
</button>
</div>
...purposely formatted weird to avoid scroll-bars...
..and this is what I got:
You may be wondering... what the $parent.$parent.matches
thing is all about.
First of all, we are working in the scope
of the Typeahead Directive
.
In this scope
we have three values: match
, index
, and query
. I needed to move up the scope
levels until we reached a parent scope
that had a listing of all returned matches
. Every scope
has the $parent
attribute, showing its parent scope
.
NOW, for your full answer! I am not sure how you plan to access your scope
for your offsetEnd
variables, but I would suggest making it accessible on your matches.
Instead of passing an array of strings
, you can pass an array of objects. This is why my template shows match.model.label
. I used an array of objects where each object was:
{
label: 'Alabama'
value: 0
}
This way I can grab any value I want from a user selection, not just the label. I would suggest placing a value on these options here somewhere and using ng-if
to help you do the matches
paging like you are talking about.
Good Luck! Hope that helped! And dang, as I was typing this up someone posted another answer!