angularjsangular-ui-bootstrapangular-ui-typeaheadangularjs-templates

How to move code of ngTemplate to an actual file?


I'm using AngularJS (not Angular) with the Typeahead directive of UI Bootstrap. For customization one can define a custom template by inserting a script tag of type text/ng-template. This works fine, see example below.

Example

<script type="text/ng-template" id="customTemplate.html">
  <a>
      <img ng-src="http://upload.wikimedia.org/wikipedia/commons/thumb/{{match.model.flag}}" width="16">
      <span ng-bind-html="match.label | uibTypeaheadHighlight:query"></span>
  </a>
</script>

Usage

<input type="text" ng-model="customSelected" placeholder="Custom template" uib-typeahead="state as state.name for state in statesWithFlags | filter:{name:$viewValue}" typeahead-template-url="customTemplate.html" class="form-control" typeahead-show-hint="true" typeahead-min-length="0">

However, this becomes messy quickly, when the template is more complex and requires additional CSS code. Furthermore, my code editor does not highlight the code properly, when it is wrapped in such a script tag.

Is there any way to move this template to an actual file customTemplate.html (without the wrapping script tag), and then include or reference it as needed (i.e. for the typeahead)? It's a bit confusing also to have an id with a file extension, but then defining the template in-place.

Source

The example above is based on the Typeahead documentation of UI Bootstrap.


Solution

  • I figured out a solution myself. It is pretty easy, to be fair. Just omit the script tag and put the content of the template in a separate HTML file.

    <a>
        <img ng-src="http://upload.wikimedia.org/wikipedia/commons/thumb/{{match.model.flag}}" width="16">
        <span ng-bind-html="match.label | uibTypeaheadHighlight:query"></span>
    </a>
    

    Then reference the file name in the typeahead-template-url attribute:

    <input type="text" ng-model="customSelected" placeholder="Custom template" uib-typeahead="state as state.name for state in statesWithFlags | filter:{name:$viewValue}" typeahead-template-url="customTemplate.html" class="form-control" typeahead-show-hint="true" typeahead-min-length="0">
    

    There is no need for any additional ngInclude or anything, AngularJS will pick up the external file automatically, as long as you reference the correct path.

    Who whould have guessed that it is this easy!