Loading and re-loading jQuery Datatble with Ajax

Here is a full example, which you can copy into a html file and run for yourself, if you wish. It uses data from a dummy JSON provider, just for testing.

The HTML, showing the table and a button. The button is how I tested the ability to call a new URL and pass new request parameters to that new URL:

<div style="margin: 20px;">
    <button id="button_one" type="button">Resubmit</button>
    <br><br>
    <table id="example" class="display" style="width:100%"></table>
</div>

Here is the related script containing the DataTable definition and a function which calls the new URL (with new request parameters):

<script>

$(document).ready(function() {

  // ajax for initial table creation:
  var requestUrl = "https://jsonplaceholder.typicode.com/posts";
  var requestData = { "name": "Abel", "location": "here" };

  var table = $('#example').DataTable( {
    ajax: {
      method: "GET",
      url: requestUrl,
      "data": function ( ) {
        return requestData;
      },
      dataSrc: "",  
    },
    "columns": [
      { "title": "User ID", "data": "userId" },
      { "title": "ID", "data": "id" },
      { "title": "Title", "data": "title" }
    ]
            
  } );
  
  $("#button_one").click(function() {
    // subsequent ajax call, with button click:
    requestUrl = "https://jsonplaceholder.typicode.com/todos";
    requestData = { "name": "Charlie", "location": "there" };
    table.ajax.url( requestUrl ).load();
  });
  
} );

</script>

The key points in this example are:

  1. There are 2 different URLs. The first one is used when DataTables is created. The second one is used when the button is clicked.
  2. There are 2 different sets of request data, for the two URLs.

Using this approach, you can repeatedly call table.ajax.url( requestUrl ).load() with different URLs and different sets of request data, without needing to destroy the DataTable.

Handling Form Data

Here is a simple HTML form:

<form id="filter-form">
    City:<input type="text" id="city" name="city">
    Country:<input type="text" id="country" name="country">
    <input type="submit" value="Submit">
</form> 

For testing, I have the following JavaScript which captures the contents of the form into an array:

var form_data = [];

$( "#filter-form" ).submit(function( event ) {
  event.preventDefault();
  form_data = $( this ).serializeArray();
  table.ajax.url( url ).load();
});

The end result is data like this in the form_data variable:

[
  {
    "name": "city",
    "value": "Berlin"
  },
  {
    "name": "country",
    "value": "Germany"
  }
]

Now I can merge that data into the automatically created server-side request data. This is where I can choose to use the $.extend() function I mentioned above:

$('#example').DataTable( {
    serverSide: true,
    ajax: { 
      method: "POST",
      url: url, // from a variable
      data: function( d ) {
        return $.extend( {}, d, { "my_extra_data": form_data } );
      }
    },
    ... //whatever else is in your DataTable definition...
  });

This function results in request data like the following:

{
    "draw": "2",
    "columns[0][data]": "id",
    "columns[0][name]": "",
      ...
    "start": "0",
    "length": "10",
    "search[value]": "",
    "search[regex]": "false",
    "my_extra_data[0][name]": "city",
    "my_extra_data[0][value]": "Berlin",
    "my_extra_data[1][name]": "country",
    "my_extra_data[1][value]": "Germany"
}

You can see your my_extra_data values are included along with the server-side auto-generated request data. And all of this gets sent to the server as part of your request.

If you are using POST then it’s in the request body.

If you are using GET, then it’s the same data – but added to the URL as a query string.

In both cases, it’s converted to the standard string representation used by form data.

It’s then up to the server-side code to access this data in the usual way.

NOTE: You may have expected your URL-encoded form data to be provided as this:

...&city=Berlin&country=Germany

But instead it is provided as arrays of name/value pairs:

&my_extra_data%5B0%5D%5Bvalue%5D=Berlin&my_extra_data%5B1%5D%5Bname%5D=country&my_extra_data%5B1%5D%5Bvalue%5D=Germany

So, there is extra server-side work needed to parse this data.

If you want to convert your form data directly into a JavaScript object like this:

{ "city": "Berlin", "country", "Germany" }

then use this;

serializeArray already does exactly that. You just need to massage the data into your required format:

function objectifyForm(formArray) {
    //serialize data function
    var returnArray = {};
    for (var i = 0; i < formArray.length; i++){
        returnArray[formArray[i]['name']] = formArray[i]['value'];
    }
    return returnArray;
}

Watch out for hidden fields which have the same name as real inputs as they will get overwritten. For more info, take a look at the answers to this question:

Convert form data to JavaScript object with jQuery

Reference

https://stackoverflow.com/questions/66243388/how-to-reload-datatable-by-using-new-url-and-some-parameters-without-reinitializ

https://datatables.net/forums/discussion/61124/transfer-table-data-to-the-server-side

Javascript setTimeout

Sometimes you might want to delay the execution of your code.

You may need certain lines of code to execute at a point in the future, when you explicitly specify, rather than all the code executing synchronously.

Something like that is possible with JavaScript. The general syntax for the setTimeout() method looks like this:

setTimeout(function_name, time);

Let’s break it down:

  • setTimeout() is a method used for creating timing events. It accepts two required parameters.
  • function_name is the first required parameter. It is the name of a callback function that contains the code you want to execute. The name of the function acts as a reference and pointer to the function definition that contains the actual block of code.
  • time is the second required parameter, and it is defined in milliseconds (for reference, 1 second = 1000 milliseconds). It represents the specified amount of time the program has to wait for the function to be executed.

Here is an example;

function TranStatusCheck() { alert ('hi') }
$(function(){
    //run above method once after 1ms
    window.setTimeout(TranStatusCheck, 100);    //100ms (1000 ms = 1 sec)
});

Remember, not to write method this way;

window.setTimeout(TranStatusCheck(), 100);

Reference

https://developer.mozilla.org/en-US/docs/Web/API/setTimeout

https://javascript.info/settimeout-setinterval

https://www.freecodecamp.org/news/javascript-wait-how-to-sleep-n-seconds-in-js-with-settimeout/

jQuery DataTable Column Selector

The best approach is to get the counts first and then try to get specific column;

var table = $('#example').DataTable();
 
var data = table
    .rows()
    .data();
 
alert( 'The table has '+data.length+' records' );

The DataTables columns() and column() (also optionally cells() and cell()) methods provide the ability to select columns from the table. Which columns are selected and how the selector actually operates is controlled by this column-selector data type.

var table = $('#example').DataTable( {
    columns: [
        { name: 'first-name' },
        { name: 'last-name' },
        { name: 'position' },
        { name: 'location' },
        { name: 'salary' }
    ]
} );
 
// Get salary column data
table.column( 'salary:name' ).data();

Reference

https://datatables.net/reference/type/column-selector

https://stackoverflow.com/questions/32598279/how-to-get-name-of-datatable-column

https://datatables.net/reference/api/columns().every()

https://datatables.net/reference/api/rows().data()

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