简体   繁体   中英

Adding click listener to custom button doesn't work in angular data tables

I've a data table as shown below:

<div class="card-body table-responsive">
          <table
            class="table display table-striped table-hover table-bordered row-border hover responsive nowrap"
            datatable
            [dtOptions]="dtOptions"
            datatable=""
            #dataTable
            id="issueTable"
          >
            <thead class="headColor"></thead>
            <tbody style="text-align: center;"></tbody>
          </table>
        </div>  

JS:

import { Component, OnInit, Renderer, AfterViewInit, ViewChild, HostListener } from '@angular/core';
import { Router, RouterLink } from '@angular/router';
import { routerTransition } from '../../router.animations';

import { DataTableDirective } from 'angular-datatables';

import { IssueDataServiceService } from './issue-data-service.service';


import 'datatables.net';
import 'datatables.net-bs4';

window['jQuery'] = window['$'] = $;

@Component({
    selector: 'app-charts',
    templateUrl: './issues.component.html',
    styleUrls: ['./issues.component.scss'],
    animations: [routerTransition()]
})
export class IssuesComponent implements OnInit, AfterViewInit {

    // viewer = document.getElementById('view');

    /**
     * gets settings of data tables
     *
     * @type {DataTables.Settings}
     * @memberof IssuesComponent
     */
    constructor(public router: Router) { }

    @ViewChild(DataTableDirective)
    datatableElement: DataTableDirective;
    message = '';
    title = 'angulardatatables';

    @ViewChild('dataTable') table: { nativeElement: any; };
    dataTable: any;
    dtOptions: DataTables.Settings = {};
    // someClickhandler(info: any): void {
    //     this.message = info.number + '-' + info.assignedto + '-' + info.company;
    //     console.log(this.message);
    // }
    ngOnInit(): void {
        this.dtOptions = {
            pagingType: 'full_numbers',
            pageLength: 15,
            processing: true,
            responsive: true,
            autoWidth: false,
            dom: 'Bfrtip',
            'ajax': {
                url: 'http://localhost:8080/incident-updated',
                type: 'GET',
                dataSrc: 'result',
            },
            columns: [
                {
                    title: 'Incident',
                    data: 'number'
                },
                {
                    title: 'Product',
                    data: 'u_product'
                },
                {
                    title: 'Status',
                    data: 'state'
                },
                {
                    title: 'Created By',
                    data: 'sys_created_by'
                },
                {
                    title: 'Group',
                    data: 'assignment_group'
                },
                {
                    title: 'Category',
                    data: 'u_category'
                },
                {
                    title: 'Updated on',
                    data: 'sys_updated_on'
                },
                {
                    title: 'Action',
                    data: null,
                    // render: function(data, type, full) {
                    //     return '<a class="btn btn-primary btn-sm" style="color: #fff;" id="view" (click)="view($event)">View</a>';
                    // }
                    defaultContent: '<button class="btn btn-sm btn-primary viewer"> View </button>'
                }
            ]
        };
        let table = this.dataTable;
        table = $(this.table.nativeElement);

        const _curClassRef = this;
        $('#issueTable tbody td').unbind();
        $('#issueTable tbody td').on('click', function (event: any) {
            event.stopPropagation();
            // const tr = $(this).closest('tr');
            // const row = table.row(tr);
            if (this.className = 'viewer') {
                _curClassRef.redirect();
            }
        });

        // function view($event: any) {
        //     event.stopPropagation();
        //     this.router.navigate(['/event-viewer']);
        // }
        // $('#viewer').on('click', function() {
        //     event.stopPropagation();
        //     this.router.navigate(['/event-viewer']);
        // });
        // console.log('table is ==>', this.dataTable);
        // $('#view tbody').on('click', 'button', function () {
        //     const data = this.dataTable.row($(this).parents('tr').data);
        //     alert('Data is ==>' + data);
        // });
    }
    redirect() {
        alert('alsjfhksjdf');
    }

    // @HostListener('click')
    // viewer() {
    //     event.stopPropagation();
    //     this.router.navigate(['/event-viewer']);
    // }

    ngAfterViewInit(): void {
        // Called after ngAfterContentInit when the component's view has been initialized. Applies to components only.
        // Add 'implements AfterViewInit' to the class.
        // this.viewer.addEventListener('click', function() {
        //     event.stopPropagation();
        //     // this.router.navigate(['/event-viewer']);
        //     alert('shdfiskludhzj');
        // });
    }
    // viewer() {
    //     alert('sdjfhsklzdjh');
    // }
    // viewer(event: any) {
    //     event.stopPropagation();
    //     this.router.navigate(['/event-viewer']);
    // }
    // buttonInRowClick(event: any): void {
    //     event.stopPropagation();
    //     console.log('Button in the row clicked.');
    //     this.router.navigate(['/event-viewer']);
    // }
    // wholeRowClick(): void {
    //     console.log('Whole row clicked.');
    // }
}  

But when I click on button, alert doesn't come, how do I fix it?

You are on ngOnInit so probably Angular didn't have time to render the table when you used JQuery here:

$('#issueTable tbody td').unbind();
$('#issueTable tbody td').on('click', function (event: any) {
    event.stopPropagation();
    // const tr = $(this).closest('tr');
    // const row = table.row(tr);
    if (this.className = 'viewer') {
        _curClassRef.redirect();
    }
});

Try wrapping this code in a setTimeout(()=> { }) like this:

setTimeout(()=> { 
    $('#issueTable tbody td').unbind();
    $('#issueTable tbody td').on('click', function (event: any) {
        event.stopPropagation();
        // const tr = $(this).closest('tr');
        // const row = table.row(tr);
        if (this.className = 'viewer') {
            _curClassRef.redirect();
        }
    });
})

By doing this you will force the Change Detection to be executed once, which should cause your table to be rendered. Only at that point Jquery will be able to select your HTML elements

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM