0

I'm trying to create a data set for datatables by accessing through a for loop and I want to reach nested arrays. Here is my loop:

function format(d) {
        // `d` is the original data object for the row
        return '<table cellpadding="5" cellspacing="0" border="0" style="padding-left:50px;">' +
          ` <tr>
                <td>{% trans 'contact-country' %}</td>
                <td>${d.country}</td>
            </tr>
            <tr>
                <td>Profession</td>
                <td>${d.job}</td>
            </tr>
            <tr>
                <td>{% trans 'contact-company' %}</td>
                <td>${d.job_title}</td>
            </tr>
            <tr>
                <td>Email</td>
                <td>${d.email}</td>
            </tr>
            <tr>
                <td>Expertises</td>
                <td>${d.expertise}</td>
            </tr>
            <tr>
                <td>Linkedin</td>
                <td>${d.linkedin}</td>
            </tr>
            <tr>
                <td>Description</td>
                <td>${d.description}</td>
            </tr>
            <tr>
                <td>Description</td>
                <td>${d.id}</td>
            </tr>
            <tr>
                <td>Description</td>
                <td>${d.languages}</td>
            </tr>
          </tr>`
             +
            '</table>';

    }



var tableData = []
for (let i = 0; i < list.length; i++){
  tableData.push(
  {
  "first_name": list[i].user.first_name,
  "last_name": list[i].user.last_name,
  "circle": "circle",
  "meeting": "meeting",
  "favorites": [list[i].favorites, list[i].id],
  "notes":list[i].id,
  "country": "country",
  "expertise": list[i].expertise,    <=== Need to get each array in this data
  "job": list[i].job,
  "job_title": list[i].job_title,
  "language":"language",
  "email": list[i].user.email,
  "linkedin": list[i].linkedin,
  "description": list[i].about,
  "id": list[i].id
  }
  );
}

Here is the result of the tableData array that I get

I need to be able to loop again in the expertise to get the original_name for each. A for loop inside the tableData.push() does not work.

And here is my DataTable :

  $(document).ready(function () {
    var table = $('#example').DataTable({

      createdRow: function (row, data, dataIndex) {
            $(row).attr('data-id', 'id');
        },
"deferRender": true,
        'columnDefs': dataLabel,
      "paging":   false,
       "info":     false,
    data: tableData,
        "aoColumns": [
          { "className": 'details-control',"orderable": false,"data": null,"defaultContent": '' },
          { "data": "first_name" },
          { "data": "last_name" },
          { "data": "circle" },
          { "data": "meeting" },
          { "data": "country", "visible": false },
          { "data": "expertise", "visible": false },
          { "data": "job", "visible": false },
          { "data": "job_title", "visible": false },
          { "data": "language", "visible": false },
          { "data": "linkedin", "visible": false },
          { "data": "description", "visible": false },   <===== Here is where I need the result
          { "data": "id", "visible": false },
          ],
        "order": [[1, 'asc']]
});

Any solution to display those data through the for loop of via DataTable is welcome.

1 Answer 1

1

You can use the DataTables "array bracket" syntax to drill into an embedded array.


Update for child rows

To do something similar in a child row, you have more flexibility.

The child row format function is:

function format ( d ) {

  ...
}

Here, the d represents the entire row's data - so you can access the nested expertise array data using d.expertise.

You can therefore build a string containing the formatted data for your child row. In this example, the data is formatted as a mini-table containing one column, and one row per expertise:

function format ( d ) {
  let html = '<table cellpadding="5" cellspacing="0" border="0" style="padding-left:50px;">';
  html = html + '<tr><td>Expertise Name</td></tr>';

  d.expertise.forEach((exp) => { 
    html = html + '<tr><td>' + exp.original_name + '</td></tr>';
  } )

  html = html + '</table>';

  return html;
}

But you could just as easily format this as one row with multiple columns (one column per expertise).

Or you could concatenate all the expertise values into one string, so you can show them all in one cell:

var stringOfExpertises = d.expertise.join(', ');

With this last approach, you can build a row containing all the other values you want to also show in the child.


Here is a demo, based on a simplified version of your data:

var dataSet = [
    {
      "first_name": "Tiger",
      "last_name": "Nixon",
      "expertise": [
        { "id": 1, "original_name": "name one" },
        { "id": 2, "original_name": "name two" },
        { "id": 2, "original_name": "name three" }
      ],
    },
    {
      "first_name": "Garrett",
      "last_name": "Winters",
      "expertise": [
        { "id": 4, "original_name": "name four" },
        { "id": 5, "original_name": "name five" },
        { "id": 6, "original_name": "name six" }
      ],
    },
    {
      "first_name": "Ashton",
      "last_name": "Cox",
      "expertise": [
        { "id": 7, "original_name": "name seven" },
        { "id": 8, "original_name": "name eight" },
        { "id": 9, "original_name": "name nine" }
      ],
    }
];

function format ( d ) {
  let html = '<table cellpadding="5" cellspacing="0" border="0" style="padding-left:50px;">';
  html = html + '<tr><td>Expertise Name</td></tr>';

  d.expertise.forEach((exp) => { 
html = html + '<tr><td>' + exp.original_name + '</td></tr>';
  } )

  html = html + '</table>';

  return html;
}

$(document).ready(function() {

  var table = $('#example').DataTable( {
"data": dataSet,
"columns": [
  {
    "className": 'details-control',
    "orderable": false,
    "data": null,
    "defaultContent": ''
  },
  { 
    "title": "First Name", 
    "data": "first_name"
  },
  { 
    "title": "Last Name", 
    "data": "last_name"
  },
  { 
    "title": "Expertise", 
    "data": "expertise[, ].original_name"
  },
]
  } );

  $('#example tbody').on('click', 'td.details-control', function () {
var tr = $(this).closest('tr');
var row = table.row( tr );
 
if ( row.child.isShown() ) {
  // This row is already open - close it
  row.child.hide();
  tr.removeClass('shown');
}
else {
  // Open this row
  row.child( format(row.data()) ).show();
  tr.addClass('shown');
}
  } );


} );
<head>
  <meta charset="UTF-8">
  <title>Demo</title>
  <script src="https://code.jquery.com/jquery-3.5.1.js"></script>
  <script src="https://cdn.datatables.net/1.10.22/js/jquery.dataTables.js"></script>
  <link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.22/css/jquery.dataTables.css">
  <link rel="stylesheet" type="text/css" href="https://datatables.net/media/css/site-examples.css">
</head>

<body>

<div style="margin: 20px;">

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

</div>
</body>

The key part of this is the following column definition:

"data": "expertise[, ].original_name"

The [, ] syntax causes each selected field to be concatenated with a comma followed by a space. In this case, the field being used is original_name.

You can see an example of this, with more details, on the official web site here.

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

7 Comments

It does work indeed but not in the child rows.. I just edited the question and added the function format(d). Thanks a lot for the answer though!
The row that you open here is the exemple datatables.net/examples/api/….
I saw your edit - but I must be missing something, here. Your screenshot shows you already have the nested array of expertise objects. Can you clarify what you mean by "in the child rows"?
Ah - child rows in the Data Table. Now I understand. What data do you need to see in each child row - and how do you want it to be presented?
Lol the same, expertise[, ].original_name, that should display in a cell "original_name0, original_name1, original_name2" that does work if i display it in the normal rows, but not in the child rows, so I assume that its the function format(d) that is the problem?
|

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.