datatable—Ajax数据源中的动态列?

时间:2022-12-04 15:37:52

I am trying to get DataTables to read the column names from an AJAX data source but it seems that there must be something that I must be missing here.

我试图让DataTables从AJAX数据源读取列名,但这里似乎缺少一些东西。

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

我做了一个小提琴,我可以手动定义表使用的数据和列。

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

表在HTML中声明,不需要定义列名(..):

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

In the JS we manually define the data:

在JS中,我们手工定义数据:

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 titles:

然后手动定义列名或标题:

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

Then when we initialise the table we simply pass the previously declared information across for DataTables to use:

然后,当我们初始化表时,我们只需将先前声明的信息传递给DataTables以供使用:

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

Which results in:

结果:

datatable—Ajax数据源中的动态列?

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

现在我的问题是,如果数据包含在AJAX服务器端响应中,我将如何使它工作?

I have tried this in various ways and forms but nothing really seems to work out here and I am battling to find relative documentation on this.

我已经尝试了各种方法和形式,但这里似乎没有什么实际效果,我正在努力寻找有关这方面的相关文档。

For example if the server side processing sent back a JSON response which includes the column names at the end:

例如,如果服务器端处理返回一个JSON响应,其中包含末尾的列名:

{
  "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 response, I tried to configure DataTables to use an AJAX data source for the row information as follows:

鉴于这是响应,我尝试将DataTables配置为对行信息使用AJAX数据源,如下所示:

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

But obviously columns is undefined here.

但显然列在这里没有定义。

So I get the column data before hand:

所以我得到了之前的列数据:

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 an error in the console saying TypeError: p is undefined.

并将其传递给上述的datatable。但这一次,我在运行示例时得到的只是控制台中的一个错误,它说TypeError: p没有定义。

So then how could I make use of the dynamically generated columns that are being returned within the server side response? Is there not a simpler way to achieve this?

那么,如何利用服务器端响应中返回的动态生成的列呢?难道没有更简单的方法来实现这一点吗?

EDIT:

编辑:

DataTables Editor code for server side processing / to generate the JSON response mentioned above:

服务器端处理/生成上面提到的JSON响应的DataTables编辑器代码:

<?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 );

1 个解决方案

#1


5  

If you don't use the built in DataTables ajax it should be easy enough given the structure of your data:

如果您不使用内置的datatable ajax,那么考虑到您的数据结构,这应该足够简单:

$(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're limited then to loading all the data at once but that shouldn't be a huge issue... unless you alter it get the columns from the initial ajax call and once the DataTable is initiated then add the built-in ajax - I've not tried this though...

像这个JSFiddle一样,您被限制一次加载所有的数据,但是这应该不是什么大问题……除非您修改它,否则从初始的ajax调用中获取列,并且一旦开始了DataTable,然后添加内置的ajax——我还没有尝试过……

#1


5  

If you don't use the built in DataTables ajax it should be easy enough given the structure of your data:

如果您不使用内置的datatable ajax,那么考虑到您的数据结构,这应该足够简单:

$(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're limited then to loading all the data at once but that shouldn't be a huge issue... unless you alter it get the columns from the initial ajax call and once the DataTable is initiated then add the built-in ajax - I've not tried this though...

像这个JSFiddle一样,您被限制一次加载所有的数据,但是这应该不是什么大问题……除非您修改它,否则从初始的ajax调用中获取列,并且一旦开始了DataTable,然后添加内置的ajax——我还没有尝试过……