l-lin / angular-datatables

DataTables with Angular
https://l-lin.github.io/angular-datatables/
MIT License
1.58k stars 486 forks source link

Adding child rows doesn't work correctly when data is loaded from serverside #1372

Closed alok-prasad closed 5 years ago

alok-prasad commented 5 years ago

Hi,

I am new to github, so sorry in advance if I miss any details.

I am struggling to add child rows correctly when data is loaded using serverside angular way.

I am referencing below links:

Below is my code for reference -

html -

`<table datatable [dtOptions]="dtOptions" class="row-border hover">

ID First name Last name
            <tbody *ngIf="persons?.length != 0">
                <tr #trRef *ngFor="let person of persons">
                    <td><a (click)="expandRow(trRef)" style="font-size: 1.5em;">+</a> {{ person.id }}</td>
                    <td>{{ person.firstName }}</td>
                    <td>{{ person.lastName }}</td>
                </tr>
            </tbody>
            <tbody *ngIf="persons?.length == 0">
                <tr>
                    <td colspan="3" class="no-data-available">No data!</td>
                </tr>
            </tbody>
        </table>`

typescript -

`import { Component, OnInit, ComponentFactoryResolver, ComponentRef, ViewContainerRef, ViewChild } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { DemoChildComponent } from './demo-child/demo-child.component'; import { DataTableDirective } from 'angular-datatables';

class DataTablesResponse { data: any[]; draw: number; recordsFiltered: number; recordsTotal: number; }

@Component({ selector: 'app-server-side-angular-way', templateUrl: 'server-side-angular-way.component.html', styleUrls: ['server-side-angular-way.component.css'] }) export class ServerSideAngularWayComponent implements OnInit { dtOptions: DataTables.Settings = {}; persons: any[];

@ViewChild(DataTableDirective) private datatableElement: DataTableDirective;

private childRow: ComponentRef;

constructor( private http: HttpClient, private compFactory: ComponentFactoryResolver, private viewRef: ViewContainerRef ) { }

expandRow(trRef) { this.datatableElement.dtInstance.then((dtInstance: DataTables.Api) => { var row = dtInstance.row(trRef); if (row.child.isShown()) { row.child.hide(); } else { let factory = this.compFactory.resolveComponentFactory(DemoChildComponent); this.childRow = this.viewRef.createComponent(factory); row.child(this.childRow.location.nativeElement).show(); } }) } ngOnInit(): void { // uncomment this to load static array // this.loadData(); const that = this; this.dtOptions = { pagingType: 'full_numbers', pageLength: 2, serverSide: true, processing: true, ajax: (dataTablesParameters: any, callback) => { that.http .post( 'https://angular-datatables-demo-server.herokuapp.com/', dataTablesParameters, {} ).subscribe(resp => { that.persons = resp.data;

        callback({
          recordsTotal: resp.recordsTotal,
          recordsFiltered: resp.recordsFiltered,
          data: []
        });
      });
  }, 
  columns: [{ data: 'id' }, { data: 'firstName' }, { data: 'lastName' }]
};

}

loadData() { this.persons = [ { "id": "3", "firstName": "Cartman", "lastName": "Whateveryournameis" }, { "id": "10", "firstName": "Cartman", "lastName": "Titi" } ] } } `

When I enable serverside processing and try to add a child row it gets added at the very bottom of the table. Refer below screenshot -

withajax

And if I load data from static array instead of serverside (uncomment loadData() and comment serverside processing configuration from dtOptions) it works fine. Refer below screenshot -

withoutajax

Please help!!!

alok-prasad commented 5 years ago

Closed by mistake

alok-prasad commented 5 years ago

Solved it!

callback({
              recordsTotal: resp.recordsTotal,
              recordsFiltered: resp.recordsFiltered,
              data: resp.data
            }); 

Sending back data parameter as empty array was the problem. Removed rendering of tbody manually and used rowCallBack to add dynamically child rows