KoolReport's Forum

Official Support Area, Q&As, Discussions, Suggestions and Bug reports.
Forum's Guidelines

ClientEvent index Column with DataTables #2078

Closed Keith opened this topic on on May 13, 2021 - 6 comments

Keith commented on May 13, 2021

I'm trying to implement an index column that is rendered client side. Exactly like this example: https://datatables.net/examples/api/counter_columns.html where the index always stays the same no matter the column re-ordering and filtering.

This is my code from my view.php

    <?php
    DataTables::create(
        array(
            "name"      => "reportTable",
            "dataSource" => $this->dataStore("result"),
            "cssClass"   => array(
                "table" => "table  table-bordered table-striped table-hover nowrap"
            ),
            "plugins"    => ["Buttons"],
            "options"    => array(
                "searching"  => true,
                "paging"     => TRUE,
                "buttons"    => ["csv", "excel", "pdf", "colvis"],
                "scrollX"    => TRUE,
                "fastRender" => TRUE
            ),
            "clientEvents"=>array(
                "draw"=>"function(e,dt,type,indexes, reportTable){
                    console.log('test');

                    var tab = $('#reportTable').DataTable({
                        retrieve: true,
                        'columnDefs': [ {
                            'searchable': false,
                            'orderable': false,
                            'targets': 0
                        } ],
                        'order': [[ 1, 'asc' ]]
                    });

                    tab.on( 'order.dt search.dt', function () {
                            tab.column(0, {search:'applied', order:'applied'}).nodes().each( function (cell, i) {
                            cell.innerHTML = i+1;
                        } );
                    } ).draw();
                    
                }",
                
                )
            ));
            
    ?>

I have a couple issues:

1. console.log('test'); isn't executing when I first refresh the page. Which I believe it should when it draws the DataTable for the first time?

2. An infinite loop is running because I'm calling draw every time a draw function is called. I've tried other events such as 'pre-row-reorder', 'row-reorder', 'row-reordered', 'init'. So far I can only seem to see my console logs with the draw clientEvent.

Is this the right way to implement an index column with Koolreports on the client side?

Thank you.

Sebastian Morales commented on May 13, 2021

Pls add the search listener in "onReady" property, i.e after DataTables is loaded and ready:

    DataTables::create(array(
        "name" => "reportTable",
        ...,
        "onReady" => "function() { 
                    reportTable.on( 'order.dt search.dt', function () {
                            reportTable.column(0, {search:'applied', order:'applied'}).nodes().each( function (cell, i) {
                            cell.innerHTML = i+1;
                        } );
                    } ).draw();
        }"
    ));

Let us know if this does what you want. Tks,

Keith commented on May 13, 2021

I added the onReady property, and I can see the function is running when I put console.logs, but no new column is being drawn. Instead, its treating the very first column as the index column. Can I instead prepend a new column to the beginning?

Sebastian Morales commented on May 13, 2021

You might have to convert the following js property to DataTables' options in php:

                        retrieve: true,
                        'columnDefs': [ {
                            'searchable': false,
                            'orderable': false,
                            'targets': 0
                        } ],
                        'order': [[ 1, 'asc' ]] 

"clientEvents" is for attaching client events directly to the widget while "onReady" is a script meant to be run after the widget is created. In your case you can also use this:

    DataTables::create(array(
        "name" => "reportTable",
        ...,
        "clientEvents" => array(
            'order.dt search.dt' => "function () {
                        reportTable.column(0, {search:'applied', order:'applied'}).nodes().each( function (cell, i) {
                            cell.innerHTML = i+1;
                        } );
                    }",
    ));
Keith commented on May 13, 2021

Sorry I edited my previous comment.

The onReady property is running, but now it's treating the first column in my original dataStore('results') as the index column instead of creating a new column. Is it possible to create a new column instead?

Sebastian Morales commented on May 13, 2021

Just add an empty fake column to DataTables like this:

$columns = ["indexColumn" => ["label" => "Index", "formatValue" => function($value, $row] { return ""; }];
$columns = array_merge($columns, $this->dataStore("result")->meta()["columns"]);
    DataTables::create(array(
        "name" => "reportTable",
        "columns" => $columns,
        ...
Keith commented on May 13, 2021

Works! Thanks you.

Build Your Excellent Data Report

Let KoolReport help you to make great reports. It's free & open-source released under MIT license.

Download KoolReport View demo
help needed

DataGrid