Reputation: 1634
I am using the angular datatables module in my project and i configured a function using the rowrollback
function to perform actions when clicked on the row. but when using that i can't click on buttons in my row, like actions designed for each row (e.g delete modify client ).
I tried not to add the Actions column in my dtconfig
object but it made my datatable not get triggered.
here is my code :
dtOptions :
dtOptions = {
pagingType: 'full_numbers',
pageLength: 10,
columns: [{
title: 'Current Owner',
data: 'CurrentOwner'
},{
title: 'Doc Hash',
data: 'hash'
},{
title: 'Doc Name',
data: 'name'
},{
title: 'Doc Owner',
data: 'DocumentOwner'
},{
title: 'Time Stamp',
data: 'Timestamp'
},{
title: 'Actions',
data: 'actions'
}],
rowCallback: (row: Node, data: Object |any[] , index: number) => {
try{
const self = this;
// Unbind first in order to avoid any duplicate handler
// (see https://github.com/l-lin/angular-datatables/issues/87)
$('td', row).unbind('click');
$('td', row).bind('click', () => {
let X ={};
Object.assign(X,data);
console.log(X)
console.log(this.Certificates[index]);
self.DetailedCertificate=this.Certificates[index];
$(this.detailRef.nativeElement);
$(this.detailRef.nativeElement).modal("show");
});
return row;
}
catch (e){
console.error("error"+e);
}
}
HTML Table :
<tr *ngFor="let row of dataRows" class=".row" >
<td style="text-overflow: ellipsis; overflow-wrap: break-word">{{row.CO}}</td>
<td>{{row.KC}}</td>
<td>{{row.DocName}}</td>
<td>{{row.DocOwner}}</td>
<td>{{row.TimeStamp}}</td>
<td class="text-right">
<button class="btn btn-lg btn-simple btn-info btn-icon" (click)="CO(row.KC,row.DocOwner)"><i class="material-icons">person_pin_circle</i></button>
<button class="btn btn-lg btn-simple btn-danger btn-icon" (click)="RC(row.KC,row.DocOwner)"><i class="material-icons">close</i></button>
</td>
</tr>
Upvotes: 1
Views: 6642
Reputation: 77
I am struggling with the same situation on 2024 using Angular 14 and the angular-datatable library. I solved the issue so I think is important to share if anyone leads again with this..
It kind of sucks of using a non-Angular way to solve the problem but this is how I handle that situation because it happens like you said, even if you place the (click) directive on buttons, seems it ignores it when the data table is rendered.
I solved this one using the Renderer2 class from Angular/core to listen the click events and inspecting the DOM, then if the tag from event comes with a specific class that I created, then I retrieve the id from that tag, that in this case is the user.id and then i lookup for the user instance in my user list that I did use in my ngfor for placing the info on the datatable, so I am using that instance to do whatever I want to it, here is the code:
Component code *.ts:
users : AccountCRUD[];
constructor(private _usersService : UsersService, private _rendererDataTable: Renderer2) {
//any code you use in your constructor,
//the important this is to declare the _rendererDataTable attribute.
}
ngAfterViewInit():void{
//Note: we are using this solution instead of (click) native angular directive because
//we are using datatables and declaring the (click) is not working, so that's why
//we are using this one.
this._rendererDataTable.listen('document', 'click', (event) => {
//console.log(event);
//console.log(event.target);
if (event.target.className.includes('deleteButton')) {
let userInstanceId:string = event.target.getAttribute("id");
//console.log(userInstanceId);
let userInstance = this.users.find(u => u.UserId == userInstanceId);
this.logicDeleteUser(userInstance);
}
});
}
logicDeleteUser(user:AccountCRUD) : void{
//logictodelete
}
And this is how it looks my template of component (html):
<div class="d-flex justify-content-center">
<div class="col-12">
<div class="card">
<div class="header">
<button type="button" (click)="newUser()" class="btn btn-primary w3-animate-left">Agregar Usuario</button>
</div>
<div class="content">
<br/>
<table datatable [dtOptions]="dataTableOptions" [dtTrigger]="dtTrigger" class="row-border hover">
<thead>
<tr>
<th>Usuario</th>
<th>Email</th>
<th>Rol</th>
<th></th>
</tr>
</thead>
<tbody>
<tr *ngFor="let user of users" >
<td>{{user.UserName}}</td>
<td>{{user.Email}}</td>
<td>{{ user.Role | userRolePipe }}</td>
<td>
<button id="{{user.UserId}}" type="button" class="btn btn-danger deleteButton">Eliminar</button>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
Upvotes: 0
Reputation: 13
You can invoke the CO() function by using jquery call in AfterViewInit interface like below. And get 'row.KC' value by setting it as id in html
ngAfterViewInit(){
var _thisDoc = this;
$('#user-table').on('click', '.btn-circle', function(){
_thisDoc.CO(this.id);
});
}
CO(e) {
console.log(e); //row.KC value
}
Upvotes: 0
Reputation: 140
Here is an example of a table in angular that accomplishes what you want.
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
title = 'app';
dataRows: any[] = [
{ kc: 'kc1', docName: 'Document 1', docOwner: 'Johnny', timeStamp: 'last week'},
{ kc: 'kc2', docName: 'Document 2', docOwner: 'Jacob', timeStamp: 'yesterday'},
{ kc: 'kc3', docName: 'Document 3', docOwner: 'Jingleheimer', timeStamp: 'today'},
{ kc: 'kc4', docName: 'Document 4', docOwner: 'Schmidt', timeStamp: 'tomorrow'}
];
buttonInRowClick(event: any): void {
event.stopPropagation();
console.log('Button in the row clicked.');
}
wholeRowClick(): void {
console.log('Whole row clicked.');
}
}
<table>
<tr>
<th>KC</th>
<th>Doc Name</th>
<th>Doc Owner</th>
<th>Time Stamp</th>
<th>Button</th>
</tr>
<tr *ngFor="let row of dataRows" (click)="wholeRowClick()">
<td>{{row.kc}}</td>
<td>{{row.docName}}</td>
<td>{{row.docOwner}}</td>
<td>{{row.timeStamp}}</td>
<td><button (click)="buttonInRowClick($event)">do thing</button></td>
</tr>
</table>
This line adds the function call to every row that ngFor generates.
<tr *ngFor="let row of dataRows" (click)="myFunction()">...</tr>
The key to making sure the click events on buttons within the rows don't interfere with the overall row click is to add event.stopPropagation();
in the functions that the nested buttons call.
Upvotes: 1