0

I use Angular App and DataTables. In one of my components I have a DataTable which pulls data from an external API using the "ajax" property of the options object.

export class ChartsDetailsComponent implements OnInit {
  ngOnInit(): void {
   var opts: any = {
       ajax :{
          url: this.appConfigService.analyseConfig.chartsApiUrl + "/api/Charts/GetChartDetails?type=" + this.chartType,
          dataSrc: "ChartData." + this.chartType
       },
       columns:[
                  {title:"Name"},
                  {title:"Status"},
       ] 
   };
   var table = $('#details').DataTable(opts); 
  }
}

The returned data has the following structure:

{
"ChartData":{
            "FQCInLocalChart":[
                               ["EM/AC.08.2.01","Remote"],
                               ["EM/AC.08.2.03","Remote"]
                              ]
            }
 }

The FQCInLocalChart is dynamic. It is not static property. That's why in the dataSrc property I put "ChartData." + this.chartType, where this.chartType is a private property of the Angular component.

The data source contains only the columns that has to be displayed, but I would like to have a row number before the columns that are filled with the returned from the API data. Is there a way to achieve this behavior?

Thanks in advance Julian

5
  • Does this answer your question? Add row number column to jquery datatables Commented Aug 19, 2020 at 12:41
  • I'm not sure, because I define the columns property of the options to be an array like [{title:"First Column"},{title;"Second Column"}], and when I add for example an empty column (or another object in the array), the first column is always containing the first column from the data that is coming from the ajax response. Is there a way to shift (somehow) and tell to fill the datasource from the second column? Commented Aug 20, 2020 at 10:46
  • Can you edit your question to show more information: (1) the DataTables definition, (2) a sample of the JSON data received by your ajax call, so we can see its structure. Thank you. Commented Aug 20, 2020 at 12:21
  • @andrewjames thanks for the answer. I've updated the original question. Hope I provided enough information regarding my question. Commented Aug 20, 2020 at 12:52
  • Thanks for the update. Yes, the fact that the source data is provided in arrays (as opposed to objects) does make things a bit more awkward. But I have proposed one approach for you. Commented Aug 20, 2020 at 14:08

2 Answers 2

2

I managed to solve my problem. Here is how I've done it: First I've changed the dataSrc property to be function, not string:

export class ChartsDetailsComponent implements OnInit {
  chartType: string = "FQCInLocalChart";

  convertData(json: object){
     var ret = <Array<Array<string>>>json["ChartData"][this.chartType];
     ret.map((value)=>{
           value.unshift('');
         });
   return ret;
  }
  ngOnInit(): void {
    var opts: any = {
      ajax :{
      url: this.appConfigService.analyseConfig.chartsApiUrl + "/api/Charts/GetChartDetails?type=" + this.chartType,
      dataSrc: this.converData.bind(this)
      },
      columns:[
              {title:"Nr."},
              {title:"Name"},
              {title:"Status"},
      ] 
  };
  var table = $('#details').DataTable(opts); 
  table.on('order.dt search.dt', function () {
  table.column(0, { search: 'applied', order: 'applied' }).nodes().each(function (cell, i) {
    cell.innerHTML = i + 1;
    });
  });

 }
}

Basically I hook to the dataSrc function from the angular component and bind the context to be the class of the component, that is how I gained access to the this.chartType property, added another element in front of the element of the array (to hold the row number) and then at the end hook up the table.on() order and search events, to fill up the row numbers itself.

I hope this will help somebody with same or similar problem as mine!

Regards,

Julian

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

Comments

1

One approach is to use DataTables events to add and update a column of row numbers to your table. There are two aspects to this: (1) the initial rendering of the table; (2) subsequent re-draws for sorting and filtering.

For my demo, instead of using ajax, I will provide hard-coded data - but my approach should be compatible with your ajax approach.

The table:

 <table id="example" class="display dataTable cell-border" style="width:100%">
 </table>

My test data:

var dataSet = {
    "ChartData": {
        "FQCInLocalChart": [
            ["EM/AC.08.2.01", "Remote1"],
            ["EM/AD.08.2.01", "Remote2"],
            ["EM/AC.08.2.01", "Remote3"],
            ["EM/AC.08.2.03", "Remote2"]
        ]
    }
};

The dataTable code:

$(document).ready(function() {

    var table = $('#example').DataTable( {
      data: dataSet.ChartData.FQCInLocalChart,
      columns: [
        { title: "Name" },
        { title: "Status" }
      ],
      "initComplete": function() {
        addColNumbers();
      }
    } );

    table.on( 'draw', function () {
      rewriteColNumbers()
    } );

    function addColNumbers() {
      $('#example thead tr').prepend('<th>Num.</th>');
      $('#example tbody tr').each(function( index ) {
        $(this).prepend('<td>' + (index + 1) + '</td>');
      } );
    }

    function rewriteColNumbers() {
      $('#example tbody tr').each(function( index ) {
        $('td', this ).first().html(index + 1);
      } );
    }

} );

In the above approach, the initComplete() function handles the addition of a new column to the table.

And the table.on( 'draw' ) function captures subsequent re-draws for sorting/filtering.

The end result:

enter image description here

This approach means that the data in this new column is not visible to DataTables (it only gets added to the DOM) - and therefore does not take part in any sorting/filtering.

It also means the data would not be a part of any data export, if you use DataTables export add-ons.

You may want to add some styling/css to this new column, to control its width.

2 Comments

hi @andrewjames I've applied this to my scenario here, and the result is: I got now 3 rows (Nr. Name, Status), but the first two have the row number, and the third is right. And when you have more than one page (more than 10 rows) on the second (and so on) pages I have three columns but the first one is the row number and the second is named "Name" but contains the data for "status", and the "status" column is empty
OK - interesting. I don't get that behavior in my test case. But I like the solution you posted.

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.