简体   繁体   English

收到 AJAX POST 响应后 DataTable 未刷新 onclick

[英]DataTable not getting refreshed after AJAX POST response is received onclick of next page

My problem statement is as below:我的问题陈述如下:

Display 10 rows per page on DataTable.在 DataTable 上每页显示 10 行。 When the user clicks on the next page number, use that number in flask to calculate row_count.当用户点击下一个页码时,使用 flask 中的那个数字来计算 row_count。 Select rows from database that are equal to the above row_count.数据库中的 Select 行等于上述 row_count。 Display these selected rows on DataTable.在 DataTable 上显示这些选定的行。

Following code gives me json response on console.log, but my DataTable is not getting refreshed.以下代码在 console.log 上给了我 json 响应,但我的 DataTable 没有刷新。

JQuery snippet: JQuery 片段:

$(document).ready(function() {
       var buttonCommon = {
        exportOptions: {
            format: {
                body: function ( data, row, column, node ) {
                                return data;
                                }
                            }
                    }
            };

var table = $("#myTable").DataTable({
 "lengthMenu": [
   [10, 25, 50, -1],
   [10, 25, 50, "All"]
 ],
 drawCallback: function() {
   $(".paginate_button", this.api().table().container())
     .on("click", function() {

       var pageNum= table.page.info().page;

        $.ajax({
            data: JSON.stringify({ "pageNum": pageNum }),
            dataType: "json",
            type: "POST",
            contentType: "application/json; charset=utf-8",
            url: "/my/url",
            success: function(data){
                data = JSON.parse(data);
                $("#myTable").DataTable({
                    data: data.data,
                    columns: [
                            { "data": "name" },
                            { "data": "branch" },
                            { "data": "city" },
                            { "data": "state" },
                            { "data": "country" },
                            { "data": "pin" },
                            { "data": "landmark" },
                            ]
                    })
                }
            })
        })
    }   
})

Flask snippet: Flask 片段:

@my_api.route('/url', methods=['POST', 'GET'])
def myfunc():

    conn = get_pgsql_conn_obj()
    cursor = conn.cursor()

    if request.get_json():
        number = request.json['pageNum']
        start_num = number * 20 + 1
        stop_num = start_num + 9

        select_sql = "select name, branch, city, state, country, pin, landmark from (select name, branch, city, state, country, pin, landmark, row_number() over (order by pin) as rnum from table) as r where r.rnum <= {}".format(stop_num)
     
        cursor.execute(select_sql)

        myData = cursor.fetchall()
    
        c_data = []
        for c in myData:
            c_data.append({
                'name': c[0],
                'branch': c[1],
                'city': c[2],
                'state': c[3],
                'country': c[4],
                'pin': c[5],
                'landmark': c[6],
                })
     
        return json.dumps(c_data)

    elif request.get_json() is None:

        number = 0
        select_sql = "select name, branch, city, state, country, pin, landmark from (select name, branch, city, state, country, pin, landmark, row_number() over (order by pin) as rnum from table) as r where r.rnum = 1 or r.rnum <= 20"
        cursor.execute(select_sql)

        myData = cursor.fetchall()


        c_data = []
        for c in myData:
            c_data.append({
                'name': c[0],
                'branch': c[1],
                'city': c[2],
                'state': c[3],
                'country': c[4],
                'pin': c[5],
                'landmark': c[6],
                })

        return render_template('my.html', c_data=c_data)

    else:
    *Do something else*

I can see the response in the Network Response something like below:我可以在网络响应中看到如下响应:

[{"name": "XYZ", "branch": "main", "city": "Tokyo", "state": "P3", "country": "Japan", "pin": "110011", "landmark": "L1"},{"name": "XYZ", "branch": "main", "city": "Tokyo", "state": "P3", "country": "Japan", "pin": "110011", "landmark": "L2"},...{"name": "XYZ", "branch": "main", "city": "Tokyo", "state": "P3", "country": "Japan", "pin": "110011", "landmark": "L30"}] [{“name”:“XYZ”,“branch”:“main”,“city”:“Tokyo”,“state”:“P3”,“country”:“Japan”,“pin”:“110011”, “地标”:“L1”},{“名称”:“XYZ”,“分支”:“主要”,“城市”:“东京”,“州”:“P3”,“国家”:“日本”, “pin”:“110011”,“landmark”:“L2”},...{“name”:“XYZ”,“branch”:“main”,“city”:“Tokyo”,“state”:“ P3”,“国家”:“日本”,“pin”:“110011”,“地标”:“L30”}]

EDIT:编辑:

I've tried the following 2 solutions, but still not able to get the datatable refreshed:我尝试了以下两种解决方案,但仍然无法刷新数据表:

Solution 1:解决方案1:

 var table = $("#myTable").DataTable({
 "lengthMenu": [
   [10, 25, 50, -1],
   [10, 25, 50, "All"]
 ],
 "columnDefs": [{
    "defaultContent": "-",
    "targets": "_all"
 }],
 drawCallback: function() {
   $(".paginate_button", this.api().table().container())
     .on("click", function() {

       var pageNum= table.page.info().page;

        $.ajax({
            data: JSON.stringify({ "pageNum": pageNum }),
            dataType: "json",
            type: "POST",
            contentType: "application/json; charset=utf-8",
            url: "/my/url",
            success: function(data){
                    console.log(data);
                    table.clear();
                    table.rows.add(data);
                    table.draw();
                    }                
         });
     });
    }
});

This gives me first 20 records with pagination, ie 10 records per page.这给了我前 20 条分页记录,即每页 10 条记录。 On clicking page number 2, it returns an array like below on network response:单击第 2 页时,它会在网络响应中返回如下所示的数组:

[{"name": "XYZ", "branch": "main", "city": "Tokyo", "state": "P3", "country": "Japan", "pin": "110011", "landmark": "L1"},{"name": "XYZ", "branch": "main", "city": "Tokyo", "state": "P3", "country": "Japan", "pin": "110011", "landmark": "L2"},...{"name": "XYZ", "branch": "main", "city": "Tokyo", "state": "P3", "country": "Japan", "pin": "110011", "landmark": "L30"}] [{“name”:“XYZ”,“branch”:“main”,“city”:“Tokyo”,“state”:“P3”,“country”:“Japan”,“pin”:“110011”, “地标”:“L1”},{“名称”:“XYZ”,“分支”:“主要”,“城市”:“东京”,“州”:“P3”,“国家”:“日本”, “pin”:“110011”,“landmark”:“L2”},...{“name”:“XYZ”,“branch”:“main”,“city”:“Tokyo”,“state”:“ P3”,“国家”:“日本”,“pin”:“110011”,“地标”:“L30”}]

But there's no change to the datatable.但是数据表没有变化。

Solution 2 (As suggested by Mtxz):解决方案 2(如 Mtxz 建议的那样):

    var table = $("#myTable").DataTable({
 "lengthMenu": [
   [10, 25, 50, -1],
   [10, 25, 50, "All"]
 ],
});


$(".paginate_button", this.api().table().container())
     .on("click", function() {

       makeRequest();

});

function makeRequest() {
    var pageNum = table.hasOwnProperty('page') ? table.page.info().page : 1;
     if (pageNum > 0) {
            $.ajax({
            data: JSON.stringify({ "pageNum": pageNum }),
            dataType: "json",
            type: "POST",
            contentType: "application/json; charset=utf-8",
            url: "/my/url",
            success: function(data){
                    var new_data = JSON.parse(data);
                    table.clear();
                    table.rows.add(new_data);
                    table.draw();
                    }
            })

    }

}

This gives me first 20 records with pagination, ie 10 records per page.这给了我前 20 条分页记录,即每页 10 条记录。 On clicking page number 2, It gives me Uncaught SyntaxError: Unexpected token o in JSON at position 1 at JSON.parse ()在单击第 2 页时,它给了我Uncaught SyntaxError: Unexpected token o in JSON at position 1 at JSON.parse ()

When I try without JSON.parse, it gives me DataTables warning: table id=objectTable - Requested unknown parameter '0' for row 0, column 0 , but returns an array like below on console log, clears the table data, and adds an extra page number 3 (response array has 30 records and length is set to 10 per page):当我尝试不使用 JSON.parse 时,它给了我DataTables 警告:table id=objectTable - Requested unknown parameter '0' for row 0, column 0 ,但在控制台日志中返回如下所示的数组,清除表数据,并添加一个额外的页码 3(响应数组有 30 条记录,长度设置为每页 10 条):

0: {"name": "XYZ", "branch": "main", "city": "Tokyo", "state": "P3", "country": "Japan", "pin": "110011", "landmark": "L1"} 1: {"name": "XYZ", "branch": "main", "city": "Tokyo", "state": "P3", "country": "Japan", "pin": "110011", "landmark": "L2"} 29: {"name": "XYZ", "branch": "main", "city": "Tokyo", "state": "P3", "country": "Japan", "pin": "110011", "landmark": "L30"} 0:{“name”:“XYZ”,“branch”:“main”,“city”:“Tokyo”,“state”:“P3”,“country”:“Japan”,“pin”:“110011” , "landmark": "L1"} 1: {"name": "XYZ", "branch": "main", "city": "Tokyo", "state": "P3", "country": "Japan ", "pin": "110011", "landmark": "L2"} 29: {"name": "XYZ", "branch": "main", "city": "Tokyo", "state": " P3”,“国家”:“日本”,“pin”:“110011”,“地标”:“L30”}

From your script, it seems that your re-init your table with each click.从您的脚本来看,您似乎每次点击都会重新初始化您的表格。 What I would do:我会做什么:

  1. Server-side processing - Datatable has an ajax parameter (check examples here and here ), and a table.ajax.reload();服务器端处理- Datatable 有一个ajax参数(在此处此处查看示例)和一个table.ajax.reload(); reload method.重载方法。 It also has a ajax.url() to alter the query URL if you need to add query parameters.如果您需要添加查询参数,它还有一个ajax.url()来更改查询 URL。 So you could directly add your API URL to your datatable instance, and use "server-side" processing.因此,您可以直接将您的 API URL 添加到您的数据表实例中,并使用“服务器端”处理。 Your API sending the correct paginated JSON collection based on the parameters Datatable will add to the request.您的 API 根据 Datatable 将添加到请求的参数发送正确的分页 JSON 集合。 (I believe it's possible to customize the ajax request to add an authentication header or else). (我相信可以自定义 ajax 请求以添加身份验证 header 或其他)。 You should check all ajax.* related Datatable documentation pages, also google about "jquery datatable server-side processing PHP example" ( see ).您应该检查所有ajax.*相关的 Datatable 文档页面,还有关于“jquery datatable server-side processing PHP example”的谷歌(参见)。 It's the cleanest way if you want to the sorting, the search, and the pagination working with the remote data source, and of course NOT loading the entire set of data:).如果您想对远程数据源进行排序、搜索和分页,当然不加载整个数据集,这是最简洁的方法:)。

  2. From your script logic (using the Datatable data parameter)从您的脚本逻辑(使用 Datatable data参数)

  • make a separate method that will handle the ajax call, with a page parameter.使用页面参数创建一个单独的方法来处理 ajax 调用。 This method will return the $result ajax result in a variable此方法将在变量中返回$result ajax 结果
  • on page load, and call this method with page 1 to get the ajax $result , and init your datatable with this $result在页面加载时,使用第 1 页调用此方法以获取 ajax $result ,并使用此$result初始化您的数据表

var table = $('#example').DataTable({data: jQuery.parseJSON($result), ...

  • 2.1 on the ajax success handler, update the $result variable with new request-response, and call table.ajax.reload(); 2.1在 ajax 成功处理程序上,使用新的请求响应更新$result变量,并调用table.ajax.reload(); to refresh the datatable and redraw with new data.刷新数据表并用新数据重绘。 EDIT : I'm not sure that just using a variable as data source and refreshing will work (but the linked examples does, so it need further tests).编辑:我不确定仅使用变量作为数据源并刷新是否有效(但链接的示例可以,因此需要进一步测试)。 I think you'll have to follow something like this to handle your pagination manually.我认为您必须按照类似的方法手动处理分页。

Still, it's only the pagination.不过,这只是分页。 And the search and sorting will only append in the paginated dataset.并且在分页数据集中搜索和排序只会 append 。 To have the full power of search, filtering, sorting without having to load the entire dataset onload: you need server-side processing.要在无需加载整个数据集的情况下拥有搜索、过滤、排序的全部功能:您需要服务器端处理。 To handle the PHP side, you can simply put your API url as ajax parameter, and on your PHP side dump the entire $_GET variable while changing sorting, filtering, search on the frontend. To handle the PHP side, you can simply put your API url as ajax parameter, and on your PHP side dump the entire $_GET variable while changing sorting, filtering, search on the frontend. So you'll see how Datatable handles the filtering parameters, and be able to adapt your database queries to take those parameters in consideration, along with pagination: server-side processing.因此,您将看到 Datatable 如何处理过滤参数,并能够调整您的数据库查询以考虑这些参数,以及分页:服务器端处理。

  1. Examples:例子:

This post is about updating the dataset with new data and can be adapted to your needs. 这篇文章是关于使用新数据更新数据集的,并且可以根据您的需要进行调整。 This post and the related comments, as it's a similar case (and it's this example that also uses data parameter with a custom ajax handling, that the refresh is also working in this case, with a variable for data ) 这篇文章和相关评论,因为它是一个类似的案例(这个例子也使用了自定义 ajax 处理的data参数,刷新在这种情况下也有效,带有一个data变量)

Here is something I've NOT tested that could inspire you:这是我没有测试过的可以启发你的东西:

 $(document).ready(function() { var buttonCommon = { exportOptions: { format: { body: function (data, row, column, node) { return data; } } } }; //init table with empty data var table = $("#myTable").DataTable({ "lengthMenu": [ [10, 25, 50, -1], [10, 25, 50, "All"] ], data: [] }); //on button click $(".paginate_button", this.api().table().container()).on("click", function () { makeRequest(); //this is from the example where ajax.reloads works when the data is a variable that is updated by a custom ajax handler //From this example, it seems that the ajax reload also works when the data is a variable - todo make some test //table.ajax.reload(); }) //make async request function makeRequest() { var pageNum = table.hasOwnProperty('page')? table.page.info().page: 1; //if table is not init yet (first call) use page 1 $.ajax({ data: JSON.stringify({ "pageNum": pageNum }), dataType: "json", type: "POST", //you could use GET and?page=1 parameter contentType: "application/json; charset=utf-8", url: "/my/url", success: function(data){ var new_data = JSON.parse(data); table.clear(); table.rows.add(new_data); table.draw(); } }) } });

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如果刷新/重新打开页面,Django POST响应将引发异常 - Django POST Response throws exception if page is refreshed/reopened 刷新页面后取消POST - Cancel the POST when the page is refreshed 如何在使用 AJAX/jQquery POST 请求后在客户端页面上显示来自服务器的响应 - How to show response from server on client page after POST request using AJAX/jQquery Django:成功 login() 后,下次刷新 request.user 页面时,它再次变为“匿名” - Django: after successful login() the next time the request.user page is refreshed it becomes “anonymous” again 在 Flask 中使用 HTML POST 操作刷新变量 - Variables getting refreshed with HTML POST operation in Flask 页面刷新后,Ajax POST to Flask无法正常工作 - Ajax POST to Flask not working after page refresh Flask Ajax 调用,没有错误,但没有收到回复 - Flask Ajax Call, No Error, but no Response Received Back 为什么代码在收到响应后没有执行 - Why is code not executing after response received 如何使用ajax函数发送表单而不刷新页面,我缺少什么?我必须使用rest-framework吗? - how to use ajax function to send form without page getting refreshed, what am I missing?Do I have to use rest-framework for this? 如何从请求的响应中检查是否存在下一页,而不会出现“关键错误”。 蟒蛇 - How to check if there is a next page or not from the response of requests without getting Key Error. Python
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM