A. Gladkiy
A. Gladkiy

Reputation: 3450

angular datatables row details feature

I have Angular 8 app with using Angular Datatables plugin. I need row details feature as in DataTables example

So, my html:

<table [dtOptions]="dtOptions" [dtTrigger]="dtTrigger" datatable>
    <thead>
        <tr>
            <th>...</th>
            ...
        </tr>
    </thead>
    <tbody>
        <tr *ngFor="let item of items">
            <td class="details-control" (click)="toggleDetails()">...</td>
            <td>...</td>
            ...
        </tr>
    </tbody>
</table>

And code into ts:

ngOnInit() {
    this.dtOptions = {
        ...
        rowCallback: (row: Node, data: any[] | Object, index: number) => {
            // Unbind first in order to avoid any duplicate handler
            // (see https://github.com/l-lin/angular-datatables/issues/87)
            $('.details-control', row).unbind('click');
            $('.details-control', row).bind('click', () => {
                this.datatableElement.dtInstance.then((dtInstance: DataTables.Api) => {
                    let selectedRow = dtInstance.row($(row));
                    if (selectedRow.child.isShown()) {
                        this.expandedItem = null;
                        selectedRow.child.hide();
                    } else {
                        selectedRow.child(this.detailsRow(this.item)).show();
                    }
                });
            });
                return row;
            }
        };
}

detailsRow(item: any) {
    return '<span [hidden]="' + !item.description.includes('.docx') + '">' +
                '<a (click)="convertFile(' + item.id + ', \'pdf\')"><i class="far fa-file-pdf"></i> Download as PDF</a>' +
            '</span>';
}

HTML was inserted right but angular isn't compiled, I mean click handler isn't available for me.

How can I resolve this issue?

UPDATE

demo

Upvotes: 0

Views: 1345

Answers (2)

Allabakash
Allabakash

Reputation: 2027

You can html content dynamically and bind the click event in component itself like below.

The following code will go into rowCallback function.

selectedRow.child(this.detailsRow(item, index)).show();
const type = item.name.includes('.docx') ? 'docx' : (
item.name.includes('.pdf') ? 'pdf' : ''
);
if (type !== '') {
    $(`.pointer${index}`).bind('click', () => {
        this.convertFile(item.id, type);
    });
}

and following will be detailsRow function.

detailsRow(item: any, index: number) {

    if (item.name.includes('.docx')) {

      return `<span> <a class="pointer${index} ml-3">
        <i class="far fa-file-pdf"></i> Download as DOCX</a>
        </span>`;
    } else if (item.name.includes('.pdf')) {

      return `<span> <a class="pointer${index} ml-3">
        <i class="far fa-file-pdf"></i> Download as PDF</a>
        </span>`;
    }

    return '';
  }

this way you can bind the click event. Hope this helps.

Upvotes: 1

GaryB
GaryB

Reputation: 384

If you want exactly the same just add "responsive: true" to this.dtOptions. ( you need the responsive add-on as well link )

edit:

If you add const self = this; to the first line in the rowcallback and act on self afterwards your code will work.

Upvotes: 0

Related Questions