Joe B.
Joe B.

Reputation: 820

AngularJS md-autocomplete return all possible substrings

I'm using md-autocomplete to let users search through subjects at my university.

The problem is my search function only searches sequentially (left to right) through each display value.

For example: If I search "Arts and Architecture" I get "no results found", which I do not want to happen.

I would like "Arts and Architecture" to return a result.

The subjects are in this format:

$scope.subjects = [
  {
    value: 'AA',
    display: 'AA - Arts and Architecture'
  },
  {
    value: 'AAAS',
    display: 'AAAS - African/Afr Amer Studies'
  },
  {
    value: 'ABA',
    display: 'ABA - Applied Behavior Analysis'
  },
  {
    value: 'ABE',
    display: 'ABE - Ag and Biological Engineering'
  }
]

Here is my search method:

$scope.searchQuery = function(text) {
  text = text.toUpperCase();
  var result = $scope.subjects.filter(function(item) {
    return item.display.includes(text);
  });
  return result;
}

Here is my html:

<md-autocomplete 
   md-selected-item="selectedItem"
   md-search-text="searchText" 
   md-items="item in searchQuery(searchText)" 
   md-item-text="item.display" 
   md-min-length="0" 
   placeholder="Select a subject">
  <md-item-template>
    <span md-highlight-text="searchText">{{item.display}}</span>
  </md-item-template>
  <md-not-found>
    No matches found.
  </md-not-found>
</md-autocomplete>

Upvotes: 0

Views: 217

Answers (3)

Matthew Cawley
Matthew Cawley

Reputation: 2818

Problem

This is due to case sensitivity, i.e. you're actually doing the equivalent of...

"Arts and Architecture".includes("ARTS AND ARCHITECTURE"); // false

...and because includes is case sensitive, it returns false. It just so happened to work at the beginning of your string because all of the letters are uppercase and the input too was uppercase:

"AA".includes("AA"); // true (fluke!)

Solution

If you make item.display and text both uppercase it should work:

$scope.searchQuery = function(text) {
  var result = $scope.subjects.filter(function(item) {
    return item.display.toUpperCase().includes(text.toUpperCase());
  });
  return result;
}

Upvotes: 1

Mohammad Umair Khan
Mohammad Umair Khan

Reputation: 410

"includes" function checks only if searched string exists in target string or not. For md-autocomplete to work, you need to match those objects from the array which contains your searched text or part of searched text. Modify your code to:

$scope.searchQuery = function(text) {
    var result = $scope.subjects.filter(function(item) {
       if (item.display.toUpperCase().indexOf(text.toUpperCase()) >-1)
          return item;
});
    return result;
}

Upvotes: 0

guilhebl
guilhebl

Reputation: 8990

As per documentation JS method str.includes(searchString[, position]) states:

Params: position -> Optional. The position within the string at which to begin searching for searchString.(defaults to 0).

so your code is starting from index 0.

How about using indexOf instead ? changing this line: return item.display.includes(text);

to return item.display.indexOf(text) !== -1;

Upvotes: 0

Related Questions