AngularJS: Best way to create a typeahead if search result contains 200 Items?

754 Views Asked by At

I'm using angular-bootsrap typeahead to provide a search functionality. For some cases the search data is almost consisting of more than 200 items which is taking a lot of time to create the DOM. What should be the best way to handle this amount of data? I tried to create a custom typeahead template consisting of pagination, however I'm not able to see anything being created in the DOM. This is where I stand :

The HTML

<td id="scrollable-dropdown-menu">
    <input type="text" ng-model="item.product" 
     placeholder="Search Product...." 
     uib-typeahead="product as product.name for product in searchProduct($viewValue)" typeahead-loading="loadingLocations" 
     typeahead-no-results="noResults"  
     typeahead-popup-template-url="customTypeaheadTemplate.html"
     class="form-control">
    <i ng-show="loadingLocations"  class="fa fa-spinner" aria-hidden="true"></i>
    <div ng-show="noResults">
       <i class="fa fa-times" aria-hidden="true"></i> No Results Found
    </div>
 </td>

customTypeaheadTemplate.html

<script type="text/ng-template" id="customTypeaheadTemplate.html">
    <div class="">
        <ul class="dropdown-menu" ng-show="isOpen() && !moveInProgress" ng-style="{top: position().top+'px', left: position().left+'px'}" style="display: block;" role="listbox" aria-hidden="{{!isOpen()}}">
            <li style="border-bottom: solid 1px lightgray" class="customFadeAnimate" ng-repeat="match in matches | startFrom:(currentPage*8)-8 | limitTo: 8 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>
            <div ng-click="$event.stopPropagation()" ng-hide="matches.length - 8 < 1" style="text-align:center;margin: 5px;color: #808080;min-width:250px">
                <span> {{((currentPage || 1)*8)-8+1}} to {{((currentPage || 1)*8 > matches.length) ? matches.length : (currentPage || 1)*8}} of {{matches.length}}     </span>
                <pager style="margin-top:-20px;margin-bottom:4px" total-items="matches.length" ng-model="currentPage" items-per-page="8" align="true" previous-text="Prev" next-text="Next"></pager>
            </div>
        </ul>
    </div>
</script>

The JS

$scope.searchProduct = function(viewValue){
      $scope.invalidProduct = false;
      if(viewValue.length < 3){
        return;
      }

      return $http.get('/api/v1/searchProducts', {
       params: {
         compId: user.companyId,
         name: viewValue
       }
     }).then(function(response){
       return response.data.map(function(item){
         item.quantity = 1;
         item.discount = 0;
         item.tax = 0;
         if(item.gst != null){
           item.tax = item.gst.rate;
         }
         item.subtotal = item.quantity * item.mrp
         item.subtotal = item.subtotal - (item.subtotal * item.discount/100);
         item.subtotal = item.subtotal + (item.subtotal * item.tax/100);
         return item;
       });
     });
   }

Sample JSON (item)

{
  "id": 858,
  "name": "COVER OIL FILTER",
  "mrp": 15,
  "sp": 0,
  "cp": 0,
  "stocks": 0,
  "isPublished": true,
  "partNumber": "15441KWS900S",
  "category": {
    "id": 2,
    "name": "oil",
    "created_at": "2017-06-03T10:29:44.000Z",
    "updated_at": "2017-06-03T10:29:44.000Z",
    "company_id": 1,
    "tax": 0
  },
  "gst": {
    "id": 1,
    "rate": 28,
    "name": "87141090",
    "remark": "NULL",
    "created_at": "2017-07-22T14:28:38.000Z",
    "updated_at": "2017-07-22T14:28:38.000Z",
    "company_id": 1
  },
  "quantity": 1,
  "discount": 0,
  "tax": 28,
  "subtotal": 19.2
}
0

There are 0 best solutions below