Search code examples
angularjsautocompleteangular-ui-bootstrapangular-uitypehead

AngularUI-Bootstrap Typeahead: Grouping titles by type


I am implementing typeahead using AngularUI-Bootstrap. I need to show the results grouped based on some values coming from the database. Here's a example of result

[{
    "id": 1,
    "label": "type_1",
    "titles": [{
        "id": 1,
        "label": "title_1"
    }, {
        "id": 2,
        "label": "title_2"
    }, {
        "id": 3,
        "label": "title_3"
    }]
}, {
    "id": 2,
    "label": "type_2",
    "titles": [{
        "id": 4,
        "label": "title_4"
    }, {
        "id": 6,
        "label": "title_6"
    }]
}, {
    "id": 3,
    "label": "type_3",
    "titles": [{
        "id": 8,
        "label": "title_8"
    }, {
        "id": 9,
        "label": "title_9"
    }]
}]
  • How can grouping titles by type in AngularUI-Bootstrap Typeahead

Solution

  • JB Nizet is right, you should use a custom template (default). Look at

    // view
    <script type="text/ng-template" id="typeahead-match.html">
      <div ng-if="match.model.isGroup">{{match.label}}</div>
      <a ng-if="!match.model.isGroup" ng-bind-html="match.label | uibTypeaheadHighlight:query">
        &nbsp;&nbsp;{{match.label}}
      </a>
    </script>
    
    <input
      type="text"
      ng-model="selected"
      uib-typeahead="item as item.label for item in getItems($viewValue)"
      class="form-control"
      typeahead-template-url="typeahead-match.html">
    
    // controller
    myApp.controller('MainController', ['$scope', function($scope) {
      var data = [{
        "id": 1,
        "label": "type_1",
        "titles": [{
          "id": 1,
          "label": "title_1"
        }, {
          "id": 2,
          "label": "title_2"
        }, {
          "id": 3,
          "label": "title_3"
        }]
      }, {
        "id": 2,
        "label": "type_2",
        "titles": [{
          "id": 4,
          "label": "title_4"
        }, {
          "id": 6,
          "label": "title_6"
        }]
      }, {
        "id": 3,
        "label": "type_3",
        "titles": [{
          "id": 8,
          "label": "title_8"
        }, {
          "id": 9,
          "label": "title_9"
        }]
      }];
    
      $scope.getItems = function(text) {
        var result = [];
    
        _.each(data, function(group) {
          result.push({
            label: group.label,
            isGroup: true
          });
    
          _.each(group.titles, function(item) {
            if(_.startsWith(item.label, text)) {
              result.push(item);
            }
          });
    
          if(result && result[result.length-1].isGroup) {
            result.pop();
          }
        });
    
        return result;
      };
    }]);
    

    Example