Skip to content

Instantly share code, notes, and snippets.

@pkozlowski-opensource
Last active November 12, 2018 06:33
Show Gist options
  • Star 8 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pkozlowski-opensource/4998969 to your computer and use it in GitHub Desktop.
Save pkozlowski-opensource/4998969 to your computer and use it in GitHub Desktop.
AngularJS Typeahead interface design

Examples

Simple, static array

 $scope.states = ['Alabama', 'California', 'Delaware', ...] 

would be used as:

<input ng-model='state' typeahead='states | filter:$viewValue'>

and model would be bound with a selected item from an array.

Simple array, retrieved from async call

 $scope.getStates = function($viewValue) {
   //hey, we can return promises and typeahead will understand them!
   return $http.get('/mybackend/states', {
    params : {query: $viewValue}
   }).then(function(response){
     //assuming that backend will return an array here
     //I can do any transformations, sorting, limiting etc. at this point
     return response.data; 
   });
 }

would be used as:

<input ng-model='state' typeahead='getStates($viewValue)'>

Static array of objects

 $scope.states = [{name: 'Alabama'}, {name: 'California'}, {name: 'Delaware'}, ...] 

would be used as:

<input ng-model='state' typeahead='state.name for state in states | filter:$viewValue>

Model will be bound with a full object, ex.: {name: 'California'}

Arrays of complex objects

 $scope.states = [{code: 'AL', name: 'Alabama'}, {code: 'CA', name: 'California'}, {code: 'DE', name: 'Delaware'}, ...] 

would be used as:

<input ng-model='state' typeahead='state.name+' ('+state.code+')' as state.code for state in states | filter:$viewValue | orderBy:"name"'>

Model will be bound with a state code, ex.: CA while label will be combination of a name and code: California (CA)

Arrays of complex objects retrieved via $http

<input ng-model='state' typeahead='state.name+' ('+state.code+')' as state.code for state in getStates($viewValue)'>

where the filtering and orderign would be done inside the getStates function.

General syntax

Generally spaking syntax is very similar to the one used by the <select> directive: http://docs.angularjs.org/api/ng.directive:select Those combination would be supported:

  • typeahead='sourceExpression' - source for the typeahead, where sourceExpression can be either an array or a promie resolving to an array. A special variable $viewValue is available while evaluating this expression
  • typeahead='labelExpression for tempVariable in sourceExpression'
  • typeahead='labelExpression as modelToBeBound for tempVariable in sourceExpression'

All the filtering and ordering can be done in expressions so no options are needed for this. Same for higlighting (!).

The only options (other attributes) that would stay are:

  • typeahead-min-length - The minimum character length needed before triggering autocomplete suggestions - defaults to 1
  • typeahead-item-template - killer here - people could specify a template (or templateUrl!) for an individual item so people can add makup referencing other directives (for example.: ng-src to include images in typeahead results)
@rgaskill
Copy link

Is your complex object example above is the typeahead syntax backwards?

<input ng-model='state' typeahead="state.name+' ('+state.code+')' as state.code for state in states | filter:$viewValue | orderBy:'name'">

In order to bind the state code to the model and the label to state and code shouldn't it be:

    <input ng-model='state' typeahead="state.code as state.name+' ('+state.code+')'  for state in states | filter:$viewValue | orderBy:'name'">

@lheneks
Copy link

lheneks commented Apr 12, 2013

The typeahead functionality works great, but on page load for an input that already has data, I see [object] in the input field instead of the 'as' expression result

see
http://plnkr.co/edit/jUaXmSCyb0aEdixb5SN4?p=preview

@dapids
Copy link

dapids commented Jun 6, 2013

I think that @rgaskill is right. The following syntax seems to work fine to me.

<input ng-model='state' typeahead="state.code as state.name+' ('+state.code+')'  for state in states | filter:$viewValue | orderBy:'name'">

The only problem is that when the page is loaded the input field contains the string " ()". Is there any way to have an empty input field instead?

Thanks in advance for your help.
David

EDIT: solved by using a function in the "as" field. ;)

@pkozlowski-opensource
Copy link
Author

@lheneks

This was fixed in 0.4.0: http://plnkr.co/edit/6GJ450MuYIkHaaWzvU6h?p=preview

BTW, you don't need dependencies on jQuery, jQuery-UI and all this nonsense to use directives from http://angular-ui.github.io/bootstrap/ effectively.

@adoueb
Copy link

adoueb commented Mar 23, 2015

Hello,

I'm trying to use AngularJS typeahead with an array of complex objects.
But it doesn't work.

Plunker: http://plnkr.co/edit/X3C0fP52ZTi55LJtXfnu?p=preview

Could you please help me ?

Regards,
Agnes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment