1

I would like to filter datatable table by a attribute class name. Here is some image. The idea is, to click on the star icon near the table header to show only entries, which are favorite.

enter image description here

I already tried some options how to achieve this, but it doesn't work. As I understood, I should define some keyup-listener for the star icon in the header. Here is some code I used by now:

$scope.dtInstanceCallback = function (dtInstance) {
                var table = dtInstance.DataTable;

                // Apply the search
                table.columns().eq(0).each(function (colIdx) {
                    if ($('i', table.column(colIdx).header())[0] != undefined) {
                        $('i', table.column(colIdx).header()).on('keyup', function () {
                            if ($scope.showFavorites) {
                                table
                                    .column(colIdx)
                                    .search('fa-star', false, false, true)
                                    .draw();
                            } else {
                                //here drop the search by the star value drop search
                            }
                        });
                    }
                });
            };

The $scope.showFavorites is just a variable containing true or false. I switch it's value when I ng-click the star icon. It's initially initialized with false:

$scope.showFavoriteOnly = function () {
                $scope.showFavorites = !$scope.showFavorites;


            };

A little problem is to no use the smart search, because the both icons (full star and empty star) differentiate only by a letter: fa-star and fa-star-o.

The .search function has been taken from https://stackoverflow.com/a/23931504/3402092.

Little Edit: I marked the column as search type string:

DTColumnDefBuilder.newColumnDef(0).withOption('orderDataType', 'fa-classes').withOption('sType', 'string')

So I can use the search-input to find fa-star-o.

Community
  • 1
  • 1
N.Zukowski
  • 600
  • 1
  • 12
  • 31

2 Answers2

1

I have the feeling, that what you really are looking for is a custom filter. A custom filter is a customized search / filter that can be either dynamic (as a regular search) or permanent, which mean that subsequent searches will be a subset of that custom filter, until it is removed.

I imagine you have columns with content like <i class="fa fa-star-o"></i> in the first column. You can implement two custom filters that filters out rows with fa-star / fa-star-o this way :

$scope.starFilter = function() {
  $.fn.dataTable.ext.search.push(
    function( settings, data, dataIndex ) {         
      return $(data[0]).hasClass('fa-star')
    }    
  )
  $scope.dtInstance.DataTable.draw()
  $.fn.dataTable.ext.search.pop() //remove this line to make the filter persistent
}

$scope.starOFilter = function() {
  $.fn.dataTable.ext.search.push(
    function( settings, data, dataIndex ) {         
      return $(data[0]).hasClass('fa-star-o')
    }    
  )
  $scope.dtInstance.DataTable.draw()
  $.fn.dataTable.ext.search.pop() //remove this line to make the filter persistent
}

Here invoked by a button click

<button ng-click="starFilter()">star filter</button>

demo -> http://plnkr.co/edit/hUSZ0XpRDZPjERsr0vF5?p=preview

The very great advantage of this approach is that you can make the filter persistent. If you not pop() the filter then subsequently user searches will be a subset of the filter subset itself, for example within "favorites", all rows with a fa-star icon.

davidkonrad
  • 83,997
  • 17
  • 205
  • 265
  • @Sirion, Thank you for accepting the answer! It was a long shot with custom filter, but I think you will like it more. Using it myself a lot to for example filter rows between date range, and then the user can search within that range, or as you filtering certain types of row out. – davidkonrad Jun 25 '16 at 20:34
  • 1
    your solutions works, but not in my case. I load icons from DB as html, and when I inspect `data` the column with the icon is a large empty string. So I decided to access column on another way. But somehow, I cannot get the filtering and sorting work together. I created a plunker with my case, could you please have a look at it? http://plnkr.co/edit/PRu8bZI0vO1ocgvjW9oA?p=preview. Somehow this simple functionality took already a lot of my time. – N.Zukowski Jun 26 '16 at 00:55
  • @Sirion, can it wait to tomorrow? It is 03.16 here in DK, and I have been drinking alcohol (it is summertime in DK). I will look into it tomorrow (sunday) – davidkonrad Jun 26 '16 at 01:18
  • It's not a problem at all. – N.Zukowski Jun 26 '16 at 10:40
  • 1
    Ok, I made it work now. I update the plunker, if you will want to have a look at it: http://plnkr.co/edit/PRu8bZI0vO1ocgvjW9oA?p=preview . P. S. jQuery is a mess. – N.Zukowski Jun 26 '16 at 17:08
1

I my case the data[index] was empty (don't really know why). But I managed to get it working with following function:

$.fn.dataTable.ext.search.push(
   function (settings, data, index, rowData, counter) {
      return $(rowData[0]).hasClass('fa-star');
   }
);

I replaced data with rowData and managed to access the html-object.

The desired functionality is shown here: plnkr.co/edit/PRu8bZI0vO1ocgvjW9oA?p=preview

N.Zukowski
  • 600
  • 1
  • 12
  • 31