How to replace all the columns dynamically in Data Table using Angular2+?
Asked Answered
K

1

7

My requirement to replace the all the columns when ever the changes/event is happening outside of the Data Table.

data table is displaying for the first time with selected columns(from event). if i select second one it's not displaying but columns in dtOptions getting changed but it's not displaying. I think clearing the view the problem but i tried using destroy it's not working out for me. some one please help me to achieve this.

HTML Code:

<div id="data-table-grid-slide">
    <table datatable [dtOptions]="dtOptions" [dtTrigger]="dtTrigger" class="row-border hover"></table>
</div>

Angular Code for DataTable:

import {Component, ViewChild, OnInit, Input, AfterViewInit, OnDestroy, Output, EventEmitter} from '@angular/core';
import { DataTableDirective } from 'angular-datatables';
import { Subject } from 'rxjs';
import { ColumnObject } from '../data-tables-net/model/data-tables-model';
import { HttpClient } from '@angular/common/http';
import { DtServiceService} from '../data-tables-net/dt-service.service';
import { WindowRef} from '../services/WindowRef';

declare var $;
@Component({
  selector: 'app-data-tables-net',
  templateUrl: './data-tables-net.component.html',
  styleUrls: ['./data-tables-net.component.css']
})
export class DataTablesNetComponent implements OnInit, AfterViewInit, OnDestroy {
  @ViewChild('dataTable', {static: true}) table;
  @ViewChild(DataTableDirective, {static: false}) dtElement: DataTableDirective;

  dataTableColumn: Array<any> = [];
  dtOptions: DataTables.Settings = {};
  @Input() dataTableGrid: boolean;
  @Input() tableShow: boolean;
  @Output() tableShowChange = new EventEmitter<boolean>();
  @Output() dataTableGridChange = new EventEmitter<boolean>();

  dtTrigger: Subject<any> = new Subject();

 // editor: any;
  columnObject: ColumnObject = {
      title: '',
      data: ''
  };
  constructor(private http: HttpClient, private dtServiceService: DtServiceService, private winRef: WindowRef) { }

  ngOnInit() {
    this.dataTableGrid = true;
    this.initDt();
  }
  ngAfterViewInit(): void {
    // This method get called on pencil click of model in Data Model Visuvalizer
    this.winRef.modelClick$.subscribe((modelObjAttributes) => {
      this.dataTableGrid = true;
      this.tableShow = false;
      this.tableShowChange.emit(this.tableShow);
      this.dataTableGridChange.emit(this.dataTableGrid);
      console.log('modelObjAttributes', modelObjAttributes);
      // tslint:disable-next-line: max-line-length
     // this.dtOptions.columns =  [{title: 'id', data: 'id'}, {title: 'name', data: 'name'}, {title: 'item code', data: 'item code'}, {title: 'addr', data: 'addr'}];
      if (this.dtOptions.columns) {
        // this.dtOptions.destroy = true;
       //  delete this.dtOptions.columns;
       



this.reRenderDataTable();
       //  console.log('columns', this.dtOptions.columns);
         this.initDt();
         this.dtOptions.columns =   this.getModelDetails(modelObjAttributes);
       //  console.log(this.dtOptions.columns);
         this.dtTrigger.next();
      } else {
        this.dtOptions.columns =   this.getModelDetails(modelObjAttributes);
        console.log(this.dtOptions.columns);
        this.dtTrigger.next();
        // this.dtOptions.destroy = true;
      }
    //  delete this.dtOptions.columns;


    });
  }
  initDt() {
    this.dtOptions = {
      // ajax: 'data/data.json',
      // columns: [{title: 'Column1', data: 'column1'}],
      paging: true,
      searching: true,
      ordering: true,
      info:     false,
      responsive: true,
      destroy: true
    };
    }

  ngOnDestroy(): void {
    // Do not forget to unsubscribe the event
    this.dtTrigger.unsubscribe();
  }

  // This method used to get the details of model on clicking of pencil icon
  getModelDetails(modelDetailsObj) {
    return this.convertModelAttributesToDataTable(modelDetailsObj.options);
    // this.getModelDetailsFromService(modelDetailsObj.id);
  }

// This method is used to  call the service to get the selected Models / Schema details from Database
 getModelDetailsFromService(schemaId): void {
  this.dtServiceService.getSelectedSchema(schemaId).subscribe(data => {
    console.log(data);
  },
  error => {
    console.log('Data is not getting');
  });
}

  // This method used to form the schema data for Data Table
  convertModelAttributesToDataTable(attributesObject) {
    this.dataTableColumn = [];
    // delete this.dtOptions.columns;

    for (const [index, obj] of attributesObject.entries()) {
      if (obj) {
          this.columnObject = { title: obj.text, data: obj.text};
          console.log('columnObject', this.columnObject);
          this.dataTableColumn.push(this.columnObject);
        //  console.log(this.dtOptions);
      }
    }
   // this.dtTrigger.next();
    return this.dataTableColumn;
  }
  // This method used re-render the data table with updated data's
  reRenderDataTable(): void {
    this.dtElement.dtInstance.then((dtInstance: DataTables.Api) => {
      // Destroy the table first
      // dtInstance.destroy();
      // Call the dtTrigger to rerender again
      this.dtTrigger.next();
    });
  }

}

I have created stackblitz for my requirement. In this example variables called columnsDataObj and dataUrl will change dynamically. it should get reflect in the data table. Please let me if you need more details:

https://stackblitz.com/edit/angular-datatables-gitter-4tavmk?file=app/app.component.ts

Katherinakatherine answered 20/1, 2020 at 15:10 Comment(5)
You need to re-create the data-table on changes when you want to dynamically set the columns. check this out #32487901Blaylock
As far as I understood what you want is to change the column of the table whenever you trigger some action, to do so just change the dataTableOptions, if your provide more insight of your code and what you want I can review the code and help with your problemAddictive
@Stratubas - I can't able to create stackbilitz with above code because this has lot of dependency with other components in my project. But i will to create stackbilitz for my requirement only.Katherinakatherine
@NavruzbekNoraliev - If you see my code i am changing the data table option but it's changing but it's reflecting the view. if i check the updated options it's getting correct. Please tell me or provide any sample.Katherinakatherine
@Katherinakatherine that was the best solution to re-create the data-tableBlaylock
P
5

You need to also "destroy" dtOptions and the previous table from the template, also you have to make sure your template notices when the change is done, this are the main changes:

First destroy your previous DT completely, i added a flag called dtRendered:

dtRendered = true;
<table *ngIf="dtRendered" datatable [dtOptions]="dtOptions" class="row-border hover">

Also at your update method you have to make sure everything is destroyed and initialized again:

updateData() {
  // destroy you current configuration
  this.dtRendered = false
  this.dtOptions = {
    data: this.jsonData1.data,
    columns: this.columnsDataObj1
  };
  // make sure your template notices it
  this.cdr.detectChanges();
  // initialize them again
  this.dtRendered = true
  this.cdr.detectChanges();
}

The this.cdr.detectChanges() call is needed so the lifecycle-hook notices about the change.

Here's your example working as expected:

https://stackblitz.com/edit/how-to-replace-all-the-columns-dynamically-in-data-table?file=app/app.component.ts

Pornography answered 27/1, 2020 at 17:42 Comment(1)
This example helped me a lot. Thanks!Garzon

© 2022 - 2024 — McMap. All rights reserved.