Naila Akbar
Naila Akbar

Reputation: 3358

Return angular datatable on angular datatable rowCallback function

I've an angular datatable with nested data and I'm trying to create another datatable on row click function.. rowCallBack function of parent datatable.

This is my outer datatable html;

<table id="tblEmailsByCase" datatable="" dt-options="dtCaseOptions" dt-columns="dtCaseColumns" dt-instance="dtCaseInstance" class="display table table-striped table-bordered table-hover">
    <!-- THIS TABLE IS GENERATED DYNAMICALLY -->
</table>

here is how I'm generating datatable;

    // adding btn column to list

    if($scope.lstEmailsByCases[i].users != null && $scope.lstEmailsByCases[i].users.length > 0 )
    {
        $scope.lstEmailsByCases[i].btn = '<button id="' + 'btn' + i + '">+</button>';
    }

// creating table's column..

    $scope.dtCaseInstance = {};
    $scope.dtCaseOptions = DTOptionsBuilder.fromSource($scope.lstEmailsByCases)
        .withOption('data', $scope.lstEmailsByCases) //pass data source here
        .withOption('dataSrc', '')
        .withOption('rowCallback', rowCallbackCases)
        .withOption('createdRow', createdRowCases)

    //define columns
    $scope.dtCaseColumns = [
        DTColumnBuilder.newColumn('btn').withTitle(''), //this is to show the '+' button
        DTColumnBuilder.newColumn('caseId').withTitle('Case Id'),


    ];

//CALLED WHEN ROW IS CREATED
function createdRowCases(row, data, dataIndex) {
    // Recompiling so we can bind Angular directive
    $compile(angular.element(row).contents())($scope);
}

//HERE IT IS CALLED WHENEVER ROW IS CLICKED
function rowCallbackCases(tabRow, data, dataIndex) {
    if(tabRow.cells[0].firstChild != null)
        {
            $(tabRow).unbind('click');
            $(tabRow).on('click', function() {

                $(this).find('.a1-icon').toggleClass('fa-rotate-180');
                var tr = $(tabRow);
                var table = $scope.dtCaseInstance.DataTable;
                var row = table.row(tr);

                if (row.child.isShown()) {
                    // This row is already open - close it
                    row.child.hide();
                    tr.removeClass('shown');
                    tabRow.cells[0].firstChild.innerHTML = "+"; //change button value to +
                } else if (typeof row.child(formatCaseUsersTable(row.data())) != "undefined") {
                    // Open this row
                    row.child(formatCaseUsersTable(row.data())).show();
                    tr.addClass('shown');
                    tabRow.cells[0].firstChild.innerHTML = "-"; //change button value to -
                }

            });
        }
}

Its working perfectly fine and generating datatable like this;

enter image description here

Now I'm trying to generate another datatable on + button click.. so this is what I'm doing in formatCaseUsersTable function that is calling from rowCallBack function of this datatable.. here is that function;

//CALLED TO CREATE SUB GRID
function formatCaseUsersTable(d) {

    //if detail does not exist
    if (typeof d.users == "undefined") return;

    //defining table
    var html2 = '<table id="tblCaseUsers" datatable="" dt-options="dtCaseUsersOptions" dt-columns="dtCaseUsersColumns" dt-instance="dtCaseUsersInstance" class="display table table-striped table-bordered table-hover">';

    $scope.dtCaseUsersInstance = {};
    $scope.dtCaseUsersOptions = DTOptionsBuilder.fromSource(d.users)
        .withOption('data', d.users) //pass data source here
        .withOption('dataSrc', '')
        .withOption('rowCallback', rowCallbackCaseUsers)
        .withOption('createdRow', createdRowCaseUsers)

    //define columns
    $scope.dtCaseUsersColumns = [
        DTColumnBuilder.newColumn('btn').withTitle(''), //this is to show the '+' button
        DTColumnBuilder.newColumn('userId').withTitle('User Id'),
        DTColumnBuilder.newColumn('userName').withTitle('User Name'),


    ];

  //add button in each row.. this button will be used to show user that the row is expandable
    for (i = 0; i < d.users.length; i++) {
        if(d.users[i].emailsDetail != null && d.users[i].emailsDetail.length > 0 )
        {
            d.users[i].btn = '<button id="' + 'btn' + i + '">+</button>';
        }
    }

    return html2;
}

but it is not working accordingly.. this is html created on + button click..

enter image description here

when I check generated html, table definition is there like this;

enter image description here

But it does not show in grid and doesn't have any columns detail.

Anyone have idea what I'm missing??

Upvotes: 1

Views: 1275

Answers (1)

Stanislav Kvitash
Stanislav Kvitash

Reputation: 4622

As we can see from your code - formatCaseUsersTable method simply returns html2 as a string, without compiling it, so AngularJS could attach datatable directive to the table element. You have to use $compile service to compile the string into template, so this should work in your case:

function formatCaseUsersTable(d) {
    //..

    //defining table
    var html2 = '<table id="tblCaseUsers" datatable="" dt-options="dtCaseUsersOptions" dt-columns="dtCaseUsersColumns" dt-instance="dtCaseUsersInstance" class="display table table-striped table-bordered table-hover">';
    //....

    return $compile(angular.element(html2))($scope);
} 

Upvotes: 2

Related Questions