Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Angularjs plugin smart table st-search through random text entered like datatablejs search #835

Open
dhavebarsalote96636677 opened this issue May 15, 2018 · 7 comments

Comments

@dhavebarsalote96636677
Copy link

Hi, i have used this angular plugin and it works very well with massive rows of data (6K rows). But i noticed something that whenever I do search for items using st-search, it does not allow me to search through text, for example i have this item description: "BOSCH AQUATAK DIY HIGH PRESSURE WASHER AQT 33-11" and so i type to the input field "BOSCH WASHER". No data is displayed. What should I do to fix this. I have looked into the st-search directive:

ng.module('smart-table')
  .directive('stSearch', ['stConfig', '$timeout','$parse', function (stConfig, $timeout, $parse) {
    return {
      require: '^stTable',
      link: function (scope, element, attr, ctrl) {
        var tableCtrl = ctrl;
        var promise = null;
        var throttle = attr.stDelay || stConfig.search.delay;
        var event = attr.stInputEvent || stConfig.search.inputEvent;
        var trimSearch = attr.trimSearch || stConfig.search.trimSearch;

        attr.$observe('stSearch', function (newValue, oldValue) {
          var input = element[0].value;
          if (newValue !== oldValue && input) {
            ctrl.tableState().search = {};
            input = ng.isString(input) && trimSearch ? input.trim() : input;
            tableCtrl.search(input, newValue);
          }
        });

        //table state -> view
        scope.$watch(function () {
          return ctrl.tableState().search;
        }, function (newValue, oldValue) {
          var predicateExpression = attr.stSearch || '$';
          if (newValue.predicateObject && $parse(predicateExpression)(newValue.predicateObject) !== element[0].value) {
            element[0].value = $parse(predicateExpression)(newValue.predicateObject) || '';
          }
        }, true);

        // view -> table state
        element.bind(event, function (evt) {
          evt = evt.originalEvent || evt;
          if (promise !== null) {
            $timeout.cancel(promise);
          }

          promise = $timeout(function () {
            var input = evt.target.value;
            input = ng.isString(input) && trimSearch ? input.trim() : input;
            tableCtrl.search(input, attr.stSearch || '');
            promise = null;
          }, throttle);
        });
      }
    };
  }]);

how can I update this to have the below image results when i do searchl.

image

@MrWook
Copy link
Contributor

MrWook commented May 15, 2018

Hello @dhavebarsalote96636677,

the stSearch directive is using a normal search. That means if you use the "Global search" it will search for the text "acc 33" in any of the column. Therefore for the Smart-Table the given text is nowhere to be found.
What you want here is that the "Global search" split the text at spaces and search in every column with every item from the splited text.
This kind of search is something that you need to do on your own. You can extend the stSearch directive or create a new one for this purpose.

But just a info you can create a column based search for every column

@dhavebarsalote96636677
Copy link
Author

dhavebarsalote96636677 commented May 16, 2018

Hello @MrWook ,
Yes indeed i need to create my own in order to achieve this. Why I am requiring it to act in this behavior, is because some of our users search for word like : "Bosch diy washer" when they happen to forgot the exact words of an item, when having the original value of the column as : " BOSCH AQUATAKÂ DIY HIGHÂ PRESSURE WASHER AQT". (I highlighted the search word the user searched).
What I have tried so far was:
altering the smart-table.js search() function when receiving the input value.
Dhave, [16.05.18 08:41]

    this.search = function search(input, predicate, comparator) {
      var predicateObjects;
      var prop;

      var strVar = input.toLowerCase().split(/\s+/);

      var predicateObjects = tableState.search.predicateObject || {};
      prop = predicate ? predicate : '$';

      for (var i = 0; i < strVar.length; i++) {
        $parse(prop).assign(predicateObjects, strVar[i]);
        // to avoid to filter out null value  
          if (!strVar) {
          deepDelete(predicateObjects, prop);
        }
      }       
      tableState.search.predicateObject = predicateObjects;
      tableState.pagination.start = 0;
      return this.pipe();
    };

That's all i have for now, it can now search for keymatch. The problem is it can't watch previous word to strictly filter the result waiting for the next key.

This guys, get's it but I wan't his logic applied to smart-table stSearch.
https://stackoverflow.com/questions/42023387/angular-smart-search-on-wildcard#

@MrWook
Copy link
Contributor

MrWook commented May 16, 2018

Oh boi i'm sorry i forgot there is a directive st-set-filter for this kind of case. Here is the filter for a global search.

app.filter('filterByObjectName', function ($filter) {
	return function(input, predicate){
		var returnArray = [];
			angular.forEach(predicate, function(value, key){
				var searchTextSplit = value.toLowerCase().split(' ');
				for (var x = 0; x < input.length; x++) {
					var count = 0;
					for (var y = 0; y < searchTextSplit.length; y++) {
						let propertyValue = input[x][key];
						if (propertyValue.toLowerCase().indexOf(searchTextSplit[y]) !== -1) {
							count++;
						}
					}
					if (count == searchTextSplit.length) {
						returnArray.push(input[x]);
					}
				}
			});
		return returnArray;
	}
});

After that you need to add the filter to the directive:
<table st-table="displayCollection" st-set-filter="filterByObjectName" class="table table-striped">

@dhavebarsalote96636677
Copy link
Author

Thank you @MrWook, I am able to get the expected result from the logic above, I just replaced
let propertyValue = input[x][key];
to
let propertyValue = input[x].ItemName;

Then, right now if I leave the st-Search field empty, the table has no data.

@dhavebarsalote96636677
Copy link
Author

Why all of a sudden after making it work, it just out of no where my propertyValue becomes Null?

@dhavebarsalote96636677
Copy link
Author

Maybe you did something not right and resulted to incorrectiveness of the programmability of your coding.

@MrWook
Copy link
Contributor

MrWook commented Jun 12, 2018

You can't just copy paste something from the internet you need to adjust it to your needs.
I wrote that this filter is only for the global search. If you use ItemName(probably your own property from your data) instead of key this won't work anymore because if you search for something and don't have the property ItemName, propertyValue will be Null.
If you just changed the value key into ItemName thats okey but don't try to use a variable as a JavaScript property that won't work. It need to be called as an array.
input[x][ItemName];

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants