1

i using Jquery Data Table for show my data.according this question Trying to show extra information in a responsive DataTable i want to show extra information within a Responsive DataTable.but there is a different with this question that my extra information must be called from ajax.i wrote this codes:

      let table = $('#data-table-order').DataTable({
      "responsive": {
        "details": {
          "renderer":async function (api, rowIdx, columns) {
            // Show hidden columns in row details
            var data = $.map(columns, function (col, i) {
              return col.hidden
                ? '<tr><td>' + col.title + ':</td> ' +
                '<td>' + col.data + '</td></tr>'
                : '';
            }).join('');
            await format(api.row(rowIdx).data(),'mobile').then(
                u=>
              {
                data += u;
                data = $('<table width="100%"/>').append( data ).prop('outerHTML');
                return data;
                
              });
              

         }
        }
      }
    });

my extra information are in format function:

    function format(d, type) {
      return new Promise((resolve, reject) => {
        let postData = "XXXXorderID=" + d[0] + "&type=" + type
    
        $.ajax({
          url: 'XXXX',
          type: 'POST',
          data: postData,
          success: function (response) {
              resolve(response);
            
          },
          error: function (data) {
           
            reject(new Error('Whoops'))
          }
        })
  });

Edit:u is a output of a procedure of sql that contains <tr><td>...</td></tr>. this procedure runs by my ajax code in format function.u is a string response of my Ajax.

but don't show any data in output. my output

EDIT2: i try add async to format function(d, type) {:

async function format(d, type) {.....

but it didn't work.

Mohadeseh
  • 360
  • 4
  • 19
  • 1
    Not an answer - just some observations: (1) What is `u`? If it's JSON, then you need to do something with `u` in `data += u` - otherwise you're just appending "Object" to your HTML string. You need to build a row of data containing whatever field you want from `u` - assuming `u` is JSON. – andrewJames Feb 02 '23 at 13:55
  • (2) I suspect (but I don't know for sure) your child row is empty because DataTables does not wait for the Ajax result - I am not sure you can just add `async` to the DataTables `renderer: async function() {...}` function and expect it to work. Test this by changing to a syncronous Ajax call - see what happens. – andrewJames Feb 02 '23 at 13:56
  • tnx @andrewJames for your attention.about `u` : actually `u` is a output of a procedure of sql that contains `...`. this procedure runs by my ajax code in format function.`u` is a string response. – Mohadeseh Feb 03 '23 at 09:01
  • about (2) actually i don't know. because i'm new in `async` and `await` in js. – Mohadeseh Feb 03 '23 at 09:06
  • Try my suggestion and see what happens. – andrewJames Feb 03 '23 at 12:29
  • you mean that `async function format(d, type)` ? when do this i got an error: `'await' expressions are only allowed within async functions and at the top levels of modules.` – Mohadeseh Feb 03 '23 at 15:52
  • Right. I am saying replace all of that with a non-async function. – andrewJames Feb 03 '23 at 15:57
  • It didn't work. – Mohadeseh Feb 03 '23 at 16:03
  • OK - but what does that mean? What code did you use? – andrewJames Feb 03 '23 at 16:19
  • please see `EDIT2` – Mohadeseh Feb 03 '23 at 16:26

1 Answers1

0

I think I did not explain myself clearly - so, my apologies for that. I wrote the following comment:

Test this by changing to a synchronous Ajax call - see what happens.

Here is one example of how you can do that - but I am not saying this is a good approach - I am only saying this is useful, as a test - and nothing more.

$(document).ready(function() {

  let table = $('#data-table-order').DataTable({
    "responsive": {
      "details": {
        "renderer": function(api, rowIdx, columns) {
          // Show hidden columns in row details
          var data = $.map(columns, function(col, i) {
            return col.hidden ?
              '<tr><td>' + col.title + ':</td> ' +
              '<td>' + col.data + '</td></tr>' :
              '';
          }).join('');
          var externalData = getExternalData(api.row(rowIdx).data(), 'mobile');
          data += '<tr><td>Extra Title:</td> ' +
            '<td>' + externalData.title + '</td></tr>';
          return $('<table width="100%"/>').append(data).prop('outerHTML');;
        }
      }
    }
  });

});

function getExternalData(d, type) {
  var externalData;
  $.ajax({
      url: 'https://jsonplaceholder.typicode.com/todos/' + d[0],
      type: 'GET',
      async: false
    })
    .done(function(data) {
      externalData = data;
    });
  return externalData;
}
<!doctype html>
<html>

<head>
  <meta charset="UTF-8">
  <title>Demo</title>
  <script src="https://code.jquery.com/jquery-3.5.1.js"></script>
  <script src="https://cdn.datatables.net/1.10.22/js/jquery.dataTables.js"></script>
  <link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.22/css/jquery.dataTables.css">
  <link rel="stylesheet" type="text/css" href="https://datatables.net/media/css/site-examples.css">

  <!-- responsive plug-in -->
  <link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/responsive/2.2.6/css/responsive.dataTables.css" />
  <script type="text/javascript" src="https://cdn.datatables.net/responsive/2.2.6/js/dataTables.responsive.js"></script>

  <style>
    table.dataTable thead tr th:first-of-type {
      width: 50%;
    }
  </style>

</head>

<body>

  <div style="margin: 20px;">

    <table id="data-table-order" class="display dataTable cell-border" style="width:100%">
      <thead>
        <tr>
          <th>ID</th>
          <th>Name</th>
          <th>Position</th>
          <th>Office</th>
          <th>Age</th>
          <th>Start date</th>
          <th>Salary</th>
        </tr>
      </thead>
      <tbody>
        <tr>
          <td>1</td>
          <td>Tiger Nixon</td>
          <td>System Architect</td>
          <td>Edinburgh</td>
          <td>61</td>
          <td>2011/04/25</td>
          <td>$320,800</td>
        </tr>
        <tr>
          <td>2</td>
          <td>Garrett Winters</td>
          <td>Accountant</td>
          <td>Tokyo</td>
          <td>63</td>
          <td>2011-07-25</td>
          <td>$170,750</td>
        </tr>
      </tbody>
    </table>

  </div>



</body>

</html>

Explanation

This demo uses a publicly available Ajax source https://jsonplaceholder.typicode.com for its test data.

Most importantly, it forces the Ajax call to be synchronous:

async: false

This is a crude approach and is not recommended in production code - but, like I say, this is only for testing.

If you run the demo, you will see that it adds new (externally sourced) data to each child record - which is what you are trying to do.

I have simplified things a bit because I do not have your data and I cannot format your data in the same way that you do here:

let postData = "XXXXorderID=" + d[0] + "&type=" + type

And also here:

data += u;

So, you will need to change my code, because of this.


The end result is this:

enter image description here


Once you have this test approach working, you can look at how you can try to enhance this for true asynchronous processing.

But, like I mentioned in the comments, I am not sure if/how this is possible - because you need to use a return statement to return your results from inside this function:

"renderer": function (api, rowIdx, columns) { ... }

There is a great walkthrough of different approaches here:

How do I return the response from an asynchronous call?

But, like I say, I am not sure if/how any of these can be adapted to the specific DataTables scenario you need.

andrewJames
  • 19,570
  • 8
  • 19
  • 51
  • thanks a lot. i think my problem is that my ajax mute be `Get`.because when i try to your code as `Post` isn't out put.but i try test with a sample get it's work for me. – Mohadeseh Feb 04 '23 at 15:29
  • The test URL I am using does not accept POST requests - only GET requests. But this is not relevant to your problem (trying to use an asynchronous function). You can use POST for your URL (if your URL accepts POSTs). – andrewJames Feb 04 '23 at 15:43
  • No , my mean that when i run my example as a post not work.but when i run a sample with get it's run.` its not work: let postData = "xxxxx" + d[0] + "&type=" + type $.ajax({ url: 'xxxxx', type: 'POST', data: postData, async: false,`... – Mohadeseh Feb 05 '23 at 05:47