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

How to clone c# list?

Shallow Copy

We can easily achieve a shallow copy of our pizzas list with any of the methods from the previous section. But a shallow copy of a List<T>, where T is a reference type, copies only the structure of the collection and references to its elements, not the elements themselves. This means that changes to the elements in any of the two lists will be reflected in both the original and copied lists.

Let’s illustrate this:

var clonedPizzas = pizzas.ToList();

var margherita = pizzas
    .FirstOrDefault(x => x.Name == "Margherita");

margherita.Toppings.Clear();

First, we create a clonedPizzas variable and clone the contents of pizzas to it using the ToList method (using any of the other methods used earlier will produce the same result). Then we get the Margherita pizza from the original list using the FirstOrDefault method. Finally, we use the Clear method to empty the list of Toppings for that pizza.

Now, let’s see what happens:

Console.WriteLine($"Original Margherita: {pizzas.First()}");
Console.WriteLine($"Cloned with ToList: {clonedPizzas.First()}");

We print the first pizza of each list to the console, which in both cases is the Margherita, using the First method.

We overrode the ToString method which will give us an easy-to-read representation of each pizza. Now, we can check the result:

Original Margherita: Pizza name: Margherita; Toppings:
Cloned with ToList: Pizza name: Margherita; Toppings:

We can see that both the original and copied Margherita pizzas now have an empty list of Toppings. This is because when creating a shallow copy, we only clone the references to the objects, not the actual objects. This is not ideal because when we change elements in one list, we change the elements everywhere we have copied that list.

This might cause serious problems for us, so let’s what we can do to prevent it. Read more here.

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