How to display an image using RowGroup?

40
September 13, 2021, at 4:10 PM

I'm using the RowGrouping add-on, all the rows are correctly grouped as shown below:

This is my implementation:

HTML

<html>
  <head>
<script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
    <link href="https://nightly.datatables.net/css/jquery.dataTables.css" rel="stylesheet" type="text/css" />
    <script src="https://nightly.datatables.net/js/jquery.dataTables.js"></script>
  <link href="https://cdn.datatables.net/rowgroup/1.1.2/css/rowGroup.dataTables.css" rel="stylesheet" type="text/css" />
<script src="https://cdn.datatables.net/rowgroup/1.1.2/js/dataTables.rowGroup.js"></script>
  
    <meta charset=utf-8 />
    <title>DataTables - JS Bin</title>
  </head>
 
    <body>
        <div class="container">
            <table id="example" class="display" width="100%">
                <thead>
                    <tr>
                        <th>Name</th>
                        <th>Position</th>
                        <th>Office</th>
                        <th>Extn</th>
                        <th>Start date</th>
                        <th>Salary</th>
                    </tr>
                </thead>
                <tfoot>
                    <tr>
                        <th>Name</th>
                        <th>Position</th>
                        <th>Office</th>
                        <th>Extn</th>
                        <th>Start date</th>
                        <th>Salary</th>
                    </tr>
                </tfoot>
            </table>
        </div>
    </body>
</html>

JS

$(document).ready(function() {
  var collapsedGroups = {};
  var table = $('#example').DataTable({
    ajax: "/ajax/objects.txt",
    order: [[ 2, "desc" ]],
    columns: [
      { "data": "name" },
      { "data": "position" },
      { "data": "office" },
      { "data": "extn" },
      { "data": "start_date" },
      { "data": "salary" }
    ],
    rowGroup: {
      dataSrc: 'office',
      startRender: function ( rows, group ) {
        var collapsed = !!collapsedGroups[group];
        rows.nodes().each(function (r) {
          r.style.display = collapsed ? 'none' : '';
        });
        return $('<tr/>')
          .append('<td colspan="8">' + group + ' (' + rows.count() + ')</td>')
          .attr('data-name', group)
          .toggleClass('collapsed', collapsed);
      },
    },
  });
  $('#example tbody tr.group-start').each(function() {
    var name = $(this).data('name');
      collapsedGroups[name] = !collapsedGroups[name];
  });
  table.draw(false);
  $('#example tbody').on('click', 'tr.group-start', function () {
    var name = $(this).data('name');
    collapsedGroups[name] = !collapsedGroups[name];
    table.draw(false);
  });  
});

This is the data structure of each object:

{
    extn: "5421",
    name: "Tiger Nixon",
    office: "Sidney",        
    position: "System Architect",
    salary: "$320,800",
    start_date: "2011/04/25",
    country: {
         id: "1",
         flag: "https://media.api-sports.io/flags/au.svg"
    }
}

I'm trying to display the flag of the country of each employee near the name of the city, but unfortunately I doesn't have access to the current row.

I tried to use rows.data().eq(0), but this actually return all the rows of the group.

Could someone give me an hand?

Answer 1

i made an experiment with this code, a bit tricky, I parse the rows.data() and search correct Object that contain the flag, then comparing with group parameter, if same then show it

  rowGroup: {
        dataSrc: 'office',
        startRender: function(rows, group) {
            let data = rows.data();
            let flag;
            Object.values(data).forEach(function(e, i) {
                if (typeof e == "object") {
                    if (e.hasOwnProperty("country") && e.hasOwnProperty('office')) {
                        if (e.office == group) {
                            flag = e.country.flag
                        }
                    }
                }
            });
            var collapsed = !!collapsedGroups[group];
            rows.nodes().each(function(r) {
                r.style.display = collapsed ? 'none' : '';
            });
            return $('<tr/>')
                .append('<td colspan="8">' + group + ' (' + rows.count() + ')  <img width="20" src=' + flag + ' /></td>')
                .attr('data-name', group)
                .toggleClass('collapsed', collapsed);
        },
    },
Answer 2

You can access the flag URL in your startRender function as follows:

rows.data().toArray()[0].country.flag

This works because the rows value is actually a Datatables API instance - and therefore contains the data you need.

In my case, I access the first row of data - and there is always guaranteed to be at least one such row - otherwise the group would not be created.

The rest of the solution uses some CSS using a flex grid for positioning and alignment.

Here is a demo:

var dataSet = [
    {
    extn: "5421",
    name: "Tiger Nixon",
    office: "Sydney",        
    position: "System Architect",
    salary: "$320,800",
    start_date: "2011/04/25",
    country: {
         id: "1",
         flag: "https://media.api-sports.io/flags/au.svg"
    }
}
  ];
$(document).ready(function() {
  var collapsedGroups = {};
  var table = $('#example').DataTable({
    //ajax: "ajax/objects.txt",
    data: dataSet,
    order: [[ 2, "desc" ]],
    columns: [
      { "data": "name" },
      { "data": "position" },
      { "data": "office" },
      { "data": "extn" },
      { "data": "start_date" },
      { "data": "salary" }
    ],
    rowGroup: {
      dataSrc: 'office',
      startRender: function ( rows, group ) {
        var flagUrl = rows.data().toArray()[0].country.flag;
        var collapsed = !!collapsedGroups[group];
        rows.nodes().each(function (r) {
          r.style.display = collapsed ? 'none' : '';
        });
        return $('<tr/>')
          .append('<td colspan="8" style="display: flex; align-items: center;"><span style="padding-right: 10px;">' + group + ' (' + rows.count() + ')</span><img src="' + flagUrl + '" width="40" height="50">' + '</td>')
          .attr('data-name', group)
          .toggleClass('collapsed', collapsed);
      },
    },
  });
  $('#example tbody tr.group-start').each(function() {
    var name = $(this).data('name');
      collapsedGroups[name] = !collapsedGroups[name];
  });
  table.draw(false);
  $('#example tbody').on('click', 'tr.group-start', function () {
    var name = $(this).data('name');
    collapsedGroups[name] = !collapsedGroups[name];
    table.draw(false);
  });  
});
<!doctype html>
<html>
  <head>
<script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
    <link href="https://nightly.datatables.net/css/jquery.dataTables.css" rel="stylesheet" type="text/css" />
    <script src="https://nightly.datatables.net/js/jquery.dataTables.js"></script>
  <link href="https://cdn.datatables.net/rowgroup/1.1.2/css/rowGroup.dataTables.css" rel="stylesheet" type="text/css" />
<script src="https://cdn.datatables.net/rowgroup/1.1.2/js/dataTables.rowGroup.js"></script>
  
    <meta charset=utf-8 />
    <title>DataTables - JS Bin</title>
  </head>
 
    <body>
        <div class="container">
            <table id="example" class="display" width="100%">
                <thead>
                    <tr>
                        <th>Name</th>
                        <th>Position</th>
                        <th>Office</th>
                        <th>Extn</th>
                        <th>Start date</th>
                        <th>Salary</th>
                    </tr>
                </thead>
                <tfoot>
                    <tr>
                        <th>Name</th>
                        <th>Position</th>
                        <th>Office</th>
                        <th>Extn</th>
                        <th>Start date</th>
                        <th>Salary</th>
                    </tr>
                </tfoot>
            </table>
        </div>

</body>
</html>

Here is a demo:

READ ALSO
Counter JS plugin by bfintal isn&#39;t working

Counter JS plugin by bfintal isn't working

In my practice project, the counter js plugin by bfintal isn't working at all, can anyone help me? https://githubcom/Farhatmahi/Gym

42
How to use case wen in db.session.query.filter_by()? Need to be optimized Python/Flask-SQLAlchemy

How to use case wen in db.session.query.filter_by()? Need to be optimized Python/Flask-SQLAlchemy

If TestDate >= '2021-01-01', filter type of Type_One items, if TestDate < '2021-01-01' query type of Type_Two items, I use below python and Flask-SQLAlchemy to realize it, but it's ugly, how to optimize below code?

28