【问题标题】:jQuery DataTables adding dynamic columnsjQuery DataTables 添加动态列
【发布时间】:2018-06-15 12:30:39
【问题描述】:
  • 要求:使用由 a 返回的 JSON 对象绘制数据表 网络服务。
  • 约束:列数未知。

我的实现如下所示,但我不确定在从 ajax 请求接收 JSON 后在哪里/如何定义列。

$("#reportTable").DataTable({
    "ajax": {
        "url": "/path/that/returns/json",
        "type": "POST",
        "data": { "formatType": "json", "dispatchType": "api" , "csrfmiddlewaretoken" : "{{ csrf_token }}"},
        "dataSrc": function ( json ) {
            console.log(json); //can i set my column definition here?
        },
    },
    "columns":["Do i need to even add this?"],
    "autoWidth": false,
    "pageLength": 50
});

这是返回的 JSON 格式,注意属性可能会有所不同:

结果 1:

    [
       {
          "fname":"Bruce",
          "lname":"Wayne",
          "id":"BatMan"
       },
       {
          "fname":"Steve",
          "lname":"Rogers",
          "id":"CptAmerica"
       },
       {
          "fname":"Tony",
          "lname":"Stark",
          "id":"IronMan"
       }
    ]

结果 2:

    [
       {
          "company":"Wayne Enterprices",
          "owner":"Bruce Wayne"
       },
       {
          "company":"Stark Industries",
          "owner":"Tony Stark"
       },
       {
          "company":"SpaceX",
          "owner":"Elon Musk"
       }
    ]

谢谢!

【问题讨论】:

  • 嘿@vignz.pie,你解决了这个问题吗?我面临同样的问题并试图在几个小时内获得解决方案......

标签: jquery ajax datatables datatables-1.10


【解决方案1】:

以下是如何实现此目的的完整示例:

      /**
     * Get random dataset
     * */
    const getData = () => {
        let data = [
            [
                {
                    "fname":"Bruce",
                    "lname":"Wayne",
                    "id":"BatMan"
                },
                {
                    "fname":"Steve",
                    "lname":"Rogers",
                    "id":"CptAmerica"
                },
                {
                    "fname":"Tony",
                    "lname":"Stark",
                    "id":"IronMan"
                }
            ],[
                {
                    "company":"Wayne Enterprices",
                    "owner":"Bruce Wayne"
                },
                {
                    "company":"Stark Industries",
                    "owner":"Tony Stark"
                },
                {
                    "company":"SpaceX",
                    "owner":"Elon Musk"
                }
            ]
        ];

        let index = Math.round(Math.random()); // 1 or 0

        return data[index];
    }

    /**
     * This function acts as an ajax call
     */
    const getAjaxData = () => {
        return new Promise((resolve, reject) => {
            let data = getData();

            return resolve(data);
        })
    }

    const buildHeader = (data) => {
        let firstRow = data[0] || [],
            keys = Object.keys(firstRow);

        return keys.map(key => ({
            data: key,
            name: key
        }))
    }
    
    /**
    * Initialize datatable with the data
    **/
    const buildDataTable = (columns, data) => {
        console.log({columns, data});

        $("#sample-table").DataTable({
            data: data,
            columns: columns,
            pageLength: 100,
            processing: true,
        });
    }

    // main
    $(window).ready(() => {
    
        // simulate ajax call
        getAjaxData().then(data => {
            let columns = buildHeader(data);

            buildDataTable(columns, data);
        }).catch(err => {
            console.log("Couldn't fetch the data", err);
        })
    })
<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>

    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">

    <script src="//ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js" integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q" crossorigin="anonymous"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script>
    <script src="//cdn.datatables.net/1.10.20/js/jquery.dataTables.min.js"></script>
    <script src="//cdn.datatables.net/1.10.20/js/dataTables.material.min.js"></script>
</head>
<body>

  <table id="sample-table" class="table">

  </table>

</body>

</html>

补充:

另外,这是我的确切情况,如果您最初有服务器端渲染,然后想使用 ajax 进行更多页面,只需生成包含 &lt;thead&gt;&lt;tbody&gt; 元素的 html 表,确保所有标题单元格匹配名称,然后使用以下方法初始化数据表:

$("#sample-table").DataTable({
    ajax: `/path/to/api/data`,
    columns: columns,
    pageLength: pageLength,
    processing: true,
    deferRender: true, /* this means we already have the first page data*/
    deferLoading: totalRecords, /*total all records*/
    serverSide: true,
    autoWidth: false,
    searching: false,
    info:     false
});

注意:

Requested unknown parameter 'foo.bar' for row y, column x. 的问题

在源数据被展平的情况下使用something.foo.bar作为列名,例如源数据:

{
   "something.foo.bar": "some text",
   "something.foo.bar.baz": 123
}

会报错,因为它会尝试在foo 里面找到bar 里面something 里面不存在。在这种情况下,您需要将 . 替换为其他内容。

【讨论】:

    【解决方案2】:
    This is a quick post about how to modify your JSON returned objects before sending them to the tables using DataTables.js. 
    In this example I am using a flat array for my JSON objects. For more uses for data sources in AJAX visit http://www.datatables.net/examples/ajax/
    
    The Code
    
    $('#example_table').DataTable({
      //'deferRender': false,
      'ajax'       : {
        "type"   : "POST",
        "url"    : http://yourURLhere.com/path/to/your/script,
        "dataSrc": function (json) {
          var return_data = new Array();
          for(var i=0;i< json.length; i++){
            return_data.push({
              'title': json[i].title,
              'url'  : '<img src="' + json[i].url + '">',
              'date' : json[i].date
            })
          }
          return return_data;
        }
      },
      "columns"    : [
        {'data': 'url'},
        {'data': 'title'},
        {'data': 'date'}
      ]
    });
    
    
    So the dataSrc property can have a function passed to it. The dataSrc property contains the returned information given from your post request. Now, since we are using a flat array like this:
    
    [
      {
       title : 'example_title',
       url   : 'example_url',
       date  : 'example_date'
      },
      {
       title : 'example_title2',
       url   : 'example_url2',
       date  : 'example_date2'
      },... and so on...
    ]
    

    a shortened version of the standard arrays.txt as the data source and simply added the column names definition. 这里的解决方案是改变响应。之前是 {"userid":"manohar", "password":"1234"},现在我把它改成了 [["manohar", "1234"]]。然后在js文件中

    $.ajax({
        url: 'userController?action=list',
        success : function(data, textStatus, jqXHR) {
            var table_data = JSON.parse(data);
            var table = $('#usermaintenancetable').DataTable( {
                data: table_data
         });
      } 
    });
    
    
        So here the response is in String format and I have change it to JSON using JSON.parse() then passed this as data to data table.
    

    【讨论】:

    • 谢谢,但就像我说的,在 ajax 响应到达之前我不会知道 JSON 属性。因此,我无法定义像您的答案那样的列。
    • 我已经修改了答案,请看一下
    • 谢谢,Brajesh,但同样,我不会知道响应中发送的每个 JSON 的长度。我更新了问题以强调每次发出 ajax 请求时,响应都会改变。如果我需要进一步说明,请告诉我。
    猜你喜欢
    • 2013-04-25
    • 1970-01-01
    • 2015-08-31
    • 1970-01-01
    • 2011-09-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多