Nested tables in jQuery DataTable

I have a dataTable with some rows. If user clicks on a row, that row should expand out and display a table within. Something like the “Accordion” effect in bootstrap.

Here is simple example;

For more info, click link below;

https://datatables.net/forums/discussion/42045/nested-tables#Comment_109541

Here is another example;

https://common.olemiss.edu/_js/datatables/examples/ajax/deep.html

https://stackoverflow.com/questions/65751413/datables-render-nested-objects-arrays-from-ajax-request

DataTables: Cannot read property ‘length’ of undefined

This errors TypeError: Cannot read property 'length' of undefined usually means that jQuery DataTables cannot find the data in the response to the Ajax request.

By default jQuery DataTables expects the data to be in one of the formats shown below. Error occurs because data is returned in the format other than default.

Array of arrays

{ 
   "data": [
      [
         "Tiger Nixon",
         "System Architect",
         "$320,800",
         "2011/04/25",
         "Edinburgh",
         "5421"
      ]
   ]
}

Array of objects

{ 
   "data": [
      {
         "name": "Tiger Nixon",
         "position": "System Architect",
         "salary": "$320,800",
         "start_date": "2011/04/25",
         "office": "Edinburgh",
         "extn": "5421"
      }
   ]
}

SOLUTION

Use default format or use ajax.dataSrc option to define data property containing table data in Ajax response (data by default).

See Data array location for more information.

It’s even simpler: just use dataSrc:'' option in the ajax definition so dataTable knows to expect an array instead of an object:

$('#pos-table2').DataTable({
                  processing: true,
                  serverSide: true,
                  ajax:{url:"pos.json",dataSrc:""}
            }
    );

If using ASP.NET MVC, the URL can be build this way in JavaScript;

let url = '@Url.Action("Action", "Controller")';

See ajax options

LINKS

See jQuery DataTables: Common JavaScript console errors for more details.

Reference

https://stackoverflow.com/questions/34287402/datatables-cannot-read-property-length-of-undefined

DataTables.js → How to update your data object for AJAX JSON data retrieval

DataTables!?

I love DataTables.js. It makes working with HTML tables a breeze and increases functionality such as search, sorting and pagination.

Their documentation is stellar, however, it’s still written by devs, so it doesn’t explain code to people like you and me. You know. Normal.

This is why I wanted to write the quick post about how to use dynamic data in your DataTables AJAX request.

The Code

Normally, you would instantiate your DataTable for ajax, like this:

//All code in these examples are written in jQuery
//Notice the code in BOLD
$('#example_table').DataTable({
  'ajax': {
    "type"   : "POST",
    "url"    : '/path/to/your/URL',
    "data"   : {
          "key_example1" : "value_example1",
          "key_example2" : "value_example2"
         },
    "dataSrc": ""
  },
  'columns': [
    {"data" : "metric_name"},
    {"data" : "metric_type"},
    {"data" : "metric_timestamp"},
    {"data" : "metric_duration"}
  ]
});

The Wrong Way

It took me a min to figure out this is how they wanted you to send the data, as their documentation makes it seems like you would write something like:

example_table.ajax.data({//object properties here});

However this way doesn’t work at all and simply throws errors.

The Right Way

Now what’s really nice about DataTables is the ability to use a function for that data property :

var example_table = $('#example_table').DataTable({
  'ajax': {
    "type"   : "POST",
    "url"    : '/path/to/your/URL',
    "data"   : function( d ) {
      d.example_key1= $('#example_input1').val();
      d.example_key2= $('#example_input2').val();
      d.example_key3= $('#example_input3').val();
    },
    "dataSrc": ""
  },
  'columns': [
    {"data" : "metric_name"},
    {"data" : "metric_type"},
    {"data" : "metric_timestamp"},
    {"data" : "metric_duration"}
  ]
});
//To Reload The Ajax
//See DataTables.net for more information about the reload method
example_table.ajax.reload()

As you can see, you simply can see any property of the parameter “d” and set a value. DataTables will then set the “data” object to those properties.

For example, if the values of example_input1, example_input2, or example_input3 change, simply reload the ajax method of DataTables by using :

example_table.ajax.reload()

and your table will perform the ajax call along with the new values provided.

Happy Coding!

Remove a Class from an HTM Element

To remove a class from an element, you use the remove() method of the classList property of the element.

Suppose you have a <div> element as follows:

<div class="primary visible info">Item</div>

To remove the visible class from the div element, you use the following code:

const div =  document.querySelector('div');
div.classList.remove('info');

The remove() method also allows you to remove multiple classes at once, like this:

const div = document.querySelector('div');
div.classList.remove('info','primary');

Here is another example using jQuery selector;

Let’s say we have these classes;

 <span class="position-absolute top-0 start-100 translate-middle badge rounded-pill bg-danger" id="spanCount">
    99+
    <span class="visually-hidden">unread messages</span>
 </span>

We are going to select span HTML element with an id of “spanCount”. We will remove badge rounded-pill and bg-danger classes;

const spanElement = $("span#spanCount");
console.log(spanElement)
$("span#spanCount").removeClass("badge rounded-pill bg-danger");

Sources

jQuery selectors

Add, Remove classes

The character + is converted into “&#x2B” in base64 encoded data

I am passing following string from MVC component (c#) to razor view;

var Count = "99+";

When I try to access this in razor view, i get &@x2B appended to it;

console.log(@Model.Count);
///
///--output
99&#x2B

Razor does some encoding. To get ride of this problem, we need to use @Html.Raw.

console.log(@Html.Raw(Model.Count)
///
///--output
99+

or better, use it with backtick operator;

let count = `@Html.Raw(Model.Count)`;
console.log(count);
///
///--output
99+

enjoy!