1

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>

3 Answers 3

1

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.

Sign up to request clarification or add additional context in comments.

4 Comments

What you mentioned is making the clicking on the row not trigger the click on the button inside that row. what i want to do is click the button not the row.
The code I posted allows you to: 1) trigger a function for a row click. 2) trigger a function on a button click within the row (like edit, delete, etc.) without firing the overall row function. I have edited my answer to clarify what I meant.
i am sorry to say that it didn't work, even removing the click event from the row doesn't work. the buttons fire nothing.
@KakiMasterOfTime Did you find a solution? I'm struggling with the same situation as you said, the given answer by Anthony is not working because when clicking on the row, it ignores completely the button click even if it is specified using the directive (click) on the button tag
0

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
  } 

Comments

0

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>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.