Angular 5 DataTables Plugin - How to pass selection data from HTML in TypeScript function call

Angular 5 DataTables Plugin - How to pass selection data from HTML in TypeScript function call

bobc02bobc02 Posts: 19Questions: 6Answers: 0

I am using SmartAdmin Angular 5 framework 1.9.1, which provides DataTables capabilities. I have installed DataTables 1.10.18, and Select 1.2.6.

I have the following component.html code, showing only the sa-datatables plugin usage"

<sa-datatable
  [options]="{
    data: sysMsgs,
    columns: [
      {data: 'checked'},
      {data: 'rowid'},
      {data: 'senderID'},
      {data: 'message'},
      {data: 'dateCreated'}
    ],
    buttons: [ 'copy', 'csv', 'pdf', 'print',
      {
        extend: 'selected',
        text: 'Delete',
        action: handleDelete()
      }
    ],
    columnDefs: [
      {
        targets: 0,
        orderable: false,
        className: 'select-checkbox'
      },
      {
        targets: [2],
        visible: true
      }
    ],
    select: {
      style: 'os',
      selector: 'td:first-child'
    },
    order: [[ 1, 'asc' ]],
    searching: true,
    search: {
      smart: false                  
    }               
  }"
  tableClass="table table-striped table-bordered table-hover">
    <thead>
      <tr>
        <th data-hide="mobile-p">Select</th>
        <th data-hide="mobile-p">ID</th>
        <th data-hide="mobile-p">Sender</th> 
        <th data-hide="mobile-p">Message</th>
        <th data-hide="mobile-p">Date Sent</th>
      </tr>
    </thead>
</sa-datatable>

The datatable that is created works fine. I get the checkboxes, and the Delete button does call function handleDelete(). My problem is not knowing how to pass, or get, the selected rows in the handleDelete() function, which I have defined in component.ts.

The DataTables Editor has a Soft Delete example, using jQuery that defines the selected rows like this:

var rows = table.rows( {selected: true} ).indexes();

I have tried modifying the sa-datatable, like so:

<sa-datatable id='table' name='table'
  [options]="{
...
      action: handleDelete(table.rows( {selected: true} ).indexes())
...
</sa-datatable>

but, it generates a compile error because table is undefined.

Any ideas on how to get a list of selected rows in component.ts?

Thanks,

Bob

This question has an accepted answers - jump to answer

Answers

  • kthorngrenkthorngren Posts: 21,303Questions: 26Answers: 4,947

    I'm not familiar with your environment but maybe this doc will help:
    https://datatables.net/manual/api#Accessing-the-API

    Just replace table with $( selector ).DataTable() if possible in your environment.

    Kevin

  • bobc02bobc02 Posts: 19Questions: 6Answers: 0

    Hi Kevin,

    Thanks for the idea. I tried several variants of your suggestion, but no success.

    I have added code to my component.ts (notifsysmsg.ts) file, to gain access to the DT plugin component (DatatableComponent). When you break in the handleDelete() function at notifsysmsg.component.ts:68, you can inspect this.ngxDatatable. I am not seeing the selected row(s) when doing this.

    If you are interested in looking:
    1) Browse to http://tanglemydata.com
    2) In left pane, select Notifications. (no login required)
    3) Expand "System Messages" to see DT.
    4) Select one or more checkboxes.
    5) Set breakpoint at notifsysmsg.component.ts:68
    6) Click Delete button.
    7) Breaks at line 68, inspect local this: NotifSysMsgComponent, ngxDatatable

    Do you see the selected row(s)?

    Thanks for all your help!
    Bob

  • kthorngrenkthorngren Posts: 21,303Questions: 26Answers: 4,947

    Someone more familiar with your environment might be able to help more than I can. I wasn't able to find anything with ngxDatatable. I was able to use the following to get selected rows:

    $('#DataTables_Table_0').DataTable().rows({ selected: true } ).indexes()
    s(2) [0, 1, context: Array(1), selector: {…}, tables: ƒ, table: ƒ, draw: ƒ, …]
    0: 0
    1: 1
    
    $('#DataTables_Table_0').DataTable().rows({ selected: true } ).data().toArray();
    0: {checked: null, rowid: "14", personID: "ALL", senderID: "ADMIN", message: "TEST DATA1 - TangleMyData has an outage planned for November 15, 2018 from 1:00 UTC until 2:00 UTC.", …}
    1: {checked: null, rowid: "15", personID: "ALL", senderID: "ADMIN", message: "TEST DATA2 - TangleMyData has an outage planned for November 15, 2018 from 1:00 UTC until 2:00 UTC.", …}
    

    Kevin

  • bobc02bobc02 Posts: 19Questions: 6Answers: 0

    Hi Kevin,

    I changed the handleDelete() to the following:

      handleDelete() {
        const selection = $('#DataTables_Table_0').DataTable().rows({ selected: true } ).data().toArray();
        console.log("NotifSysMsgComponent handleDelete - selection: " +selection);
      }
    

    But, get error:

    ERROR TypeError: $(...).DataTable is not a function

    How were you able to get the array elements?

    Thanks,
    Bob

  • kthorngrenkthorngren Posts: 21,303Questions: 26Answers: 4,947
    Answer ✓

    I haven't messed with the Chrome Dev Tools much but I do need to learn since I'm starting new node.js project. In poking around I put that statement in the Watch section at the breakpoint.

    This seems a bit convoluted but it does work without specifying the table ID:

    $($(this.nxgDatatable).DataTable.tables()).DataTable().rows({ selected: true } ).data().toArray()
    

    There may be a better way to get the ID without specifying it.

    ERROR TypeError: $(...).DataTable is not a function

    Maybe you need to use this instead:

    jQuery('#DataTables_Table_0').DataTable().rows({ selected: true } ).data().toArray();
      console.log("NotifSysMsgComponent handleDelete - selection: " +selection);
    }
    

    Kevin

  • bobc02bobc02 Posts: 19Questions: 6Answers: 0

    Hi Kevin,

    Thanks for all the help in working this out! The technique I am using is the one you developed that uses ngxDatatable. This seems like the best approach for use with the SmartAdmin DataTables plugin - but, by replacing the ngxDatatable with one of your other techniques it should be usable in other configurations.

    To tidy this up for other users, that want to know how to process selected rows, I include the code I will be using.

    component.html:
    
                  <sa-datatable
                    [options]="{
                      data: sysMsgs,
                      columns: [
                         {data: 'checked'},
                         {data: 'rowid'},
                         {data: 'senderID'},
                         {data: 'message'},
                         {data: 'dateCreated'}
                      ],
                      buttons: [
                        'copy', 'csv', 'pdf', 'print',
                        {
                            extend: 'selected',
                            text: 'Delete',
                            action: handleDelete()
                        }
                      ],
                      columnDefs: [ 
                        {
                          targets: 0,
                          orderable: false,
                          className: 'select-checkbox'
                        },
                        {
                          targets: [2],
                          visible: true
                        }
                      ],
                      select: {
                          style: 'os',
                          selector: 'td:first-child'
                      },
                      order: [[ 1, 'asc']],
                      searching: true,
                      search: {
                          smart: false                  
                      }               
                    }"
                    tableClass="table table-striped table-bordered table-hover"
                  >
                    <thead>
                    <tr>
                      <th data-hide="mobile-p">Select</th>
                      <th data-hide="mobile-p">ID</th>
                      <th data-hide="mobile-p">Sender</th> 
                      <th data-hide="mobile-p">Message</th>
                      <th data-hide="mobile-p">Date Sent</th>
                    </tr>
                    </thead>
                  </sa-datatable>
    
    
    component.ts:
    
    import { NgModule, Component, OnInit, Injectable, Inject, ViewChild, ElementRef } from '@angular/core';
    import { DatatableComponent } from '../shared/ui/datatable/datatable.component';
    
    declare let $:any;
    
    @Component({
      selector: 'sa-datatables-case',
      templateUrl: './notifsysmsg.component.html',
      styleUrls: ['../../assets/css/tmd_basic.css']
    })
    
    @Injectable()  
    export class NotifSysMsgComponent implements OnInit {
      @ViewChild(DatatableComponent) ngxDatatable: DatatableComponent;
      
      public sysMsgs: any;
    
      constructor(
        private elementRef: ElementRef
      ) {}
    
      ngOnInit() {  
        this.getNotifSysMsgData();  
      }
      
      /*
       * This is based on the Delete button action, in component.html, only calling  
       * this function when the Delete button is clicked. Right now, this function
       * is called when any table selection is made - plus, it's called multiple times. Needs Fixed.
       */ 
      handleDelete() {
        if($(this.ngxDatatable)) {      
          if($(this.ngxDatatable).DataTable) {
            const selection = $($(this.ngxDatatable).DataTable.tables()).DataTable().rows({ selected: true } ).data().toArray();
            console.log(selection.length +" row(s) selected for delete:"); 
            for(let i=0; i<selection.length; i++) { 
              console.log("  row having database ID " +selection[i].rowid); 
            }
          }    
        }
      }
      
      getNotifSysMsgData() {  
        const resStr = '['
                       + '{"checked":null,"rowid":"14","personID":"ALL","senderID":"ADMIN","message":"TEST DATA1 - TangleMyData has an outage planned for November 15, 2018 from 1:00 UTC until 2:00 UTC.","messageStatus":"NEW","messagePrimType":"SYSTEM","messageSubType":"GENERAL","dateExpires":"2018-11-15 09:02:37","dateCreated":"2018-11-05 09:02:37","dateLastUpdate":"2018-11-08 01:19:10"},'
                       + '{"checked":null,"rowid":"15","personID":"ALL","senderID":"ADMIN","message":"TEST DATA2 - TangleMyData has an outage planned for November 15, 2018 from 1:00 UTC until 2:00 UTC.","messageStatus":"NEW","messagePrimType":"SYSTEM","messageSubType":"GENERAL","dateExpires":"2018-11-15 09:02:37","dateCreated":"2018-11-05 09:02:37","dateLastUpdate":"2018-11-08 01:19:10"},'
                       + '{"checked":null,"rowid":"16","personID":"ALL","senderID":"ADMIN","message":"TEST DATA3 - TangleMyData has an outage planned for November 15, 2018 from 1:00 UTC until 2:00 UTC.","messageStatus":"NEW","messagePrimType":"SYSTEM","messageSubType":"GENERAL","dateExpires":"2018-11-15 09:02:37","dateCreated":"2018-11-05 09:02:37","dateLastUpdate":"2018-11-08 01:19:10"}'
                       + ']';
        this.sysMsgs = JSON.parse(resStr);
      }
    }
    
    

    Thanks,
    Bob

This discussion has been closed.