col vis changes and adding to cells: rowCallback or columns.render or ?

col vis changes and adding to cells: rowCallback or columns.render or ?

vttimcvttimc Posts: 4Questions: 1Answers: 0

Description of problem:
I'm trying to add an info icon to the first visible cell in each row.

Using columns.render works great, but means changes to column visibility via the built in col vis button make that cell go away and takes the info icon with it. I do like that I know I'm only changing the display orthogonal data with this function.

          aoColumns[1].render = function( data, type, row, meta ) {
                if (type === 'display') {
                        sInfoHtml = "** Extended info - click to open as dialog to copy-paste **\n";

                        for (var key in row) {
                                var sData = row[key];
                                if (sData != null)  {
                                        sData = sData.replace(/(<([^>]+)>)/ig,""); // we need to strip out tags so the hover will show everything
                                }
                                
                                 sInfoHtml += "   " + key + ": " + sData + "\n";
                        }
                        sInfoHtml += "";

                        return '<span class="ui-icon ui-icon-info hoverinfoicon noTableToolsRowSelect" title="' + sInfoHtml + '"></span>' + data;
                }

                return data;
        };

               $( "#mytable" ).DataTable({
                        columns: aoColumns,

Using DataTable.rowCallback is even cleaner - I use $('td:eq(0)', row).prepend(iconhtml) and the info icon now always goes on the leftmost column. But if the col vis button is used to change visibility and removes the leftmost column, the icon won't get added until the next table draw. (Which doesn't happen automatically after col vis changes.). I'm also not sure if I'm breaking the orthogonal data, or if at this point I'm only changing display values.

               $( "#mytable" ).DataTable({
                        "rowCallback": function (row, data) {
                                sInfoHtml = "** Extended info - click to open as dialog to copy-paste **\n";
        
                                for (var key in data) {
                                        var sData = data[key];
                                        if (sData != null)  {
                                                sData = sData.replace(/(<([^>]+)>)/ig,""); // we need to strip out tags so the hover will show everything
                                        }
                                        
                                         sInfoHtml += "   " + key + ": " + sData + "\n";
                                }
                                sInfoHtml += "";
        
                                // use the td:eq(0) selector so we always put the info icon on the first column, regardless of column visibility choices
                                $('td:eq(0)', row).prepend('<span class="ui-icon ui-icon-info hoverinfoicon noTableToolsRowSelect" title="' + sInfoHtml + '"></span>');
                        },

So I either need to use a different callback that does get called after the col vis button is changed, or find another way?

Answers

  • kthorngrenkthorngren Posts: 20,991Questions: 26Answers: 4,887

    Try using the column-visibility to call draw() to execute rowCallback.

    Kevin

  • vttimcvttimc Posts: 4Questions: 1Answers: 0

    For now, this feels like a cludgy fix, but is working. Inside initComplete I added a trigger to force a draw on every column-visibility.dt:

    $( "#mytable" ).DataTable({
    initComplete: function() {
                                    this.on('column-visibility.dt', function(e, settings, column, state ) {
                                            this.api().draw(false);
                                    });
    
    });
    
  • kthorngrenkthorngren Posts: 20,991Questions: 26Answers: 4,887

    You may need to use $('td span.ui-icon', row).remove(); to keep from building up the info icon each time the visibility changes.

    Not sure why you think its cludgy but you don't need to initiate the event in initComplete. I would probably pass "page" into draw() instead of false to keep from recalculating the ordering and searching which hasn't changed. For example:
    https://live.datatables.net/tewajalu/1/edit

    Kevin

Sign In or Register to comment.