1

Smart-table has a built in functionality to search through all columns (st-search) or through one desired column (st-search="'firstName'). Is it possible to do a search within several columns (not all)? Example: if I have table like this: name, nickname, address with such data:

  1. John, JJ, Some address
  2. Steve, John, also address
  3. Jane, Jane, John-village

and do a search for 'John' only first two columns should be as result. Is it possible?

1
  • I suggested a way to solve the problem. Take a look at the answer! Commented Sep 14, 2015 at 15:18

5 Answers 5

4

I have a similar problem and I solved using the hints in this post.

Smart Table doc says:

The stSetFilter replaces the filter used when searching through Smart Table. When the default behavior for stSearch does not meet your demands, like in a select where one entry is a substring of another, use a custom filter to achieve your goals.

and:

Note that st-safe-src is required for the select to properly display all distinct elements in the collection. Should this be omitted, the select would only contain values from elements visible in table, also affected by paging.

You can declare your own filter inside table element in HTML:

<table ... st-set-filter="myCustomFilter" class="table table-striped">

...and your can customize your filter (in your app) through a predicate function. It could work in this way:

// filter method, creating `myCustomFilter` a globally
// available filter in our module
.filter('myCustomFilter', ['$filter', function($filter) {

  // function that's invoked each time Angular runs $digest()
  return function(input, predicate) {
    searchValue = predicate['$'];
    //console.log(searchValue);
    var customPredicate = function(value, index, array) {
      console.log(value);

      // if filter has no value, return true for each element of the input array
      if (typeof searchValue === 'undefined') {
        return true;
      }

      var p0 = value['name'].toLowerCase().indexOf(searchValue.toLowerCase());
      var p1 = value['nickname'].toLowerCase().indexOf(searchValue.toLowerCase());
      if (p0 > -1 || p1 > -1) {
        // return true to include the row in filtered resultset
        return true;
      } else {
        // return false to exclude the row from filtered resultset
        return false;
      }
    }

    //console.log(customPredicate);
    return $filter('filter')(input, customPredicate, false);
  }
}])

I made this little plnkr to see the filter in action

Sign up to request clarification or add additional context in comments.

Comments

1

Nope, a workaround is to create you own directive which require the table controller and call its api twice (as the search get added)

directive('stSearch', ['$timeout', function ($timeout) {
    return {
        require: '^stTable',
        scope: {
            predicate: '=?stSearch'
        },
        link: function (scope, element, attr, ctrl) {
            var tableCtrl = ctrl;

            // view -> table state
            element.bind('input', function (evt) {
                evt = evt.originalEvent || evt;
                tableCtrl.search(evt.target.value, 'column1');
                tableCtrl.search(evt.target.value, 'column2');
            });
        }
    };
}]);

you'll find more details in the stSearch direcitve

2 Comments

I played with a part of code you suggested, but it looks like It is filtering and not searching through multiple columns. Or maybe I am missing something :) Take a look at my plunker What I am expecting in example is to get result with three rows (1,4;4,1 and 1,1), when searching for '1' in both columns.
I have tested this code in Angular 1.5.x and it fails to search through multiple fields.
0

You can solve the issue by creating the new search enabled table and combining the fields that you might be showing in one column. example:if you have IdNo1 and IdNo2 as view fileds in One column, you can combine them to add the new element in the table array.

View :

table injection:

table st-table="displayedCollection" st-safe-src="rowSearchCollection"

Search injection:

input type="search" ng-model="idSearch" st-search="idSearch" 

Controller:

$scope.rowSearchCollection = [];
vm.searchEnabledTable = function(tableDetails) {
    //$scope.rowSearchCollection = angular.copy(tableDetails); 
    var deferred = $q.defer();              
      if(_.isArray(tableDetails)) {
          _.each(tableDetails, function(element, index, list) {
            $scope.rowSearchCollection[index] = angular.copy(element);
            $scope.rowSearchCollection[index].idSearch = element.IdNo1+','+element.IdNo2;


          });
          deferred.resolve("DATA_PROCESSED");
      } else {
          deferred.reject("NOT_ARRAY");
      }             
      return deferred.promise;
}

Comments

0

the problem with stSetFilter is that the new filter will be to all the searchs (st-search) that you will use in the table.

Another idea: If your data rowCollection is not too big, in the javascript in the init() of the page do something like:

self.rowCollection.forEach(function (element) {

element.NameForFilter = element.name+ ' ' + element.nickName;
});

and then in the input of the th: st-search=NameForFilter

Comments

-1

try st-search="{{firstName + nickname}}". I tried with smart table v2.1.6 and seems working.

2 Comments

This answer is wrong. It's like st-search without parameters SO you search in everything
I tried this solution. As noted earlier it returns everything. Would be a nice feature but currently this does nothing in Smart Table other than search all.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.