0
votes

I have a Slickgrid grid (dataView) populated with data, quick filter (example-header-row.html), checkbox row selectors (example-checkbox-row-select.html) with syncGridSelection (https://github.com/mleibman/SlickGrid/wiki/DataView#synchronizing-selection--cell-css-styles). All is working fine.

By default the quick filters places a input box in the checkbox column. It would be nice if one could filter by checkboxes (rows) ALREADY selected, but I don't think any input text is possible for filtering? So, instead, I have turned off the filter input only in the checkbox column and re-placed it with a toggle button which I'm hoping could filter by checkboxes/rows already selected.

I've seen some code with the grid.getSelectedRows() but not sure how to use this in the dataView especially with the syncGridSelection function.

My goal is to toggle/filter on and off checkboxes already selected in the dataView grid for viewing. Code suggestion, examples would be much appreciated.


Maybe I need to describe what I'm looking for differently. Lets say I have 10,000 rows of data in my grid. A end user selects checkbox/row number 1, row number 450, and row number 999. After they are finished selecting rows, they will probably want to review which rows they selected. Instead of having them scroll through all 10,000 records to see what they have selected, it would be nice to filter upon which rows they already selected. Once filtered, the grid would only show 3 rows, rows 1, 450, and 999. When the filter is removed then all 10,000 records would show.

I've been approaching this problem at the filter level but struggling. Using a text based filter: The first example below would be reading the child and checking if its checked.

The second example below would be checking if "this" row number is in the array of grid.getSelectedRows(). The problem with the second approach is I'm not sure how to get the current row number we are checking against.

Any suggestions on code below?

function filter(item) {
for (var columnId in columnFilters) {
  if (columnId !== undefined && columnId != "_checkbox_selector" && columnFilters[columnId] !== "") {
    var c = grid.getColumns()[grid.getColumnIndex(columnId)];
    if (item[c.field] != columnFilters[columnId]) {
      return false;
    }               
  } else if (columnId == "_checkbox_selector") {
      /* something like....
      if input checkbox is NOT checked
      return false;
      */
  }       
}   
return true;
}

-- OR --

function filter(item) {
var rows = grid.getSelectedRows();
for (var columnId in columnFilters) {
  if (columnId !== undefined && columnId != "_checkbox_selector" && columnFilters[columnId] !== "") {
    var c = grid.getColumns()[grid.getColumnIndex(columnId)];
    if (item[c.field] != columnFilters[columnId]) {
      return false;
    }               
  } else if (columnId == "_checkbox_selector") {
     /* something like.... 
     var isFound = rows.indexOf(this.row);  
     if (isFound == -1) {
         return false;
     }
    */
  }       
}   
return true;
}         
2

2 Answers

1
votes

This is how I solved the problem. Maybe not the best solution, but it works. After following SlickGrid examples mentioned in the first paragraph of this post, I create my data objects by calling a setData function and passing my values. The value for rowIndex is a counter starting with 0 for the first object, 1 for the second object, etc.

var setData = function(rowIndex, fieldOne, fieldTwo) {
    var d = (data[rowIndex] = {});          
    d["id"] = rowIndex;
    d["c0"] = fieldOne;
    d["c1"] = fieldTwo;         
}

I then changed the default filter to the below code.

var columnFilters = {};
function filter(item) {
    var rows = grid.getSelectedRows(); // array of lines already selected 
    for (var columnId in columnFilters) {
        if (columnId !== undefined && columnId != "_checkbox_selector" && columnFilters[columnId] !== "") {
            var c = grid.getColumns()[grid.getColumnIndex(columnId)];
            if (item[c.field] != columnFilters[columnId]) {
                return false;
            }               
        } else if (columnId !== undefined && columnId == "_checkbox_selector" && columnFilters[columnId] !== "") {
          var dataViewSelectedRowIds = dataView.mapRowsToIds(grid.getSelectedRows());
          var isFound = dataViewSelectedRowIds.indexOf(item.id);  
          if (isFound == -1) {
            return false;
          }
        }       
    }   
    return true;
}

Now any character type in the checkbox filter input field will now show only checkbox selected lines in the dataView grid. Once the character is removed all lines selected or not will be displayed. Probably not the most intuitive for the end user, but works. I personally will be changing the checkbox filter input field with a font icon like a flag (solid for on and outlined for off) which will toggle the checkbox selected lines.

0
votes

If I understand you correctly, you're essentially asking for a typed filter function. This has been needing doing for a while.

The easiest approach would be to add a property 'filterAsType' to each column, and then add some code to the filter header management function to cast the text to the requisite type (eg. Y/N/True/False => boolean, 5 jan 2017 => Date) before passing to the filter function itself.

A fancier option would involve a proper UI in the filter cell, like a checkbox, dropdown or date picker. This, while definitely possible and probably not even that complicated, is a lot more work than the text based option.

You should check out my repo, it's much more up to date and has a lot of small enhancements.