Table Data is shown, but paginator is not.

Table Data is shown, but paginator is not.

Mbs14Mbs14 Posts: 7Questions: 1Answers: 0
edited August 2023 in Free community support

My <script> is:
<script src="https://cdn.datatables.net/1.13.6/js/jquery.dataTables.min.js"></script>

My server side is an old asp.net 4.8 site, where I use [webmethod] to process server-side request. My ajax function is:

tblDocTemplate = $('#tblFiles').DataTable({
    processing: true,
    serverSide: true,
    deferRender: true,
    ajax: {
        url: '/Library.aspx/GetDocTemplates',
        type: 'POST',
        contentType: 'application/json; charset=utf-8',
        data: function (d) {
            d.folderid = selectedFolder; // external variable
            return JSON.stringify(d);
        }
        ,
        dataSrc: function (response) {
            var tr = JSON.parse(response.d);
            return tr;// see cases 1, 2 and 3 below
        }
    }
    ,
    columns: [
        { data: 'Document' },
        { data: 'Created' },
        { data: 'Status' },
        { data: 'Cover' },
        { data: 'Actions' }
    ]
});

I am serializing following structure:

 internal class DocTemplates
 {
     public DocTemplates(int d, int rt)
     {
         draw = d;
         recordsTotal = rt;
         recordsFiltered = rt;   
     }
     public int draw {get; set;}
     public int recordsTotal { get; set;}
     public int recordsFiltered { get; set; }
     public List<DocTemplate> data { get; set;} = new List<DocTemplate>();
 }

all required data members are returned back to dataSrc, in "response.d" string

There are three cases of "dataSrc" implementation which I tried:
Case 1:
dataSrc: function (response) {
var tr = JSON.parse(response.d);
return tr;
}
result: neither records or pagination data is not shown in the table
Case 2:
dataSrc: function (response) {
var tr = JSON.parse(response.d);
return tr.data;
}
result: records are shown but pagination is not(Showing 0 to 0 of 0 entries (filtered from NaN total entries))
Case 3:
dataSrc: function (response) {
var tr = JSON.parse(response.d);
return {
draw: tr.draw,
data: tr.data,
recordsTotal: tr.recordsTotal,
recordsFiltered: tr.recordsFiltered
};
}
result: neither records or pagination data is not shown in the table

I will greatly appreciate any help in resolving it, I am embarrassed to say how many days I wasted on this. Thanks!

This question has an accepted answers - jump to answer

Answers

  • kthorngrenkthorngren Posts: 21,343Questions: 26Answers: 4,954

    Use the browser's network inspector tool to see the JSON response received. Please post the response here. Use triple back ticks (```) on new lines before and after the code block to format the output. Seeing the actual response will allow us to offer suggestions.

    Kevin

  • Mbs14Mbs14 Posts: 7Questions: 1Answers: 0
    edited September 2023

    dataSrs function:

    dataSrc: function (response) {
    var tr = JSON.parse(response.d);
    return tr;//.data;
    /*
    return {
    draw: tr.draw,
    data: tr.data,
    recordsTotal: tr.recordsTotal,
    recordsFiltered: tr.recordsFiltered
    };
    */
    }

    response.d value:

    '{"draw":2,"recordsTotal":3,"recordsFiltered":3,"data":[{"Document":"Cook County New","Created":"7/30/2021","Status":"Ready","Cover":"No","Actions":""},{"Document":"Usability Test","Created":"8/15/2019","Status":"Ready","Cover":"No","Actions":""},{"Document":"3Independent Contractor Payment Policy & Forms","Created":"1/15/2018","Status":"Ready","Cover":"No","Actions":""}]}'
    
  • kthorngrenkthorngren Posts: 21,343Questions: 26Answers: 4,954

    You are using JSON.parse(response.d) but the JSON response you posted doesn't have a d object. Either you didn't post the full response or you just need to use JSON.parse(response) as the above does look like a string.

    If you did not post the full JSON response and there is a d object with the above data then JSON.parse(response.d) might result in a string and not a Javascript object. If this is the case you will then need to use JSON.parse(tr) because the Datatables data was JSON encapsulated twice. If this is the case it might be better to remove the extra JSON encapsulation of the Datatables data in the server script.

    Possibly there is an issue with using ajas.DataSrc as a function with server side processing. You might try using event xhr to JSON.parse() the response and not use ajax.dataSrc

    Another option might be to not enable server side processing and just use standard ajax. Unless you are expecting many rows that will cause performance issues.

    Kevin

  • Mbs14Mbs14 Posts: 7Questions: 1Answers: 0

    testing your suggestions, will post shortly

  • Mbs14Mbs14 Posts: 7Questions: 1Answers: 0

    dataSrc function
    dataSrc: function (response) {
    console.log(response);
    console.log('typeof response: ' + (typeof response));
    console.log('typeof response.d: ' + (typeof response.d));
    var tr = JSON.parse(response.d);
    console.log(tr);
    console.log('typeof tr: ' + (typeof tr));
    return tr.data;
    }

    following is the console output

    console.log(response);
    {d: '{"draw":2,"recordsTotal":3,"recordsFiltered":3,"da…18","Status":"Ready","Cover":"No","Actions":""}]}'}d: "{\"draw\":2,\"recordsTotal\":3,\"recordsFiltered\":3,\"data\":[{\"Document\":\"Cook County New\",\"Created\":\"7/30/2021\",\"Status\":\"Ready\",\"Cover\":\"No\",\"Actions\":\"\"},{\"Document\":\"Usability Test\",\"Created\":\"8/15/2019\",\"Status\":\"Ready\",\"Cover\":\"No\",\"Actions\":\"\"},{\"Document\":\"3Independent Contractor Payment Policy & Forms\",\"Created\":\"1/15/2018\",\"Status\":\"Ready\",\"Cover\":\"No\",\"Actions\":\"\"}]}"[[Prototype]]: Object

    console.log('typeof response: ' + (typeof response)):
    typeof response: object

    console.log('typeof response.d: ' + (typeof response.d)):
    typeof response.d: string

    _
    _
    typeof tr: object

  • Mbs14Mbs14 Posts: 7Questions: 1Answers: 0

    I made one more step and created following dataSrc, without using returned data at all:
    dataSrc: function (response) {
    var tr = JSON.parse(response.d);
    // return tr.data;
    var dataArray = [
    {
    Actions: "",
    Cover: "No",
    Created: "7/30/2021",
    Document: "Cook County New",
    Status: "Ready"
    }
    ];

                return {
                    draw: tr.draw,
                    data: dataArray,
                    recordsTotal: 2,
                    recordsFiltered: 2
                };
            }
    

    Debugger correctly shows tr.draw value (1, 2 etc). The output is shown in the picture. Obviously I am doing something wrong, but what can it be if am not even using the server-side data...

  • kthorngrenkthorngren Posts: 21,343Questions: 26Answers: 4,954

    Are you always returning draw: 2? This needs to match the draw parameter sent in the request. Its used as a sequence number to match the responses. See the Server Side Processing docs](https://datatables.net/manual/server-side) for details.

    Kevin

  • Mbs14Mbs14 Posts: 7Questions: 1Answers: 0

    Value of "draw" is always assigned to the value of incoming parameter "draw", and I see it changing from request to request. I can provide the output.
    My html declaration:

    <table id="tblFiles" class="table compact">
        <thead class="thead-light">
            <tr>
                <th>Document</th>
                <th>Created</th>
                <th>Status</th>
                <th>Cover</th>
                <th>Actions</th>
            </tr>
        </thead>
        <tbody>
        </tbody>
    </table>
    

    My new hastily constructed table initialization:

    $(document).ready(function () {
        showUserFolders();
    
        tblDocTemplate = $('#tblFiles').DataTable({
            processing: true,
            serverSide: true,
            deferRender: true,
            ajax: {
                url: '/Library.aspx/GetDocTemplates',
                type: 'POST',
                contentType: 'application/json; charset=utf-8',
                data: function (d) {
                    d.folderid = selectedFolder;
                    return JSON.stringify(d);
                }
    /*
                ,
                dataSrc: function (response) {
                    var tr = JSON.parse(response.d);
                    return tr.data;
                }
                */
                ,
                xhr: function () {
                    var xhr = $.ajaxSettings.xhr(); 
                    xhr.addEventListener('load', function (event) {
                        if (xhr.readyState === 4 && xhr.status === 200) {
                            var response = JSON.parse(xhr.responseText);
                            var dataOfD = JSON.parse(response.d); 
    
                            tblDocTemplate.clear().rows.add(dataOfD.data).draw();
                        }
                    });
                    return xhr;
                }
            }
            ,
            columns: [
                { data: 'Document' },
                { data: 'Created' },
                { data: 'Status' },
                { data: 'Cover' },
                { data: 'Actions' }
            ]
        });
    });
    

    I removed 'dataSrc' function and added xhr, but I am absolutely not sure that I am doing 'xhr' correctly. "dataOfD.data" exists and it is:

  • allanallan Posts: 63,534Questions: 1Answers: 10,475 Site admin
    Answer ✓

    ajax.dataSrc tells DataTables where to get the data array to display in the table - not the overall data object, which you need for server-side processing.

    Looking at the DataTables code, I don't think there is actually a way to do what you need at the moment (I've got a feature for DT2 to sort this out). What you need to do is provide ajax as a function and make the Ajax call - i.e. something like this:

    ajax: function (data, cb) {
      data.folderid = selectedFolder;
    
      $.ajax({
        url: '/Library.aspx/GetDocTemplates',
        type: 'POST',
        contentType: 'application/json; charset=utf-8',
        data: JSON.stringify(data),
        success: function (json) {
          var usefulJson = JSON.parse(json.d);
           cb(usefulJson);
        }
      });
    }
    

    I should perhaps just put in some automatic handling for .NET's d string "JSON"... Thankfully it is a lot less prevalent these days.

    Allan

  • Mbs14Mbs14 Posts: 7Questions: 1Answers: 0

    This version worked! These past two days were quite stressful for me, but they were completely alleviated by the incredible support I received from this forum. I want to extend my heartfelt thanks to kthorngren and allan!

    I guess this thread can be closed, I will continue to read the documentation - I need to do data adjustments, such as converting "Document" to URL and adding buttons in "Actions" column, but the mechanics of getting data from the backend to UI works. Thank you again!

  • allanallan Posts: 63,534Questions: 1Answers: 10,475 Site admin

    Glad to hear that helped :)

    Allan

  • nosnetromnosnetrom Posts: 2Questions: 0Answers: 0

    Mbs14's issue is similar to mine; I'm performing a POST request to an API, but my JSON response does not seem to include the necessary parameters for pagination.

    In Allan's last code sample, what would the cb() function be doing?

  • kthorngrenkthorngren Posts: 21,343Questions: 26Answers: 4,954

    @nosnetrom

    In Allan's last code sample, what would the cb() function be doing?

    The ajax docs have this description when using it as a function:

    When the data has been obtained from the data source, the second parameter (callback here) should be called with a single parameter passed in - the data to use to draw the table.

    Basically you need to prep the data have the Server Sid eProcessing Response parameters required.

    but my JSON response does not seem to include the necessary parameters for pagination.

    What is returned in the JSON that can be used to map to the Server Sid eProcessing Response parameters? You would map the data then send the upated resposne data to the cb() function for Datatables to populate the table.

    Does this make sense?

    Kevin

Sign In or Register to comment.