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

K
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.

S
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,

K
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?

S
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;
                        } );
                    }",
    ));
K
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?

S
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,
        ...
K
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