简体   繁体   中英

How to sort list start with first and then contains string search in md-autocomplete AngularJS

I'm new to angularJs and want to filter the search result.

Here is the example : https://codepen.io/anon/pen/mpJyKm

I want search result based on query input filtered such as string starts with come first in the result list and then contains. I'm using md-autocomplete example and want to filter list in controller only.

e.g. If search input is : A
then result should be like this :
Alabama
Alaska
Arizona
Arkansas
California
Colorado
...

tried this for filtering result but returning Starts with or contains in any order without filtering as I need:

function createFilterFor(query) {
    var lowercaseQuery = angular.lowercase(query);
    return function filterFn(state) {
    return (state.value.indexOf(lowercaseQuery) != -1);
    };
}

You can use querySearch() function like this:

function querySearch (query) {
  var q = angular.lowercase(query);
  var results = self.states
    .reduce(function(res, state) {
      var idx = state.value.indexOf(q);
      if(idx === 0) {
        res[0].push(state)
      } else if(idx > 0) {
        res[1].push(state)
      }
      return res;   
    },[[],[]])
  return results[0].concat(results[1]);
}

You can go through all states and put those that match query into one of two arrays: the first one is where the state starts from query, and the second if the match is in the middle. After forming these arrays, you can concat them. Since your allStates are already sorted alphabetically, you don't need to apply extra sorting afterwards.

Also, if you want to highlight the matching pattern in case-insensitive way, you should add md-highlight-flags="i" to your item template

<md-item-template>
    <span md-highlight-text="ctrl.searchText" 
          md-highlight-flags="i">{{item.display}}</span>
</md-item-template>

CodePen: https://codepen.io/anon/pen/QajOqj/

您可以使用

md-items="item in querySearch(searchText) | orderBy : 'fieldName'"

Vadim's is an excellent solution. Here's a generic TS version:

interface QuerySearchProps {
  query: string;
  data: any;
  propToMatch: string;
}

export const querySearch = ({query, data, propToMatch}: QuerySearchProps) => {
  const q = query.toLowerCase();
  const results = data.reduce(
    function (res: any, item: any) {
      const idx = item[propToMatch].toLowerCase().indexOf(q);
      if (idx === 0) {
        res[0].push(item);
      } else if (idx > 0) {
        res[1].push(item);
      }
      return res;
    },
    [[], []],
  );
  return results[0].concat(results[1]);
};

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM