How to implement Checkbox column - Working with filters and sorting

Tags: #<Tag:0x00007f8b267e9600>

Hi… I have added a checkbox column and a check/uncheckAll option in the Handsontable. after checkbox are clicked , Any actions like filter or sorting of a particular column affects the checkbox values. currently we consider RowId check and uncheck option. i have other unique columns but the logic is getAfterRenderer which was added in the configuration of Handsontable , calls everytime and doesnt work at all .

Do we have the option of controlling the data before and after the Row Filtration and sorting along with the checkbox - ( to classify which are all checked or unchecked - as we consider only the checked ones for some operations

Can anyone pls help me with some samples ?..

Hi @raghavansrini711

in this demo, you can check how afterColumnSort and afterFilter work on checkbox type data https://jsfiddle.net/styk9hb6/2/

Thanks. Let me provide my sample code of current implementation

Actually my requirement is dynamic, means i have the column name and its column type - refers as checkbox or hyperlink. Based on the column type i have below function written and it has been assigned to

configuration has

settingOverrides.cells = getCellsCallback(settingOverrides);

var getCellsCallback = function (settingOverrides) {
  return function (row, col, prop) {

    var tableName = settingOverrides.tableName;

    var schemaName = settingOverrides.schemaName;

    // Turn off row colour coding if constructing a modal hot.

    if (settingOverrides.container == 'modal-hot') {

      tableName = null;

      schemaName = null;

    }

    return formattingService.conditionalFormatting(this, row, schemaName, tableName, settingOverrides.viewConfigurationData, settingOverrides.data, settingOverrides.hyperlinksCollection, settingOverrides.IsCallFrmScopeInspection);

  };

};

 var conditionalFormatting = function (cell, row, schemaName, tableName, 
 viewConfigurationData, TableSourecData, hyperlinkCollections, 
 isCallFromScopeInspection) {

  var cellProperties = {};

  currentTable = tableName;

  currentSchema = schemaName;

  TableSourecData = TableSourecData;

  // Sometimes the cell is passed through the application with an undefined

  // status usually on double click, or sorting. This check is used to

  // prevent the application crashing in this case. Also cell row is being

  // passed in as null in some cases. Have no idea why.

 

  if (typeof cell !== 'undefined' && cell.row !== null) {

    var rowdata = cell.instance.getSourceDataAtRow(row);

      // Get generic cell formatting rules based on what is defined in the

      // TABLE_CONFIGURATION table

      cellProperties = getColumnCellProperties(cell.prop, viewConfigurationData,rowdata, hyperlinkCollections, isCallFromScopeInspection);

      if(cellProperties)        

      // Apply cell conditional formatting rules in correct heirachy.

      // Firstly on edit cell rules. Then row conditional formatting rules.

      if (cell.comment) {

          cellProperties = editingRules(cellProperties, cell);

      } else {

          cellProperties = rowRules(cellProperties, cell, row);

      }

      return cellProperties;

  }

};

 var getColumnCellProperties = function (columnName, viewConfigurationData, rowdata, 
 hyperlinkCollections, isCallFromScopeInspection) {

  var cellProperties = {};

  if (isCallFromScopeInspection) {

    // this condition is only for Scope inspection tool which return dropdown result

    if (columnName === "CML_REPRESENTIVE") {

        var cmlArray = convertCommaSeparatedValuesToArray(rowdata.CML_REPRESENTIVELIST);

        cmlArray.sort(function(a, b) {

            return a - b;

        });

        cellProperties.source = cmlArray;

        cellProperties.type = "dropdown";

    }

    if (columnName === "Scoped") {

        cellProperties.renderer = getCellRenderer("checkbox");

    }

    cellProperties.className = getAlignmentName("MIDDLE");

    if (columnName === "INSPECTION_COUNT") {

        cellProperties.className = cellProperties.className + ' ' + getCellColor(rowdata.INSPECTION_COUNT)

    }

}

  if (viewConfigurationData) {

    var columnDetails = lookupColumnDetails(columnName, viewConfigurationData);

    if (columnDetails) {

      cellProperties.type = getCellDataType(columnDetails.DATA_TYPE);

      cellProperties.source = convertCommaSeparatedValuesToArray(columnDetails.DROPDOWN_LIST);

      cellProperties.className = getAlignmentName(columnDetails.ALIGNMENT) + ' ' + getCalculatedStatus(columnDetails.CALCULATED);

      cellProperties.format = columnDetails.DATA_FORMAT;

      if(columnDetails.DATA_TYPE  === 'hyperlink')

         {

           var link = lookupHyperlink(columnDetails.COLUMN_NAME,rowdata, hyperlinkCollections);

           if(link){

           cellProperties.hyperlinkLocation =link}

           else{

            cellProperties.hyperlinkLocation = columnDetails.HYPERLINK_LOCATION;

            cellProperties.hyperlinkFileExtension = columnDetails.HYPERLINK_FILE_EXTENSION;

           }              

         }          

      cellProperties.renderer = getCellRenderer(columnDetails.DATA_TYPE);

    }

  }

  return cellProperties;

};

 var getCellRenderer = function(dataType) {

        if (dataType === 'hyperlink') {

            return safeHtmlRenderer;

        } else if (dataType === 'checkbox') {

            return checkboxHTMLRender;

        } else {

    // Renderer for content that might be longer than the cell size, show a tooltip on hover

    return longContentRenderer;

  }

};

 function checkboxHTMLRender(instance, td, row, col, prop, value, cellProperties) {

      Handsontable.renderers.TextRenderer.apply(this, arguments);

      if (col === 0) {

          var txt;

          var isChecked = false;

          txt = "<input type='checkbox' id=" + row + " class='checkboxchecker' ";

          txt += isChecked ? 'checked="checked"' : '';

          txt += ">";

          td.innerHTML = txt;

      }

  }

Now during the checkbox click- i am storing a array list to add those unique values and rowids. Now how to get the control of data during filter. Coz for each event eg. scrolling , filtering , handsontable calls the after rederrer and it actually loops and calls the render function for each row.

Question is simple - how to save the rows of which it got checked= true ( As already told i am saving in array) and again even after the filtering some thing and unfiltering should retain this checkbox data( true or false ) and should provide me to control it and display it back to UI.
Pls help

The afterChange hook is triggered once someone changes a value, so this

afterChange: function(){
  	console.log(this.getSourceData())
  }

would give you a recent data source. And here https://jsfiddle.net/z79uoa8r/2/ is a mechanism for gathering checkbox index on change and the boolean value that comes with the change https://jsfiddle.net/z79uoa8r/2/
But this hook is not triggered when user filters or sorts data.

So may i know how to handle when during filters and sorts ?

I do not have an exact demo for that. But what I would do to keep the accurate state of the checkboxes is to call the getSourceData() after data is loaded and then update it with the afterChange hook. After user sorts or filters those values do not change - only there is a different set of row indexes in the table.

1 Like

I just tried to implement afterChange. the call to afterChange is not happening when we do some action. Ie. In my table it is first column checkbox click but that is not reaching the function. Neither sorting nor clicking on checkbox column fires the afterChange function…

Hi @raghavansrini711

do you use the built-in checkbox cell type? I checked the default checkbox and it triggers afterChange. Here is a working demo https://jsfiddle.net/q76b3yhg/1/

No. since data are dynamic i am not using built in

           var container = $("#container-div");

           container.on('mouseup', 'input.checkboxchecker', function (event) {
         
            var obj = {};

            var checkboxState = !$(this).is(':checked'); //returns boolean

            var id = $(this).attr('id') //get the checkbox id

            if (checkboxState) {

                obj["RowID"] = id;

                obj["checkboxStatus"] = checkboxState;

                $rootScope.RowID.push(obj);

            } else {

                $rootScope.RowID = jQuery.grep($rootScope.RowID, function (value) {

                    return value["RowID"] != id;

                });

            }

        });

based on the data type during the creation of table. Based on the configuration and based on the first column below code will create check box and check it.

  function checkboxHTMLRender(instance, td, row, col, prop, value, cellProperties) {

  Handsontable.renderers.TextRenderer.apply(this, arguments);

  if (col === 0) {

      var txt;

      var isChecked = false;

      txt = "<input type='checkbox' id=" + row + " class='checkboxchecker' ";

      txt += isChecked ? 'checked="checked"' : '';

      txt += ">";

      td.innerHTML = txt;

  }

}

So i am using mouse up function to check that particular checkbox. but the value of the checkbox should be synced with the actual data,. Pls help me …
If handsontable has sync operation it would be helpful…

  1. i am going click on check box it is true. it should be synced to the memory
  2. again i am going to sort and came back to the actual sorted order it should be available and it should be checked true.
    some kind of field memory kind of thing i would require… right now i am always sending false from data base. checking the checkbox should be stored in the table memory and even after i do several filters sort, checked row should keep that in memory…

Could you tell me why you use the textRenderer with an input checkbox instead of the setCellMeta with type checkbox?

I have used to render below content… This was done by some person which i am not sure… From here how to proceed and to control the values during checkbox check uncheck along with filter and sorting in handsontable…

// Custom renderer for allowing download links in table cells

          function safeHtmlRenderer(instance, td, row, col, prop, value, cellProperties) {

            Handsontable.renderers.TextRenderer.apply(this, arguments);        

            if(value)

            {  

              //var link=value.split(",");

              var escaped = Handsontable.helper.stringify(value);

              escaped = strip_tags(escaped, '<script>');

              td.innerHTML = "<a href='" + cellProperties.hyperlinkLocation + "' title='" + escaped + "' target='_blank'>" + escaped + "</a>";

            }

            else{

              var escaped = Handsontable.helper.stringify(value);

              // be sure you only allow certain HTML tags to avoid XSS threats (you

              // should also remove unwanted HTML attributes)

              escaped = strip_tags(escaped, '<script>');

              td.innerHTML = "<a href='" + cellProperties.hyperlinkLocation + escaped + cellProperties.hyperlinkFileExtension + "' title='" + escaped + "' target='_blank'>" + escaped + "</a>";

            }      

          }

          function longContentRenderer(instance, td, row, col, prop, value, cellProperties) {

            // Applys built-in renderer

            Handsontable.renderers.TextRenderer.apply(this, arguments);

            if (instance.getDataAtCell(row, col) != null && instance.getDataAtCell(row, col).length > 10) {

              td.title = value;

              td.id = row;

            }

          }

            function checkboxHTMLRender(instance, td, row, col, prop, value, cellProperties) {

                Handsontable.renderers.TextRenderer.apply(this, arguments);

                if (col === 0) {

                    var txt;

                    //var isChecked = false;

                    txt = "<input type='checkbox' id=" + row + " class='checkboxchecker' ";

                    txt += value == true ? 'checked="checked"' : '';

                    txt += ">";

                    td.innerHTML = txt;

                }

            }

@aleksandra_budnik - did you got some clue to make use of existing code and with few modifications can we able to filter and sort with checkbox ?

Hi @raghavansrini711
I know that it is hard to work on the code that was written by someone else. I propose to talk the project over on emails and discuss what is the best approach to move forward. You can reach me at support@handsontable.com

Hi @aleksandra_budnik …good news is i have replaced my custom UI hack of checkbox to built in one which u shared… I could able to use inbuilt one. and i can able to do this implementation…Now In this i have faced below issues
i have a checkbox button outside the handsontable that does check and uncheck all row checkboxes.

  1. i am clicking checkall button and if i uncheck even one. entire rows are unchecked…

  2. i am clicking checkall button and when i scroll the rows it is getting unchecked all the rows in the table …

FYI- iam using handson table “version”: “8.2.0”,
additional questiom - if we upgraded will the latest version affect my version of table ??
pls help…

There have been some changes within the major version that you should check. Here is the full list of changes https://handsontable.com/docs/release-notes/

Here are additional pages to review. Those are our migration guides

ps. could you please open a new ticket when requested for a new topic? That would help us a lot to manage the tickets.