Data tables - dynamic columns from an Ajax data source?

I'm trying to get DataTables to read column names from an AJAX data source, but it seems like there should be something that I don't need here.

I made a fiddle fiddle in which I can manually determine the data and columns that are used in the table.

The table is declared in HTML and there is no need to define column names ( <thead>..</thead> ):

 <table id="example" class="display table table-striped table-bordered" cellspacing="0" width="100%"></table> 

In JS, we manually define the data:

 var data = [ [ "Row 1 - Field 1", "Row 1 - Field 2", "Row 1 - Field 3" ], [ "Row 2 - Field 1", "Row 2 - Field 2", "Row 2 - Field 3" ], ]; 

Then manually define the column names or headers:

 var columns = [ { "title":"One" }, { "title":"Two" }, { "title":"Three" } ]; 

Then, when we initialize the table, we simply pass the previously declared information for use in the DataTables:

 $(document).ready(function() { $('#example').DataTable( { dom: "Bfrtip", data: data, columns: columns }); }); 

Result:

Summary table

Now my question is: how do I get this to work if the data is included in the server side AJAX response?

I tried it in different ways and forms, but it seems nothing works out here, and I'm afraid to find relative documentation about this.

For example, if server-side processing sends a JSON response that includes column names at the end:

 { "data": [ { "id": "1", "One": "Row 1 - Field 1", "Two": "Row 1 - Field 2", "Three": "Row 1 - Field 3" }, { "id": "2", "One": "Row 2 - Field 1", "Two": "Row 2 - Field 2", "Three": "Row 2 - Field 3" } ], "options": [], "files": [], "columns": [ { "title": "One", "data": "One" }, { "title": "Two", "data": "Two" }, { "title": "Three", "data": "Three" } ] } 

Given this is the answer, I tried to configure DataTables to use an AJAX data source for row information like this:

 $(document).ready(function() { $('#example').DataTable( { dom: "Bfrtip", "ajax": '/test.php', columns: columns }); }); 

But obviously the columns here are undefined.

So, before sending the column data:

 function getPromise() { var deferred = $.Deferred(); var dataUrl = document.location.origin+'/text.php'; $.getJSON(dataUrl, function(jsondata) { setTimeout(function() { deferred.resolve(jsondata); }, 0); }).fail(function( jqxhr, textStatus, error ) { // ********* FAILED var err = textStatus + ", " + error; console.log( "Request Failed: " + err ); }); return deferred.promise(); } // Get the columns getPromise().done(function(jsondata) { columns = jsondata.columns; console.log(columns); }); 

And pass it to DataTables as above. But this time, all I get when running the example is a console error saying TypeError: p is undefined .

So, how can I use dynamically created columns returned in response to the server? Is there an easier way to achieve this?

EDIT:

Code of the DataTables editor for server-side processing / to generate the JSON response mentioned above:

 <?php // DataTables PHP library require_once '/path/to/DataTables.php'; // Alias Editor classes so they are easy to use use DataTables\Editor, DataTables\Editor\Field, DataTables\Editor\Format, DataTables\Editor\Mjoin, DataTables\Editor\Upload, DataTables\Editor\Validate; // Build our Editor instance and process the data coming from _POST $out = Editor::inst( $db, 'example' ) ->fields( Field::inst( 'id' )->set(false), Field::inst( '`One`' )->validator( 'Validate::notEmpty' ), Field::inst( '`Two`' )->validator( 'Validate::notEmpty' ), Field::inst( '`Three`' )->validator( 'Validate::notEmpty' ) ) ->process( $_POST ) ->data(); // On 'read' remove the DT_RowId property so we can see fully how the `idSrc` // option works on the client-side. if ( Editor::action( $_POST ) === Editor::ACTION_READ ) { for ( $i=0, $ien=count($out['data']) ; $i<$ien ; $i++ ) { unset( $out['data'][$i]['DT_RowId'] ); } } // Create the thead data if (count ($out) > 0) { $columns = array(); foreach ($out['data'][0] as $column=>$relativeValue) { // Add all but the id value if ($column !== 'id') { // Add this column name $columns[] = array( "title"=>$column, "data"=>$column ); } } } // Add the the thead data to the ajax response $out['columns'] = $columns; // Send the data back to the client echo json_encode( $out ); 
+6
source share
1 answer

If you are not using the built-in DataTables ajax , this should be easy enough, given the structure of your data:

 $(document).ready(function() { $.ajax({ type: 'POST', dataType: 'json', url: '/echo/json/', data: { json: JSON.stringify(jsonData) }, success: function(d) { $('#example').DataTable({ dom: "Bfrtip", data: d.data, columns: d.columns }); } }); }); 

Like this JSFiddle , you are limited to download all the data at once, but this should not be a big problem ... if you do not change it, get the columns from the ajax initial call and after starting the DataTable, add the built-in ajax - I have not tried this, though ...

+4
source

All Articles