4

I have added inline editing data features for my datatable. I'm using service call to get the latest data and I'm binding to the datatable using dtOptions. I'm using datatable " ". intially empty data variable binding. as soon as i get data from service i'm binding to the dtOptions which is binding(showing) well. but inline editing is not working. I'm not sure how to add data to editor after getting from service. if i add accessing instance of $.fn.dataTable.Editor. it's just not working. please help to solve this issue.

HTML

<table id='dtGrid' *ngIf="dtRendered" datatable [dtOptions]="dtOptions" class="row-border hover"></table>

script

 data = [];

renderDatatable(dtColumns, modelObjAttributes) {
    console.log('dtEditor', this.dtEditor);
    const colLenth = dtColumns.length;
    this.dtRendered = false;
    this.dtOptions = {
        dom: 'Bfrtip',      
        data: this.data,
        pageLength: 100,
        columns: dtColumns,
        columnDefs: [ {
          targets: colLenth,
          defaultContent: '',
          title: '<i class="fa fa-plus plusIcon"></i>',
          orderable: false
        }],
        paging: true,
        searching: true,
      //  ordering: true,
        info:     false,
        responsive: true,
        drawCallback: () => {
          const btnElement = this.dtTableId.nativeElement.querySelector('i.plusIcon');
          this.renderer.listen(btnElement, 'click', ($event) => {
              this.onClickPlusIcon(modelObjAttributes);
           });
        },
        scrollY: '500px',
      //  bSort: false,
        scrollCollapse: true,
        select: {
          style:    'os',
          selector: 'td:first-child'
         },
        buttons: [
          { extend: 'create', editor: this.dtEditor },
          { extend: 'edit',   editor: this.dtEditor },
          { extend: 'remove', editor: this.dtEditor }
          // { extend:  'pageLength', editor: this.dtEditor}
        ]
      };
    this.cdr.detectChanges();
    this.dtRendered = true;
    this.cdr.detectChanges();
    this.attachPlusIconClickEvent(modelObjAttributes);
    this.attachDtClickEvent();
}

// This method used to initialize the data table dyanamically
initializeDtEditor(dtColumns, modelObjAttributes) {
    this.dtEditor = new $.fn.dataTable.Editor({  
    data: this.data,
    table: '#dtGrid',
    idSrc: this.uniqueField,
    fields: this.dataTableFields,
    formOptions: {
      inline: {
        onBackground:  'blur',
        onBlur:        'close',
        onComplete:    'close',
        onEsc:         'close',
        onFieldError:  'focus',
        onReturn:      'submit',
        submit:        'changed',
        scope:         'row'
      }
    }
   });
   // this.cdr.detectChanges();
    this.renderDatatable(dtColumns, modelObjAttributes);
}


// This method to get the data from service if you see i'm binding the reponseData to dtOptions. It adding to the datatable but it's not allowing to edit(inline edit). with buttong edit it's working.

getData(modelName) {
  this.dtServiceService.readData(modelName).subscribe(responseData => {
   // console.log(JSON.stringify(data));   
   this.dtOptions['data'] = responseData;
   this.dtRendered = false;
   this.cdr.detectChanges();
   this.dtRendered = true;
   this.cdr.detectChanges();

  },
  error => {
    console.log('data is not getting!');
  });
}
bagya
  • 383
  • 1
  • 11
  • 38
  • Can you please create a stackblitz instance of your issue? – Jasdeep Singh Mar 09 '20 at 09:13
  • @Prince - I have added in stackblitiz though it's not working but if you see my code you will get that what i'm asking. I'm reinitializing after getting data also. here is the link https://stackblitz.com/edit/how-to-replace-all-the-columns-dynamically-in-data-table-vgykyp?file=app%2Fapp.component.ts – bagya Mar 09 '20 at 10:04
  • @Prince - because of re-initializing datatable is flickering. – bagya Mar 09 '20 at 10:05
  • @bagya That stackblitz doesn't compile. Can you get to at least compile? – Kurt Hamilton Mar 09 '20 at 10:34
  • @KurtHamilton - Please check it now – bagya Mar 09 '20 at 13:29
  • 2
    @bagya I would request you to make a working instance with dummy data atleast. – Jasdeep Singh Mar 09 '20 at 14:40
  • 1
    Downvoting since this question does not meat the [How To Ask](https://stackoverflow.com/help/how-to-ask) criteria. Nobody would be able to answer it. There is also no actual code which reproduces the issue and we are no mind readers to be able to answer this. Also, your `stackblitz` example uses `ViewChild` chihd references to non-existing elements - `@ViewChild('dtGrid')` would search for an element in the template which like `
    – tftd Mar 12 '20 at 20:14
  • 1
    @tftd - I will reproduce the issue using stackblitz and then will update you. – bagya Mar 13 '20 at 09:27

1 Answers1

2

Angular-datatables provides a dtTrigger you can use to manually trigger the rendering of the table.

What you need to do is calling the dtTrigger to manually render the table.

Example :

HTML :

<table datatable [dtOptions]="dtOptions" [dtTrigger]="dtTrigger" class="row-border hover">
<thead>
  <tr>
    <th>ID</th>
    <th>First name</th>
    <th>Last name</th>
  </tr>
</thead>
<tbody>
  <tr *ngFor="let person of persons">
    <td>{{ person.id }}</td>
    <td>{{ person.firstName }}</td>
    <td>{{ person.lastName }}</td>
  </tr>
</tbody>
</table>

Typescript :

import { Component, OnDestroy, OnInit } from '@angular/core';
import { Http, Response } from '@angular/http';
import { Subject } from 'rxjs';
import { Person } from '../person';

import 'rxjs/add/operator/map';

@Component({
  selector: 'app-angular-way',
  templateUrl: 'angular-way.component.html'
})
export class AngularWayComponent implements OnDestroy, OnInit {
  dtOptions: DataTables.Settings = {};
  persons: Person[] = [];
  // We use this trigger because fetching the list of persons can be quite long,
  // thus we ensure the data is fetched before rendering
  dtTrigger: Subject = new Subject();

  constructor(private http: Http) { }

  ngOnInit(): void {
    this.dtOptions = {
      pagingType: 'full_numbers',
      pageLength: 2
    };
    this.http.get('data/data.json')
      .map(this.extractData)
      .subscribe(persons => {
        this.persons = persons;
        // Calling the DT trigger to manually render the table
        this.dtTrigger.next();
      });
  }

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

  private extractData(res: Response) {
    const body = res.json();
    return body.data || {};
  }
}
Oussail
  • 2,200
  • 11
  • 24